Ignore:
Timestamp:
1999-07-11T22:47:32+12:00 (25 years ago)
Author:
rjmcnab
Message:

Got something basic working.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/gsdl/src/recpt/authenaction.cpp

    r363 r369  
    1212/*
    1313   $Log$
     14   Revision 1.2  1999/07/11 10:47:32  rjmcnab
     15   Got something basic working.
     16
    1417   Revision 1.1  1999/07/10 22:19:29  rjmcnab
    1518   Initial revision.
     
    2326#include "cfgread.h"
    2427#include "cgiutils.h"
     28#include "infodbclass.h"
     29#include "gsdltimes.h"
    2530
    2631
     
    8994}
    9095
    91 static text_t generate_key (const text_t &/*username*/) {
    92   return "key";
     96// returns true if the key is still valid for this user,
     97// and false otherwise
     98static bool check_key (const text_t &keyfile, const userinfo_t &thisuser,
     99               const text_t &key, const text_t &group, int keydecay,
     100               ostream &logout) {
     101  outconvertclass text_t2ascii;
     102
     103  if (keyfile.empty() || thisuser.username.empty() ||
     104      key.empty()) return false;
     105
     106  // the keydecay is set to 1/2 minute for things requiring the
     107  // administrator
     108  if (group == "administrator") keydecay = 30;
     109 
     110  // open the key database
     111  gdbmclass keydb;
     112  if (!keydb.opendatabase (keyfile, GDBM_WRCREAT, 1000)) {
     113    logout << text_t2ascii << "Error: write open failed for key database \""
     114       << keyfile << "\"\n";
     115    return false; // failed
     116  }
     117
     118  // success if there is a key in the key database that is owned by this
     119  // user whose creation time is less that keydecay
     120  infodbclass info;
     121  bool success = false;
     122  if (keydb.getinfo (key, info))  {
     123    if (info["user"] == thisuser.username) {
     124      time_t keycreation = text2time (info["time"]);
     125      if (keycreation == (time_t)-1) {
     126    logout << text_t2ascii << "Error: failed to convert an authentication "
     127      "key into its equivalent time_t. Time text was \"" << info["time"]
     128           << "\" for key \"" << key << "\"\n";
     129
     130      } else if (difftime (time(NULL), keycreation) <= keydecay) {
     131    // succeeded, update the key's time
     132    success = true;
     133    info["time"] = time2text(time(NULL));
     134    if (!keydb.setinfo (key, info)) {
     135      logout << text_t2ascii << "Error: setinfo failed for key database \""
     136         << keyfile << "\"\n";
     137    }
     138      }
     139    }
     140  }
     141
     142  // close the database
     143  keydb.closedatabase();
     144
     145  return success;
     146}
     147
     148
     149static text_t generate_key (const text_t &keyfile, const text_t &username,
     150                ostream &logout) {
     151  static const char *numconvert = "0123456789abcdefghijklmnopqrstuvwxyz"
     152    "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
     153  outconvertclass text_t2ascii;
     154 
     155  // open the key database
     156  gdbmclass keydb;
     157  if (!keydb.opendatabase (keyfile, GDBM_WRCREAT, 1000)) {
     158    logout << text_t2ascii << "Error: write open failed for key database \""
     159       << keyfile << "\"\n";
     160    return ""; // failed
     161  }
     162
     163  // loop looking for a suitable new key
     164  text_t userkey;
     165  do {
     166    int userkey_int = rand ();
     167    while (userkey_int > 0) {
     168      userkey.push_back (numconvert[userkey_int%62]);
     169      userkey_int /= 62;
     170    }
     171
     172    // make sure this key is not in the database
     173    if (keydb.exists (userkey)) userkey.clear();
     174  } while (userkey.empty());
     175
     176  // enter the key into the database
     177  infodbclass keydata;
     178  keydata["user"] = username;
     179  keydata["time"] = time2text(time(NULL));
     180 
     181  if (!keydb.setinfo (userkey, keydata)) {
     182    logout << text_t2ascii << "Error: setinfo failed for key database \""
     183       << keyfile << "\"\n";
     184    userkey.clear(); // failed
     185  }
     186 
     187  // close the database
     188  keydb.closedatabase();
     189 
     190  return userkey;
    93191}
    94192
     
    113211
    114212authenaction::authenaction () {
     213  keydecay = 600; // 10 minutes
     214  recpt = NULL;
     215
    115216  // this action uses cgi variable "a"
    116217  cgiarginfo arg_ainfo;
     
    201302  if (cfgline.size() == 1) {
    202303    if (key == "passwdfile") passwdfile = cfgline[0];
    203     else if (key == "gsdlhome" && passwdfile.empty()) {
    204       passwdfile = filename_cat (cfgline[0], "etc", "passwd");
     304    else if (key == "keyfile") keyfile = cfgline[0];
     305    else if (key == "keydecay") keydecay = cfgline[0].getint();
     306    else if (key == "gsdlhome") {
     307      if (passwdfile.empty())
     308    passwdfile = filename_cat (cfgline[0], "etc", "passwd");
     309      if (keyfile.empty())
     310    keyfile = filename_cat (cfgline[0], "etc", "key.db");
    205311    }
    206312  }
     
    256362    if (!args_pw.empty()) {
    257363      // we are authenticating using a password
    258       if (check_passwd (thisuser, args_pw))
     364      if (check_passwd (thisuser, args_pw)) {
    259365    args_ua = "1"; // succeeded
     366      }
    260367     
    261368    } else if (!args_ky.empty()) {
    262369      // we are authenticating using a key
    263       args_ua = "1"; // succeeded !!!!!!!!!!!!!!!!!!!
     370      if (check_key (keyfile, thisuser, args_ky, args_ug, keydecay, logout))
     371    args_ua = "1";
     372      else args_us = "stalekey";
    264373    }
    265374  }
     
    269378  if (!args_ua.empty()) {
    270379    if (thisuser.status==userinfo_t::enabled) {
    271       // succeeded, get info about this user
    272       args_us = "enabled";
    273       args_ug = thisuser.groups;
    274       args_ky = generate_key (args_un); // new key
     380      // check to make sure the user is in the required group
     381      if (!args_ug.empty()) {
     382    thisuser.status = userinfo_t::permissiondenied;
     383    text_t::const_iterator group_here = thisuser.groups.begin();
     384    text_t::const_iterator group_end = thisuser.groups.end();
     385    text_t thisgroup;
     386    while (group_here != group_end) {
     387      group_here = getdelimitstr (group_here, group_end, ',', thisgroup);
     388      if (thisgroup == args_ug) {
     389        thisuser.status = userinfo_t::enabled;
     390        break;
     391      }
     392    }
     393      }
     394
     395      if (thisuser.status==userinfo_t::enabled) {
     396    // succeeded, get info about this user
     397    // note: we don't need to set "ug" as it is already set to
     398    // what it needs to be
     399    args_us = "enabled";
     400    args_ky = generate_key (keyfile, args_un, logout); // new key
     401   
     402      } else {
     403    // succeeded, however, the user is not in the correct group
     404    args_ua.clear();
     405    args_us = "permissiondenied";
     406    args_ug.clear();
     407    args_ky.clear();
     408   
     409      }
    275410    } else {
    276411      // succeeded, however, the account is disabled
     
    311446                      recptproto */*collectproto*/, ostream &/*logout*/) {
    312447  // sets _authen:messageextra_ based on the value of args["us"]
     448  //      _authen:hiddenargs_   to contain all the arguments that were
     449  //                            explicitly set
    313450  disp.setmacro ("messagestatus", "authen", ("_authen:message" + args["us"]
    314                          + "_"));
     451                         + "_"));
     452
     453  // get a list of saved configuration arguments (if possible)
     454  text_t saveconf;
     455  text_tset saveconfset;
     456  if (recpt != NULL) {
     457    saveconf = recpt->get_configinfo().saveconf;
     458    splitchar (saveconf.begin(), saveconf.end(), '-', saveconfset);
     459  }
     460 
     461  text_t hiddenargs;
     462  cgiargsclass::const_iterator args_here = args.begin();
     463  cgiargsclass::const_iterator args_end = args.end();
     464  while (args_here != args_end) {
     465    // set this as a hidden argument if it came from the cgi arguments,
     466    // its not the compressed arguments, the query string, a user name or
     467    // password, and if it is not in the compressed arguments
     468    if ((*args_here).second.source == cgiarg_t::cgi_arg &&
     469    (*args_here).first != "e" && (*args_here).first != "q" &&
     470    (*args_here).first != "un" && (*args_here).first != "pw" &&
     471    saveconfset.find((*args_here).first) == saveconfset.end()) {
     472      hiddenargs += "<input type=hidden name=\"" + (*args_here).first +
     473    "\" value=\"_cgiarg" + (*args_here).first + "_\">\n";
     474    }
     475   
     476    args_here++;
     477  }
     478
     479  disp.setmacro ("hiddenargs", "authen", hiddenargs);
    315480}
    316481
Note: See TracChangeset for help on using the changeset viewer.