Re: [qmailadmin] qmailadmin-rww -- md5 session ID
You might be able to piggy-back off the md5 code in vpopmail... Yes, it looks very close to a drop-in replacement to the one I found. I don't even have to change the build process again. The file names match. Wish I would have seen that sooner! I have added three defines in qmailadmin.h, that should actually be set by ./configure options: I think we should also add a probability how often the garbage collector is executed and deletes the expired session files. Executing it every time QmailAdmin is executed is IMO to much and slows it only down. I already garbage collect only after a successful login, so it doesn't run with every hit, but probability testing won't be hard to add. I should also make it so the page paints before the garbage collection starts so it doesn't slow the user. You could read from /dev/random or /dev/urandom, if present. There's a patch pending for vpopmail that uses that device for random data. I guess if vpopmail uses it it should be safe for QmailAdmin. I know that should work on my Linux boxes... How do you tell if it is present? ./configure? What happens if it is not there? I suspect the whole block of code and configure.in(?) can be stolen from vpopmail. Random numbers are more or less always generated out of the current time, but I think we perhaps could generate the SESSION_SECRET string randomly, too. Or repeat the hashing a random time (1-10 for example). If you always have a good random generator avialble that is much better than a preset secret. I don't know enough about c portability to decide. One thing I've heard is that /dev/?random can sometimes block if there isn't enough enthropy available. That could be bad on a lightly loaded machine. I don't need to retain the random input values for anything, I am just trying to make it very hard to predict SessionID values. Why get the things messed up? I would do a logout like 1) Delete the cookie/no more sids in the urls 2) Delete the session file on the server On a relogin you create everything new as it would be the first login. What it does now... in get_session_id() The first time you hit QmailAdmin the program checks for a cookie. There is none, so it sets SessionFromCookie = 0. Then it checks for SessionID in Request.(Get/Put) Again there is none so it generates a new SessionID. in paint_headers() Since SessionFromCookie is 0 (false) and SessionID is set a Set-cookie header for SessionID will be sent. Since there is no session file associated with the new SessionID and the [Login] button was not clicked, you are only allowed to login. show_login() calls send_template() and paints the login page, then the progran is done. Since SessionFromCookie is 0 a hidden field is included in the page containing SessionID. -- the user enters user/domain/password then clicks [login] -- This time through... in get_session_id() SessionID is found in Cookie, so SessionFromCookie = 1, and SessionID is set. in paint_headers SessionFromCookie is 1, so do not send a SetCookie header. Still no session file matching your SessionID, but this time [Login] was clicked so verify the login. If the login is good create the session file then call show_menu -- else call show_login, with the fields still filled in the way the user left them. (I hate having to re-enter everything even more than I hate being dropped into an error page that tells me to hit [Back] and try again.) As long as a cookie is found, the SessionID will not be appended to link URLS, and the hidden field may not be added to forms. Right now it is always added, and that does not hurt anything. Mere mortals will never see it. A ##t? could be used to hide the hidden SessionID field. On the other hand it might be nice to be able to view the SessionID with View Source if you have a problem. I don't have to decide yet... -- the user does whatever, then clicks the exit link -- in get_session_id() SessionID is found in Cookie, so SessionFromCookie = 1, and SessionID is set. in main() Since exit was selected, delete the session file, set SessionFromCookie to 0, and set SessionID = . in paint_headers() Since SessionFromCookie is 0 and SessionID is blank, send a Set-cookie header with an old Expires value. The browser will delete the cookie. Then we need to paint something to the browser... But what? Things I have considered... o Delay setting the cookie until there is a valid login. I very much like setting the SessionID cookie the first time I paint the show_login.html template. This way I know that the next operation will be a form entry. If I wait until I have a valid login the next operation will be a menu, and every link will have to have the SessionID appended in case cookies are off. That looks uggly... o Don't worry about leaving the cookie in the browser. Things worked well right up to the time I decided it wasn't cool to do a logout without cleaning up the cookie. That is tacky... o Have an exit page that tells you that
[qmailadmin] qmailadmin-rww -- md5 session ID
QUESTION: Is there a better way to 'touch' the session file to extend the session than opening it for append, then closing it? The goal is to update the mtime without altering the file contents. Anyway, I have been working on session handling. I found this MD5 library on SourceForge, and it appears to me that we can add the md5.c and md5.h files to our distribution (unchanged) and add a note where they came from, and how to get the entire package in our docs. http://sourceforge.net/projects/libmd5-rfc/ I have added three defines in qmailadmin.h, that should actually be set by ./configure options: SESSION_PATH - Where to store the session files. SESSION_LIFETIME - How long (in seconds) until a session expires. SESSION_SECRET- A string that should be different at each site that is mixed into the MD5 hash. This should make it harder for an outsider to guess session ID values. The session ID is currently the MD5 hash of the SESSION_SECRET and the current time. If anyone has a portable suggestion on increasing the randomness, please let me know. If cookies are available I store the MD5 hash there, if not I pass it either in the URL of a link, or in a hidden field for forms. I no longer pass user, dom and time in any URLs. (But you can still set the fields on the login page by passing them.) I am currently storing the IP address of the client, returntext, returnhttp, AdminType, LoginUserName, and LoginDomainName in the session. It is very easy to add additional items, but I want to restrict session use to things that identify the current user, leaving info on what they are doing to the URL. That will allow you to have more than one QmailAdmin window open into different parts of your mail system. All your windows will have the same access rights. Are returntext and returnhttp documented anywhere? If not I'll write something... Logging in and logging out are working, but I have a problem if you logout and want to log back in. I want to delete the cookie from your browser when you logout, but if I do that then drop you into the login page things get confused and the login does not work. Right now I am working around it by dropping you into a page that tells you that you are logged out, and providing a link back to login - but that does not currently maintain any user= and dom= passed when QmailAdmin was first run. I guess I can store them in the session file when you first login. Anyone have a better idea? I am also continuing my attack on global variables, and increasing the use of function parms. Currently everything but the login/logout functions are very broken. When I am done the following global variables will be gone: Password, Gecos, Quota, Time, Action, Newu, Password1, Password2, Crypted, Alias, AliasType, LineData, Message, SearchUser, Mytime and possibly others. TmpCGI has been renamed to Request, and I have added Cookie and PathInfo. All are dynamic strings allocated after I know their actual lengths, and will be kept around for the entire run so you can call GetValue() on them to retrieve data. I will be moving the GetValue calls closer to where they are used, and store the result in function locals. It will be a few days before I post updated code... Rick
Re: [qmailadmin] qmailadmin-rww -- md5 session ID
Rick Widmer wrote: QUESTION: Is there a better way to 'touch' the session file to extend the session than opening it for append, then closing it? The goal is to update the mtime without altering the file contents. hmm, interesting question. I don't see no other way then the one you described at the moment. [...] I have added three defines in qmailadmin.h, that should actually be set by ./configure options: SESSION_PATH - Where to store the session files. SESSION_LIFETIME - How long (in seconds) until a session expires. SESSION_SECRET- A string that should be different at each site that is mixed into the MD5 hash. This should make it harder for an outsider to guess session ID values. I think it would be good if we could make SESSION_SECRET independent from the configure-line. It should IMO be possible to run only ./configure without any options. I think we should also add a probability how often the garbage collector is executed and deletes the expired session files. Executing it every time QmailAdmin is executed is IMO to much and slows it only down. The session ID is currently the MD5 hash of the SESSION_SECRET and the current time. If anyone has a portable suggestion on increasing the randomness, please let me know. Random numbers are more or less always generated out of the current time, but I think we perhaps could generate the SESSION_SECRET string randomly, too. Or repeat the hashing a random time (1-10 for example). [...] Logging in and logging out are working, but I have a problem if you logout and want to log back in. I want to delete the cookie from your browser when you logout, but if I do that then drop you into the login page things get confused and the login does not work. Right now I am working around it by dropping you into a page that tells you that you are logged out, and providing a link back to login - but that does not currently maintain any user= and dom= passed when QmailAdmin was first run. I guess I can store them in the session file when you first login. Anyone have a better idea? Why get the things messed up? I would do a logout like 1) Delete the cookie/no more sids in the urls 2) Delete the session file on the server On a relogin you create everything new as it would be the first login. [...] It will be a few days before I post updated code... You are really doing a great job! Thanks. Rick Philipp
Re: [qmailadmin] qmailadmin-rww -- md5 session ID
On Jan 18, 2004, at 8:29 PM, Rick Widmer wrote: QUESTION: Is there a better way to 'touch' the session file to extend the session than opening it for append, then closing it? The goal is to update the mtime without altering the file contents. That's probably the best method. I googled for the source to touch.c, and found one version that actually read the first byte, rewound the file, and wrote it back. Anyway, I have been working on session handling. I found this MD5 library on SourceForge, and it appears to me that we can add the md5.c and md5.h files to our distribution (unchanged) and add a note where they came from, and how to get the entire package in our docs. http://sourceforge.net/projects/libmd5-rfc/ You might be able to piggy-back off the md5 code in vpopmail... I have added three defines in qmailadmin.h, that should actually be set by ./configure options: SESSION_PATH - Where to store the session files. SESSION_LIFETIME - How long (in seconds) until a session expires. SESSION_SECRET- A string that should be different at each site that is mixed into the MD5 hash. This should make it harder for an outsider to guess session ID values. I'm sure we can add these to the configure.in script. It might even be possible to randomly build SESSION_SECRET. The session ID is currently the MD5 hash of the SESSION_SECRET and the current time. If anyone has a portable suggestion on increasing the randomness, please let me know. You could read from /dev/random or /dev/urandom, if present. There's a patch pending for vpopmail that uses that device for random data. If cookies are available I store the MD5 hash there, if not I pass it either in the URL of a link, or in a hidden field for forms. I no longer pass user, dom and time in any URLs. (But you can still set the fields on the login page by passing them.) Excellent. Logging in and logging out are working, but I have a problem if you logout and want to log back in. I want to delete the cookie from your browser when you logout, but if I do that then drop you into the login page things get confused and the login does not work. Why doesn't it work? Are you drawing the page before you have a chance to send a blank cookie in the header? Right now I am working around it by dropping you into a page that tells you that you are logged out, and providing a link back to login - but that does not currently maintain any user= and dom= passed when QmailAdmin was first run. I guess I can store them in the session file when you first login. Anyone have a better idea? I am also continuing my attack on global variables, and increasing the use of function parms. Currently everything but the login/logout functions are very broken. When I am done the following global variables will be gone: Password, Gecos, Quota, Time, Action, Newu, Password1, Password2, Crypted, Alias, AliasType, LineData, Message, SearchUser, Mytime and possibly others. This is wonderful. Thanks for putting in the time and effort to clean this up. It will be a few days before I post updated code... Once 1.2.0 is released as final, I'll add you to SourceForge, branch CVS off for the 1.2 series, and you can take control of the development series with your work. -- Tom Collins - [EMAIL PROTECTED] QmailAdmin: http://qmailadmin.sf.net/ Vpopmail: http://vpopmail.sf.net/ Info on the Sniffter hand-held Network Tester: http://sniffter.com/