Attachment 'security_string15.patch'
Download 1 * looking for arch@arch.thinkmo.de--2003-archives/moin--main--1.5--patch-361 to compare with
2 * comparing to arch@arch.thinkmo.de--2003-archives/moin--main--1.5--patch-361
3 M MoinMoin/auth.py
4 M MoinMoin/multiconfig.py
5 M MoinMoin/request.py
6 M MoinMoin/user.py
7 M MoinMoin/userform.py
8 A MoinMoin/util/securitystring.py
9
10 * modified files
11
12 --- orig/MoinMoin/auth.py
13 +++ mod/MoinMoin/auth.py
14 @@ -45,6 +45,7 @@
15
16 import Cookie
17 from MoinMoin import user
18 +from MoinMoin.util import securitystring
19
20 def moin_cookie(request, **kw):
21 """ authenticate via the MOIN_ID cookie """
22 @@ -54,17 +55,17 @@
23 u = user.User(request, name=name, password=password,
24 auth_method='login_userpassword')
25 if u.valid:
26 + # Update the User security_string,
27 + # If he don't have security_string.
28 + try:
29 + u.security_string
30 + except AttributeError:
31 + u.security_string = securitystring.gen(30)
32 + u.save()
33 request.user = u # needed by setCookie
34 request.setCookie()
35 return u, False
36 return None, True
37 -
38 - if kw.get('logout'):
39 - # clear the cookie in the browser and locally. Does not
40 - # check if we have a valid user logged, just make sure we
41 - # don't have one after this call.
42 - request.deleteCookie()
43 - return None, True
44
45 try:
46 cookie = Cookie.SimpleCookie(request.saved_cookie)
47 @@ -72,23 +73,59 @@
48 # ignore invalid cookies, else user can't relogin
49 cookie = None
50 if cookie and cookie.has_key('MOIN_ID'):
51 - u = user.User(request, id=cookie['MOIN_ID'].value,
52 + # Use security_string to handle the Cookie.
53 + u = user.User(request, hmac_uid_string=cookie['MOIN_ID'].value,
54 auth_method='moin_cookie', auth_attribs=())
55 if u.valid:
56 - return u, False
57 + if kw.get('logout'):
58 + # FrankieChow: Why Does not check it?
59 + # Please see: http://moinmoin.wikiwikiweb.de/MoinMoinBugs/LogoutHandle
60 + #
61 + # clear the cookie in the browser and locally. Does not
62 + # check if we have a valid user logged, just make sure we
63 + # don't have one after this call.
64 + request.deleteCookie()
65 + # When the user do global logout then change the
66 + # security_string. ( in here. All logout is global logout. )
67 + u.security_string = securitystring.gen(30)
68 + u.save()
69 + return None, True
70 + else:
71 + return u, False
72 +
73 + # If the brower don't have MOIN_ID cookie, just delete the cookie.
74 + if kw.get('logout'):
75 + request.deleteCookie()
76 + return None, True
77 +
78 return None, True
79
80
81 +def moin_url(request, **kw):
82 + # The url syntax is like this: action=userform&uid=
83 + action = request.form.get('action',[None])[0]
84 + uid = request.form.get('uid',[None])[0]
85 + user_obj = user.User(request)
86 + if action == 'userform' :
87 + u = user.User(request, auth_method='moin_url', hmac_uid_string=uid )
88 + if u.valid:
89 + u.security_string = securitystring.gen(30)
90 + u.save()
91 + request.user = u
92 + request.setCookie()
93 + return u, False
94 + return None, True
95 +
96 #
97 # idea: maybe we should call back to the request object like:
98 # username, password, authenticated, authtype = request.getUserPassAuth()
99 -# WhoEver geheim false basic (twisted, doityourself pw check)
100 -# WhoEver None true basic/... (apache)
101 -#
102 +# WhoEver geheim false basic (twisted, doityourself pw check)
103 +# WhoEver None true basic/... (apache)
104 +#
105 # thus, the server specific code would stay in request object implementation.
106 #
107 # THIS IS NOT A WIKI PAGE ;-)
108 -
109 +
110 def http(request, **kw):
111 """ authenticate via http basic/digest/ntlm auth """
112 from MoinMoin.request import RequestTwisted, RequestCLI
113
114
115 --- orig/MoinMoin/multiconfig.py
116 +++ mod/MoinMoin/multiconfig.py
117 @@ -172,7 +172,7 @@
118 actions_excluded = [] # ['DeletePage', 'AttachFile', 'RenamePage']
119 allow_xslt = 0
120 attachments = None # {'dir': path, 'url': url-prefix}
121 - auth = [authmodule.moin_cookie]
122 + auth = [authmodule.moin_cookie, authmodule.moin_url]
123
124 backup_compression = 'gz'
125 backup_users = []
126
127
128 --- orig/MoinMoin/request.py
129 +++ mod/MoinMoin/request.py
130 @@ -9,7 +9,7 @@
131
132 import os, time, sys, cgi, StringIO
133 from MoinMoin import config, wikiutil, user
134 -from MoinMoin.util import MoinMoinNoFooter, IsWin9x
135 +from MoinMoin.util import MoinMoinNoFooter, IsWin9x, securitystring
136
137 # Timing ---------------------------------------------------------------
138
139 @@ -1216,7 +1216,16 @@
140 # Set the cookie
141 from Cookie import SimpleCookie
142 c = SimpleCookie()
143 - c['MOIN_ID'] = self.user.id
144 + # Modify the Cookie String Syntax.
145 + # Keep the self.user.id in Cookie.
146 + # 1. easy for auth.
147 + # 2. and don't need to care the
148 + # securitystring.make_security_key(security_string, self.user.id)
149 + # is unique.
150 + c['MOIN_ID'] = '%s%s%s' %(
151 + securitystring.make_security_key(self.user.security_string, self.user.id),
152 + securitystring.luck(self),
153 + self.user.id )
154 c['MOIN_ID']['max-age'] = maxage
155 if self.cfg.cookie_domain:
156 c['MOIN_ID']['domain'] = self.cfg.cookie_domain
157
158
159 --- orig/MoinMoin/user.py
160 +++ mod/MoinMoin/user.py
161 @@ -17,7 +17,7 @@
162 PICKLE_PROTOCOL = pickle.HIGHEST_PROTOCOL
163
164 from MoinMoin import config, caching, wikiutil
165 -from MoinMoin.util import datetime, filesys
166 +from MoinMoin.util import datetime, filesys, securitystring
167
168
169 def getUserList(request):
170 @@ -191,7 +191,9 @@
171 class User:
172 """A MoinMoin User"""
173
174 - def __init__(self, request, id=None, name="", password=None, auth_username="", **kw):
175 + # FrankieChow: I think keep the hmac_uid_string auth in User,
176 + # It is better then other, just alter more core code.
177 + def __init__(self, request, id=None, name="", password=None, auth_username="", hmac_uid_string=None, **kw):
178 """ Initialize User object
179
180 @param request: the request object
181 @@ -255,6 +257,7 @@
182 # attrs not saved to profile
183 self._request = request
184 self._trail = []
185 + self._hmac_uid_string = hmac_uid_string
186
187 # we got an already authenticated username:
188 check_pass = 0
189 @@ -272,6 +275,11 @@
190 self.load_from_id(1)
191 else:
192 self.id = self.make_id()
193 + elif self._hmac_uid_string:
194 + try:
195 + self._hmac_string, self.id = self._hmac_uid_string.split( securitystring.luck(self._request) )[:2]
196 + except: pass
197 + self.load_from_id(check_pass=0, check_hmac_string=1)
198 else:
199 self.id = self.make_id()
200
201 @@ -331,7 +339,9 @@
202 """
203 return os.path.exists(self.__filename())
204
205 - def load_from_id(self, check_pass=0):
206 + # In User Class, here is handle User Auth.
207 + # So change it to require the check_hmac_string.
208 + def load_from_id(self, check_pass=0, check_hmac_string=0):
209 """ Load user account data from disk.
210
211 Can only load user data if the id number is already known.
212 @@ -375,6 +385,17 @@
213 return
214 else:
215 self.trusted = 1
216 +
217 + # If User haven't security_string, Don't handle in here,
218 + # Just handle in auth.py in moin_cookie after the user done passd auth.
219 + if check_hmac_string:
220 + if not user_data['security_string']:
221 + return
222 + valid, changed = self._validateHmacString(user_data)
223 + if not valid:
224 + return
225 + else:
226 + self.trusted = 1
227
228 # Remove ignored checkbox values from user data
229 for key, label in self._cfg.user_checkbox_fields:
230 @@ -488,6 +509,11 @@
231 # No encoded password match, this must be wrong password
232 return False, False
233
234 + def _validateHmacString(self, data):
235 + if self._hmac_string == securitystring.make_security_key(data['security_string'], self.id):
236 + return True, False
237 + return False, False
238 +
239 def save(self):
240 """ Save user account data to user account file on disk.
241
242 @@ -935,14 +961,18 @@
243 from MoinMoin.util import mail
244 _ = self._request.getText
245
246 + # If MoinMoin use security_string logic to do url_auth.
247 + # When use SSHA to disable the Login Password.
248 text = '\n' + _("""\
249 Login Name: %s
250
251 -Login Password: %s
252 -
253 -Login URL: %s/?action=userform&uid=%s
254 +Login URL: %s/?action=userform&uid=%s%s%s
255 """, formatted=False) % (
256 - self.name, self.enc_password, self._request.getBaseURL(), self.id)
257 + self.name, self._request.getBaseURL(),
258 + securitystring.make_security_key(self.security_string, self.id),
259 + securitystring.luck(self._request),
260 + self.id
261 + )
262
263 text = _("""\
264 Somebody has requested to submit your account data to this email address.
265
266
267 --- orig/MoinMoin/userform.py
268 +++ mod/MoinMoin/userform.py
269 @@ -8,7 +8,7 @@
270
271 import string, time, re
272 from MoinMoin import user, util, wikiutil
273 -from MoinMoin.util import web, mail, datetime
274 +from MoinMoin.util import web, mail, datetime, securitystring
275 from MoinMoin.widget import html
276
277 _debug = 0
278 @@ -77,6 +77,10 @@
279 for uid in users:
280 theuser = user.User(self.request, uid)
281 if theuser.valid and theuser.email.lower() == email:
282 + # Change the security_string
283 + # When the user request the account_sendmail.
284 + theuser.security_string = securitystring.gen(30)
285 + theuser.save()
286 msg = theuser.mailAccountData()
287 return wikiutil.escape(msg)
288
289 @@ -148,6 +152,8 @@
290 if thisuser.email == theuser.email and not thisuser.disabled:
291 return _("This email already belongs to somebody else.")
292
293 + # Before create the user's profile, create the user's security_string.
294 + theuser.security_string = securitystring.gen(30)
295 # save data
296 theuser.save()
297 if form.has_key('create_and_mail'):
298
299
300 --- orig/MoinMoin/util/securitystring.py
301 +++ mod/MoinMoin/util/securitystring.py
302 @@ -0,0 +1,31 @@
303 +"""
304 + MoinMoin - Handle the Security String
305 + @copyright: (c) Bastian Blank, Florian Festi, Thomas Waldmann
306 + @copyright: MoinMoin:FrankieChow
307 + @license: GNU GPL, see COPYING for details.
308 +"""
309 +import os, hmac, string, random
310 +
311 +# Follow http://moinmoin.wikiwikiweb.de/MoinMoinBugs/Cookie_is_not_secure_enough
312 +# This code is write by Nir Soffer
313 +
314 +def gen(number):
315 + # Make the number is more security.
316 + random_number = random.randint(number/2,number)
317 + safe = string.ascii_letters + string.digits + '_-'
318 + return "%s" % (''.join([random.choice(safe) for i in range(random_number)]))
319 +
320 +###
321 +
322 +def luck(request):
323 + # ':=:' is FrankieChow luck string. maybe you can change this to
324 + # self.cfg.site_luck_string
325 + return ':=:'
326 +
327 +def make_security_key(securitystring, userid):
328 + """
329 + Make the hmac value for
330 + Key: securitystring
331 + msg: userid
332 + """
333 + return hmac.new(securitystring, userid).hexdigest()
334
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.