OLD | NEW |
| (Empty) |
1 # -*- test-case-name: twisted.test.test_newcred-*- | |
2 | |
3 # Copyright (c) 2001-2008 Twisted Matrix Laboratories. | |
4 # See LICENSE for details. | |
5 | |
6 | |
7 from zope.interface import implements, Interface | |
8 | |
9 import hmac | |
10 import time | |
11 import random | |
12 | |
13 | |
14 | |
15 class ICredentials(Interface): | |
16 """ | |
17 I check credentials. | |
18 | |
19 Implementors _must_ specify which sub-interfaces of ICredentials | |
20 to which it conforms, using zope.interface.implements(). | |
21 """ | |
22 | |
23 | |
24 | |
25 class IUsernameHashedPassword(ICredentials): | |
26 """ | |
27 I encapsulate a username and a hashed password. | |
28 | |
29 This credential is used when a hashed password is received from the | |
30 party requesting authentication. CredentialCheckers which check this | |
31 kind of credential must store the passwords in plaintext (or as | |
32 password-equivalent hashes) form so that they can be hashed in a manner | |
33 appropriate for the particular credentials class. | |
34 | |
35 @type username: C{str} | |
36 @ivar username: The username associated with these credentials. | |
37 """ | |
38 | |
39 def checkPassword(password): | |
40 """Validate these credentials against the correct password. | |
41 | |
42 @param password: The correct, plaintext password against which to | |
43 check. | |
44 | |
45 @return: a deferred which becomes, or a boolean indicating if the | |
46 password matches. | |
47 """ | |
48 | |
49 | |
50 | |
51 class IUsernamePassword(ICredentials): | |
52 """ | |
53 I encapsulate a username and a plaintext password. | |
54 | |
55 This encapsulates the case where the password received over the network | |
56 has been hashed with the identity function (That is, not at all). The | |
57 CredentialsChecker may store the password in whatever format it desires, | |
58 it need only transform the stored password in a similar way before | |
59 performing the comparison. | |
60 | |
61 @type username: C{str} | |
62 @ivar username: The username associated with these credentials. | |
63 | |
64 @type password: C{str} | |
65 @ivar password: The password associated with these credentials. | |
66 """ | |
67 | |
68 def checkPassword(password): | |
69 """Validate these credentials against the correct password. | |
70 | |
71 @param password: The correct, plaintext password against which to | |
72 check. | |
73 | |
74 @return: a deferred which becomes, or a boolean indicating if the | |
75 password matches. | |
76 """ | |
77 | |
78 | |
79 | |
80 class IAnonymous(ICredentials): | |
81 """ | |
82 I am an explicitly anonymous request for access. | |
83 """ | |
84 | |
85 | |
86 | |
87 class CramMD5Credentials: | |
88 implements(IUsernameHashedPassword) | |
89 | |
90 challenge = '' | |
91 response = '' | |
92 | |
93 def __init__(self, host=None): | |
94 self.host = host | |
95 | |
96 def getChallenge(self): | |
97 if self.challenge: | |
98 return self.challenge | |
99 # The data encoded in the first ready response contains an | |
100 # presumptively arbitrary string of random digits, a timestamp, and | |
101 # the fully-qualified primary host name of the server. The syntax of | |
102 # the unencoded form must correspond to that of an RFC 822 'msg-id' | |
103 # [RFC822] as described in [POP3]. | |
104 # -- RFC 2195 | |
105 r = random.randrange(0x7fffffff) | |
106 t = time.time() | |
107 self.challenge = '<%d.%d@%s>' % (r, t, self.host) | |
108 return self.challenge | |
109 | |
110 def setResponse(self, response): | |
111 self.username, self.response = response.split(None, 1) | |
112 | |
113 def moreChallenges(self): | |
114 return False | |
115 | |
116 def checkPassword(self, password): | |
117 verify = hmac.HMAC(password, self.challenge).hexdigest() | |
118 return verify == self.response | |
119 | |
120 | |
121 class UsernameHashedPassword: | |
122 implements(IUsernameHashedPassword) | |
123 | |
124 def __init__(self, username, hashed): | |
125 self.username = username | |
126 self.hashed = hashed | |
127 | |
128 def checkPassword(self, password): | |
129 return self.hashed == password | |
130 | |
131 | |
132 class UsernamePassword: | |
133 implements(IUsernamePassword) | |
134 | |
135 def __init__(self, username, password): | |
136 self.username = username | |
137 self.password = password | |
138 | |
139 def checkPassword(self, password): | |
140 return self.password == password | |
141 | |
142 | |
143 class Anonymous: | |
144 implements(IAnonymous) | |
145 | |
146 | |
147 | |
148 class ISSHPrivateKey(ICredentials): | |
149 """ | |
150 I encapsulate an SSH public key to be checked against a users private | |
151 key. | |
152 | |
153 @ivar username: Duh? | |
154 | |
155 @ivar algName: The algorithm name for the blob. | |
156 | |
157 @ivar blob: The public key blob as sent by the client. | |
158 | |
159 @ivar sigData: The data the signature was made from. | |
160 | |
161 @ivar signature: The signed data. This is checked to verify that the user | |
162 owns the private key. | |
163 """ | |
164 | |
165 | |
166 | |
167 class SSHPrivateKey: | |
168 implements(ISSHPrivateKey) | |
169 def __init__(self, username, algName, blob, sigData, signature): | |
170 self.username = username | |
171 self.algName = algName | |
172 self.blob = blob | |
173 self.sigData = sigData | |
174 self.signature = signature | |
175 | |
176 | |
177 class IPluggableAuthenticationModules(ICredentials): | |
178 """I encapsulate the authentication of a user via PAM (Pluggable | |
179 Authentication Modules. I use PyPAM (available from | |
180 http://www.tummy.com/Software/PyPam/index.html). | |
181 | |
182 @ivar username: The username for the user being logged in. | |
183 | |
184 @ivar pamConversion: A function that is called with a list of tuples | |
185 (message, messageType). See the PAM documentation | |
186 for the meaning of messageType. The function | |
187 returns a Deferred which will fire with a list | |
188 of (response, 0), one for each message. The 0 is | |
189 currently unused, but is required by the PAM library. | |
190 """ | |
191 | |
192 class PluggableAuthenticationModules: | |
193 implements(IPluggableAuthenticationModules) | |
194 | |
195 def __init__(self, username, pamConversion): | |
196 self.username = username | |
197 self.pamConversion = pamConversion | |
198 | |
OLD | NEW |