Skip to content

Commit eefa56f

Browse files
author
Richard Jones
committed
Fixed various cookie-related bugs:
. [SF#477685] base64.decodestring breaks . [SF#477837] lynx does not like the cookie . [SF#477892] Password edit doesn't fix login cookie Also closed a security hole - a logged-in user could edit another user's details.
1 parent 2aec716 commit eefa56f

File tree

2 files changed

+68
-21
lines changed

2 files changed

+68
-21
lines changed

CHANGES.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ Fixed:
2121
. bug #477107 ] HTTP header problem
2222
. bug #477687 ] conforming html
2323
. bug #474372 ] Netscape 4.77 do not render Support form
24+
. bug #477685 ] base64.decodestring breaks
25+
. bug #477837 ] lynx does not like the cookie
26+
. bug #477892 ] Password edit doesn't fix login cookie
2427

2528
2001-10-23 - 0.3.0 pre 3
2629
Feature:

roundup/cgi_client.py

Lines changed: 65 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
# $Id: cgi_client.py,v 1.48 2001-11-03 01:30:18 richard Exp $
18+
# $Id: cgi_client.py,v 1.49 2001-11-04 03:07:12 richard Exp $
1919

2020
import os, cgi, pprint, StringIO, urlparse, re, traceback, mimetypes
2121
import binascii, Cookie, time
@@ -312,13 +312,58 @@ def shownode(self, message=None):
312312
showmsg = shownode
313313

314314
def showuser(self, message=None):
315-
''' display an item
315+
'''Display a user page for editing. Make sure the user is allowed
316+
to edit this node, and also check for password changes.
316317
'''
317-
if self.user in ('admin', self.db.user.get(self.nodeid, 'username')):
318-
self.shownode(message)
319-
else:
318+
if self.user == 'anonymous':
319+
raise Unauthorised
320+
321+
user = self.db.user
322+
323+
# get the username of the node being edited
324+
node_user = user.get(self.nodeid, 'username')
325+
326+
if self.user not in ('admin', node_user):
320327
raise Unauthorised
321328

329+
#
330+
# perform any editing
331+
#
332+
keys = self.form.keys()
333+
num_re = re.compile('^\d+$')
334+
if keys:
335+
try:
336+
props, changed = parsePropsFromForm(self.db, user, self.form,
337+
self.nodeid)
338+
if self.nodeid == self.getuid() and 'password' in changed:
339+
set_cookie = self.form['password'].value.strip()
340+
else:
341+
set_cookie = 0
342+
user.set(self.nodeid, **props)
343+
self._post_editnode(self.nodeid, changed)
344+
# and some feedback for the user
345+
message = '%s edited ok'%', '.join(changed)
346+
except:
347+
s = StringIO.StringIO()
348+
traceback.print_exc(None, s)
349+
message = '<pre>%s</pre>'%cgi.escape(s.getvalue())
350+
else:
351+
set_cookie = 0
352+
353+
# fix the cookie if the password has changed
354+
if set_cookie:
355+
self.set_cookie(self.user, set_cookie)
356+
357+
#
358+
# now the display
359+
#
360+
self.pagehead('User: %s'%node_user, message)
361+
362+
# use the template to display the item
363+
item = htmltemplate.ItemTemplate(self, self.TEMPLATES, 'user')
364+
item.render(self.nodeid)
365+
self.pagefoot()
366+
322367
def showfile(self):
323368
''' display a file
324369
'''
@@ -578,7 +623,6 @@ def login_action(self, message=None):
578623
password = self.form['__login_password'].value
579624
else:
580625
password = ''
581-
print self.user, password
582626
# make sure the user exists
583627
try:
584628
uid = self.db.user.lookup(self.user)
@@ -593,14 +637,16 @@ def login_action(self, message=None):
593637
self.make_user_anonymous()
594638
return self.login(message='Incorrect password')
595639

596-
# construct the cookie
597-
uid = self.db.user.lookup(self.user)
598-
user = binascii.b2a_base64('%s:%s'%(self.user, password)).strip()
599-
path = '/'.join((self.env['SCRIPT_NAME'], self.env['INSTANCE_NAME'],
600-
''))
601-
self.header({'Set-Cookie': 'roundup_user=%s; Path=%s;'%(user, path)})
640+
self.set_cookie(self.user, password)
602641
return self.index()
603642

643+
def set_cookie(self, user, password):
644+
# construct the cookie
645+
user = binascii.b2a_base64('%s:%s'%(user, password)).strip()
646+
path = '/'.join((self.env['SCRIPT_NAME'], self.env['INSTANCE_NAME']))
647+
self.header({'Set-Cookie': 'roundup_user="%s"; Path="%s";'%(user,
648+
path)})
649+
604650
def make_user_anonymous(self):
605651
# make us anonymous if we can
606652
try:
@@ -612,11 +658,11 @@ def make_user_anonymous(self):
612658
def logout(self, message=None):
613659
self.make_user_anonymous()
614660
# construct the logout cookie
615-
path = '/'.join((self.env['SCRIPT_NAME'], self.env['INSTANCE_NAME'],
616-
''))
617661
now = Cookie._getdate()
662+
path = '/'.join((self.env['SCRIPT_NAME'], self.env['INSTANCE_NAME']))
618663
self.header({'Set-Cookie':
619-
'roundup_user=deleted; Max-Age=0; expires=%s; Path=%s;'%(now, path)})
664+
'roundup_user=deleted; Max-Age=0; expires="%s"; Path="%s";'%(now,
665+
path)})
620666
return self.login()
621667

622668
def newuser_action(self, message=None):
@@ -633,12 +679,7 @@ def newuser_action(self, message=None):
633679
uid = cl.create(**props)
634680
self.user = self.db.user.get(uid, 'username')
635681
password = self.db.user.get(uid, 'password')
636-
# construct the cookie
637-
uid = self.db.user.lookup(self.user)
638-
user = binascii.b2a_base64('%s:%s'%(self.user, password)).strip()
639-
path = '/'.join((self.env['SCRIPT_NAME'], self.env['INSTANCE_NAME'],
640-
''))
641-
self.header({'Set-Cookie': 'roundup_user=%s; Path=%s;'%(user, path)})
682+
self.set_cookie(self.user, password)
642683
return self.index()
643684

644685
def main(self, dre=re.compile(r'([^\d]+)(\d+)'),
@@ -878,6 +919,9 @@ def parsePropsFromForm(db, cl, form, nodeid=0):
878919

879920
#
880921
# $Log: not supported by cvs2svn $
922+
# Revision 1.48 2001/11/03 01:30:18 richard
923+
# Oops. uses pagefoot now.
924+
#
881925
# Revision 1.47 2001/11/03 01:29:28 richard
882926
# Login page didn't have all close tags.
883927
#

0 commit comments

Comments
 (0)