1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """
23 Flumotion Twisted credentials
24 """
25
26 import crypt
27 import md5
28
29 import random
30
31 from flumotion.common import log
32 from twisted.cred import credentials
33 from flumotion.twisted.compat import implements
34
36 """
37 I am your average username and password credentials.
38 """
39 implements(credentials.IUsernamePassword)
40 - def __init__(self, username, password=''):
43
46
48 """
49 I encapsulate a username and check crypted passwords.
50
51 This credential interface is used when a crypt password is received
52 from the party requesting authentication.
53 CredentialCheckers which check this kind of credential must store
54 the passwords in plaintext or crypt form.
55
56 @type username: C{str}
57 @ivar username: The username associated with these credentials.
58 """
59
61 """
62 Validate these credentials against the correct crypt password.
63
64 @param cryptPassword: The correct, crypt password against which to
65 check.
66
67 @return: a deferred which becomes, or a boolean indicating if the
68 password matches.
69 """
70
72 """
73 I take a username and a plaintext password.
74 I implement IUsernameCryptPassword.
75 """
76
77 implements(IUsernameCryptPassword)
78 - def __init__(self, username, password):
81
82 - def checkCryptPassword(self, cryptPassword):
83 """Check credentials against the given cryptPassword."""
84 salt = cryptPassword[:2]
85 encrypted = crypt.crypt(self.password, salt)
86 return encrypted == cryptPassword
87
89 """
90 I take a username and a crypt password.
91 When using me you should make sure the password was crypted with the
92 correct salt (which is stored in the crypt password backend of whatever
93 checker you use); otherwise your password may be a valid crypt, but
94 with a different salt.
95 I implement IUsernameCryptPassword.
96 """
97
98 implements(IUsernameCryptPassword)
99 - def __init__(self, username, cryptPassword=None):
102
104 """
105 Given the plaintext password and the salt,
106 set the correct cryptPassword.
107 """
108 assert len(salt) == 2
109
110 self.cryptPassword = crypt.crypt(password, salt)
111
113 """
114 Check credentials against the given cryptPassword.
115 """
116 return self.cryptPassword == cryptPassword
117
119 """
120 Respond to a given crypt challenge with our cryptPassword.
121 """
122 import md5
123 md = md5.new()
124 md.update(cryptPassword)
125 md.update(challenge)
126 return md.digest()
127
129 """
130 Take a string of bytes, and return a string of two-digit hex values.
131 """
132 l = []
133 for c in data:
134 l.append("%02x" % ord(c))
135 return "".join(l)
136
137
139 """
140 I return some random data.
141 """
142 crap = ''
143 for x in range(random.randrange(15,25)):
144 crap = crap + chr(random.randint(65,90) + x - x)
145 crap = md5.new(crap).digest()
146 return crap
147
149 """
150 I take a username.
151
152 Authenticator will give me a salt and challenge me.
153 Requester will respond to the challenge.
154 At that point I'm ready to be used by a checker.
155 The response function used is
156 L{flumotion.twisted.credentials.cryptRespond()}
157
158 I implement IUsernameCryptPassword.
159 """
160
161 implements(IUsernameCryptPassword)
162
164 self.username = username
165 self.salt = None
166 self.challenge = None
167 self.response = None
168
170 """
171 I encode a given plaintext password using the salt, and respond
172 to the challenge.
173 """
174 assert self.salt
175 assert self.challenge
176 assert len(self.salt) == 2
177 cryptPassword = crypt.crypt(password, self.salt)
178 self.response = cryptRespond(self.challenge, cryptPassword)
179
181 """
182 Check credentials against the given cryptPassword.
183 """
184 if not self.response:
185 return False
186
187 expected = cryptRespond(self.challenge, cryptPassword)
188 return self.response == expected
189
190 -class IToken(credentials.ICredentials):
191 """I encapsulate a token.
192
193 This credential is used when a token is received from the
194 party requesting authentication.
195
196 @type token: C{str}
197 @ivar token: The token associated with these credentials.
198 """
199
205
207 """
208 I encapsulate a username and check SHA-256 passwords.
209
210 This credential interface is used when a SHA-256 algorithm is used
211 on the password by the party requesting authentication..
212 CredentialCheckers which check this kind of credential must store
213 the passwords in plaintext or SHA-256 form.
214
215 @type username: C{str}
216 @ivar username: The username associated with these credentials.
217 """
218
220 """
221 Validate these credentials against the correct SHA-256 password.
222
223 @param sha256Password: The correct SHA-256 password against which to
224 check.
225
226 @return: a deferred which becomes, or a boolean indicating if the
227 password matches.
228 """
229
230
231
233 """
234 I take a username.
235
236 Authenticator will give me a salt and challenge me.
237 Requester will respond to the challenge.
238 At that point I'm ready to be used by a checker.
239 The response function used is
240 L{flumotion.twisted.credentials.cryptRespond()}
241
242 I implement IUsernameSha256Password.
243 """
244
245 implements(IUsernameSha256Password)
246
248 self.username = username
249 self.salt = None
250 self.challenge = None
251 self.response = None
252
254 """
255 I encode a given plaintext password using the salt, and respond
256 to the challenge.
257 """
258 assert self.salt
259 assert self.challenge
260 from Crypto.Hash import SHA256
261 hasher = SHA256.new()
262 hasher.update(self.salt)
263 hasher.update(password)
264 sha256Password = self.salt + dataToHex(hasher.digest())
265 self.response = cryptRespond(self.challenge, sha256Password)
266
268 """
269 Check credentials against the given sha256Password.
270 """
271 if not self.response:
272 return False
273
274 expected = cryptRespond(self.challenge, sha256Password)
275 return self.response == expected
276