From 688a9f2f5387af7151ecc5f96374c4e234afa6e6 Mon Sep 17 00:00:00 2001 From: Rob van Son Date: Tue, 29 May 2012 14:47:36 +0200 Subject: [PATCH] Working Login again --- CGIscriptor.pl | 38 +++++++++++++++++++++++--------------- Private/.Passwords/test | 1 + 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/CGIscriptor.pl b/CGIscriptor.pl index 482db0b..6d30744 100755 --- a/CGIscriptor.pl +++ b/CGIscriptor.pl @@ -60,6 +60,7 @@ ENDOFPREHELPTEXT1 ############################################################################ # # Changes (document ALL changes with date, name and email here): +# 29 May 2012 - CGIsafeFileName does not accept filenames starting with '.' # 29 May 2012 - Added CGIscriptor::BrowseAllDirs to handle browsing directories # correctly. # 22 May 2012 - Added Access control with Session Tickets linked to @@ -346,7 +347,7 @@ $ENV{"RANDOMHASHCMD"} = 'dd count=1 if=/dev/urandom 2>/dev/null | shasum-5.12 -b # # File patterns of files which require a login. %LoginRequiredPatterns = ( -'^/Private/' => "Private/.Sessions\tPrivate/.Passwords\t/Private/Login.html\t+36000" +'^/Private(/|$)' => "Private/.Sessions\tPrivate/.Passwords\t/Private/Login.html\t+36000" ); # Session Ticket Directory: .Session/ # Password Directory: .Password/ @@ -2625,19 +2626,23 @@ sub Log_In_Access # () -> 0 = Access Allowed, Login page if access is not allowe # No patterns, no login return 0 unless %LoginRequiredPatterns; - # Get and initialize values + # Get and initialize values (watch out for stuff processed by BinaryMap files) my ($SessionPath, $PasswordsPath, $Login, $valid_duration) = ("", "", "", 0); - my $PATH_INFO = $ENV{'PATH_INFO'}; + my $PATH_INFO = $ENV{'CGI_BINARY_FILE'} ? $ENV{'CGI_BINARY_FILE'} : $ENV{'PATH_INFO'}; my $REMOTE_ADDR = $ENV{'REMOTE_ADDR'}; - + + # Get and check the tickets. Tickets are restricted to word-characters (alphanumeric+_) CGIexecute::defineCGIvariable('LOGINTICKET', ""); my $LOGINTICKET = ${"CGIexecute::LOGINTICKET"}; - return 0 unless !$LOGINTICKET || CGIscriptor::CGIsafeFileName($LOGINTICKET); + return 0 if ($LOGINTICKET && $LOGINTICKET =~ /[^\w]/isg); CGIexecute::defineCGIvariable('SESSIONTICKET', ""); my $SESSIONTICKET = ${"CGIexecute::SESSIONTICKET"}; - return 0 unless !$SESSIONTICKET || CGIscriptor::CGIsafeFileName($SESSIONTICKET); + return 0 if ($SESSIONTICKET && $SESSIONTICKET =~ /[^\w]/isg); + + # Username and password CGIexecute::defineCGIvariable('USERNAME', ""); my $username = ${"CGIexecute::USERNAME"}; + return 0 if $username =~ m!^[^\w]!isg || $username =~ m![^\w \-]!isg; my $userfile = lc($username); $userfile =~ s/[^\w]/_/isg; CGIexecute::defineCGIvariable('PASSWORD', ""); @@ -2702,12 +2707,13 @@ sub authorize_login # ($loginfile, $authorizationfile, $password, $SessionPath) # Get Randomsalt my $Randomsalt = $loginticket->{'Randomsalt'}->[0]; + return "" unless $Randomsalt; my $storedpassword = $authorization->{'Password'}->[0]; return "" unless $storedpassword; # Without the "bash -c", the 'echo -n' could use sh, which does not recognize the -n option - my $Hashedpassword = `bash -c 'echo -n $Randomsalt$storedpassword| $ENV{'SHASUMCMD'}'`; + my $Hashedpassword = `bash -c 'echo -n $Randomsalt$storedpassword| $ENV{"SHASUMCMD"}'`; chomp($Hashedpassword); return "" unless $password eq $Hashedpassword; @@ -2772,7 +2778,7 @@ sub check_ticket_validity # ($type, $ticketfile, $address, $path) my $path = shift || ""; # Is there a session ticket of this name? - return 0 unless -s "$ticket"; + return 0 unless -s "$ticketfile"; # There is a session ticket, is it linked to this IP address? my $ticket = read_ticket($ticketfile); @@ -2804,7 +2810,7 @@ sub check_ticket_validity # ($type, $ticketfile, $address, $path) ++$Expired if($CurrentTime > $ticket->{"Expires"}->[0]); }; return 0 if $Expired; - + return 1; }; @@ -4558,7 +4564,7 @@ sub CGIsafeFileName # FileName -> FileName or "" { my $FileName = shift || ""; return "" if $FileName =~ m?[^$::FileAllowedChars]?; - return "" if $FileName =~ m!(^|/|\:)\-!; + return "" if $FileName =~ m!(^|/|\:)[\-\.]!; return "" if $FileName =~ m@\.\.\Q$::DirectorySeparator\E@; # Higher directory not allowed return "" if $FileName =~ m@\Q$::DirectorySeparator\E\.\.@; # Higher directory not allowed return "" if $::BlockPathAccess && $FileName =~ m@$::BlockPathAccess@; # Invisible (blocked) file @@ -4594,17 +4600,19 @@ sub read_url # ($URL) -> page/file # # usage: # # # Allows to browse all directories. Stops at '/'. If the directory contains -# an indexfile, eg, index.html, that file will be used instead. Default is -# CGIscriptor::BrowseAllDirs('/', 'index.html') +# an indexfile, eg, index.html, that file will be used instead. Files must match +# the $Pattern, if it is given. Default is +# CGIscriptor::BrowseAllDirs('/', 'index.html', '') # -sub BrowseAllDirs # (Directory, indexfile) -> Print HTML code +sub BrowseAllDirs # (Directory, indexfile, $Pattern) -> Print HTML code { my $Directory = shift || '/'; my $indexfile = shift || 'index.html'; + my $Pattern = shift || ''; $Directory =~ s!/$!!g; # If the index directory exists, use that one @@ -4650,7 +4658,7 @@ sub BrowseAllDirs # (Directory, indexfile) -> Print HTML code next if $::BlockPathAccess && "$Directory/$file" =~ m@$::BlockPathAccess@; - if(!$Patterns || $file =~ m@$Pattern@) + if(!$Pattern || $file =~ m@$Pattern@) { my $Date = localtime($^T - (-M "$::CGI_HOME$Directory/$file")*3600*24); my $Size = -s "$::CGI_HOME$Directory/$file"; diff --git a/Private/.Passwords/test b/Private/.Passwords/test index 41ed904..9794fa0 100644 --- a/Private/.Passwords/test +++ b/Private/.Passwords/test @@ -3,4 +3,5 @@ Username: test Password: 30f75849b5fd059ef99b93bc0e278183ebf90c57 Salt: cc6b3fb0149b31b2deb905b97692e9282a7ea03b AllowedPaths: ^/Private/index.html$ +AllowedPaths: ^/Private/?$ IPaddress: 127.0.0.1 -- 2.11.4.GIT