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.
  • [get | view] (2005-12-29 12:11:24, 10.1 KB) [[attachment:security_string.patch]]
  • [get | view] (2006-01-07 08:59:28, 10.0 KB) [[attachment:security_string11.patch]]
  • [get | view] (2006-01-07 11:50:10, 11.4 KB) [[attachment:security_string13.patch]]
  • [get | view] (2006-01-08 01:35:46, 11.6 KB) [[attachment:security_string15.patch]]
  • [get | view] (2006-01-09 00:05:23, 11.6 KB) [[attachment:security_string16.patch]]
  • [get | view] (2006-01-21 11:44:21, 11.9 KB) [[attachment:security_string17.patch]]
  • [get | view] (2005-12-30 06:26:38, 8.9 KB) [[attachment:security_string6.patch]]
  • [get | view] (2005-12-30 09:14:39, 7.0 KB) [[attachment:security_string7.patch]]
  • [get | view] (2006-01-05 11:04:41, 10.6 KB) [[attachment:security_string8.patch]]
  • [get | view] (2006-01-04 15:03:44, 4.1 KB) [[attachment:securitystring.old.py]]
  • [get | view] (2006-01-04 15:04:58, 4.1 KB) [[attachment:securitystring.py]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.