checkPrefs($prefs) ) { NSSError("The preferences are not configured properly!","Invalid Configuration"); exit(1); } // Get the database open: $db = new Sql($prefs, $this); if ( ! $db ) { NSSError("Could create ZendTo database handle"); return; } $this->database = $db; // ZendTo or MyZendTo ??? // This is now redundant, but harmless. Use MYZENDTO instead. $this->MYZENDTO = $MyZendTo; // Instance copies of the preference data: $this->_dropboxDirectory = $prefs['dropboxDirectory']; $this->_recaptchaPublicKey = $prefs['recaptchaPublicKey']; $this->_recaptchaPrivateKey = $prefs['recaptchaPrivateKey']; $this->_emailDomainRegexp = $prefs['emailDomainRegexp']; $this->_dropboxLog = $prefs['logFilePath']; $this->_cookieName = $prefs['cookieName']; $this->_defaultEmailDomain = $prefs['defaultEmailDomain']; $this->_usernameRegexp = $prefs['usernameRegexp']; // Bail out right now if we just want a database connection. // Must do it here as we must have the dropboxLog setup right. if ($dbOnly) { return 0; } if ( ! ($this->_emailSenderAddr = $smarty->getConfigVariable('EmailSenderAddress')) ) { $execAsUser = posix_getpwuid(posix_geteuid()); $this->_emailSenderAddr = sprintf("%s <%s@%s>", $smarty->getConfigVariable('ServiceTitle'), $execAsUser['name'], $_SERVER['SERVER_NAME'] ); } if ( $intValue = intval( $prefs['numberOfDaysToRetain'] ) ) { $this->_retainDays = $intValue; } if ( $prefs['cookieSecret'] ) { $this->_secretForCookies = $prefs['cookieSecret']; } if ( $intValue = intval($prefs['cookieTTL']) ) { $this->_cookieTTL = $intValue; } if ( $intValue = intval($prefs['maxBytesForFile']) ) { $this->_maxBytesForFile = $intValue; } if ( $intValue = intval($prefs['maxBytesForDropoff']) ) { $this->_maxBytesForDropoff = $intValue; } if ( $prefs['validEmailRegexp'] ) { $this->_validEmailRegexp = $prefs['validEmailRegexp']; } if ( $prefs['showRecipsOnPickup'] === FALSE ) { $this->_showRecipsOnPickup = FALSE; } if ( $prefs['clamdscan'] ) { $this->_clamdscan = $prefs['clamdscan']; } if ( $prefs['maxnotelength'] ) { $this->_maxnotelength = $prefs['maxnotelength']; } if ( $prefs['loginFailMax'] ) { $this->_loginFailMax = $prefs['loginFailMax']; } if ( $prefs['loginFailTime'] ) { $this->_loginFailTime = $prefs['loginFailTime']; } // Create an authenticator based on our prefs: $this->_authenticator = NSSAuthenticator($prefs, $this->database); // Create an authenticator based on our prefs: if ( ! $this->_authenticator ) { NSSError("The ZendTo preferences.php has no authentication method selected.","Authentication Error"); exit(1); } // First try an authentication, since it _could_ override a cookie // that was already set. If that doesn't work, then try the cookie: if ( $this->userFromAuthentication() ) { $this->writeToLog("authenticated as '".$this->_authorizedUser."'"); // Set the cookie now: setcookie( $this->_cookieName, $this->cookieForSession(), time() + $this->_cookieTTL, "/", "", FALSE // TRUE ); } else { if ( $this->userFromCookie() ) { // Update the cookie's time-to-live: setcookie( $this->_cookieName, $this->cookieForSession(), time() + $this->_cookieTTL, "/", "", FALSE // TRUE ); } } } else { NSSError("The preferences are not configured properly (they're empty)!","Invalid Configuration"); exit(1); } } /*! @function description Debugging too, for the most part. Give a description of the instance. */ public function description() { return sprintf("NSSDropbox { directory: %s log: %s retainDays: %d recaptchaPublicKey: %s recaptchaPrivateKey:%s emailDomainRegexp: %s secretForCookies: %s authorizedUser: %s authenticator: %s }", $this->_dropboxDirectory, $this->_dropboxLog, $this->_retainDays, $this->_recaptchaPublicKey, $this->_recaptchaPrivateKey, $this->_emailDomainRegexp, $this->_secretForCookies, $this->_authorizedUser, ( $this->_authenticator ? $this->_authenticator->description() : "" ) ); } /*! @function logout Logout the current user. This amounts to nulling our cookie and giving it a zero second time-to-live, which should force the browser to drop the cookie. */ public function logout() { $this->writeToLog("logged-out user '".$this->_authorizedUser."'"); setcookie( $this->_cookieName, "", 0, "/", "", TRUE ); $this->_authorizedUser = NULL; $this->_authorizedUserData = NULL; } /*! @function dropboxDirectory Accessor pair for getting/setting the directory where dropoffs are stored. Always use a canonical path -- and, of course, be sure your web server is allowed to write to it!! */ public function dropboxDirectory() { return $this->_dropboxDirectory; } public function setDropBoxDirectory( $dropboxDirectory ) { if ( $dropboxDirectory && $dropboxDirectory != $this->_dropboxDirectory && is_dir($dropboxDirectory) ) { $this->_dropboxDirectory = $dropboxDirectory; } } /*! @function dropboxLog Accessor pair for getting/setting the path to the log file for this dropbox. Make sure your web server has access privs on the file (or the enclosing directory, in which case the file will get created automatically the first time we log to it). */ public function dropboxLog() { return $this->_dropboxLog; } public function setDropBoxLog( $dropboxLog ) { if ( $dropboxLog && $dropboxLog != $this->_dropboxLog ) { $this->_dropboxLog = $dropboxLog; } } /*! @function retainDays Accessor pair for getting/setting the number of days that a dropoff is allowed to reside in the dropbox. The "cleanup.php" admin script actually removes them, we don't do it from the web interface. */ public function retainDays() { return $this->_retainDays; } public function setRetainDays( $retainDays ) { if ( intval($retainDays) > 0 && intval($retainDays) != $this->_retainDays ) { $this->_retainDays = intval($retainDays); } } /*! @function maxBytesForFile Accessor pair for getting/setting the maximum size (in bytes) of a single file that is part of a dropoff. Note that there is a PHP system parameter that you must be sure is set high-enough to accomodate what you select herein! */ public function maxBytesForFile() { return $this->_maxBytesForFile; } public function setMaxBytesForFile( $maxBytesForFile ) { if ( ($intValue = intval($maxBytesForFile)) > 0 ) { $this->_maxBytesForFile = $intValue; } } /*! @function maxBytesForDropoff Accessor pair for getting/setting the maximum size (in bytes) of a dropoff (all files summed). Note that there is a PHP system parameter that you must be sure is set high-enough to accomodate what you select herein! */ public function maxBytesForDropoff() { return $this->_maxBytesForDropoff; } public function setMaxBytesForDropoff( $maxBytesForDropoff ) { if ( ($intValue = intval($maxBytesForDropoff)) > 0 ) { $this->_maxBytesForDropoff = $intValue; } } /*! @function validEmailRegexp Accessor pair for getting/setting the regexp that defines a valid sender email address. */ public function validEmailRegexp() { return $this->_validEmailRegexp; } public function setvalidEmailRegexp( $validEmailRegexp ) { if ( $validEmailRegexp && $validEmailRegexp != $this->_validEmailRegexp ) { $this->_validEmailRegexp = $validEmailRegexp; } } // JKF Start // /*! @function clamdscan Accessor pair for getting/setting the clamdscan command-line. */ public function clamdscan() { return $this->_clamdscan; } public function setclamdscan( $clamdscan ) { $this->_clamdscan = $clamdscan; } /*! @function maxnotelength Accessor pair for getting/setting the max length of the note to recips. */ public function maxnotelength() { return $this->_maxnotelength; } public function setmaxnotelength( $maxnotelength ) { $this->_maxnotelength = $maxnotelength; } /*! @function cookieName Accessor pair for getting/setting the max length of the note to recips. */ public function cookieName() { return $this->_cookieName; } public function setcookieName( $cookieName ) { $this->_cookieName = $cookieName; } // // JKF End /*! @function recaptchaPublicKey Accessor pair for getting/setting the recaptchaPublicKey. */ public function recaptchaPublicKey() { return $this->_recaptchaPublicKey; } public function setrecaptchaPublicKey( $recaptchaPublicKey ) { if ( $recaptchaPublicKey && $recaptchaPublicKey != $this->_recaptchaPublicKey ) { $this->_recaptchaPublicKey = $recaptchaPublicKey; } } /*! /*! @function recaptchaPrivateKey Accessor pair for getting/setting the recaptchaPrivateKey. */ public function recaptchaPrivateKey() { return $this->_recaptchaPrivateKey; } public function setrecaptchaPrivateKey( $recaptchaPrivateKey ) { if ( $recaptchaPrivateKey && $recaptchaPrivateKey != $this->_recaptchaPrivateKey ) { $this->_recaptchaPrivateKey = $recaptchaPrivateKey; } } /*! @function emailDomainRegexp Accessor pair for getting/setting the description 6 of users that are properly authenticated and thus "inside" users. */ public function emailDomainRegexp() { return $this->_emailDomainRegexp; } public function setemailDomainRegexp( $emailDomainRegexp ) { if ( $emailDomainRegexp && $emailDomainRegexp != $this->_emailDomainRegexp ) { $this->_emailDomainRegexp = $emailDomainRegexp; } } /*! @function defaultEmailDomain Accessor pair for getting/setting the default email domain that are properly authenticated and thus "inside" users. */ public function defaultEmailDomain() { return $this->_defaultEmailDomain; } public function setdefaultEmailDomain( $defaultEmailDomain ) { if ( $defaultEmailDomain && $defaultEmailDomain != $this->_defaultEmailDomain ) { $this->_defaultEmailDomain = $defaultEmailDomain; } } /*! @function defaultEmailDomain Accessor pair for getting/setting the default email domain that are properly authenticated and thus "inside" users. */ public function usernameRegexp() { return $this->_usernameRegexp; } public function setusernameRegexp( $usernameRegexp ) { if ( $usernameRegexp && $usernameRegexp != $this->_usernameRegexp ) { $this->_usernameRegexp = $usernameRegexp; } } /*! @function contactHelp Accessor pair for getting/setting the description 6 of users that are properly authenticated and thus "inside" users. */ public function contactHelp() { return $this->_contactHelp; } public function setcontactHelp( $contactHelp ) { if ( $contactHelp && $contactHelp != $this->_contactHelp ) { $this->_contactHelp = $contactHelp; } } /*! @function secretForCookies Accessor pair for getting/setting the secret string that we include in the MD5 sum that gets sent off as our cookie values. */ public function secretForCookies() { return $this->_secretForCookies; } public function setSecretForCookies( $secretForCookies ) { if ( $secretForCookies && $secretForCookies != $this->_secretForCookies ) { $this->_secretForCookies = $secretForCookies; } } /*! @function loginFailMax Returns the value of _loginFailMax. */ public function loginFailMax() { return $this->_loginFailMax; } /*! @function loginFailTime Returns the value of _loginFailTime. */ public function loginFailTime() { return $this->_loginFailTime; } /*! @function isNewDatabase Returns TRUE if the backing-database was newly-created by this instance. */ public function isNewDatabase() { return $this->_newDatabase; } /*! @function database Returns a reference to the database object (class is SQLiteDatabase) backing this dropbox. */ public function &database() { return $this->database; } /*! @function authorizedUser If the instance was created and was able to associate with a valid user (either via cookie or explicit authentication) the username in question is returned. */ public function authorizedUser() { return $this->_authorizedUser; } /*! @function authorizedUserData If the instance was created and was able to associate with a valid user (either via cookie or explicit authentication) then this function returns either the entire hash of user information (if $field is NULL) or a particular value from the hash of user information. For example, you could grab the user's email address using: $userEmail = $aDropbox->authorizedUserData('mail'); If the field you request does not exist, NULL is returned. Note that as the origin of this data is probably an LDAP lookup, there _may_ be arrays involved if a given field has multiple values. */ public function authorizedUserData( $field = NULL ) { if ( $field ) { return $this->_authorizedUserData[$field]; } return $this->_authorizedUserData; } public function showRecipsOnPickup() { return $this->_showRecipsOnPickup; } public function setShowRecipsOnPickup( $showIt ) { $this->_showRecipsOnPickup = $showIt; } /*! @function directoryForDropoff If $claimID enters with a value already assigned, then this function attempts to find the on-disk directory which contains that dropoff's files; the directory is returned in the $claimDir variable-reference. If $claimID is NULL, then we're being requested to setup a new dropoff. So we pick a new claim ID, make sure it doesn't exist, and then create the directory. The new claim ID goes back in $claimID and the directory goes back to the caller in $claimDir. Returns TRUE on success, FALSE on failure. */ public function directoryForDropoff( &$claimID = NULL, &$claimDir = NULL ) { if ( $claimID ) { if ( is_dir($this->_dropboxDirectory."/$claimID") ) { $claimDir = $this->_dropboxDirectory."/$claimID"; return TRUE; } } else { while ( 1 ) { $claimID = NSSGenerateCode(); // Is it already in the database? $this->database->DBListClaims($claimID, $extant); if ( !$extant || (count($extant) == 0) ) { // Make sure there's no directory hanging around: if ( ! file_exists($this->_dropboxDirectory."/$claimID") ) { if ( mkdir($this->_dropboxDirectory."/$claimID",0700) ) { $claimDir = $this->_dropboxDirectory."/$claimID"; return TRUE; } $this->writeToLog("unable to create ".$this->_dropboxDirectory."/$claimID"); break; } } } } return FALSE; } /*! @function authenticator Returns the authenticator object (subclass of NSSAuthenticator) that was created when we were initialized. */ public function authenticator() { return $this->_authenticator; } /*! @function deliverEmail Send the $content of an email message to (one or more) address(es) in $toAddr. */ public function deliverEmail( $toAddr, $fromAddr, $subject, $content ) { return mail( $toAddr, $subject, $content, ($fromAddr==""?"":sprintf("From: %s\r\nReply-to: %s\r\n", $fromAddr, $fromAddr) ) ); } /*! @function writeToLog Write the $logText to the log file. Each line is formatted to have a date and time, as well as the name of this dropbox. */ public function writeToLog( $logText ) { global $smarty; $logText = sprintf("%s [%s]: %s\n",strftime("%Y-%m-%d %T"), $smarty->getConfigVariable('ServiceTitle'), $logText); if (!file_put_contents($this->_dropboxLog,$logText,FILE_APPEND | LOCK_EX)) { NSSError(sprintf("Could not write to log file %s, ensure that web server user can write to the log file as set in preferences.php",$this->_dropboxLog)); } } /*! @function SetupPage End the section; write-out the standard stuff for the -- the page header with title, etc. Upon exit, the caller should begin writing HTML content for the page. We also get a chance here to spit-out an error if the authentication of a user failed. The single argument gives the text field that we should throw focus to when the page loads. You should pass the text field as "[form name].[field name]", which the function turns into "document.[form name].[field name].focus()". */ public function SetupPage( $focusTarget = NULL ) { global $NSSDROPBOX_URL; global $smarty; $smarty->assign('zendToURL', $NSSDROPBOX_URL); $smarty->assign('focusTarget', $focusTarget); $smarty->assign('padlockImage', ($this->_authorizedUser?"images/locked.png":"images/unlocked.png")); $smarty->assign('padlockImageAlt', ($this->_authorizedUser?"locked":"unlocked")); $smarty->assign('isAuthorizedUser', ($this->_authorizedUser?TRUE:FALSE)); $smarty->assign('isIndexPage', preg_match('/^index\.php.*/',basename($_SERVER['PHP_SELF']))); $smarty->assign('ztVersion', ZTVERSION); $smarty->assign('whoAmI', $this->authorizedUserData("displayName")); $smarty->assign('isAdminUser', $this->_authorizedUserData['grantAdminPriv']?TRUE:FALSE); if ( $this->_authorizationFailed ) { NSSError("The username or password was incorrect.","Authentication Error"); } } // // JKF // // Setup the new database tables I need. // Must be able to add this on the fly if a SELECT fails. public function setupDatabaseAuthTable() { if ( $this->database ) { if ( ! $this->database->DBCreateAuth() ) { $this->writeToLog("Failed to add authtable to database"); return FALSE; } $this->writeToLog("Added authtable to database"); return TRUE; } return FALSE; } // Setup the new database table I need. // Must be able to add this on the fly if a SELECT fails. public function setupDatabaseUserTable() { if ( $this->database ) { if ( ! $this->database->DBCreateUser() ) { $this->writeToLog("Failed to add usertable to database"); return FALSE; } $this->writeToLog("Added usertable to database"); return TRUE; } return FALSE; } // Setup the new database table I need. // Must be able to add this on the fly if a SELECT fails. public function setupDatabaseRegexpsTable() { if ( $this->database ) { if ( ! $this->database->DBCreateRegexps() ) { $this->writeToLog("Failed to add regexps table to database"); return FALSE; } $this->writeToLog("Added regexps table to database"); return TRUE; } return FALSE; } // Setup the new database table I need. // Must be able to add this on the fly if a SELECT fails. public function setupDatabaseLoginlogTable() { if ( $this->database ) { if ( ! $this->database->DBCreateLoginlog() ) { $this->writeToLog("Failed to add loginlog table to database"); return FALSE; } $this->writeToLog("Added loginlog table to database"); return TRUE; } return FALSE; } /*! @function cookieForSession Returns an appropriate cookie for the current session. An initial key is constructed using the username, remote IP, current time, a random value, the user's browser agent tag, and our special cookie secret. This key is hashed, and included as part of the actual cookie. The cookie contains more or less all but the secret value, so that the initial key and its hash can later be reconstructed for authenticity's sake. */ private function cookieForSession() { $now = time(); $nonce = mt_rand(); $digestString = sprintf("%s %s %d %d %s %s %s", $this->_authorizedUser, $_SERVER['REMOTE_ADDR'], $now, $nonce, $_SERVER['HTTP_USER_AGENT'], $this->_cookieName, $this->_secretForCookies ); return sprintf("%s,%s,%d,%d,%s", $this->_authorizedUser, $_SERVER['REMOTE_ADDR'], $now, $nonce, md5($digestString) ); } /*! @function userFromCookie Attempt to parse our cookie (if it exists) and establish the current user's username. */ private function userFromCookie() { if ( $cookieVal = $_COOKIE[$this->_cookieName] ) { if ( preg_match('/^(.+)\,([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+),([0-9]+),([0-9]+),([A-Fa-f0-9]+)$/',$cookieVal,$cookiePieces) ) { // Coming from the same remote IP? if ( $cookiePieces[2] != $_SERVER['REMOTE_ADDR'] ) { return FALSE; } // How old is the internal timestamp? if ( time() - $cookiePieces[3] > $this->_cookieTTL ) { return FALSE; } // Verify the MD5 checksum. This implies that everything // (including the HTTP agent) is unchanged. $digestString = sprintf("%s %s %d %d %s %s %s", $cookiePieces[1], $cookiePieces[2], $cookiePieces[3], $cookiePieces[4], $_SERVER['HTTP_USER_AGENT'], $this->_cookieName, $this->_secretForCookies ); if ( md5($digestString) != $cookiePieces[5] ) { return FALSE; } // Success! Verify the username as valid: if ( $this->_authenticator->validUsername($cookiePieces[1],$this->_authorizedUserData) ) { $this->_authorizedUser = $cookiePieces[1]; return TRUE; } } } return FALSE; } /*! @function userFromAuthentication Presumes that a username and password have come in POST'ed form data. We need to do an LDAP bind to verify the user's identity. */ private function userFromAuthentication() { $result = FALSE; if ( ($usernameRegex = $this->usernameRegexp()) == NULL ) { $usernameRegex = '/^([a-zA-Z0-9][a-zA-Z0-9\_\.\-]*)$/'; } if ( $this->_authenticator && preg_match($usernameRegex,$_POST['uname']) && $_POST['password'] ) { $password = stripslashes($_POST['password']); $uname = stripslashes($_POST['uname']); if ( $result = $this->_authenticator->authenticate($uname,$password,$this->_authorizedUserData) ) { // They have been authenticated, yay! if ( $this->database->DBLoginlogLength($uname, time()-$this->_loginFailTime) >= $this->_loginFailMax ) { // There have been too many failure attempts. $this->_authorizationFailed = TRUE; $this->writeToLog("authorization attempt for locked-out user $uname"); // Add a new failure record $this->database->DBAddLoginlog($uname); $result = FALSE; } elseif ($result == 2){ $this->_authorizationFailed = TRUE; $this->writeToLog("authorization attempt for not authorized user $uname - please add the group"); } else { // Successful login attempt with no lockout! :-) $this->_authorizedUser = $uname; $this->_authorizationFailed = FALSE; $this->writeToLog("authorization succeeded for ".$uname); // Reset their login log $this->database->DBDeleteLoginlog($uname); } } else { $this->_authorizationFailed = TRUE; $this->writeToLog("authorization failed for ".$uname); // Add a new failure record $this->database->DBAddLoginlog($uname); $result = FALSE; } } return $result; } /*! @function checkRecipientDomain Given a complete recipient email address, check if it is valid. The result is ignored if the user has logged in, this is only for un-authenticated users. */ public function checkRecipientDomain( $recipient ) { $result = FALSE; $data = explode('@', $recipient); $recipDomain = $data[1]; $re = $this->emailDomainRegexp(); if (preg_match('/^\/.*[^\/]$/', $re)) { // emailDomainRegexp() is a filename. // Get all the current regexps from the database, and use the // timestamp of one of them to compare against the modtime of the // text config file. If there aren't any, or the timestamp is older // than the modtime, then rebuild all the regexps. // emailDomainRegexps are hereby decreed to be type number 1. $relist = $this->database->DBReadRegexps(1); if ($relist) { $rebuildtime = $relist[0]['created']; } else { // There weren't any stored, so build for 1st time. $rebuildtime = 0; } if (filemtime($re) > $rebuildtime) { // File has been modified since we last read it. // Build and store the regexps, and read them back in. $this->RebuildDomainRegexps(1, $re); $relist = $this->database->DBReadRegexps(1); } // Check against every RE we built from the file foreach ($relist as $rerow) { $re = $rerow['re']; if ($re != '') { // If we have a match, then set result and short-cut out of here! if (preg_match($re, $recipDomain)) { $result = TRUE; break; } } } } else { // It is not a filename so must be an attempt at a Regexp. // Add a / on the front if not already there. if (!preg_match('/^\//', $re)) { $re = '/' . $re; } // Add a / on the end if not already there. if (!preg_match('/\/[a-z]?$/', $re)) { $re = $re . '/'; } if (preg_match($re, $recipDomain) ) { $result = TRUE; } } // Ask the authenticator if it has a different idea of the truth return $this->_authenticator->checkRecipient($result, $recipient); } // Rebuild the list of regular expressions given in the $filename. // Put 10 domains in each regexp to make sure we don't make them // too long. // Need to collect 10 at a time into a little array, then call // another function to make an re from a list of domain names. private function RebuildDomainRegexps($type, $filename) { if (!is_readable($filename)) { $this->writeToLog("Domains list file $filename is not readable or does not exist"); return; } // Read $filename into an array $contents = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (! $contents) { NSSError("Could not read local domain list file $filename"); return; } // For each line, add the domain to the temporary list of domains. // Once we have 10 domains, convert it into a regexp and zap the temp list. $relist = array(); $domainlist = array(); $size = 0; $counter = 0; foreach($contents as $l) { // Ignore blank lines and # comment lines $line = trim(strtolower($l)); if ($line == '' || preg_match('/(^#|^\/\/)/', $line)) { continue; } // It's probably a domain, so store it $domainlist[] = $line; $size++; $counter++; // Have we got 10 yet, which is enough for 1 RE ? if ($size >= 10) { $relist[] = $this->MakeDomainRE($domainlist); $domainlist = array(); $size = 0; } } // Don't forget the last trailing few in the file if ($size > 0) { $relist[] = $this->MakeDomainRE($domainlist); } // Now we have all the regexps in $relist. So store them in the db. $this->database->DBOverwriteRegexps($type, $relist); $this->writeToLog("Updated list of $counter local domains from $filename"); } // Given a ref to a regular expression variable and a list of domains, // construct an RE which will match ^([a-zA-Z0-9-]+\.)?(domain1|domain2)$ private function MakeDomainRE($domains) { // Error checking on inputs if (! $domains) { return; } else { // Replace every '.' with '\.' $dfixed = array(); foreach ($domains as $d) { $dfixed[] = strtolower(preg_replace('/\./','\.',$d)); } // Turn the list of domain names into an RE that matches them all $re = implode('|', $dfixed); $re = '/^([a-zA-Z0-9\-]+\.)?('.$re.')$/'; return $re; } } /*! @function checkPrefs Examines a preference hash to be sure that all of the required parameters are extant. */ private function checkPrefs( $prefs ) { static $requiredKeys = array( 'dropboxDirectory', 'recaptchaPublicKey', 'recaptchaPrivateKey', 'emailDomainRegexp', 'defaultEmailDomain', 'logFilePath', 'cookieName', 'authenticator' ); foreach ( $requiredKeys as $key ) { if ( !$prefs[$key] || ($prefs[$key] == "") ) { NSSError("You must provide a value for the following preference key: '$key'","Undefined Preference Key"); return FALSE; } } return TRUE; } // // JKF // // Add a record to the database for this user, right now. // Return the auth string to use in forms, or '' on failure. public function WriteAuthData( $name, $email, $org ) { $randint = mt_rand(); $hash = strtolower(md5($randint)); $expiry = time() + 86400; // Add to database: return $this->database->DBWriteAuthData($this, $hash, $name, $email, $org, $expiry, $filename, $claimID); } // // JKF // // ReadAuthData(authkey, name, email, org, expiry) // public function ReadAuthData( $authkey, &$name, &$email, &$org, &$expiry ) { // Only allow letters and numbers in $authkey $authkey = preg_replace('/[^a-zA-Z0-9]/', '', $authkey); $name = ''; $email = ''; $org = ''; $expiry = ''; $recordlist = $this->database->DBReadAuthData($authkey); if ( $recordlist && count($recordlist) ) { // @ob_end_clean(); //turn off output buffering to decrease cpu usage $name = htmlentities($recordlist[0]['FullName'], ENT_QUOTES); // Trim accidental whitespace, it's hard to detect and will cause failure $email = trim($recordlist[0]['Email']); // This is already checked carefully $org = htmlentities($recordlist[0]['Organization'], ENT_QUOTES); $expiry= $recordlist[0]['Expiry']; return 1; } return 0; } public function DeleteAuthData( $authkey ) { $authkey = preg_replace('/[^a-zA-Z0-9]/', '', $authkey); $this->database->DBDeleteAuthData($authkey); } public function PruneAuthData( ) { $old = time() - 86400; // 1 day ago $this->database->DBPruneAuthData($old); } } ?>