{ "info": { "author": "pohmelie", "author_email": "multisosnooley@gmail.com", "bugtrack_url": null, "classifiers": [ "Programming Language :: Python", "Programming Language :: Python :: 3" ], "description": "# siosocks\n![Travis status for master branch](https://travis-ci.com/pohmelie/siosocks.svg?branch=master)\n![Codecov coverage for master branch](https://codecov.io/gh/pohmelie/siosocks/branch/master/graph/badge.svg)\n![Pypi version](https://img.shields.io/pypi/v/siosocks.svg)\n![Pypi downloads count](https://img.shields.io/pypi/dm/siosocks)\n\n[Sans-io](https://sans-io.readthedocs.io/) socks 4/5 client/server library/framework.\n\n# Reasons\n* No one-shot socks servers\n* Sans-io\n* asyncio-ready [`twunnel3`](https://github.com/jvansteirteghem/twunnel3) is dead\n* [`aiosocks`](https://github.com/nibrag/aiosocks) do not mimic `asyncio.open_connection` arguments (maybe dead too)\n* Fun\n\n# Features\n* Only tcp connect (no bind, no udp)\n* Both client and server\n* Socks versions: 4, 4a, 5\n* Socks5 auth: no auth, username/password\n* Couple io backends: asyncio, trio, socketserver\n* One-shot socks server (`python -m siosocks`)\n\n# License\n`siosocks` is offered under MIT license.\n\n# Requirements\n* python 3.6+\n\n# IO implementation matrix\n\nFramework | Client | Server\n--- | :---: | :---:\nasyncio | + | +\ntrio | + | +\nsocket | | +\n\nFeel free to make it bigger :wink:\n\n# Usage\nEnd user implementations mimic \u00abparent\u00bb library api.\n## Client\n* asyncio: [`open_connection`](https://docs.python.org/3/library/asyncio-stream.html#asyncio.open_connection)\n* trio: [`open_tcp_stream`](https://trio.readthedocs.io/en/stable/reference-io.html#trio.open_tcp_stream)\n\nExtra keyword-only arguments:\n* `socks_host`: string\n* `socks_port`: integer\n* `socks_version`: integer (4 or 5)\n* `username`: optional string (default: `None`)\n* `password`: optional string (default: `None`)\n* `encoding`: optional string (default: `\"utf-8\"`)\n* `socks4_extras`: optional dictionary\n* `socks5_extras`: optional dictionary\n\nExtras:\n* socks4\n * `user_id`: string (default: `\"\"`)\n* socks5\n * None at this moment, added for uniform api\n## Server\nEnd user implementations mimic \u00abparent\u00bb library server request handlers.\n* asyncio: [`start_server`](https://docs.python.org/3/library/asyncio-stream.html#asyncio.start_server)\n* trio: [`serve_tcp`](https://trio.readthedocs.io/en/stable/reference-io.html#trio.serve_tcp)\n* socketserver: [`ThreadingTCPServer`](https://docs.python.org/3/library/socketserver.html#socketserver.ThreadingTCPServer)\n\nYou should use [`partial`](https://docs.python.org/3/library/functools.html#functools.partial) to bind socks specific arguments:\n* `allowed_versions`: set of integers (default: `{4, 5}`)\n* `username`: optional string (default: `None`)\n* `password`: optional string (default: `None`)\n* `strict_security_policy`: boolean, if `True` exception will be raised if authentication required and 4 is in allowed versions set (default: `True`)\n* `encoding`: optional string (default: `\"utf-8\"`)\n\nNothing to say more. Typical usage can be found at [`__main__.py`](https://github.com/pohmelie/siosocks/blob/master/siosocks/__main__.py)\n\n# Examples\n## High-level\nThis section will use `asyncio` as backend, since it is main target/reason for `siosocks`\n### Client\n``` python\nimport asyncio\n\nfrom siosocks.io.asyncio import open_connection\n\n\nHOST = \"api.ipify.org\"\nREQ = \"\"\"GET /?format=json HTTP/1.1\nHost: api.ipify.org\nUser-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\nAccept-Language: en,en-US;q=0.7,ru;q=0.3\nAccept-Encoding: gzip, deflate\nDNT: 1\nConnection: keep-alive\nUpgrade-Insecure-Requests: 1\nCache-Control: max-age=0\n\n\"\"\"\n\n\nasync def main():\n # assume we have tor started\n r, w = await open_connection(HOST, 80, socks_host=\"localhost\", socks_port=9050, socks_version=5)\n w.write(REQ.replace(\"\\n\", \"\\r\\n\").encode())\n await w.drain()\n print(await r.read(8192))\n w.close()\n\n\nloop = asyncio.get_event_loop()\nloop.run_until_complete(main())\n```\n### Server\n``` python\nimport socket\nimport asyncio\nimport contextlib\n\nfrom siosocks.io.asyncio import socks_server_handler\n\n\nloop = asyncio.get_event_loop()\nserver = loop.run_until_complete(asyncio.start_server(socks_server_handler, port=1080))\naddresses = []\nfor sock in server.sockets:\n if sock.family in (socket.AF_INET, socket.AF_INET6):\n host, port, *_ = sock.getsockname()\n addresses.append(f\"{host}:{port}\")\nprint(f\"Socks4/5 proxy serving on {', '.join(addresses)}\")\nwith contextlib.suppress(KeyboardInterrupt):\n loop.run_forever()\n```\nBut if you just want one-shot socks server then try:\n``` bash\npython -m siosocks\n```\nThis will start socks 4, 5 server on all interfaces on 1080 port. For more information try `--help`\n``` bash\npython -m siosocks --help\nusage: siosocks [-h] [--backend {asyncio,socketserver,trio}] [--host HOST]\n [--port PORT] [--family {ipv4,ipv6,auto}] [--socks SOCKS]\n [--username USERNAME] [--password PASSWORD]\n [--encoding ENCODING] [--no-strict] [-v]\n\nSocks proxy server\n\noptional arguments:\n -h, --help show this help message and exit\n --backend {asyncio,socketserver,trio}\n Socks server backend [default: asyncio]\n --host HOST Socks server host [default: None]\n --port PORT Socks server port [default: 1080]\n --family {ipv4,ipv6,auto}\n Socket family [default: auto]\n --socks SOCKS Socks protocol version [default: []]\n --username USERNAME Socks auth username [default: None]\n --password PASSWORD Socks auth password [default: None]\n --encoding ENCODING String encoding [default: utf-8]\n --no-strict Allow multiversion socks server, when socks5 used with\n username/password auth [default: False]\n -v, --version Show siosocks version\n```\n## Low-level\nShadowsocks-like [client/server](https://github.com/pohmelie/siosocks/blob/master/examples/shadowsocks-like.py). Shadowsocks-like built on top of socks5 and encryption. It have \u00abclient\u00bb, which is actually socks server and \u00abserver\u00bb. So, precisely there are two servers: client side and server side. Purpose of shadowsocks is to encrypt data between \u00abincoming\u00bb and \u00aboutgoing\u00bb servers. In common this looks like:\n```\nclient (non-encrypted socks) \u00abincoming\u00bb socks server (encrypted socks) \u00aboutgoing\u00bb socks server (non-socks connection) target server\n```\nExample above use Caesar cipher for simplicity (and security of course).\n\n# Roadmap/contibutions\n* [ ] add more backends (average)\n* [ ] speed up `passthrough` implementation (seems hard)\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/pohmelie/siosocks", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "siosocks", "package_url": "https://pypi.org/project/siosocks/", "platform": "", "project_url": "https://pypi.org/project/siosocks/", "project_urls": { "Homepage": "https://github.com/pohmelie/siosocks" }, "release_url": "https://pypi.org/project/siosocks/0.1.0/", "requires_dist": [ "pytest ; extra == 'tests'", "pytest-cov ; extra == 'tests'", "pytest-asyncio ; extra == 'tests'", "trio ; extra == 'tests'", "pytest-trio ; extra == 'tests'", "trio ; extra == 'trio'" ], "requires_python": ">= 3.6", "summary": "sans-io socks proxy client/server with couple io backends", "version": "0.1.0" }, "last_serial": 5866256, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "86cb165e35b4e0f3db279a2de81a789b", "sha256": "89d66053dfc922a511171e48183e25fa4714a4bcab1aea0e3426395b0c5bc341" }, "downloads": -1, "filename": "siosocks-0.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "86cb165e35b4e0f3db279a2de81a789b", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">= 3.6", "size": 7330, "upload_time": "2019-08-02T14:56:13", "url": "https://files.pythonhosted.org/packages/13/d7/546bc1cb218787b17086296051ffb7048610dd55fe90120a5304ef00a4a0/siosocks-0.0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "d6fbb08d058aa3f382f0fed6fd83ee40", "sha256": "7eab25d3dfb89e3fc76b7f0591ed7c9366e55af26e227b9c11a4a69e771c3fa4" }, "downloads": -1, "filename": "siosocks-0.0.1.tar.gz", "has_sig": false, "md5_digest": "d6fbb08d058aa3f382f0fed6fd83ee40", "packagetype": "sdist", "python_version": "source", "requires_python": ">= 3.6", "size": 5768, "upload_time": "2019-08-02T14:56:15", "url": "https://files.pythonhosted.org/packages/66/a2/58cf0907f6920c1c45156148bc3d334743a8a073c52fb207d4150b72359c/siosocks-0.0.1.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "aadb2ea45e816b1627b82c558931f230", "sha256": "6a067fe5b7fabb5a3c7e74cb80775da78cbd5f4e879c75a4c3b301709f306605" }, "downloads": -1, "filename": "siosocks-0.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "aadb2ea45e816b1627b82c558931f230", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">= 3.6", "size": 13552, "upload_time": "2019-08-02T15:09:26", "url": "https://files.pythonhosted.org/packages/4e/b8/6c936c3f084c1152e0b718dc67743f6be49ac2b05b08f3a03c81b0952724/siosocks-0.0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1d28480c54418ad47a739212d40a3194", "sha256": "51d307cb12f5845872b3732ece7c7bc172b534de3c93504ae475c5eb163eb483" }, "downloads": -1, "filename": "siosocks-0.0.2.tar.gz", "has_sig": false, "md5_digest": "1d28480c54418ad47a739212d40a3194", "packagetype": "sdist", "python_version": "source", "requires_python": ">= 3.6", "size": 34581, "upload_time": "2019-08-02T15:09:29", "url": "https://files.pythonhosted.org/packages/84/05/d41ba32839e2499a0fb35fa464a314ca91f234ad6195550c2a297c99d02c/siosocks-0.0.2.tar.gz" } ], "0.1.0": [ { "comment_text": "", "digests": { "md5": "d7a2e05812825977e2df3442eeb757d4", "sha256": "344dd80ac5bd139a4b401589dd7158a22e06472c429f482b2d2fc6733cff219e" }, "downloads": -1, "filename": "siosocks-0.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "d7a2e05812825977e2df3442eeb757d4", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">= 3.6", "size": 13830, "upload_time": "2019-09-21T14:57:45", "url": "https://files.pythonhosted.org/packages/2f/15/346e0efe94011cb920e6d2b234e76c6f167b3c3a9d6546940006ad6f6b14/siosocks-0.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "58989068597853af361cb8f72755b02a", "sha256": "fec516338e16a036b415a4e0468742d5648fa2c87b3b9802f3c04803d397bbda" }, "downloads": -1, "filename": "siosocks-0.1.0.tar.gz", "has_sig": false, "md5_digest": "58989068597853af361cb8f72755b02a", "packagetype": "sdist", "python_version": "source", "requires_python": ">= 3.6", "size": 45595, "upload_time": "2019-09-21T14:57:47", "url": "https://files.pythonhosted.org/packages/62/50/d9783d11f39b072b60cc935ee13a52da1650faa9e26940ee5168ad49d281/siosocks-0.1.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "d7a2e05812825977e2df3442eeb757d4", "sha256": "344dd80ac5bd139a4b401589dd7158a22e06472c429f482b2d2fc6733cff219e" }, "downloads": -1, "filename": "siosocks-0.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "d7a2e05812825977e2df3442eeb757d4", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">= 3.6", "size": 13830, "upload_time": "2019-09-21T14:57:45", "url": "https://files.pythonhosted.org/packages/2f/15/346e0efe94011cb920e6d2b234e76c6f167b3c3a9d6546940006ad6f6b14/siosocks-0.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "58989068597853af361cb8f72755b02a", "sha256": "fec516338e16a036b415a4e0468742d5648fa2c87b3b9802f3c04803d397bbda" }, "downloads": -1, "filename": "siosocks-0.1.0.tar.gz", "has_sig": false, "md5_digest": "58989068597853af361cb8f72755b02a", "packagetype": "sdist", "python_version": "source", "requires_python": ">= 3.6", "size": 45595, "upload_time": "2019-09-21T14:57:47", "url": "https://files.pythonhosted.org/packages/62/50/d9783d11f39b072b60cc935ee13a52da1650faa9e26940ee5168ad49d281/siosocks-0.1.0.tar.gz" } ] }