Changeset 27318

Show
Ignore:
Timestamp:
08.05.2013 20:27:02 (6 years ago)
Author:
ak19
Message:

Authentication at perl level for when setting user-added comments. 1. metadata-server.plnow encrypts the key, so that it can be checked against what's in the key db. 2. gdslCGI.pm now has an encrypt_key subroutine. 3. baseaction.pm's authentication_enabled is turned on and the authenticate_user() subroutine now follows recpt's userdb.cpp::check_key by first checking for a given key when no password is given, and if the key validates and isn't stale, then its timestamp in the key db is updated. The code for checking the group that the user belongs to (which had been commented out since user comments can be set by anyone with a GS account, they don't need to belong to a collection editing group) has been moved to a new function called check_group, with the line calling it commented out. 4. style.dm passes in un and ky cgi args to the gsapi object's constructor. 5. gsajaxapi.js's constructor takes the un and ky parameters and then uses these in the Get and Post methods when making calls to metadata-server.pl.

Location:
main/trunk/greenstone2
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • main/trunk/greenstone2/common-src/cgi-bin/gsdlCGI.pm

    r27158 r27318  
    802802    }else{ 
    803803    $java_classpath = $java_gsdl3_classpath . ";" . $java_remaining_classpath; 
    804     } 
     804    } # can't use util::envvar_prepend(), since the $java_classpath here is not a $ENV type env variable 
    805805     
    806806    my $java_command="\"$java\" -classpath \"$java_classpath\" org.greenstone.gsdl3.service.Authentication \"$password\""; # 2>&1"; 
     
    808808 
    809809    return $hashedpwd; 
     810} 
     811 
     812sub encrypt_key 
     813{ 
     814    my $self = shift @_; 
     815 
     816    # I think the encryption method used on the key may be the same for GS3 and GS2 
     817    # (The encryption method used on the pw definitely differs between the two GS versions) 
     818    if (defined $self->param("ky")) { 
     819    require "$self->{'gsdlhome'}/perllib/cpan/Crypt/UnixCrypt.pm";  # This is OK on Windows 
     820    $self->param('-name' => "ky", '-value' => &Crypt::UnixCrypt::crypt($self->clean_param("ky"), "Tp")); 
     821    } 
    810822} 
    811823 
  • main/trunk/greenstone2/common-src/cgi-bin/metadata-server.pl

    r27295 r27318  
    5555    $gsdl_cgi->checked_chdir($gsdlhome); 
    5656 
    57     # Encrypt the password 
     57    # Encrypt the password and key 
    5858    $gsdl_cgi->encrypt_password(); 
     59    $gsdl_cgi->encrypt_key(); 
    5960 
    6061    require cgiactions::metadataaction; 
  • main/trunk/greenstone2/macros/style.dm

    r27313 r27318  
    240240    \} 
    241241 
    242     var gsapi = new GSAjaxAPI("_gwcgi_","_cgiargc_"); 
     242    var un = "_cgiargun_"; 
     243    var ky = "_cgiargky_"; 
     244    var gsapi = new GSAjaxAPI("_gwcgi_","_cgiargc_","_cgiargun_","_cgiargky_"); 
    243245     
    244246    // http://stackoverflow.com/questions/6312993/javascript-seconds-to-time-with-format-hhmmss 
  • main/trunk/greenstone2/perllib/cgiactions/baseaction.pm

    r27295 r27318  
    3131use inexport; 
    3232 
    33 our $authentication_enabled = 0; # debugging flag (can debug without authentication when set to 0) 
     33# for time conversion and formatting functions 
     34use Time::Local; 
     35use POSIX; 
     36 
     37our $authentication_enabled = 1; # debugging flag (can debug without authentication when set to 0) 
    3438our $mail_enabled = 0; 
    3539 
     
    225229    my $collection = shift(@_); 
    226230 
     231    my $keydecay = 1800; # 30 mins same as in runtime-src/recpt/authentication.cpp 
     232 
    227233    my $gsdl_cgi = $self->{'gsdl_cgi'}; 
    228234 
    229235    # Remove the pw argument (since this can mess up other scripts) 
    230236    my $user_password = $gsdl_cgi->clean_param("pw"); 
     237    my $user_key = $gsdl_cgi->clean_param("ky"); 
     238 
    231239    $gsdl_cgi->delete("pw"); 
    232  
    233     if ((!defined $user_password) || ($user_password =~ m/^\s*$/)) { 
    234     $gsdl_cgi->generate_error("Authentication failed: no password specified."); 
     240    $gsdl_cgi->delete("ky"); 
     241 
     242    if ((!defined $user_password || $user_password =~ m/^\s*$/) && (!defined $user_key || $user_key =~ m/^\s*$/)) { 
     243    $gsdl_cgi->generate_error("Authentication failed: no password or key specified."); 
    235244    } 
    236245 
     
    259268    $gsdl_cgi->generate_error("Authentication failed: no account for user '$username'."); 
    260269    } 
    261  
     270     
    262271    # Check password 
    263     my ($valid_user_password) = ($user_data =~ /\<password\>(.*)/); 
    264     if ($user_password ne $valid_user_password) { 
    265     $gsdl_cgi->generate_error("Authentication failed: incorrect password."); 
     272    if(defined $user_password) { 
     273    my ($valid_user_password) = ($user_data =~ /\<password\>(.*)/); 
     274    if ($user_password ne $valid_user_password) { 
     275        $gsdl_cgi->generate_error("Authentication failed: incorrect password."); 
     276    } 
     277    }  
     278    else { # check $user_key #if(!defined $user_password && defined $user_key) { 
     279     
     280    # check to see if there is a key for this particular user in the database that hasn't decayed. 
     281    # if the key validates, refresh the key again by setting its timestamp to the present time. 
     282 
     283    # Use db2txt to get the key accounts information 
     284    my $key_db_file_path = &util::filename_cat($etc_directory, "key.gdb"); 
     285     
     286    my $key_db_content = ""; 
     287    open(USERS_DB, "db2txt \"$key_db_file_path\" |"); 
     288    while (<USERS_DB>) { 
     289        $key_db_content .= $_; 
     290    } 
     291     
     292    my %key_db_data = (); 
     293    foreach my $key_db_entry (split(/-{70}/, $key_db_content)) { 
     294        if ($key_db_entry =~ /\n?\[(.+)\]\n/) { 
     295        $key_db_data{$1} = $key_db_entry; 
     296        } 
     297    } 
     298 
     299    # check key entry 
     300    my $key_data = $key_db_data{$user_key}; 
     301    if (!defined $key_data) { 
     302         
     303        #$gsdl_cgi->generate_error("Authentication failed: invalid key $user_key. Does not exist."); 
     304        $gsdl_cgi->generate_error("Authentication failed: invalid key. No entry for the given key."); 
     305    } 
     306    else { 
     307        my ($valid_username) = ($key_data =~ /\<user\>(.*)/); 
     308        if ($username ne $valid_username) { 
     309        $gsdl_cgi->generate_error("Authentication failed: key does not belong to user."); 
     310        } 
     311         
     312        # http://stackoverflow.com/questions/12644322/how-to-write-the-current-timestamp-in-a-file-perl 
     313        # http://stackoverflow.com/questions/2149532/how-can-i-format-a-timestamp-in-perl 
     314        # http://stackoverflow.com/questions/7726514/how-to-convert-text-date-to-timestamp 
     315         
     316        my $current_timestamp = time; #localtime(time); 
     317         
     318        my ($keycreation_time) = ($key_data =~ /\<time\>(.*)/); # of the form: 2013/05/06 14:39:23 
     319        if ($keycreation_time !~ m/^\s*$/) { # not empty 
     320         
     321        my ($year,$mon,$mday,$hour,$min,$sec) = split(/[\s\/:]+/, $keycreation_time); # split by space, /, : 
     322        my $key_timestamp = timelocal($sec,$min,$hour,$mday,$mon-1,$year); 
     323         
     324        if(($current_timestamp - $key_timestamp) > $keydecay) { 
     325            $gsdl_cgi->generate_error("Authentication failed: key has expired."); 
     326        } else { 
     327            # succeeded, update the key's time in the database 
     328             
     329            # beware http://community.activestate.com/forum/posixstrftime-problem-e-numeric-day-month 
     330            my $current_time = strftime("%Y/%m/%d %H:%M:%S\n", localtime($current_timestamp)); # POSIX 
     331             
     332            my $infodbtype = $self->{'infodbtype'}; 
     333            my $key_rec = &dbutil::read_infodb_entry($infodbtype, $key_db_file_path, $user_key); 
     334            $key_rec->{"time"}->[0] = $current_time; 
     335            my $status = &dbutil::set_infodb_entry($infodbtype, $key_db_file_path, $user_key, $key_rec); 
     336             
     337            if ($status != 0) { 
     338            $gsdl_cgi->generate_error("Error updating authentication key."); 
     339            } 
     340        } 
     341        } else { 
     342        $gsdl_cgi->generate_error("Authentication failed: Invalid key entry. No time stored for key."); 
     343        }        
     344    } 
    266345    } 
    267346 
     
    271350    # the user doesn't need to be a specific collection's editor in order to add comments to that collection. 
    272351    # So we no longer check the user is in the group here. 
     352#    $self->check_group($collection, $username, $user_data); 
     353} 
     354 
     355 
     356sub check_group 
     357{ 
     358    my $self = shift @_; 
     359    my $collection = shift @_; 
     360    my $username = shift @_; 
     361    my $user_data = shift @_; 
     362 
     363 
     364    my $gsdl_cgi = $self->{'gsdl_cgi'}; 
    273365 
    274366    # Check group 
    275 #    my ($user_groups) = ($user_data =~ /\<groups\>(.*)/); 
    276 #    if ($collection eq "") { 
    277 #   # If we're not editing a collection then the user doesn't need to be in a particular group 
    278 #   return $user_groups;  # Authentication successful 
    279 #    } 
    280 #    foreach my $user_group (split(/\,/, $user_groups)) { 
     367    my ($user_groups) = ($user_data =~ /\<groups\>(.*)/); 
     368    if ($collection eq "") { 
     369    # If we're not editing a collection then the user doesn't need to be in a particular group 
     370    return $user_groups;  # Authentication successful 
     371    } 
     372    foreach my $user_group (split(/\,/, $user_groups)) { 
    281373    # Does this user have access to all collections? 
    282 #   if ($user_group eq "all-collections-editor") { 
    283 #       return $user_groups;  # Authentication successful 
    284 #   } 
     374    if ($user_group eq "all-collections-editor") { 
     375        return $user_groups;  # Authentication successful 
     376    } 
    285377    # Does this user have access to personal collections, and is this one? 
    286 #   if ($user_group eq "personal-collections-editor" && $collection =~ /^$username\-/) { 
    287 #       return $user_groups;  # Authentication successful 
    288 #   } 
     378    if ($user_group eq "personal-collections-editor" && $collection =~ /^$username\-/) { 
     379        return $user_groups;  # Authentication successful 
     380    } 
    289381    # Does this user have access to this collection 
    290 #   if ($user_group eq "$collection-collection-editor") { 
    291 #       return $user_groups;  # Authentication successful 
    292 #   } 
    293 #    } 
    294 # 
    295 #    $gsdl_cgi->generate_error("Authentication failed: user is not in the required group."); 
    296 } 
    297  
    298  
     382    if ($user_group eq "$collection-collection-editor") { 
     383        return $user_groups;  # Authentication successful 
     384    } 
     385    } 
     386     
     387    $gsdl_cgi->generate_error("Authentication failed: user is not in the required group."); 
     388} 
    299389 
    300390sub check_installation 
  • main/trunk/greenstone2/web/script/gsajaxapi.js

    r27313 r27318  
    11 
    2 function GSAjaxAPI(gwcgi,collect)  
     2function GSAjaxAPI(gwcgi,collect,un,ky)  
    33{ 
    44    var gwcgi_   = gwcgi; 
    55    var collect_ = collect; 
     6    var un_ = un; 
     7    var ky_ = ky; 
    68 
    79 
     
    101103    } 
    102104 
     105       if(un_ != null) { 
     106       url += "&un=" + un_; 
     107       } 
     108       if(ky_ != null) { 
     109       url += "&ky=" + ky_; 
     110       } 
     111        
    103112    xmlHttp.open("GET",url,true); 
    104113    xmlHttp.send(null); 
     
    130139         } 
    131140       } 
     141 
     142       if(un_ != null) { 
     143       url += "&un=" + un_; 
     144       } 
     145       if(ky_ != null) { 
     146       url += "&ky=" + ky_; 
     147       } 
    132148     
    133149       xmlHttp.open("GET",url,false); 
     
    178194//        } 
    179195//    } 
     196     
     197    if(un_ != null) { 
     198    params += "&un=" + un_; 
     199    } 
     200    if(ky_ != null) { 
     201    params += "&ky=" + ky_; 
     202    } 
    180203 
    181204    xmlHttp.send(params); // needs to be escaped/encoded 
    182205 
     206    //alert(scriptURL + "?" + params); 
    183207    //alert(xmlHttp.responseText); // if synchronous, process xmlHttp.responseText AFTER send() call 
    184208    return xmlHttp.responseText;