ispman/ispman-web/htdocs/admin index.cgi,1.19,1.20

Joerg Delker <[email protected]>
Newsgroups gmane.comp.isp.ispman.cvs
Message-ID <[email protected]>
Update of /cvsroot/ispman/ispman/ispman-web/htdocs/admin
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18295/ispman-web/htdocs/admin

Modified Files:
	index.cgi 
Log Message:
fixed bug [ 986136 ] reseller/client login does not work
first code cleanup
improved security with "session ip match" (needs updated CGI::Session libs!)


Index: index.cgi
===================================================================
RCS file: /cvsroot/ispman/ispman/ispman-web/htdocs/admin/index.cgi,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- index.cgi	8 Jun 2004 19:22:53 -0000	1.19
+++ index.cgi	7 Jul 2004 20:15:15 -0000	1.20
@@ -1,65 +1,64 @@
 #!/usr/bin/perl -w
 use strict;
 
+# FIXME: this shouldn't be a package
 package ISPMan;
 
-# see the subroutine at the bottom to figure out the installation location
-locateInstallDir();
-
-use vars qw($InstallDir);
-unshift @INC, $ISPMan::InstallDir . "/lib";
-
-use vars qw($r $ispman);
-
-require CGI::Session::File;
-import CGI::Session::File;
+use FindBin;
+unshift @INC, "$FindBin::Bin/../../lib";
 
-require CGI;
-import CGI;
+use CGI;
+use CGI::Session qw(-ip-match);
+use CGI::Carp qw(fatalsToBrowser);
 
-require CGI::Carp;
-import CGI::Carp "fatalsToBrowser";
+# global vars
+our $ispman;
+our $r;
 
+# create new CGI object
 undef $r;
 $r = new CGI;
 
-my $sid = $r->cookie("SESSION_ID") || $r->param("sid") || undef;
-
-my $session = new CGI::Session::File(
-    $sid,
-    {
-        LockDirectory => '/tmp',
-        Directory     => '/tmp'
-    }
-);
+# check for session cookie
+my $sid = $r->cookie("CGISESSID") || undef;
 
-$sid = $session->id();
+# get/create session
+my $session = new CGI::Session("driver:File", $sid, {Directory=>'/tmp'});
 
-my $cookie = $r->cookie( -name => "SESSION_ID", -value => $sid );
+# do we have a authenticated session?
+if ($session->param("uid")) { # yes
+    
+    # is this a logout request?
+    if ($r->param("logout")){
+        # delete session and invalidate cookie
+        $session->delete();
+        my $cookie = $r->cookie(CGISESSID => "" );
 
-if ( $session->param("uid") ) {
-    if ( $r->param("logout") ) {
-        $session->clear( [ "uid", "pass", "language" ] );
-        print $r->redirect( -url => $ENV{'SCRIPT_NAME'} );
+        # redirect to login page
+        print $r->redirect( -url => $ENV{'SCRIPT_NAME'},
+                            -cookie => $cookie );
         exit;
     }
 }
-else {
+else { # no session
+
+    # get ispman config
     require ISPMan::Config;
-    import ISPMan::Config;
     my $config = ISPMan::Config->new();
-    if ( $r->param("uid") && $r->param("pass") ) {
+
+    # do we have login credentials?
+    if ( $r->param("uid") && $r->param("pass") ) { # yes, so try logon
+
+        # create LDAP object
         require Net::LDAP;
-        import Net::LDAP;
-        my $ldap =
-          Net::LDAP->new( $config->{'ldapHost'},
-            version => $config->{'ldapVersion'} )
-          or die "$@";
+        my $ldap = Net::LDAP->new( $config->{'ldapHost'},
+                                   version => $config->{'ldapVersion'} )
+            or die "$@";
 
+        my ( $binddn, $base, $filter, $scope );
         my $uid = $r->param("uid");
 
-        my ( $dn, $base, $filter, $scope );
-
+        # prepare binddn
         if ( $r->param("logintype") && $r->param("logintype") ne "admin" ) {
             if ( $r->param("logintype") eq "reseller" ) {
                 $base   = "ou=ispman,$config->{'ldapBaseDN'}";
@@ -71,6 +70,8 @@
                 $scope  = "sub";
                 $filter = "&(objectClass=ispmanClient)(uid=$uid)";
             }
+
+            # search for binddn
             my $mesg = $ldap->search(
                 base    => $base,
                 scope   => $scope,
@@ -78,7 +79,6 @@
                 "attrs" => []
             );
             my ($entry) = $mesg->entry(0);
-
             unless ($entry) {
                 print $r->header();
                 print "Entry not found.<br>";
@@ -90,58 +90,59 @@
                 exit;
             }
 
-            $dn = $entry->dn();
+            $binddn = $entry->dn();
         }
-        else {
-
-            # there was no logintype set.
-            # set this to "admin"
-            # backwards compatibility.
+        else { # logintype undef or admin
+            
             $r->param( "logintype", "admin" );
-            $dn = join ',',
+            $binddn = join ',',
               (
                 sprintf( "uid=%s", $r->param("uid") ),
                 "ou=admins", $config->{'ldapBaseDN'}
               );
         }
 
-        my $result = $ldap->bind( $dn, password => $r->param("pass") );
+        # authenticate to ldap server
+        my $result = $ldap->bind( $binddn, password => $r->param("pass") );
         if ( $result->code ) {
             print $r->header();
             print $result->error;
-            exit;
+            $ldap->unbind();
         }
-        else {
+        else { # success
 
-            # set the cookie and the session
-            $session->param( "dn", $dn );
-            my @attr = split( /\s*,\s*/, CGI::unescape($dn) );
-            for (@attr) {
-                my ( $var, $val ) = split( /\s*=\s*/, $_ );
-                $session->param( $var, $val );
+            # save necessary data in session and continue login
+            $session->save_param($r, ["logintype","language"]);
+            $session->param( "sessID", time );
+            $session->param( "uid", $uid );
+            if ($binddn =~ /ispmanResellerId=(\d+)/){
+                $session->param("ispmanResellerId",$1);
             }
-            # disabled due to bug [940878]
-            #$session->save_param($r);
+            if ($binddn =~ /ispmanClientId=(\d+)/){
+                $session->param("ispmanClientId",$1);
+            }                
+
+            # create session cookie
+            my $cookie = $r->cookie(CGISESSID => $session->id );
+
+            # start from the beginning with this new session
             print $r->redirect(
                 -url    => $ENV{'SCRIPT_NAME'},
                 -cookie => $cookie
             );
         }
+
+        # finished user authentication
+        $ldap->unbind();
+        exit;
     }
-    else {
+    else { # no sessions, no credentials
+        
         require ISPMan::L10N;
-        import ISPMan::L10N;
         require Text::Template;
-        import Text::Template;
-        my $templateDirectory;
-        if ( -d "$config->{'installDir'}/cgi-bin" ) {
-            $templateDirectory = "$config->{'installDir'}/cgi-bin/tmpl";
-        }
-        else {
-            $templateDirectory =
-              "$config->{'installDir'}/ispman-web/cgi-bin/tmpl";
-        }
 
+        # prepare HTML template for login page
+        my $templateDirectory = "$config->{'installDir'}/cgi-bin/tmpl";
         my $template = new Text::Template(
             DELIMITERS => [ '<perl>', '</perl>' ],
             TYPE       => "FILE",
@@ -154,23 +155,9 @@
 
 }
 
-if ( !$session->param("sessID") || $r->param("newSession") ) {
-    $session->param( "sessID",    time );
-    $session->param( "logintype", $r->param("logintype") );
-    $session->param( "language",  $r->param("language") );
-
-    # disabled session save because
-    # a) cookie expires at session end, so no need for saving the session
-    # b) security breach! password is saved in clear
-    #   $session->save_param($r);
-}
-
-if ( $r->param("language") ) {
-    $session->param( "language", $r->param("language") );
-
-    # disabled due to bug [940878]
-    #$session->save_param($r);
-}
+# NOTICE:
+# This point is *only* reached with a valid session id.
+# So the user is properly authenticated...
 
 print $r->header( -charset => "UTF-8" );
 
@@ -178,29 +165,16 @@
 #print "<p>Request Language is ", $r->param("language");
 
 require ISPMan;
-require ISPMan::Log;
 import ISPMan;
-import ISPMan::Log;
 
 $ENV{'LANGUAGE'} = $r->param("language") || $session->param("language");
 
+# create ISPMan object
 $ispman = ISPMan->new();
 
 $ispman->remote_user( $session->param("uid") );
 $ispman->{'sessID'} = $session->param("sessID");
 
-if ( $r->param("domain") ) {
-    $r->param( "ispmanDomain", $r->param("domain") );
-}
-
-if ( $r->param("dn") ) {
-    my @attr = split( /\s*,\s*/, CGI::unescape( $r->param("dn") ) );
-    for (@attr) {
-        my ( $var, $val ) = split( /\s*=\s*/, $_ );
-        $r->param( $var, $val );
-    }
-}
-
 my $_path = $ENV{'SCRIPT_NAME'};
 $_path =~ s!/admin/index.cgi!!;
 $ispman->setConfig( "ispmanUrlPrefix", $_path );
@@ -214,45 +188,12 @@
     $mode ||= "ispman";
 }
 
+# save session in ispman object
 $ispman->{'session'} = $session;
+
+# proceed with action
 $ispman->$mode($r);
 
 1;
 
-sub locateInstallDir {
-    my @script_components = split '/', $ENV{'SCRIPT_FILENAME'};
-
-    #remove the script name
-    pop @script_components;
-
-    #now @script_components contains all the directories from the / in an array
-
-    my $chopDirs = 0;
-
-    if ( -e "../../lib/ISPMan.pm" ) {
-
-        #remove two directories from the end
-        $chopDirs = 2;
-    }
-    elsif ( -e "../../../lib/ISPMan.pm" ) {
-
-        #Developers/maintainers. Without Install
-        $chopDirs = 3;
-    }
-    else {
-
-        #There should be more code here to determine the InstallationPath
-        print "Content-type: text/plain\n\n";
-        print "Cannot determine Installation Path\n";
-        exit;
-    }
-
-    if ($chopDirs) {
-        for ( 1 .. $chopDirs ) {
-            pop @script_components;
-        }
-    }
-    $ISPMan::InstallDir = join '/', @script_components;
-    return $ISPMan::InstallDir;
-}
 



-------------------------------------------------------
This SF.Net email sponsored by Black Hat Briefings & Training.
Attend Black Hat Briefings & Training, Las Vegas July 24-29 - 
digital self defense, top technical experts, no vendor pitches, 
unmatched networking opportunities. Visit www.blackhat.com
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.