1
2 '''
3 Crypto transforms (encrypting, hashing, etc), and misc auth crap.
4
5 @author: Michael Eddington
6 @version: $Id: Peach.Transformers.crypto-pysrc.html 1138 2008-08-16 19:39:03Z meddingt $
7 '''
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 import md5, sha, fcrypt, md5crypt, hmac
39
40
41
42
43 from Peach.transformer import Transformer
44 from Peach.Generators import static
45
47 '''
48 UNIX style crypt. If no salt is specified will use first
49 two chars of data, ala pwd style.
50
51 This transform uses a pure Python implementation of the crypt
52 function which had been ported from an old C version. See
53 fcrypt.py for licensing differences.
54
55 From underlying docs:
56
57 I{Generate an encrypted hash from the passed password. If the password
58 is longer than eight characters, only the first eight will be used.}
59
60 I{The first two characters of the salt are used to modify the encryption
61 algorithm used to generate in the hash in one of 4096 different ways.
62 The characters for the salt should be upper- and lower-case letters A
63 to Z, digits 0 to 9, '.' and '/'.}
64
65 I{The returned hash begins with the two characters of the salt, and
66 should be passed as the salt to verify the password.}
67 '''
68
69 _salt = None
70
72 '''
73 @type salt: string
74 @param salt: Salt for crypt (optional)
75 '''
76 Transformer.__init__(self)
77 self._salt = salt
78
83
85 crypted = "heD1umJOQHx9A"
86 t = Crypt()
87 print "Crypt 1: " + t.realEncode("hello world")
88 if crypted != t.realEncode('hello world'):
89 raise Exception("Crypt::unittest(): Failed to match 'hello world' with 'he' salt.")
90 print "Crypt: " + t.realEncode("<script> alert('meow') </script>")
91 unittest = staticmethod(unittest)
92
93
95 '''
96 UNIX style MD5 crypt. If no salt is specified will use first
97 two chars of data, ala pwd style.
98
99 From underlying docs:
100
101 I{unix_md5_crypt() provides a crypt()-compatible interface to the
102 rather new MD5-based crypt() function found in modern operating systems.
103 It's based on the implementation found on FreeBSD 2.2.[56]-RELEASE and
104 contains the following license in it:}
105
106 I{"THE BEER-WARE LICENSE" (Revision 42):
107 <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
108 can do whatever you want with this stuff. If we meet some day, and you think
109 this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp}
110 '''
111
112 _salt = None
113 _magic = None
114
115 - def __init__(self, salt = None, magic = None):
116 '''
117 @type salt: string
118 @param salt: Salt for crypt (optional)
119 @type magic: string
120 @param magic: Magic, usually $1$ on unix (optional)
121 '''
122 Transformer.__init__(self)
123 self._salt = salt
124 self._magic = magic
125
130
137
138
139
140 unittest = staticmethod(unittest)
141
142
144 '''
145 Apache style MD5 crypt. If no salt is specified will use first two chars of
146 data, ala pwd style.
147
148 Uses '$apr1$' as magic.
149
150 From underlying docs:
151
152 I{apache_md5_crypt() provides a function compatible with Apache's
153 .htpasswd files. This was contributed by Bryan Hart <bryan@eai.com>.}
154
155 I{"THE BEER-WARE LICENSE" (Revision 42):
156 <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
157 can do whatever you want with this stuff. If we meet some day, and you think
158 this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp}
159 '''
160
161 _salt = None
162
164 '''
165 @type salt: string
166 @param salt: Salt for crypt (optional)
167 '''
168 Transformer.__init__(self)
169 self._salt = salt
170
175
182
183
184
185 unittest = staticmethod(unittest)
186
187
189 '''
190 CVS pserver password scramble
191 '''
192
193 _shifts = [
194 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
195 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
196 114,120, 53, 79, 96,109, 72,108, 70, 64, 76, 67,116, 74, 68, 87,
197 111, 52, 75,119, 49, 34, 82, 81, 95, 65,112, 86,118,110,122,105,
198 41, 57, 83, 43, 46,102, 40, 89, 38,103, 45, 50, 42,123, 91, 35,
199 125, 55, 54, 66,124,126, 59, 47, 92, 71,115, 78, 88,107,106, 56,
200 36,121,117,104,101,100, 69, 73, 99, 63, 94, 93, 39, 37, 61, 48,
201 58,113, 32, 90, 44, 98, 60, 51, 33, 97, 62, 77, 84, 80, 85,223,
202 225,216,187,166,229,189,222,188,141,249,148,200,184,136,248,190,
203 199,170,181,204,138,232,218,183,255,234,220,247,213,203,226,193,
204 174,172,228,252,217,201,131,230,197,211,145,238,161,179,160,212,
205 207,221,254,173,202,146,224,151,140,196,205,130,135,133,143,246,
206 192,159,244,239,185,168,215,144,139,165,180,157,147,186,214,176,
207 227,231,219,169,175,156,206,198,129,164,150,210,154,177,134,127,
208 182,128,158,208,162,132,167,209,149,241,153,251,237,236,171,195,
209 243,233,253,240,194,250,191,155,142,137,245,235,163,242,178,152
210 ]
211
213 s = []
214 for i in range(len(data)):
215 s.append(data[i])
216 s.append(None)
217 for i in range(len(data)):
218 s[i+1] = "%c" % self._shifts[ord(data[i])]
219
220 out = ''
221 for i in range(len(s)):
222 out += s[i]
223
224 return out
225
229 unittest = staticmethod(unittest)
230
231
232 -class Md5(Transformer):
233 '''
234 MD5 transform (hex and binary)
235 '''
236
237 _asHex = 0
238
240 '''
241 @type asHex: number
242 @param asHex: 1 is hex, 0 is binary
243 '''
244 Transformer.__init__(self)
245 self._asHex = asHex
246
248 if self._asHex == 0:
249 return md5.new(data).digest()
250 return md5.new(data).hexdigest()
251
255 unittest = staticmethod(unittest)
256
257
258 -class Sha1(Transformer):
259 '''
260 SHA-1 transform (hex and binary)
261 '''
262
263 _asHex = 0
264
266 '''
267 @type asHex: number
268 @param asHex: 1 is hex, 0 is binary
269 '''
270 Transformer.__init__(self)
271 self._asHex = asHex
272
274 if self._asHex == 0:
275 return sha.new(data).digest()
276 return sha.new(data).hexdigest()
277
281 unittest = staticmethod(unittest)
282
283
284 -class Hmac(Transformer):
285 '''
286 HMAC as described in RFC 2104. Key is a generator.
287 '''
288
289 _key = None
290 _digestmod = None
291 _asHex = None
292
293 - def __init__(self, key, digestmod = md5, asHex = 0):
294 '''
295 Key is a generator for HMAC key, digestmod is hash to use (md5 or sha)
296
297 @type key: Generator
298 @param key: HMAC key
299 @type digestmod: md5 or sha
300 @param digestmod: Which digest to use
301 @type asHex: number
302 @param asHex: 1 is hex, 0 is binary
303 '''
304 Transformer.__init__(self)
305 self._key = key
306 self._digestmod = digestmod
307 self._asHex = asHex
308
313
319 unittest = staticmethod(unittest)
320
321
322
323
324