Ticket #5808: cred-open-5808-2.patch

File cred-open-5808-2.patch, 11.3 KB (added by thijs, 4 years ago)
  • twisted/cred/checkers.py

     
    88
    99from twisted.internet import defer
    1010from twisted.python import failure, log
     11from twisted.python.filepath import FilePath
    1112from twisted.cred import error, credentials
    1213
    1314
     
    9798
    9899
    99100class FilePasswordDB:
    100     """A file-based, text-based username/password database.
     101    """
     102    A file-based, text-based username/password database.
    101103
    102104    Records in the datafile for this class are delimited by a particular
    103105    string.  The username appears in a fixed field of the columns delimited
     
    193195
    194196    def _loadCredentials(self):
    195197        try:
    196             f = file(self.filename)
     198            f = FilePath(self.filename).open()
    197199        except:
    198200            log.err()
    199201            raise error.UnauthorizedLogin()
  • twisted/test/test_newcred.py

     
    1212from twisted.trial import unittest
    1313from twisted.cred import portal, checkers, credentials, error
    1414from twisted.python import components
     15from twisted.python.filepath import FilePath
    1516from twisted.internet import defer
    16 from twisted.internet.defer import deferredGenerator as dG, waitForDeferred as wFD
     17from twisted.internet.defer import (deferredGenerator as dG,
     18    waitForDeferred as wFD)
    1719
    1820try:
    1921    from crypt import crypt
     
    170172        c = credentials.CramMD5Credentials()
    171173        self.failIf(c.checkPassword('secret'))
    172174
     175
     176
    173177class OnDiskDatabaseTestCase(unittest.TestCase):
    174178    users = [
    175179        ('user1', 'pass1'),
     
    177181        ('user3', 'pass3'),
    178182    ]
    179183
     184    def setUp(self):
     185        self.dbfile = FilePath(self.mktemp())
    180186
    181     def testUserLookup(self):
    182         dbfile = self.mktemp()
    183         db = checkers.FilePasswordDB(dbfile)
    184         f = file(dbfile, 'w')
    185         for (u, p) in self.users:
    186             f.write('%s:%s\n' % (u, p))
    187         f.close()
     187    def test_userLookup(self):
     188        db = checkers.FilePasswordDB(self.dbfile.path)
     189        with self.dbfile.open('w') as f:
     190            for (u, p) in self.users:
     191                f.write('%s:%s\n' % (u, p))
    188192
    189193        for (u, p) in self.users:
    190194            self.failUnlessRaises(KeyError, db.getUser, u.upper())
    191195            self.assertEqual(db.getUser(u), (u, p))
    192196
    193     def testCaseInSensitivity(self):
    194         dbfile = self.mktemp()
    195         db = checkers.FilePasswordDB(dbfile, caseSensitive=0)
    196         f = file(dbfile, 'w')
    197         for (u, p) in self.users:
    198             f.write('%s:%s\n' % (u, p))
    199         f.close()
     197
     198    def test_caseInSensitivity(self):
     199        db = checkers.FilePasswordDB(self.dbfile.path, caseSensitive=0)
     200        with self.dbfile.open('w') as f:
     201            for (u, p) in self.users:
     202                f.write('%s:%s\n' % (u, p))
    200203
    201204        for (u, p) in self.users:
    202205            self.assertEqual(db.getUser(u.upper()), (u, p))
    203206
    204     def testRequestAvatarId(self):
    205         dbfile = self.mktemp()
    206         db = checkers.FilePasswordDB(dbfile, caseSensitive=0)
    207         f = file(dbfile, 'w')
    208         for (u, p) in self.users:
    209             f.write('%s:%s\n' % (u, p))
    210         f.close()
     207
     208    def test_requestAvatarId(self):
     209        db = checkers.FilePasswordDB(self.dbfile.path, caseSensitive=0)
     210        with self.dbfile.open('w') as f:
     211            for (u, p) in self.users:
     212                f.write('%s:%s\n' % (u, p))
     213
    211214        creds = [credentials.UsernamePassword(u, p) for u, p in self.users]
    212215        d = defer.gatherResults(
    213216            [defer.maybeDeferred(db.requestAvatarId, c) for c in creds])
    214217        d.addCallback(self.assertEqual, [u for u, p in self.users])
    215218        return d
    216219
    217     def testRequestAvatarId_hashed(self):
    218         dbfile = self.mktemp()
    219         db = checkers.FilePasswordDB(dbfile, caseSensitive=0)
    220         f = file(dbfile, 'w')
    221         for (u, p) in self.users:
    222             f.write('%s:%s\n' % (u, p))
    223         f.close()
     220
     221    def test_requestAvatarId_hashed(self):
     222        db = checkers.FilePasswordDB(self.dbfile.path, caseSensitive=0)
     223        with self.dbfile.open('w') as f:
     224            for (u, p) in self.users:
     225                f.write('%s:%s\n' % (u, p))
     226
    224227        creds = [credentials.UsernameHashedPassword(u, p) for u, p in self.users]
    225228        d = defer.gatherResults(
    226229            [defer.maybeDeferred(db.requestAvatarId, c) for c in creds])
     
    240243    def hash(self, u, p, s):
    241244        return crypt(p, s)
    242245
     246
    243247    def setUp(self):
    244         dbfile = self.mktemp()
    245         self.db = checkers.FilePasswordDB(dbfile, hash=self.hash)
    246         f = file(dbfile, 'w')
    247         for (u, p) in self.users:
    248             f.write('%s:%s\n' % (u, crypt(p, u[:2])))
    249         f.close()
     248        dbfile = FilePath(self.mktemp())
     249        self.db = checkers.FilePasswordDB(dbfile.path, hash=self.hash)
     250        with dbfile.open('w') as f:
     251            for (u, p) in self.users:
     252                f.write('%s:%s\n' % (u, crypt(p, u[:2])))
    250253        r = TestRealm()
    251254        self.port = portal.Portal(r)
    252255        self.port.registerChecker(self.db)
    253256
    254     def testGoodCredentials(self):
     257
     258    def test_goodCredentials(self):
    255259        goodCreds = [credentials.UsernamePassword(u, p) for u, p in self.users]
    256260        d = defer.gatherResults([self.db.requestAvatarId(c) for c in goodCreds])
    257261        d.addCallback(self.assertEqual, [u for u, p in self.users])
    258262        return d
    259263
    260     def testGoodCredentials_login(self):
     264
     265    def test_goodCredentials_login(self):
    261266        goodCreds = [credentials.UsernamePassword(u, p) for u, p in self.users]
    262267        d = defer.gatherResults([self.port.login(c, None, ITestable)
    263268                                 for c in goodCreds])
     
    265270        d.addCallback(self.assertEqual, [u for u, p in self.users])
    266271        return d
    267272
    268     def testBadCredentials(self):
     273
     274    def test_badCredentials(self):
    269275        badCreds = [credentials.UsernamePassword(u, 'wrong password')
    270276                    for u, p in self.users]
    271277        d = defer.DeferredList([self.port.login(c, None, ITestable)
     
    273279        d.addCallback(self._assertFailures, error.UnauthorizedLogin)
    274280        return d
    275281
    276     def testHashedCredentials(self):
     282
     283    def test_hashedCredentials(self):
    277284        hashedCreds = [credentials.UsernameHashedPassword(u, crypt(p, u[:2]))
    278285                       for u, p in self.users]
    279286        d = defer.DeferredList([self.port.login(c, None, ITestable)
     
    281288        d.addCallback(self._assertFailures, error.UnhandledCredentials)
    282289        return d
    283290
     291
    284292    def _assertFailures(self, failures, *expectedFailures):
    285293        for flag, failure in failures:
    286294            self.assertEqual(flag, defer.FAILURE)
     
    290298    if crypt is None:
    291299        skip = "crypt module not available"
    292300
     301
     302
    293303class PluggableAuthenticationModulesTest(unittest.TestCase):
    294304
    295305    def setUp(self):
     
    362372    if not pamauth:
    363373        skip = "Can't run without PyPAM"
    364374
     375
     376
    365377class CheckersMixin:
    366378    def testPositive(self):
    367379        for chk in self.getCheckers():
     
    379391                self.assertRaises(error.UnauthorizedLogin, r.getResult)
    380392    testNegative = dG(testNegative)
    381393
     394
     395
    382396class HashlessFilePasswordDBMixin:
    383397    credClass = credentials.UsernamePassword
    384398    diskHash = None
     
    389403        ('user2', 'password2'),
    390404        ('user3', 'password3')]
    391405
     406
    392407    def getGoodCredentials(self):
    393408        for u, p in self._validCredentials:
    394409            yield self.credClass(u, self.networkHash(p)), u
    395410
     411
    396412    def getBadCredentials(self):
    397413        for u, p in [('user1', 'password3'),
    398414                     ('user2', 'password1'),
    399415                     ('bloof', 'blarf')]:
    400416            yield self.credClass(u, self.networkHash(p))
    401417
     418
    402419    def getCheckers(self):
    403420        diskHash = self.diskHash or (lambda x: x)
    404         hashCheck = self.diskHash and (lambda username, password, stored: self.diskHash(password))
     421        hashCheck = self.diskHash and (lambda username, password,
     422            stored: self.diskHash(password))
    405423
    406424        for cache in True, False:
    407             fn = self.mktemp()
    408             fObj = file(fn, 'w')
    409             for u, p in self._validCredentials:
    410                 fObj.write('%s:%s\n' % (u, diskHash(p)))
    411             fObj.close()
    412             yield checkers.FilePasswordDB(fn, cache=cache, hash=hashCheck)
    413 
    414             fn = self.mktemp()
    415             fObj = file(fn, 'w')
    416             for u, p in self._validCredentials:
    417                 fObj.write('%s dingle dongle %s\n' % (diskHash(p), u))
    418             fObj.close()
    419             yield checkers.FilePasswordDB(fn, ' ', 3, 0, cache=cache, hash=hashCheck)
    420 
    421             fn = self.mktemp()
    422             fObj = file(fn, 'w')
    423             for u, p in self._validCredentials:
    424                 fObj.write('zip,zap,%s,zup,%s\n' % (u.title(), diskHash(p)))
    425             fObj.close()
    426             yield checkers.FilePasswordDB(fn, ',', 2, 4, False, cache=cache, hash=hashCheck)
     425            fn = FilePath(self.mktemp())
     426            with fn.open('w') as fObj:
     427                for u, p in self._validCredentials:
     428                    fObj.write('%s:%s\n' % (u, diskHash(p)))
     429            yield checkers.FilePasswordDB(fn.path, cache=cache, hash=hashCheck)
     430
     431            fn = FilePath(self.mktemp())
     432            with fn.open('w') as fObj:
     433                for u, p in self._validCredentials:
     434                    fObj.write('%s dingle dongle %s\n' % (diskHash(p), u))
     435            yield checkers.FilePasswordDB(fn.path, ' ', 3, 0, cache=cache,
     436                hash=hashCheck)
     437
     438            fn = FilePath(self.mktemp())
     439            with fn.open('w') as fObj:
     440                for u, p in self._validCredentials:
     441                    fObj.write('zip,zap,%s,zup,%s\n' % (u.title(),
     442                        diskHash(p)))
     443            yield checkers.FilePasswordDB(fn.path, ',', 2, 4, False,
     444                cache=cache, hash=hashCheck)
     445
     446
    427447
    428448class LocallyHashedFilePasswordDBMixin(HashlessFilePasswordDBMixin):
    429449    diskHash = staticmethod(lambda x: x.encode('hex'))
    430450
     451
     452
    431453class NetworkHashedFilePasswordDBMixin(HashlessFilePasswordDBMixin):
    432454    networkHash = staticmethod(lambda x: x.encode('hex'))
    433455    class credClass(credentials.UsernameHashedPassword):
    434456        def checkPassword(self, password):
    435457            return self.hashed.decode('hex') == password
    436458
    437 class HashlessFilePasswordDBCheckerTestCase(HashlessFilePasswordDBMixin, CheckersMixin, unittest.TestCase):
     459
     460
     461class HashlessFilePasswordDBCheckerTestCase(HashlessFilePasswordDBMixin,
     462                                            CheckersMixin, unittest.TestCase):
    438463    pass
    439464
    440 class LocallyHashedFilePasswordDBCheckerTestCase(LocallyHashedFilePasswordDBMixin, CheckersMixin, unittest.TestCase):
     465
     466
     467class LocallyHashedFilePasswordDBCheckerTestCase(LocallyHashedFilePasswordDBMixin,
     468                                              CheckersMixin, unittest.TestCase):
    441469    pass
    442470
    443 class NetworkHashedFilePasswordDBCheckerTestCase(NetworkHashedFilePasswordDBMixin, CheckersMixin, unittest.TestCase):
     471
     472
     473class NetworkHashedFilePasswordDBCheckerTestCase(NetworkHashedFilePasswordDBMixin,
     474                                             CheckersMixin, unittest.TestCase):
    444475    pass
    445476