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