From: Faye G. <fgi...@st...> - 2007-05-14 11:00:08
|
Hi, Disclaimer: Please forgive a slashcode novice if this discussion covers well trod land. The default install of slashcode attaches Slash::Apache::User to PerlAccessHandler. PerlAccessHandler is run before PerlAuthenHandler which is in turn runs before PerlAuthzHandler. So if using Apache external authentication the REMOTE_USER env var is not available at the "PerlAccessHandler" but _is_ available at the "PerlAuthzHandler" phase. This makes it difficult to setup accounts based upon the Authentication phase. So to gain finer control over user access would it not make sense to move Slash::Apache::User to the PerlAuthzHandler phase? Yours Faye -- --------------------------------------------------------- Faye Gibbins, Computing Officer (Infrastructure Services) GeoS KB; Linux, Unix, Security and Networks; 0131 6506426 --------------------------------------------------------- |
From: Clifton W. <cli...@gm...> - 2007-05-15 22:49:01
|
Ah, you make a good point, here. It's probably easier to think about things in this manner, and it's been a while since I've done mod_perl 1 so I think I might have missed critical differences in each of the necessary handlers -- there are *3*, not 2. Presented in the order they execute (I hope I have this right): PerlAccessHandler - Determine if the client is to have access to a specific resource, this is generally used to deal with IP banning as such and doesn't require the need for specific credentials (usually indicated by directives like "AuthType", "AuthName", and "require"). THIS is why Slash uses this handler. Really, Slash::Apache::User is probably doing too much, but since there is an IP ban list in Slash, it was probably just easier to handle everything in one piece of monolithic code. If other Slash sites needed the extra security, they could handle those pieces on their own. As it is, the only "authentication" necessary is handled by Slash's perl scripts and need *not* be handled by specific client/server interaction. (as is the case with PerlAuthenHandler and PerlAuthzHandler). The only distinction that Slash cares about at this point is "logged in" and "not logged in", and this is handled by the presence of a specific cookie. All other security measures are handled by the script code, not by specific server code. PerlAuthenHandler - Handles authorization, ala verifying user credentials and the like. You would think that this would be the natural place for your code, but it isn't, as it would require an "AuthType", "AuthName" and "require" directive, which Slash doesn't use. Since Slash has already done it's magic in PerlAccessHandler, this also makes this handler redundant. PerlAuthzHandler - Determins if an *authenticated user* is to have access to specific site resources. This assumes that a client *has already authenticated* based on the results of PerlAuthenHandler and is intrinsically linked to that particular phase. Since PerlAuthenHandler isn't used for Slash, neither is PerlAuthzHandler. Slash doesn't need $REMOTE_USER to do it's magic, you do. What you might want to try is to use stacked PerlAccessHandlers to check $REMOTE_USER. You would perform this check and automatically generate a properly formatted Slash cookie for that user, then let Slash's existing code run afterwards to do that voodoo that it do. For your purposes, your code would need to run first, and then the existing Slash handler would run last. PerlAccessHandler Slash::Apache::User::RemoteUserCheck Slash::Apache::User Here's an outline on how I think your PerlAccessHandler should work: - Check $REMOTE_USER. Robust code says you should do this. Do not expect it to exist. If it doesn't, fail out ("return Apache::Constants::FORBIDDEN" -- Apache::Constants::AUTH_REQUIRED might work here, too.). - [optional] If it exists, perform a check to see if the Kerberos credentials are valid. - Do a query on the $REMOTE_USER user in the database, if she does not exist, create an account with your default password. - If any errors, return "Apache::Constants::SERVER_ERROR". - If you get to this point with no problems, bake a properly formed Slash cookie, and send it to the client. - Done. "return Apache::Constants::OK" I *think* this is how it should work. I had to go back to the mod_perl 1.0 docs and check my assumptions and this is maybe the 3rd or 4th version of this email since I got several things wrong! ;-) -- I'm sure that probably doesn't instill great confidence in what I've written above, but it's the best I've got to offer at this time. If anyone else can correct any errors or misconceptions in the above, please do. I know I ain't perfect and am not arrogant enough to push forward that assertion. ^_^ Hope this helps! - Cliff >On 5/14/07, Faye Gibbins <fgi...@st...> wrote: > Hi, > > Disclaimer: > Please forgive a slashcode novice if this discussion covers > well trod land. > > The default install of slashcode attaches Slash::Apache::User to > PerlAccessHandler. > > PerlAccessHandler is run before PerlAuthenHandler which is in turn > runs before PerlAuthzHandler. > > So if using Apache external authentication the REMOTE_USER env var is > not available at the "PerlAccessHandler" but _is_ available at the > "PerlAuthzHandler" phase. This makes it difficult to setup accounts > based upon the Authentication phase. > > So to gain finer control over user access would it not make sense to > move Slash::Apache::User to the PerlAuthzHandler phase? > > Yours > Faye > > -- > --------------------------------------------------------- > Faye Gibbins, Computing Officer (Infrastructure Services) > GeoS KB; Linux, Unix, Security and Networks; 0131 6506426 > --------------------------------------------------------- |
From: Faye G. <fgi...@st...> - 2007-05-16 08:31:54
|
Hi Cliff, Yep this helps. I did some more testing with a stripped down set of scripts and this is what I've found out: * User opens up a brand new Firefox session with no cookies or history of any sort. * Request comes in to apache and the first relavent thing apache does is PerlAccessHandler. $r->user is undefined. * Then apache (which is setup to do Cosign (i.e. kerberos with cookies) calls its Authentication routines but does not call PerlAuthenHandler, ever (or at least I can't get it to) * At this point the users is taken to another URL, asked to enter their password etc. Then they are returned to the original URL /with/ a brand new encrypted authentication (Cosgin) cookie. * So Apache starts up again and the call reaches PerlAccessHandler which now has a defined $r->user. * Again Apache doesn't call PerlAuthenHandler. But does its cosign stuff again but as we have a valid cookie it passes through OK and doesn't redirect. * Then we get to PerlAuthzHandler, which does get called and has a defined $r->user. I.e, in order PerlAccessHandler Apache Auth PerlAccessHandler PerlAuthzHandler --- So the upshot of this is that I need to rely upon $r->user (and therefore REMOTE_USER). And it seems to me (but I'm prepared to stand corrected) that the first time Slash::Apache::User gets called it looks to slash like we're anonymous. What I've not investigated yet is weather slash gives me a cookie at that point which says "I'm anonymous". --- Which is why from MPOV it'd be better to either: 1) Move the whole shebang to PerlAuthzHandler, or 2) Leave the IP blocking stuff of Slash::Apache::User on the PerlAccessHandler and move every thing else to PerlAuthzHandler Either way instead of hacking my fix directly into Slash::Apache::User I might just put a hook into it and make things a bit more generic. If I get to to work I'll submit a patch. Yours Faye Clifton Wood wrote: > Ah, you make a good point, here. It's probably easier to think about > things in this manner, and it's been a while since I've done mod_perl > 1 so I think I might have missed critical differences in each of the > necessary handlers -- there are *3*, not 2. Presented in the order > they execute (I hope I have this right): > > PerlAccessHandler - Determine if the client is to have access to a > specific resource, this is generally used to deal with IP banning as > such and doesn't require the need for specific credentials (usually > indicated by directives like "AuthType", "AuthName", and "require"). > THIS is why Slash uses this handler. Really, Slash::Apache::User is > probably doing too much, but since there is an IP ban list in Slash, > it was probably just easier to handle everything in one piece of > monolithic code. If other Slash sites needed the extra security, they > could handle those pieces on their own. As it is, the only > "authentication" necessary is handled by Slash's perl scripts and need > *not* be handled by specific client/server interaction. (as is the > case with PerlAuthenHandler and PerlAuthzHandler). The only > distinction that Slash cares about at this point is "logged in" and > "not logged in", and this is handled by the presence of a specific > cookie. All other security measures are handled by the script code, > not by specific server code. > > PerlAuthenHandler - Handles authorization, ala verifying user > credentials and the like. You would think that this would be the > natural place for your code, but it isn't, as it would require an > "AuthType", "AuthName" and "require" directive, which Slash doesn't > use. Since Slash has already done it's magic in PerlAccessHandler, > this also makes this handler redundant. > > PerlAuthzHandler - Determins if an *authenticated user* is to have > access to specific site resources. This assumes that a client *has > already authenticated* based on the results of PerlAuthenHandler and > is intrinsically linked to that particular phase. Since > PerlAuthenHandler isn't used for Slash, neither is PerlAuthzHandler. > > Slash doesn't need $REMOTE_USER to do it's magic, you do. What you > might want to try is to use stacked PerlAccessHandlers to check > $REMOTE_USER. You would perform this check and automatically generate > a properly formatted Slash cookie for that user, then let Slash's > existing code run afterwards to do that voodoo that it do. > > For your purposes, your code would need to run first, and then the > existing Slash handler would run last. > > PerlAccessHandler Slash::Apache::User::RemoteUserCheck Slash::Apache::User > > Here's an outline on how I think your PerlAccessHandler should work: > - Check $REMOTE_USER. Robust code says you should do this. Do not expect it > to exist. If it doesn't, fail out ("return > Apache::Constants::FORBIDDEN" -- > Apache::Constants::AUTH_REQUIRED might work here, too.). > - [optional] If it exists, perform a check to see if the Kerberos > credentials are valid. > - Do a query on the $REMOTE_USER user in the database, if she does not exist, > create an account with your default password. > - If any errors, return "Apache::Constants::SERVER_ERROR". > - If you get to this point with no problems, bake a properly formed > Slash cookie, > and send it to the client. > - Done. "return Apache::Constants::OK" > > I *think* this is how it should work. I had to go back to the mod_perl > 1.0 docs and check my assumptions and this is maybe the 3rd or 4th > version of this email since I got several things wrong! ;-) -- I'm > sure that probably doesn't instill great confidence in what I've > written above, but it's the best I've got to offer at this time. If > anyone else can correct any errors or misconceptions in the above, > please do. I know I ain't perfect and am not arrogant enough to push > forward that assertion. ^_^ > > Hope this helps! > > - Cliff > >> On 5/14/07, Faye Gibbins <fgi...@st...> wrote: >> Hi, >> >> Disclaimer: >> Please forgive a slashcode novice if this discussion covers >> well trod land. >> >> The default install of slashcode attaches Slash::Apache::User to >> PerlAccessHandler. >> >> PerlAccessHandler is run before PerlAuthenHandler which is in turn >> runs before PerlAuthzHandler. >> >> So if using Apache external authentication the REMOTE_USER env var is >> not available at the "PerlAccessHandler" but _is_ available at the >> "PerlAuthzHandler" phase. This makes it difficult to setup accounts >> based upon the Authentication phase. >> >> So to gain finer control over user access would it not make sense to >> move Slash::Apache::User to the PerlAuthzHandler phase? >> >> Yours >> Faye >> >> -- >> --------------------------------------------------------- >> Faye Gibbins, Computing Officer (Infrastructure Services) >> GeoS KB; Linux, Unix, Security and Networks; 0131 6506426 >> --------------------------------------------------------- > > ------------------------------------------------------------------------- > This SF.net email is sponsored by DB2 Express > Download DB2 Express C - the FREE version of DB2 express and take > control of your XML. No limits. Just data. Click to get it now. > http://sourceforge.net/powerbar/db2/ > _______________________________________________ > Slashcode-development mailing list > Sla...@li... > https://lists.sourceforge.net/lists/listinfo/slashcode-development > -- --------------------------------------------------------- Faye Gibbins, Computing Officer (Infrastructure Services) GeoS KB; Linux, Unix, Security and Networks; 0131 6506426 --------------------------------------------------------- |
From: Clifton W. <cli...@gm...> - 2007-05-16 20:24:48
|
On 5/16/07, Faye Gibbins <fgi...@st...> wrote: > > Hi Cliff, > > Yep this helps. I did some more testing with a stripped down set of > scripts and this is what I've found out: > > * User opens up a brand new Firefox session with no cookies or history > of any sort. > > * Request comes in to apache and the first relavent thing apache does is > PerlAccessHandler. $r->user is undefined. > > * Then apache (which is setup to do Cosign (i.e. kerberos with cookies) > calls its Authentication routines but does not call PerlAuthenHandler, > ever (or at least I can't get it to) Right. PerlAuthenHandler depends on there being an "AuthName", "AuthType" and "require" directive in that configuration context. If there isn't, then the handler isn't run. > > * At this point the users is taken to another URL, asked to enter their > password etc. Then they are returned to the original URL /with/ a brand > new encrypted authentication (Cosgin) cookie. > > * So Apache starts up again and the call reaches PerlAccessHandler which > now has a defined $r->user. Which is promising, because then stacked PerlAccessHandlers should work. > * Again Apache doesn't call PerlAuthenHandler. But does its cosign stuff > again but as we have a valid cookie it passes through OK and doesn't > redirect. > > * Then we get to PerlAuthzHandler, which does get called and has a > defined $r->user. Ah! I thought PerlAuthzHandler was attached to PerlAuthenHandler. If this isn't the case, then I was wrong in my previous email. > I.e, in order > > PerlAccessHandler > Apache Auth > PerlAccessHandler > PerlAuthzHandler Well, yes -- however, according to an earlier paragraph, it's more like: PerlAccessHandler (Slash may think we're anonymous but it doesn't matter since we...) Redirect Apache Auth PerlAccessHandler PerlAuthzHandler > So the upshot of this is that I need to rely upon $r->user (and > therefore REMOTE_USER). And it seems to me (but I'm prepared to stand > corrected) that the first time Slash::Apache::User gets called it looks > to slash like we're anonymous. > > What I've not investigated yet is weather slash gives me a cookie at > that point which says "I'm anonymous". I'm not sure either, but if it does that cookie would be replaced by the "I'm logged in cookie", otherwise there would be problems with Slash. Moot point, I think. ^_^ > Which is why from MPOV it'd be better to either: > > 1) Move the whole shebang to PerlAuthzHandler, or > 2) Leave the IP blocking stuff of Slash::Apache::User on the > PerlAccessHandler and move every thing else to PerlAuthzHandler > > Either way instead of hacking my fix directly into Slash::Apache::User I > might just put a hook into it and make things a bit more generic. Well, you could do that. I'd prefer a stacked PerlAccessHandler because it seems to be more straight forward and would involve less work on your end. However if you'd feel better doing things this way, you'd probably be better off *subclassing* Slash::Apache::User in a PLUGIN (which is basically a Perl module) and changing things there [you can then "use base qw(Slash::Apache::User)" and when you need to use the old behavior just make a call to SUPER:: Or you could just rewrite the class entirely to your liking, and use that class for your handlers instead of Slash::Apache::User and do things as you like it. The options are numerous. > If I get to to work I'll submit a patch. > It's better that you do this in your own module first before worrying about patching main Slash. Make sure you have something that works, first. Good luck, Faye! - Cliff |
From: <fgi...@st...> - 2007-05-22 09:46:12
|
Hi, It turned out to be easier than I though to do what I wanted (with =20 CVS head as of a couple of weeks ago (start of May 2007)). I edited =20 the start of the handler in Slash::Apache::User (S::A::U) and added =20 this code: snip--- sub handler { =09my($r) =3D @_; =09return DECLINED unless $r->is_main; =09my $uri =3D $r->uri; # --new-- =09my $uid ; =09{ =09 my $user =3D $r->user; =09 my $slashdb =3D getCurrentDB(); =09 #print STDERR "User: ",$user,"\n"; =09 #print STDERR "UID: ",$slashdb->getUserUID($user),"\n"; =09 $uid =3D $slashdb->getUserUID($user); =09 if(!$uid){ =09=09# create user; =09=09my $matchname =3D nick2matchname($user); =09=09#print STDERR "Matchname: $matchname\n"; =09=09$uid=3D$slashdb->createUser( =09=09=09$matchname, $user."\@xxx.xx.ac.uk",$user); =09=09$slashdb->sqlUpdate('users', {newpasswd =3D> "foobar"}, 'uid=3D'.$uid)= ; =09 } my $newpass; =09 ($uid,$newpass)=3DuserLogin($slashdb->getUserUID($user),"foobar"); =09 #print STDERR "UID: $uid\n"; =09 #print STDERR "NEWPASS: $newpass\n"; =09 $r->subprocess_env(SLASH_USER =3D> $uid); =09} # --end of new-- snip--- About line 167 there's a "my $uid" which I've commented out. Then I removed the login form from index.shtml and edited the =20 default:misc:mainmenu template to remove the change password link. Then I edited apache's config to redirect any link for "login.pl" back =20 to the main page. Works like a treat. It still needs some optimization and I'll want to =20 abstract it bit, but basically it works. The one snag is that it doesn't log you in on the very first page, a =20 user needs to click on any link to get logged in. I need to find a way =20 to fake the cookie to fix this so I don't mess with the structure of =20 S::A::U too much. Yours Faye Quoting Clifton Wood <cli...@gm...>: > On 5/16/07, Faye Gibbins <fgi...@st...> wrote: >> >> Hi Cliff, >> >> Yep this helps. I did some more testing with a stripped down set of >> scripts and this is what I've found out: >> >> * User opens up a brand new Firefox session with no cookies or history >> of any sort. >> >> * Request comes in to apache and the first relavent thing apache does is >> PerlAccessHandler. $r->user is undefined. >> >> * Then apache (which is setup to do Cosign (i.e. kerberos with cookies) >> calls its Authentication routines but does not call PerlAuthenHandler, >> ever (or at least I can't get it to) > > Right. PerlAuthenHandler depends on there being an "AuthName", > "AuthType" and "require" directive in that configuration context. If > there isn't, then the handler isn't run. > >> >> * At this point the users is taken to another URL, asked to enter their >> password etc. Then they are returned to the original URL /with/ a brand >> new encrypted authentication (Cosgin) cookie. >> >> * So Apache starts up again and the call reaches PerlAccessHandler which >> now has a defined $r->user. > > Which is promising, because then stacked PerlAccessHandlers should work. > >> * Again Apache doesn't call PerlAuthenHandler. But does its cosign stuff >> again but as we have a valid cookie it passes through OK and doesn't >> redirect. >> >> * Then we get to PerlAuthzHandler, which does get called and has a >> defined $r->user. > > Ah! I thought PerlAuthzHandler was attached to PerlAuthenHandler. If > this isn't the case, then I was wrong in my previous email. > >> I.e, in order >> >> PerlAccessHandler >> Apache Auth >> PerlAccessHandler >> PerlAuthzHandler > > Well, yes -- however, according to an earlier paragraph, it's more like: > > PerlAccessHandler > (Slash may think we're anonymous but it doesn't matter > since we...) > Redirect > Apache Auth > PerlAccessHandler > PerlAuthzHandler > >> So the upshot of this is that I need to rely upon $r->user (and >> therefore REMOTE_USER). And it seems to me (but I'm prepared to stand >> corrected) that the first time Slash::Apache::User gets called it looks >> to slash like we're anonymous. >> >> What I've not investigated yet is weather slash gives me a cookie at >> that point which says "I'm anonymous". > > I'm not sure either, but if it does that cookie would be replaced by > the "I'm logged in cookie", otherwise there would be problems with > Slash. Moot point, I think. ^_^ > >> Which is why from MPOV it'd be better to either: >> >> 1) Move the whole shebang to PerlAuthzHandler, or >> 2) Leave the IP blocking stuff of Slash::Apache::User on the >> PerlAccessHandler and move every thing else to PerlAuthzHandler >> >> Either way instead of hacking my fix directly into Slash::Apache::User I >> might just put a hook into it and make things a bit more generic. > > Well, you could do that. I'd prefer a stacked PerlAccessHandler > because it seems to be more straight forward and would involve less > work on your end. However if you'd feel better doing things this way, > you'd probably be better off *subclassing* Slash::Apache::User in a > PLUGIN (which is basically a Perl module) and changing things there > [you can then "use base qw(Slash::Apache::User)" and when you need to > use the old behavior just make a call to SUPER:: > > Or you could just rewrite the class entirely to your liking, and use > that class for your handlers instead of Slash::Apache::User and do > things as you like it. The options are numerous. > >> If I get to to work I'll submit a patch. >> > > It's better that you do this in your own module first before worrying > about patching main Slash. Make sure you have something that works, > first. > > Good luck, Faye! > > - Cliff |