Ticket #5066: 5066_patch_2.diff

File 5066_patch_2.diff, 5.0 KB (added by Sergey, 9 years ago)

The second try

  • twisted/words/protocols/jabber/sasl_mechanisms.py

     
    8585    name = 'DIGEST-MD5'
    8686
    8787    def __init__(self, serv_type, host, serv_name, username, password):
     88        """
     89        @type serv_type: C{unicode}
     90
     91        @type host: C{unicode}
     92
     93        @type serv_name: C{unicode}
     94       
     95        @type username: C{unicode}
     96
     97        @type password: C{unicode}
     98        """
    8899        self.username = username
    89100        self.password = password
    90101        self.defaultRealm = host
    91102
    92         self.digest_uri = '%s/%s' % (serv_type, host)
     103        self.digest_uri = u'%s/%s' % (serv_type, host)
    93104        if serv_name is not None:
    94             self.digest_uri += '/%s' % serv_name
     105            self.digest_uri += u'/%s' % serv_name
    95106
    96107
    97108    def getInitialResponse(self):
     
    200211            return binascii.b2a_hex(n)
    201212
    202213        def KD(k, s):
    203             return H('%s:%s' % (k, s))
     214            return H(u'%s:%s' % (k, s))
    204215
    205216        try:
    206217            username = self.username.encode(charset)
    207218            password = self.password.encode(charset)
     219            realm = realm.encode(charset)
     220            digest_uri = self.digest_uri.encode(charset)
    208221        except UnicodeError:
    209222            # TODO - add error checking
    210223            raise
     
    217230        a1 = "%s:%s:%s" % (H("%s:%s:%s" % (username, realm, password)),
    218231                           nonce,
    219232                           cnonce)
    220         a2 = "AUTHENTICATE:%s" % self.digest_uri
     233        a2 = "AUTHENTICATE:%s" % digest_uri
    221234
    222235        response = HEX( KD ( HEX(H(a1)),
    223                              "%s:%s:%s:%s:%s" % (nonce, nc,
    224                                                  cnonce, "auth", HEX(H(a2)))))
     236                            "%s:%s:%s:%s:%s" % (nonce, nc,
     237                                                cnonce, "auth", HEX(H(a2)))))
    225238
    226239        directives = {'username': username,
    227240                      'realm' : realm,
     
    229242                      'cnonce' : cnonce,
    230243                      'nc' : nc,
    231244                      'qop' : qop,
    232                       'digest-uri': self.digest_uri,
     245                      'digest-uri': digest_uri,
    233246                      'response': response,
    234247                      'charset': charset}
    235248
     
    237250
    238251
    239252    def _gen_nonce(self):
    240         return md5("%s:%s:%s" % (str(random.random()) , str(time.gmtime()),str(os.getpid()))).hexdigest()
     253        return md5("%s:%s:%s" % (random.random(),
     254                                 time.gmtime(),
     255                                 os.getpid())).hexdigest()
  • twisted/words/test/test_jabbersaslmechanisms.py

     
    44"""
    55Tests for L{twisted.words.protocols.jabber.sasl_mechanisms}.
    66"""
     7import binascii
    78
    89from twisted.trial import unittest
    910
    1011from twisted.words.protocols.jabber import sasl_mechanisms
     12from twisted.python.hashlib import md5
    1113
    1214class PlainTest(unittest.TestCase):
    1315    def test_getInitialResponse(self):
     
    4446        """
    4547        self.assertIdentical(self.mechanism.getInitialResponse(), None)
    4648
     49    def test_getResponseUnicode(self):
     50        def H(s):
     51            return md5(s).digest()
     52
     53        def HEX(n):
     54            return binascii.b2a_hex(n)
     55
     56        def KD(k, s):
     57            return H(u'%s:%s' % (k, s))
     58
     59        domain = u'\u0418example.org'
     60        password = u'\u0418secret'
     61        username = u'test\u0418'
     62        for encoding in ('utf-8', 'cp1251'):
     63            self.mechanism = sasl_mechanisms.DigestMD5(u'xmpp', domain, None,
     64                                                       username, password)
     65            challenge = 'nonce="1234",qop="auth",charset=%s,algorithm=md5-sess' % (
     66                encoding
     67            )
     68            directives = self.mechanism._parse(self.mechanism.getResponse(challenge))
     69            self.assertEqual(directives['realm'], domain.encode(encoding))
     70            self.assertEqual(directives['username'], username.encode(encoding))
     71            a1 = "%s:%s:%s" % (H(("%s:%s:%s" % (username, domain, password)).encode(encoding)),
     72                               1234,
     73                               directives['cnonce'])
     74            a2 = "AUTHENTICATE:xmpp/%s" % domain
     75            a2 = a2.encode(encoding)
     76            nc = '%08x' % 1 # TODO: support subsequent auth.
     77            response = HEX( KD ( HEX(H(a1)),
     78                                "%s:%s:%s:%s:%s" % (1234, nc,
     79                                                    directives['cnonce'],
     80                                                    "auth", HEX(H(a2)))))
     81            self.assertEqual(directives['response'], response)
     82
    4783    def test_getResponse(self):
    4884        """
    4985        Partially test challenge response.