{ "info": { "author": "Ian Good", "author_email": "icgood@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "Intended Audience :: Information Technology", "License :: OSI Approved :: MIT License", "Programming Language :: Python", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8" ], "description": "pysasl\n======\n\nPure Python SASL client and server library. The design of the library is\nintended to be agnostic of the protocol or network library.\n\nThe library currently offers `PLAIN`, `LOGIN`, and `CRAM-MD5` mechanisms by\ndefault. The `EXTERNAL` and `XOAUTH2` mechanisms are also available for special\ncircumstances.\n\nThere are currently no plans to implement security layer negotiation support.\n\n[![Build Status](https://travis-ci.org/icgood/pysasl.svg)](https://travis-ci.org/icgood/pysasl)\n[![Coverage Status](https://coveralls.io/repos/icgood/pysasl/badge.svg?branch=master)](https://coveralls.io/r/icgood/pysasl?branch=master)\n[![PyPI](https://img.shields.io/pypi/v/pysasl.svg)](https://pypi.python.org/pypi/pysasl)\n[![PyPI](https://img.shields.io/pypi/pyversions/pysasl.svg)](https://pypi.python.org/pypi/pysasl)\n[![PyPI](https://img.shields.io/pypi/l/pysasl.svg)](https://pypi.python.org/pypi/pysasl)\n\n#### [API Documentation](https://icgood.github.io/pysasl/)\n\nInstallation\n============\n\nAvailable in [PyPi](https://pypi.python.org/):\n\n```\npip install pysasl\n```\n\n### Running Tests\n\nInstall into a virtual environment:\n\n```\npython3 -m venv .venv\nsource .venv/bin/activate\n\npip install -r test/requirements.txt\npip install -e .\n```\n\nRun the tests and report coverage metrics:\n\n```\npy.test --cov=pysasl\n```\n\nUsage\n=====\n\n## Server-side\n\nServer-side SASL has three basic requirements:\n\n* Must advertise supported mechanisms,\n* Must issue authentication challenges to the client and read responses,\n* Must determine if credentials are considered valid.\n\n#### Advertising Mechanisms\n\nImplementations may decide on any sub-set of mechanisms to advertise. Make this\nchoice when instantiating the [`SASLAuth`][1] object:\n\n```python\nfrom pysasl import SASLAuth\n\nauth1 = SASLAuth.defaults() # equivalent to...\nauth2 = SASLAuth.named([b'PLAIN', b'LOGIN'])\n```\n\nTo get the names of all available mechanisms:\n\n```python\nmechanisms = [mech.name for mech in auth1.server_mechanisms]\nmech = auth1.get(b'PLAIN')\n```\n\n#### Issuing Challenges\n\nOnce a mechanism has been chosen by the client, enter a loop of issuing\nchallenges to the client:\n\n```python\ndef server_side_authentication(sock, mech):\n challenges = []\n while True:\n try:\n creds, _ = mech.server_attempt(challenges)\n return creds\n except ServerChallenge as chal:\n sock.send(chal.data + b'\\r\\n')\n resp = sock.recv(1024).rstrip(b'\\r\\n')\n challenges.append(ChallengeResponse(chal.data, resp))\n```\n\nIt's worth noting that implementations are not quite that simple. Most will\nexpect all transmissions to base64-encoded, often with a prefix before the\nserver challenges such as `334` or `+`. See the appropriate RFC for your\nprotocol, such as [RFC 4954 for SMTP][3] or [RFC 3501 for IMAP][4].\n\n#### Checking Credentials\n\nOnce the challenge-response loop has been completed and we are left with the\na [`AuthenticationCredentials`][2] object, we can access information from the\nattempt:\n\n```python\nprint('Authenticated as:', result.authcid)\nprint('Authorization ID:', result.authzid)\nprint('Assumed identity:', result.identity)\n\n# To compare to a known password...\nassert result.check_secret('s3kr3t')\n# Or to compare hashes...\nassert password_hash == hash(result.secret)\n```\n\nSome mechanisms (e.g. `CRAM-MD5`, `EXTERNAL`) will not support direct access to\nthe secret. In this case, `result.has_secret` will be `False` and you should\nuse `result.check_secret()` instead.\n\n## Client-side\n\nThe goal of client-side authentication is to respond to server challenges until\nthe authentication attempt either succeeds or fails.\n\n#### Choosing a Mechanism\n\nThe first step is to pick a SASL mechanism. The protocol should allow the server\nto advertise to the client which mechanisms are available to it:\n\n```python\nfrom pysasl import SASLAuth\n\nauth = SASLAuth.named(advertised_mechanism_names)\nmech = auth.client_mechanisms[0]\n```\n\nAny mechanism name that is not recognized will be ignored.\n\n#### Issuing Responses\n\nOnce a mechanism is chosen, we enter of a loop of responding to server\nchallenges:\n\n```python\nfrom pysasl import AuthenticationCredentials\n\ndef client_side_authentication(sock, mech, username, password):\n creds = AuthenticationCredentials(username, password)\n challenges = []\n while True:\n resp = mech.client_attempt(creds, challenges)\n sock.send(resp + b'\\r\\n')\n data = sock.recv(1024).rstrip(b'\\r\\n')\n if data == 'SUCCESS':\n return True\n elif data == 'FAILURE':\n return False\n challenges.append(ServerChallenge(data))\n```\n\nAs you might expect, a real protocol probably won't return `SUCCESS` or\n`FAILURE`, that will depend entirely on the details of the protocol.\n\n## Supporting Initial Responses\n\nSome protocols (e.g. SMTP) support the client ability to send an initial\nresponse before the first server challenge, for mechanisms that support it.\nA perfectly valid authentication can then have no challenges at all:\n\n```\nAUTH PLAIN AHVzZXJuYW1lAHBhc3N3b3Jk\n235 2.7.0 Authentication successful\n```\n\nIn this case, both client-side and server-side authentication should be\nhandled a bit differently. For example for server-side:\n\n```python\nchallenges = []\nif initial_response:\n challenges.append(ChallengeResponse(b'', initial_response))\n```\n\nAnd for client-side, just call `resp = mech.client_attempt(creds, [])`\nto get the initial response before starting the transmission. All\nmechanisms should either return an initial response or an empty string\nwhen given an empty list for the second argument.\n\n[1]: https://icgood.github.io/pysasl/#pysasl.SASLAuth\n[2]: https://icgood.github.io/pysasl/#pysasl.AuthenticationCredentials\n[3]: https://tools.ietf.org/html/rfc4954\n[4]: https://tools.ietf.org/html/rfc3501#section-6.2.2\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/icgood/pysasl/", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "pysasl", "package_url": "https://pypi.org/project/pysasl/", "platform": "", "project_url": "https://pypi.org/project/pysasl/", "project_urls": { "Homepage": "https://github.com/icgood/pysasl/" }, "release_url": "https://pypi.org/project/pysasl/0.5.0/", "requires_dist": [ "passlib ; extra == 'passlib'" ], "requires_python": "~=3.6", "summary": "Pure Python SASL client and server library.", "version": "0.5.0" }, "last_serial": 5999875, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "ae10ae195844729d9f22826a048975ee", "sha256": "d6dc45e4481e60e27c975235dd4de5794cb93a53aad45f1e839fe256090e35e7" }, "downloads": -1, "filename": "pysasl-0.1.0-py2.6.egg", "has_sig": false, "md5_digest": "ae10ae195844729d9f22826a048975ee", "packagetype": "bdist_egg", "python_version": "2.6", "requires_python": null, "size": 12582, "upload_time": "2014-12-29T20:22:35", "url": "https://files.pythonhosted.org/packages/02/e4/74086acf7889ceb39981c7eea9e6b4a5db561c1ea12da3fe4a4f5d139bff/pysasl-0.1.0-py2.6.egg" }, { "comment_text": "", "digests": { "md5": "571872ea7a872d7d184cfb21eb726653", "sha256": "8d4bc94893d2929d04bb5f9b1da264691cad480c6d63b2b308db34d97f7a59ea" }, "downloads": -1, "filename": "pysasl-0.1.0-py2.7.egg", "has_sig": false, "md5_digest": "571872ea7a872d7d184cfb21eb726653", "packagetype": "bdist_egg", "python_version": "2.7", "requires_python": null, "size": 12563, "upload_time": "2014-12-29T20:21:31", "url": "https://files.pythonhosted.org/packages/26/9c/ab3d5bf30885f323b18d0167a4f231b9b95a782039b977fa1791427868ef/pysasl-0.1.0-py2.7.egg" }, { "comment_text": "", "digests": { "md5": "0c1ccd43938c5251e0751644fdabcd04", "sha256": "60e4feb764426a939696c4191077605a179769a3fa3175b6d82eaf4a2cf2f81c" }, "downloads": -1, "filename": "pysasl-0.1.0-py3.4.egg", "has_sig": false, "md5_digest": "0c1ccd43938c5251e0751644fdabcd04", "packagetype": "bdist_egg", "python_version": "3.4", "requires_python": null, "size": 12847, "upload_time": "2014-12-29T20:23:38", "url": "https://files.pythonhosted.org/packages/80/f6/6f2f100a53c569cdfa0e5c66f9a64c1abd65cc092f5e7eb3242f9ce823de/pysasl-0.1.0-py3.4.egg" }, { "comment_text": "", "digests": { "md5": "90e217d643ee0f420d6a4e360c789d27", "sha256": "0f60ba0a74958bb17c0abf4f74180c43f5000e923df54e967f41a50622b7be7d" }, "downloads": -1, "filename": "pysasl-0.1.0.tar.gz", "has_sig": false, "md5_digest": "90e217d643ee0f420d6a4e360c789d27", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5128, "upload_time": "2014-12-29T20:21:28", "url": "https://files.pythonhosted.org/packages/03/44/b953a67e3013034f81e5fb66598f58ec6bad6cfb3af2ab0125b7d6cc683f/pysasl-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "446204429ce4e2141364bcd4a54d90ac", "sha256": "6ab9eb63d234b6d5febb3621d96df348853b05cc88ba154638755b6cb3e812c0" }, "downloads": -1, "filename": "pysasl-0.1.1.tar.gz", "has_sig": false, "md5_digest": "446204429ce4e2141364bcd4a54d90ac", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5164, "upload_time": "2015-04-18T19:26:47", "url": "https://files.pythonhosted.org/packages/41/c9/c65bf536fbff114ae312b2ee6d6f21b0322d49d1a9ccf4557415fe681ea2/pysasl-0.1.1.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "12fda5dc256928a20e8bf577e07f2133", "sha256": "bc81f43fbf786a0c66dc8e0f65c1fa01b8887d15d25fa31f648e281cbe9d444b" }, "downloads": -1, "filename": "pysasl-0.2.0.tar.gz", "has_sig": false, "md5_digest": "12fda5dc256928a20e8bf577e07f2133", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6571, "upload_time": "2015-09-29T02:32:06", "url": "https://files.pythonhosted.org/packages/4c/80/518ff932224d93df680f8d77c4fcacffb14c1dad8e4d9267d8de205de78f/pysasl-0.2.0.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "1f53a816b69f658712b5ac7ae598131a", "sha256": "03dc6c1bb641bb6a913804890623e0d4254506af688c3d4cfc9db4fc74f46eff" }, "downloads": -1, "filename": "pysasl-0.2.1-py2-none-any.whl", "has_sig": false, "md5_digest": "1f53a816b69f658712b5ac7ae598131a", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 11254, "upload_time": "2018-01-03T02:59:44", "url": "https://files.pythonhosted.org/packages/6b/89/3fb7b6827c3f77bb39cca20153f9c119eb666a25334a6d84e0ca9665b4c2/pysasl-0.2.1-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b1a6f929d64d1e9bb352df54a774c5c4", "sha256": "474b01ecdf92e96fee315cd61d226eb0896d6ad49b42d5352bea8f06bac24ce9" }, "downloads": -1, "filename": "pysasl-0.2.1.tar.gz", "has_sig": false, "md5_digest": "b1a6f929d64d1e9bb352df54a774c5c4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6766, "upload_time": "2018-01-03T02:59:42", "url": "https://files.pythonhosted.org/packages/3b/9c/c61447611c27e8ad283a8944ddadaa7a05b198b271f098cdbaaa9055ec62/pysasl-0.2.1.tar.gz" } ], "0.2.3": [ { "comment_text": "", "digests": { "md5": "2f8725a58d98970c00aad8e4eb263660", "sha256": "061069d1c2899218a3327da796ceecbe4135f5896125cda7a3ebc03ebd6fe7b4" }, "downloads": -1, "filename": "pysasl-0.2.3-py3-none-any.whl", "has_sig": false, "md5_digest": "2f8725a58d98970c00aad8e4eb263660", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 13652, "upload_time": "2018-10-14T00:14:02", "url": "https://files.pythonhosted.org/packages/8a/6b/cab5956e1bb680a4c9fbc23ae9319dfd7077294137acf00f5c98ebdf8939/pysasl-0.2.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "10594ca79821e0378cb74c8f17bcb462", "sha256": "f14880f78d7f529492dea6ac94b3c8cbb9ff7cc68cd7ca6215dfb272cff6563c" }, "downloads": -1, "filename": "pysasl-0.2.3.tar.gz", "has_sig": false, "md5_digest": "10594ca79821e0378cb74c8f17bcb462", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11881, "upload_time": "2018-10-14T00:14:03", "url": "https://files.pythonhosted.org/packages/09/d7/2c7ea98268eb9af052f4b2f401e17ead2d0d4a4fc86b01d520c8d87ac708/pysasl-0.2.3.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "287dece93b78d6e89f976c66440c7ac0", "sha256": "7e847522d0bd09cc893167083ebcd7b1aaca74b88385c87996938c5c904e3c37" }, "downloads": -1, "filename": "pysasl-0.3.0-py3-none-any.whl", "has_sig": false, "md5_digest": "287dece93b78d6e89f976c66440c7ac0", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12223, "upload_time": "2018-10-17T23:14:55", "url": "https://files.pythonhosted.org/packages/a6/bd/f2b69f2b0b2d8f0c8e40147b57b567f785eb41f38d0fda7db7554662611b/pysasl-0.3.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "7b4d0831855c8c3527c2dfb45787044e", "sha256": "c9d3cb1e92d6d4131057199e947b3e1dd2e7b5839b2cb0b691e6349fa9817eae" }, "downloads": -1, "filename": "pysasl-0.3.0.tar.gz", "has_sig": false, "md5_digest": "7b4d0831855c8c3527c2dfb45787044e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12531, "upload_time": "2018-10-17T23:14:56", "url": "https://files.pythonhosted.org/packages/8f/ad/92bcd8da271fc1a19b3a13fc5e6f1063109e6e1232c3391bbd9ae02d3ab0/pysasl-0.3.0.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "96074044e7221bcc7c8fb9bfe3f2353b", "sha256": "a558b5c1f5fc7eee306f862f21ac464fcd7fe8d1bb46bc6971f98648742e6058" }, "downloads": -1, "filename": "pysasl-0.3.1-py3-none-any.whl", "has_sig": false, "md5_digest": "96074044e7221bcc7c8fb9bfe3f2353b", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12458, "upload_time": "2019-01-18T23:56:31", "url": "https://files.pythonhosted.org/packages/32/b5/4a4a7ce44d9fc71405a2bcad104a73ec8ec1461c7d190968e8cf1a47eaea/pysasl-0.3.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ebdd74957f809bc3529c0b04188aedc6", "sha256": "5382472d8aebe01b3ee94d6f6d762dc79f3abc6470961a57452ea58975a8c56f" }, "downloads": -1, "filename": "pysasl-0.3.1.tar.gz", "has_sig": false, "md5_digest": "ebdd74957f809bc3529c0b04188aedc6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12749, "upload_time": "2019-01-18T23:56:32", "url": "https://files.pythonhosted.org/packages/92/14/5bc91b5436451da8bf5e8f6e19d5501fd5ba775e12240c79a9f57f7c243d/pysasl-0.3.1.tar.gz" } ], "0.4.0": [ { "comment_text": "", "digests": { "md5": "8e6a3d627d9d6a66b4c697cc8bf15133", "sha256": "1fef84464bb0cd09ec1758a6f8f052e005a14ed29680a9f1b0f4f3421a0af057" }, "downloads": -1, "filename": "pysasl-0.4.0-py3-none-any.whl", "has_sig": false, "md5_digest": "8e6a3d627d9d6a66b4c697cc8bf15133", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "size": 12831, "upload_time": "2019-01-31T01:55:13", "url": "https://files.pythonhosted.org/packages/bd/20/77282819922da5f860a3f03f13b4f813db14e1af86372c7204acd6b322c2/pysasl-0.4.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b035fff151a81ab0aae1f1619394990e", "sha256": "b326abd38a4678ed1f66e2b796ebe335af6affaaece7876fb70b36dca9574a62" }, "downloads": -1, "filename": "pysasl-0.4.0.tar.gz", "has_sig": false, "md5_digest": "b035fff151a81ab0aae1f1619394990e", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "size": 13290, "upload_time": "2019-01-31T01:55:14", "url": "https://files.pythonhosted.org/packages/bb/1f/294067bbfee761d6efbdd2bb6b37f1a41eb46954bf235fa4c89a11f9d7a5/pysasl-0.4.0.tar.gz" } ], "0.4.1": [ { "comment_text": "", "digests": { "md5": "88fc8655a1ce25be007062f30d39652c", "sha256": "337e8a2f9659a8072562938490a27da59d2fde016795cc4cb5eeed0d95f17be2" }, "downloads": -1, "filename": "pysasl-0.4.1-py3-none-any.whl", "has_sig": false, "md5_digest": "88fc8655a1ce25be007062f30d39652c", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "size": 12959, "upload_time": "2019-02-08T01:20:10", "url": "https://files.pythonhosted.org/packages/0a/f1/8443bc893c5f6f3e00a95bdbf74cd42eaca9c5ed93c66d7736104666791b/pysasl-0.4.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b5174641a3410f3ba04178f8c97223dd", "sha256": "4187f7cafc3daab62b60be8badde9c9d5eebbac9f57808a899e29ab335a7a700" }, "downloads": -1, "filename": "pysasl-0.4.1.tar.gz", "has_sig": false, "md5_digest": "b5174641a3410f3ba04178f8c97223dd", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "size": 13593, "upload_time": "2019-02-08T01:20:12", "url": "https://files.pythonhosted.org/packages/46/b7/172765ba909f8ff1097db3477a3ad5f36e5dfb109166615711fddc2eb1ff/pysasl-0.4.1.tar.gz" } ], "0.5.0": [ { "comment_text": "", "digests": { "md5": "2ccfcddcd6658e9677e230a916955212", "sha256": "ee39eff6a8e916acbb4e3d10e2294d5c6ce15905acca20069359366efa684691" }, "downloads": -1, "filename": "pysasl-0.5.0-py3-none-any.whl", "has_sig": false, "md5_digest": "2ccfcddcd6658e9677e230a916955212", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": "~=3.6", "size": 12208, "upload_time": "2019-10-19T13:51:47", "url": "https://files.pythonhosted.org/packages/ab/cb/f9e494efdb6d798fcc1abc17c770b6119119072c44789381702ffe5ecad3/pysasl-0.5.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "15907fe18f07465fa0adcb5377707e9c", "sha256": "b9a426cf82b5721ae93988e5937aa4736ab3440f629336e61c3c0e4f9bc2c383" }, "downloads": -1, "filename": "pysasl-0.5.0.tar.gz", "has_sig": false, "md5_digest": "15907fe18f07465fa0adcb5377707e9c", "packagetype": "sdist", "python_version": "source", "requires_python": "~=3.6", "size": 13621, "upload_time": "2019-10-19T13:51:48", "url": "https://files.pythonhosted.org/packages/fd/5d/b502334d5c80fc37963ca2231785d64d12373b086291cad1ddf6fc3bbbda/pysasl-0.5.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "2ccfcddcd6658e9677e230a916955212", "sha256": "ee39eff6a8e916acbb4e3d10e2294d5c6ce15905acca20069359366efa684691" }, "downloads": -1, "filename": "pysasl-0.5.0-py3-none-any.whl", "has_sig": false, "md5_digest": "2ccfcddcd6658e9677e230a916955212", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": "~=3.6", "size": 12208, "upload_time": "2019-10-19T13:51:47", "url": "https://files.pythonhosted.org/packages/ab/cb/f9e494efdb6d798fcc1abc17c770b6119119072c44789381702ffe5ecad3/pysasl-0.5.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "15907fe18f07465fa0adcb5377707e9c", "sha256": "b9a426cf82b5721ae93988e5937aa4736ab3440f629336e61c3c0e4f9bc2c383" }, "downloads": -1, "filename": "pysasl-0.5.0.tar.gz", "has_sig": false, "md5_digest": "15907fe18f07465fa0adcb5377707e9c", "packagetype": "sdist", "python_version": "source", "requires_python": "~=3.6", "size": 13621, "upload_time": "2019-10-19T13:51:48", "url": "https://files.pythonhosted.org/packages/fd/5d/b502334d5c80fc37963ca2231785d64d12373b086291cad1ddf6fc3bbbda/pysasl-0.5.0.tar.gz" } ] }