1 # -*- test-case-name: twisted.test.test_strcred -*-
3 # Copyright (c) Twisted Matrix Laboratories.
4 # See LICENSE for details.
7 Cred plugin for UNIX user accounts.
10 from zope.interface import implements
12 from twisted import plugin
13 from twisted.cred.strcred import ICheckerFactory
14 from twisted.cred.checkers import ICredentialsChecker
15 from twisted.cred.credentials import IUsernamePassword
16 from twisted.cred.error import UnauthorizedLogin
17 from twisted.internet import defer
21 def verifyCryptedPassword(crypted, pw):
22 if crypted[0] == '$': # md5_crypt encrypted
23 salt = '$1$' + crypted.split('$')[2]
32 raise NotImplementedError("cred_unix not supported on this platform")
33 return crypt.crypt(pw, salt) == crypted
37 class UNIXChecker(object):
39 A credentials checker for a UNIX server. This will check that
40 an authenticating username/password is a valid user on the system.
42 Does not work on Windows.
44 Right now this supports Python's pwd and spwd modules, if they are
45 installed. It does not support PAM.
47 implements(ICredentialsChecker)
48 credentialInterfaces = (IUsernamePassword,)
51 def checkPwd(self, pwd, username, password):
53 cryptedPass = pwd.getpwnam(username)[1]
55 return defer.fail(UnauthorizedLogin())
57 if cryptedPass in ('*', 'x'):
58 # Allow checkSpwd to take over
60 elif verifyCryptedPassword(cryptedPass, password):
61 return defer.succeed(username)
64 def checkSpwd(self, spwd, username, password):
66 cryptedPass = spwd.getspnam(username)[1]
68 return defer.fail(UnauthorizedLogin())
70 if verifyCryptedPassword(cryptedPass, password):
71 return defer.succeed(username)
74 def requestAvatarId(self, credentials):
75 username, password = credentials.username, credentials.password
83 checked = self.checkPwd(pwd, username, password)
84 if checked is not None:
93 checked = self.checkSpwd(spwd, username, password)
94 if checked is not None:
98 return defer.fail(UnauthorizedLogin())
102 unixCheckerFactoryHelp = """
103 This checker will attempt to use every resource available to
104 authenticate against the list of users on the local UNIX system.
105 (This does not support Windows servers for very obvious reasons.)
107 Right now, this includes support for:
109 * Python's pwd module (which checks /etc/passwd)
110 * Python's spwd module (which checks /etc/shadow)
112 Future versions may include support for PAM authentication.
117 class UNIXCheckerFactory(object):
119 A factory for L{UNIXChecker}.
121 implements(ICheckerFactory, plugin.IPlugin)
123 authHelp = unixCheckerFactoryHelp
124 argStringFormat = 'No argstring required.'
125 credentialInterfaces = UNIXChecker.credentialInterfaces
127 def generateChecker(self, argstring):
129 This checker factory ignores the argument string. Everything
130 needed to generate a user database is pulled out of the local
137 theUnixCheckerFactory = UNIXCheckerFactory()