From 82c6bdbac1fa4d5e408d5b79db15f36197e25b6b Mon Sep 17 00:00:00 2001 From: Bernie Hackett Date: Mon, 16 Apr 2018 16:58:17 -0700 Subject: [PATCH] PYTHON-1526 - Update SCRAM-SHA-256 for spec change --- pymongo/auth.py | 3 +-- test/test_auth.py | 53 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/pymongo/auth.py b/pymongo/auth.py index 6f2586adc..954f337b4 100644 --- a/pymongo/auth.py +++ b/pymongo/auth.py @@ -197,13 +197,12 @@ def _parse_scram_response(response): def _authenticate_scram(credentials, sock_info, mechanism): """Authenticate using SCRAM.""" + username = credentials.username if mechanism == 'SCRAM-SHA-256': digestmod = sha256 - username = saslprep(credentials.username) data = saslprep(credentials.password).encode("utf-8") else: digestmod = sha1 - username = credentials.username data = _password_digest(username, credentials.password).encode("utf-8") source = credentials.source diff --git a/test/test_auth.py b/test/test_auth.py index 53648df26..ab0cbb71a 100644 --- a/test/test_auth.py +++ b/test/test_auth.py @@ -30,7 +30,7 @@ from pymongo import MongoClient, monitoring from pymongo.auth import HAVE_KERBEROS, _build_credentials_tuple from pymongo.errors import OperationFailure from pymongo.read_preferences import ReadPreference -from pymongo.saslprep import saslprep, HAVE_STRINGPREP +from pymongo.saslprep import HAVE_STRINGPREP from test import client_context, SkipTest, unittest, Version from test.utils import (delay, ignore_deprecations, @@ -460,29 +460,64 @@ class TestSCRAM(unittest.TestCase): 'not-a-user', 'pwd') if HAVE_STRINGPREP: + # Test the use of SASLprep on passwords. For example, + # saslprep(u'\u2136') becomes u'IV' and saslprep(u'I\u00ADX') + # becomes u'IX'. SASLprep is only supported when the standard + # library provides stringprep. client_context.create_user( 'testscram', - saslprep(u'\u2168'), u'\u2168', + u'\u2163', + roles=['dbOwner'], + mechanisms=['SCRAM-SHA-256']) + + client_context.create_user( + 'testscram', + u'IX', + u'IX', roles=['dbOwner'], mechanisms=['SCRAM-SHA-256']) self.assertTrue( - client.testscram.authenticate(u'\u2168', u'\u2168')) + client.testscram.authenticate(u'\u2168', u'\u2163')) client.testscram.command('dbstats') client.testscram.logout() self.assertTrue( client.testscram.authenticate( - u'\u2168', u'\u2168', mechanism='SCRAM-SHA-256')) + u'\u2168', u'\u2163', mechanism='SCRAM-SHA-256')) + client.testscram.command('dbstats') + client.testscram.logout() + self.assertTrue( + client.testscram.authenticate(u'\u2168', u'IV')) + client.testscram.command('dbstats') + client.testscram.logout() + + self.assertTrue( + client.testscram.authenticate(u'IX', u'I\u00ADX')) + client.testscram.command('dbstats') + client.testscram.logout() + self.assertTrue( + client.testscram.authenticate( + u'IX', u'I\u00ADX', mechanism='SCRAM-SHA-256')) + client.testscram.command('dbstats') + client.testscram.logout() + self.assertTrue( + client.testscram.authenticate(u'IX', u'IX')) client.testscram.command('dbstats') client.testscram.logout() - self.assertRaises( - OperationFailure, - client.testscram.authenticate, - u'\u2168', u'\u2168', mechanism='SCRAM-SHA-1') client = rs_or_single_client_noauth( - u'mongodb://\u2168:\u2168@%s:%d/testscram' % (host, port)) + u'mongodb://\u2168:\u2163@%s:%d/testscram' % (host, port)) + client.testscram.command('dbstats') + client = rs_or_single_client_noauth( + u'mongodb://\u2168:IV@%s:%d/testscram' % (host, port)) + client.testscram.command('dbstats') + + client = rs_or_single_client_noauth( + u'mongodb://IX:I\u00ADX@%s:%d/testscram' % (host, port)) + client.testscram.command('dbstats') + client = rs_or_single_client_noauth( + u'mongodb://IX:IX@%s:%d/testscram' % (host, port)) client.testscram.command('dbstats') self.listener.results.clear()