mce has asked for the wisdom of the Perl Monks concerning the following question:

Hi wize ones,

I am working on a cgi project involving security. The server is apache on solaris. I cannot change any of the apache configuration and cannot recompile it. Nor can I change perl. (I cannot add suidperl). I cannot install sudo or similar.

Now my question: I want the user to authenticate via the web browser via cookies (f.e. via this.)

The setup is that I need to authenticate via Unix user and passwords (/etc/passwd and /etc/shadow).

I have this code that works fine if ran as root
use strict; use Data::Dumper; use CfgTie::TieShadow; my $userid=shift || die "missing argument"; my $guess=shift || die "missing argument"; my %passwd; my %allgroup; tie %passwd, 'CfgTie::TieShadow'; die "cannot init passwd hash" if not keys %passwd; my $rc=1; if ( $passwd{$userid} ) { my $password=$passwd{$userid}->{password} ; if ( crypt($guess,$password) eq $password ) { $rc=0; my @mygroups; $mygroups[0]=getgrgid($passwd{$userid}->{groupid}); # Get the groups my $regex=qr/\b$userid\b/; while ( my ($group,$passwd,$gid,$members)= getgrent ) { if ( $members =~ $regex ) { push @mygroups, $group; } } print join(',',@mygroups); } else { warn "Authentication Failed"; } } else { warn "User $userid does not exist"; } exit $rc;
But not as the apache user (this is normal as /etc/shadow is not readable as a normal user, unix perms prevents this).

So I desided to put the suid flag on an authetication script, and call this with a system call. Since I have no suidperl I need to compile it. p2e does the trick, but this will NOT let suid scripts run.

To make a long store short. Is there a way to autheniticate unix users/groups via cgi-bin? Is there a way to compile perl code so that suid bits work?

I hope this question is clear enough.
---------------------------
Dr. Mark Ceulemans
Senior Consultant
IT Masters, Belgium

Replies are listed 'Best First'.
Re: authenticate via cgi-bin
by valdez (Monsignor) on Jan 07, 2003 at 11:17 UTC

    Hi mce,
    you probably already know that using system passwords is not a good idea and using a setuid script is even worst :) Anyway, a simple solution is to copy periodically your /etc/shadow somewhere and make it accessible to Apache httpd using a cron job owned by root.

    Ciao, Valerio

Re: authenticate via cgi-bin
by submersible_toaster (Chaplain) on Jan 07, 2003 at 11:59 UTC
    ++valdez

    Seriously mce any solution you reach is probably going to be the least worst of a bad bunch. My thoughts were to have a local daemon running as root - and let your cgi script use some kind of IPC to talk to it. I suppose it's a pseudo system_auth proxy. This is rather more complicated than valdez's solution, but it should be said that having your cgi read the hashed passwords itself is begging to be exploited by one of many vulnerabilities that permit clients to see script source or god forbid fiddle with the file itself.

    Whatever ideas you come up with, exercise caution.

    I can't believe it's not psellchecked
      Hi,

      First, I cannot change the apache configuration, so I cannot play around with mod_auth.

      Second, why write a daemon if you already have them: ftp, telnet, rlogin, etc... .

      I know what I am doing. My code is quite secure and well tainted.
      Is there less harm in finding out passwords of Mysql, htpasswd etc, than there is of system accounts? It all depends on the setup and what you want to do.
      ---------------------------
      Dr. Mark Ceulemans
      Senior Consultant
      IT Masters, Belgium

        erm... mod_auth , don't recall mentioning it.

        Second, why write a daemon if you already have them: ftp, telnet, rlogin, etc... .
        What can I say but ,why write a cgi with authentication when there are daemons that support auth to /etc/shadow like rlogin... oh that's right this is a web application. My gist was that whilst your cgi gets called on demand by apache, you can have an entirely different and non-cgi accessible script that runs as root , hence has carte-blanche over things like getpwbyname that are simply unavailable to for instance - the apache user.

        I do not for a minute suggest that you don't know what you are doing. I am pleased your code is quite secure and well tainted.


        Is there less harm in finding out passwords of Mysql, htpasswd etc, than there is of system accounts?

        Obviously none are desirable, but owning a system account gives rise to far more possibilities for harming that particular system IMHO.


        I can't believe it's not psellchecked
Re: authenticate via cgi-bin
by mce (Curate) on Jan 07, 2003 at 12:15 UTC
    Hi,

    First of all, it is not my idea to use system passwords. It is the one of the project mgr. And why not use system passwords???? One can ftp or telnet to the machine anyway, and it is to be used only in our intranet. Nobody can access this machine from the internet.

    This said, I came up with this solution, it changes the verify subroutine in Merlyn WT 61 (see link in my original post).

    sub verify { my $username=shift || die "missing argument"; my $passwd=shift || die "missing argument"; require Net::FTP; my $t = new Net::FTP("localhost"); my $rc=0; if ( $t->login($username, $passwd) ) { $rc=1; } $t->quit(); return $rc; }
    This is not an elegant technique, but it works quite performant.

    Net::FTP is faster than Net::Telnet so I prefer this one. And since the machine is also an ftp server there is no harm.


    ---------------------------
    Dr. Mark Ceulemans
    Senior Consultant
    IT Masters, Belgium

      Brilliant - simple solution. ++ mce , --submersible_toaster and his high horse (read above), for which I can only apologise for , and attribute to ..erm ... gross somethingorother... but definatly gross


      I can't believe it's not psellchecked
Re: authenticate via cgi-bin
by traveler (Parson) on Jan 07, 2003 at 13:38 UTC
    Have you considered one of the PAM modules such as Authen::PAM? Perhaps that will help (if your system has PAM...)

    HTH, --traveler

      Yep,

      I tried that one also

      Authen::PAM works also only as root. You always get a authentication failure when you try it as a normal user.
      ---------------------------
      Dr. Mark Ceulemans
      Senior Consultant
      IT Masters, Belgium

        Hi ,

        The perlauthenhandler (sub directive) can be used to bypass the cgi from authenticating (if you could change the conf files .

        The use of suexec shall make the CGI process to run in the unix id itself ( not the nice way infact not recommended)

        You could install module in your own directory , that making it global (installing as a root) . The summary is people tend to go from seeing the /etc/passwd or configuring suexec on (as there are better ways to authenticate or authorize than the unixids)
Re: authenticate via cgi-bin
by strredwolf (Chaplain) on Jan 07, 2003 at 23:19 UTC
    Hmmm.... intresting question. However, didn't you think of a more direct solution, such as "Reading /etc/passwd and /etc/shadow, pharsing it, and whatnot?" Having a daemon copy /etc/shadow over so that's it's readable by Apache's user is also a better, simpler idea which goes well with it, and I think Perl's "crypt" has some code you can use to verify that a password is legit or not.

    --
    $Stalag99{"URL"}="http://stalag99.keenspace.com";