> 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 you have been logged out.  More
work...  To do this cleanly I will have to modify ##x in the template
processor.  I will want both the returntext/returnhttp link, and a
logout link.  With cookies enabled you will be able to follow the
return* link, and come back to your QmailAdmin session -- already in
progress.

I'm leaning towards the exit page.


One other thing I an looking at...


If you enter a user name and a password, but leave the domain name
blank, check the system passwords. (via PAM?) If the username/password
match then check to see if the user is a member of the vchkpw group.  If
so then present them with a list of all domains. Allow them to edit, add
and delete domains. Selecting a domain from the list will take you to
the main menu for that domain.  A link will be provided to go back to
the domain list.  A single login can manage all domains.

It may be better to have our own password file for SYSTEM_ADMINS.
Either way the program already sets AdminType = SYSTEM_ADMIN if you
login as rwidmer, with domain blank and anything in password.  All my
rights checking is done with < or > and the most important checks have
been moved into command.c.  I just have to figure out how to
authenticate the login.


NO_ADMIN 0 USER_ADMIN 1 DOMAIN_ADMIN 2 SYSTEM_ADMIN 3


Rick








Reply via email to