From 27e2c6ec318fec6ad7d874b0ee17ff460b5e33e0 Mon Sep 17 00:00:00 2001 From: richard Date: Sun, 4 Nov 2001 03:07:12 +0000 Subject: [PATCH] Fixed various cookie-related bugs: . bug #477685 ] base64.decodestring breaks . bug #477837 ] lynx does not like the cookie . bug #477892 ] Password edit doesn't fix login cookie Also closed a security hole - a logged-in user could edit another user's details. git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@364 57a73879-2fb5-44c3-a270-3262357dd7e2 --- CHANGES.txt | 3 ++ roundup/cgi_client.py | 86 ++++++++++++++++++++++++++++++++----------- 2 files changed, 68 insertions(+), 21 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 3d3c7b3..2b81018 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -21,6 +21,9 @@ Fixed: . bug #477107 ] HTTP header problem . bug #477687 ] conforming html . bug #474372 ] Netscape 4.77 do not render Support form + . bug #477685 ] base64.decodestring breaks + . bug #477837 ] lynx does not like the cookie + . bug #477892 ] Password edit doesn't fix login cookie 2001-10-23 - 0.3.0 pre 3 Feature: diff --git a/roundup/cgi_client.py b/roundup/cgi_client.py index b17745c..c565c54 100644 --- a/roundup/cgi_client.py +++ b/roundup/cgi_client.py @@ -15,7 +15,7 @@ # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. # -# $Id: cgi_client.py,v 1.48 2001-11-03 01:30:18 richard Exp $ +# $Id: cgi_client.py,v 1.49 2001-11-04 03:07:12 richard Exp $ import os, cgi, pprint, StringIO, urlparse, re, traceback, mimetypes import binascii, Cookie, time @@ -312,13 +312,58 @@ class Client: showmsg = shownode def showuser(self, message=None): - ''' display an item + '''Display a user page for editing. Make sure the user is allowed + to edit this node, and also check for password changes. ''' - if self.user in ('admin', self.db.user.get(self.nodeid, 'username')): - self.shownode(message) - else: + if self.user == 'anonymous': + raise Unauthorised + + user = self.db.user + + # get the username of the node being edited + node_user = user.get(self.nodeid, 'username') + + if self.user not in ('admin', node_user): raise Unauthorised + # + # perform any editing + # + keys = self.form.keys() + num_re = re.compile('^\d+$') + if keys: + try: + props, changed = parsePropsFromForm(self.db, user, self.form, + self.nodeid) + if self.nodeid == self.getuid() and 'password' in changed: + set_cookie = self.form['password'].value.strip() + else: + set_cookie = 0 + user.set(self.nodeid, **props) + self._post_editnode(self.nodeid, changed) + # and some feedback for the user + message = '%s edited ok'%', '.join(changed) + except: + s = StringIO.StringIO() + traceback.print_exc(None, s) + message = '
%s
'%cgi.escape(s.getvalue()) + else: + set_cookie = 0 + + # fix the cookie if the password has changed + if set_cookie: + self.set_cookie(self.user, set_cookie) + + # + # now the display + # + self.pagehead('User: %s'%node_user, message) + + # use the template to display the item + item = htmltemplate.ItemTemplate(self, self.TEMPLATES, 'user') + item.render(self.nodeid) + self.pagefoot() + def showfile(self): ''' display a file ''' @@ -578,7 +623,6 @@ class Client: password = self.form['__login_password'].value else: password = '' - print self.user, password # make sure the user exists try: uid = self.db.user.lookup(self.user) @@ -593,14 +637,16 @@ class Client: self.make_user_anonymous() return self.login(message='Incorrect password') - # construct the cookie - uid = self.db.user.lookup(self.user) - user = binascii.b2a_base64('%s:%s'%(self.user, password)).strip() - path = '/'.join((self.env['SCRIPT_NAME'], self.env['INSTANCE_NAME'], - '')) - self.header({'Set-Cookie': 'roundup_user=%s; Path=%s;'%(user, path)}) + self.set_cookie(self.user, password) return self.index() + def set_cookie(self, user, password): + # construct the cookie + user = binascii.b2a_base64('%s:%s'%(user, password)).strip() + path = '/'.join((self.env['SCRIPT_NAME'], self.env['INSTANCE_NAME'])) + self.header({'Set-Cookie': 'roundup_user="%s"; Path="%s";'%(user, + path)}) + def make_user_anonymous(self): # make us anonymous if we can try: @@ -612,11 +658,11 @@ class Client: def logout(self, message=None): self.make_user_anonymous() # construct the logout cookie - path = '/'.join((self.env['SCRIPT_NAME'], self.env['INSTANCE_NAME'], - '')) now = Cookie._getdate() + path = '/'.join((self.env['SCRIPT_NAME'], self.env['INSTANCE_NAME'])) self.header({'Set-Cookie': - 'roundup_user=deleted; Max-Age=0; expires=%s; Path=%s;'%(now, path)}) + 'roundup_user=deleted; Max-Age=0; expires="%s"; Path="%s";'%(now, + path)}) return self.login() def newuser_action(self, message=None): @@ -633,12 +679,7 @@ class Client: uid = cl.create(**props) self.user = self.db.user.get(uid, 'username') password = self.db.user.get(uid, 'password') - # construct the cookie - uid = self.db.user.lookup(self.user) - user = binascii.b2a_base64('%s:%s'%(self.user, password)).strip() - path = '/'.join((self.env['SCRIPT_NAME'], self.env['INSTANCE_NAME'], - '')) - self.header({'Set-Cookie': 'roundup_user=%s; Path=%s;'%(user, path)}) + self.set_cookie(self.user, password) return self.index() def main(self, dre=re.compile(r'([^\d]+)(\d+)'), @@ -878,6 +919,9 @@ def parsePropsFromForm(db, cl, form, nodeid=0): # # $Log: not supported by cvs2svn $ +# Revision 1.48 2001/11/03 01:30:18 richard +# Oops. uses pagefoot now. +# # Revision 1.47 2001/11/03 01:29:28 richard # Login page didn't have all close tags. # -- 2.30.2