// After all that, we start the page body and write-out the HTML for // the form. // // If the user is authenticated then some of the fields will be // already-filled-in (sender name and email). // //if ( $_POST['Action'] == "verify" ) { // // We wouldn't be here if they hadn't failed // $smarty->assign('verifyFailed', TRUE); //} //$smarty->assign('senderName', ($theDropbox->authorizedUser() ? $theDropbox->authorizedUserData("displayName") : htmlentities(stripslashes($_POST['senderName'])))); //$smarty->assign('senderOrg', ($theDropbox->authorizedUser() ? $theDropbox->authorizedUserData("organization") : htmlentities(stripslashes($_POST['senderOrganization'])))); //$smarty->assign('senderEmail', ($theDropbox->authorizedUser() ? strtolower($theDropbox->authorizedUserData("mail")) : htmlentities(stripslashes($_POST['senderEmail'])))); $smarty->assign('senderName', $theDropbox->authorizedUser() ? $theDropbox->authorizedUserData("displayName") : (isset($_POST['senderName']) ? htmlentities(paramPrepare($_POST['senderName'])) : NULL)); $smarty->assign('senderOrg', $theDropbox->authorizedUser() ? $theDropbox->authorizedUserData("organization") : (isset($_POST['senderOrganization']) ? htmlentities(paramPrepare($_POST['senderOrganization'])) : NULL)); $smarty->assign('senderEmail', $theDropbox->authorizedUser() ? strtolower($theDropbox->authorizedUserData("mail")) : (isset($_POST['senderEmail']) ? htmlentities(paramPrepare($_POST['senderEmail'])) : NULL)); if (!$theDropbox->authorizedUser()) { $captcha = $theDropbox->captcha(); if ($captcha === 'areyouahuman') { $smarty->assign('recaptchaHTML', $ayah->getPublisherHTML()); $smarty->assign('recaptchaDisabled', FALSE); } elseif ($captcha === 'google' || $captcha === '') { // Using Google or an old version without this set $reCaptchaPublicKey = $theDropbox->recaptchaPublicKey(); if ($reCaptchaPublicKey === 'disabled') { $smarty->assign('recaptchaDisabled', TRUE); } else { $smarty->assign('recaptchaHTML', recaptcha_get_html($reCaptchaPublicKey)); $smarty->assign('recaptchaDisabled', FALSE); } } else {
// configuration! // require "../config/preferences.php"; require_once NSSDROPBOX_LIB_DIR . "Smartyconf.php"; require_once NSSDROPBOX_LIB_DIR . "NSSDropbox.php"; if ($theDropbox = new NSSDropbox($NSSDROPBOX_PREFS)) { $theDropbox->SetupPage(); if ($theDropbox->authorizedUser() && $theDropbox->authorizedUserData('grantAdminPriv')) { if ($_POST['action'] == 'unlock') { // Unlock the ticked users $output = array(); for ($i = 0; $i <= $_POST['unlockMax']; $i++) { $user = $_POST['unlocktick_' . $i]; if ($user) { // Unlock the user $theDropbox->database->DBDeleteLoginlog(htmlentities(paramPrepare($user))); $output[] = $user; } } if ($output) { NSSError("Unlocked " . implode(', ', $output) . "."); } } // Build the list of locked users $all = $theDropbox->database->DBLoginlogAll(time() - $theDropbox->loginFailTime()); $failures = array(); $lockedout = array(); $names = array(); $unlockMax = 0; $max = $theDropbox->loginFailMax(); foreach ($all as $rec) {
public function DBAddFile2($d, $dropoffID, $tmpname, $filename, $contentLen, $mimeType, $description, $claimID) { if (!$this->DBStartTran()) { $d->writeToLog("failed to BEGIN transaction block while adding {$filename} to dropoff {$claimID}"); return false; } $query = sprintf("INSERT INTO file (dID,tmpname,basename,lengthInBytes,mimeType,description) VALUES (%d,'%s','%s',%.0f,'%s','%s')", $dropoffID, $this->database->real_escape_string(basename($tmpname)), $this->database->real_escape_string(paramPrepare($filename)), $contentLen, $this->database->real_escape_string($mimeType), $this->database->real_escape_string(paramPrepare($description))); if (!$this->database->query($query)) { // Exit gracefully -- dump database changes and remove the dropoff // directory: $d->writeToLog("error while adding {$filename} to dropoff {$claimID}"); if (!$this->DBRollbackTran()) { $d->writeToLog("failed to ROLLBACK after botched addition of {$filename} to dropoff {$claimID}"); } return false; } return $this->DBCommitTran(); }
private function userFromAuthentication() { $result = FALSE; if (($usernameRegex = $this->usernameRegexp()) == NULL) { $usernameRegex = '/^([a-zA-Z0-9][a-zA-Z0-9\\_\\.\\-\\@\\\\]*)$/'; } if ($this->_authenticator && isset($_POST['uname']) && preg_match($usernameRegex, $_POST['uname']) && isset($_POST['password']) && $_POST['password']) { $password = $_POST['password']; // JKF Don't unquote the password as it might break passwords with backslashes in them. stripslashes($_POST['password']); $uname = paramPrepare(strtolower($_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); $this->_authorizedUserData = NULL; $this->_authorizedUser = ''; $result = FALSE; } 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); $result = TRUE; } } else { $this->_authorizationFailed = TRUE; $this->writeToLog("authorization failed for " . $uname); // Add a new failure record $this->database->DBAddLoginlog($uname); $result = FALSE; } } else { // Login attempt failed, check for bad usernames and report them. // But only if there is a username and a password, or else this will // false alarm on any page that displays the login box. if (isset($_POST['uname']) && $_POST['uname'] != "" && !preg_match($usernameRegex, $_POST['uname'])) { $this->writeToLog("Illegal username \"" . paramPrepare($_POST['uname']) . "\" attempted to login"); $this->_authorizationFailed = TRUE; $this->_authorizedUserData = NULL; $this->_authorizedUser = ''; $result = FALSE; } } return $result; }
public function sendVerifyEmail() { global $smarty; global $NSSDROPBOX_URL; if ($this->_dropbox->authorizedUser()) { // They are an authenticated user so try to get their name and email // from the authentication system. $senderName = $this->_dropbox->authorizedUserData("displayName"); if (!$senderName) { $senderName = paramPrepare($_POST['senderName']); } $senderEmail = strtolower($this->_dropbox->authorizedUserData("mail")); if (!$senderEmail) { $senderEmail = paramPrepare($_POST['senderEmail']); } } else { // They are not an authenticated user so get their name and email // from the form. $senderName = paramPrepare($_POST['senderName']); $senderEmail = paramPrepare(strtolower($_POST['senderEmail'])); } $senderOrganization = paramPrepare($_POST['senderOrganization']); // Sanitise the data // Still needs doing to save us from nasty crap in email! $senderName = preg_replace('/[^a-zA-Z0-9\\.\\-\\_\\+\\"\'\\@\\/\\:\\&\\,\\$ ]/', '', $senderName); $senderEmail = preg_replace('/[^a-zA-Z0-9\\.\\-\\_\\+\\"\'\\@\\/\\:\\&\\,\\$ ]/', '', $senderEmail); $senderOrganization = preg_replace('/[^a-zA-Z0-9\\.\\-\\_\\+\\"\'\\@\\/\\:\\&\\,\\$ ]/', '', $senderOrganization); if (!$senderName) { return FALSE; } if (!$senderEmail) { return FALSE; } if (!preg_match($this->_dropbox->validEmailRegexp(), $senderEmail, $emailParts)) { return FALSE; } // $senderEmail = $emailParts[1]."@".$emailParts[2]; // Insert into database: $auth = $this->_dropbox->WriteAuthData($senderName, $senderEmail, $senderOrganization); if ($auth == '') { NSSError("Database failure writing authentication key. Please contact your system administrator."); return FALSE; } $this->_senderName = $senderName; $this->_senderOrganization = $senderOrganization; $this->_senderEmail = $senderEmail; // If they are authenticated user, then generate a form containing // the data and auto-post it. if ($this->_dropbox->authorizedUser()) { Header("HTTP/1.1 302 Moved Temporarily"); Header("Location: " . $NSSDROPBOX_URL . "dropoff.php?auth=" . $auth); $this->_dropbox->writeToLog(sprintf("auto-verification for logged in user %s", $senderEmail)); } else { // Construct the email notification and deliver: $smarty->assign('senderName', $senderName); $smarty->assign('senderOrg', $senderOrganization); $smarty->assign('senderEmail', $senderEmail); $smarty->assign('URL', $NSSDROPBOX_URL . "dropoff.php?auth={$auth}"); $emailSubject = $smarty->getConfigVariable('VerifyEmailSubject'); $success = $this->_dropbox->deliverEmail($senderEmail, $smarty->getConfigVariable('EmailSenderAddress'), $emailSubject, $smarty->fetch('verify_email.tpl')); if ($success) { $this->_dropbox->writeToLog(sprintf("address verification email delivered successfully to %s", $senderEmail)); } else { $this->_dropbox->writeToLog(sprintf("address verification email not delivered successfully to %s", $senderEmail)); return FALSE; } } // Everything worked and the mail was sent! return TRUE; }
private function initWithFormData($recipEmail) { global $NSSDROPBOX_URL; // They are an authenticated user so try to get their name and email // from the authentication system. $senderName = $this->_dropbox->authorizedUserData("displayName"); if (!$senderName) { $senderName = paramPrepare($_POST['senderName']); } $senderEmail = strtolower($this->_dropbox->authorizedUserData("mail")); if (!$senderEmail) { $senderEmail = paramPrepare($_POST['senderEmail']); } $senderOrganization = paramPrepare($_POST['senderOrganization']); $recipName = paramPrepare($_POST['recipName']); # This is now read from a parameter passed to us #$recipEmail = stripslashes(strtolower($_POST['recipEmail'])); // SLASH $note = stripslashes($_POST['note']); $note = $_POST['note']; $subject = paramPrepare($_POST['subject']); // Sanitise the data $senderName = preg_replace('/[^a-zA-Z0-9\\.\\-\\_\\+\\"\'\\@\\/\\:\\&\\, ]/', '', $senderName); $senderEmail = preg_replace('/[^a-zA-Z0-9\\.\\-\\_\\+\\"\'\\@\\/\\:\\&\\, ]/', '', $senderEmail); $senderOrganization = preg_replace('/[^a-zA-Z0-9\\.\\-\\_\\+\\"\'\\@\\/\\:\\&\\, ]/', '', $senderOrganization); $recipName = preg_replace('/[^a-zA-Z0-9\\.\\-\\_\\+\\"\'\\@\\/\\:\\&\\, ]/', '', $recipName); $recipEmail = preg_replace('/[^a-zA-Z0-9\\.\\-\\_\\+\\"\'\\@\\/\\:\\&\\, ]/', '', $recipEmail); if (!$senderName) { return "You must specify your name in the form. Use the back button in your browser to go back and fix this omission before trying again."; } if (!$senderEmail) { return "You must specify your own email address in the form. Use the back button in your browser to go back and fix this omission before trying again."; } if (!$recipName) { return "You must specify the recipient's name in the form. Use the back button in your browser to go back and fix this omission before trying again."; } if (!$recipEmail) { return "You must specify the recipient's email address in the form. Use the back button in your browser to go back and fix this omission before trying again."; } if (!preg_match($this->_dropbox->validEmailRegexp(), $senderEmail, $emailParts)) { return "Your email address you entered was invalid. Use the back button in your browser to go back and fix this omission before trying again."; } $senderEmail = $emailParts[1] . "@" . $emailParts[2]; if (!preg_match($this->_dropbox->validEmailRegexp(), $recipEmail, $emailParts)) { return "The recipient's email address you entered was invalid. Use the back button in your browser to go back and fix this omission before trying again."; } $recipEmail = $emailParts[1] . "@" . $emailParts[2]; // Check the length of the subject. $subjectlength = strlen($subject); $maxlen = $this->_dropbox->maxsubjectlength(); if ($subjectlength > $maxlen) { return sprintf($smarty->getConfigVariable('ErrorSubjectTooLong'), $subjectlength, $maxlen); } // The subject line of the files will be a "Re: +subject" $reSubject = trim($subject); if (!preg_match('/^Re:/i', $reSubject)) { $reSubject = 'Re: ' . $reSubject; } // Insert into database: $words = $this->_dropbox->WriteReqData($senderName, $senderEmail, $senderOrganization, $recipName, $recipEmail, $note, $reSubject); if ($words == '') { return "Database failure writing request information. Please contact your system administrator."; } else { $this->_words = $words; $this->_auth = preg_replace('/[^a-zA-Z0-9]/', '', $words); $this->_senderName = $senderName; $this->_senderEmail = $senderEmail; $this->_senderOrg = $senderOrg; $this->_recipName = $recipName; $this->_recipEmail = $recipEmail; $this->_note = $note; $this->_subject = $subject; } return ""; }
exit; } // They are either trying to submit or display the "New Request" form, // so they must be logged in. if (!$theDropbox->authorizedUser()) { $theDropbox->SetupPage(); NSSError($smarty->getConfigVariable('ErrorNotLoggedIn'), "Access Denied"); $smarty->display('error.tpl'); exit; } if ($_POST['Action'] == "send") { // Read the contents of the form, and send the email of it all // Loop through all the email addresses we were given, creating a new // Req object for each one. Then piece together the bits of the output // we need to make the resulting web page look pretty. $emailAddrs = preg_split('/[;, ]+/', paramPrepare(strtolower($_POST['recipEmail'])), NULL, PREG_SPLIT_NO_EMPTY); $wordList = array(); $emailList = array(); // This is the output list, separate for safety foreach ($emailAddrs as $re) { $req = new Req($theDropbox, $re); if ($req->formInitError() != "") { $theDropbox->SetupPage(); NSSError($req->formInitError(), "Request error"); $smarty->display('error.tpl'); exit; } if (!$req->sendReqEmail()) { $theDropbox->SetupPage(); NSSError("Sending the request email failed.", "Email error"); $smarty->display('error.tpl');
private function initWithFormData() { global $NSSDROPBOX_URL; global $smarty; // Start off with the data from the form posting, overwriting it with // stored data as necessary. $senderName = paramPrepare($_POST['senderName']); $senderEmail = paramPrepare(strtolower($_POST['senderEmail'])); $senderOrganization = paramPrepare($_POST['senderOrganization']); // SLASH $note = stripslashes($_POST['note']); $note = $_POST['note']; $expiry = 0; // If they have a valid req key, then they don't need to be verified // or logged in. $reqSubject = ''; $req = ''; if ($_POST['req'] != '') { $dummy = ''; $recipName = ''; // Never actually use this $recipEmail = ''; // Never actually use this $req = preg_replace('/[^a-zA-Z0-9]/', '', $_POST['req']); if ($this->_dropbox->ReadReqData($req, $recipName, $recipEmail, $senderOrganization, $senderName, $senderEmail, $dummy, $reqSubject, $expiry)) { if ($expiry < time()) { $this->_dropbox->DeleteReqData($req); return $smarty->getConfigVariable('ErrorReadAuth'); } // It was a valid req key, so leave $req alone (and true). $reqSubject = trim($reqSubject); $this->_subject = $reqSubject; } else { // Invalid request code, so ignore them $req = FALSE; $reqSubject = ''; } } // It is not a request, or not a valid request if ($req == '') { // So now they must be authorized as it's not a request if (!$this->_dropbox->authorizedUser()) { $auth = $_POST['auth']; // JKF Get the above from the auth database // JKF Fail if it doesn't exist or it's a pickup auth not a dropoff $authdatares = $this->_dropbox->ReadAuthData($auth, $senderName, $senderEmail, $senderOrganization, $expiry); if (!$authdatares) { return $smarty->getConfigVariable('ErrorReadAuth'); } // If the email is blank (and name has no spaces) then it's a pickup. // In a pickup, the name is used as the sender's IP address. if (!preg_match('/ /', $senderName) && $senderEmail == '') { return $smarty->getConfigVariable('ErrorReadAuth'); } if ($expiry < time()) { $this->_dropbox->DeleteAuthData($auth); return $smarty->getConfigVariable('ErrorReadAuth'); } } else { // Logged-in user so just read their data $senderName = $this->_dropbox->authorizedUserData("displayName"); $senderOrganization = paramPrepare($_POST['senderOrganization']); $senderEmail = trim($this->_dropbox->authorizedUserData("mail")); } } // Erase the note if it is just white space. if (preg_match('/^\\s*$/', $note)) { $note = ""; } // Check the length of the note. $notelength = strlen($note); $maxlen = $this->_dropbox->maxnotelength(); if ($notelength > $maxlen) { return sprintf($smarty->getConfigVariable('ErrorNoteTooLong'), $notelength, $maxlen); } $confirmDelivery = $_POST['confirmDelivery'] ? TRUE : FALSE; $informRecipients = $_POST['informRecipients'] ? TRUE : FALSE; $recipients = array(); $recipIndex = -1; // <0 => no recipients found $arraykeys = array_keys($_POST); foreach ($arraykeys as $arraykey) { $matches = array(); if (preg_match('/^recipient_(\\d+)/', $arraykey, $matches)) { $recipIndex = $matches[1]; //while ( array_key_exists('recipient_'.$recipIndex,$_POST) ) { $recipName = paramPrepare($_POST['recipName_' . $recipIndex]); $recipEmail = paramPrepare($_POST['recipEmail_' . $recipIndex]); if ($recipName || $recipEmail) { // Take the email to purely lowercase for simplicity: $recipEmail = strtolower($recipEmail); // Just a username? We add an implicit "@domain.com" for these and validate them! $emailParts[1] = NULL; $emailParts[2] = NULL; if (preg_match('/\\@/', $recipEmail)) { // Has an @ sign so is an email address. Must be valid! if (!preg_match($this->_dropbox->validEmailRegexp(), $recipEmail, $emailParts)) { return sprintf($smarty->getConfigVariable('ErrorBadRecipient'), $recipEmail); } } else { // No @ sign so just stick default domain in right hand side $emailParts[1] = $recipEmail; $emailParts[2] = $this->_dropbox->defaultEmailDomain(); } $recipEmailDomain = $emailParts[2]; // Don't think this line is needed any more, but harmless $recipEmail = $emailParts[1] . "@" . $emailParts[2]; // Look at the recipient's email domain; un-authenticated users can only deliver // to the dropbox's domain: // JKF Changed checkRecipientDomain to return true if it's a local user if (!$this->_dropbox->authorizedUser() && !$this->_dropbox->checkRecipientDomain($recipEmail)) { return $smarty->getConfigVariable('ErrorWillNotSend'); } $recipients[] = array($recipName ? $recipName : "", $recipEmail); } else { if ($recipName && !$recipEmail) { return $smarty->getConfigVariable('ErrorNoEmail'); } } //$recipIndex++; } } // No recipients found? if ($recipIndex < 0) { return $smarty->getConfigVariable('ErrorNoEmail'); } // // Check for an uploaded CSV/TXT file containing addresses: // if ($_FILES['recipient_csv']['tmp_name']) { if ($_FILES['recipient_csv']['error'] != UPLOAD_ERR_OK) { $error = sprintf($smarty->getConfigVariable('ErrorWhileUploading'), $_FILES['recipient_csv']['name']); switch ($_FILES['recipient_csv']['error']) { case UPLOAD_ERR_INI_SIZE: $error .= $smarty->getConfigVariable('ErrorRecipientsTooBigForPHP'); break; case UPLOAD_ERR_FORM_SIZE: $error .= sprintf($smarty->getConfigVariable('ErrorRecipientsFileTooBig'), $this->_dropbox->maxBytesForFile()); break; case UPLOAD_ERR_PARTIAL: $error .= $smarty->getConfigVariable('ErrorRecipientsPartialUpload'); break; case UPLOAD_ERR_NO_FILE: $error .= $smarty->getConfigVariable('ErrorNoRecipientsFile'); break; case UPLOAD_ERR_NO_TMP_DIR: $error .= $smarty->getConfigVariable('ErrorNoTemp'); break; case UPLOAD_ERR_CANT_WRITE: $error .= $smarty->getConfigVariable('ErrorBadTemp'); break; } return $error; } // Parse the CSV/TXT file: if ($csv = fopen($_FILES['recipient_csv']['tmp_name'], 'r')) { while ($fields = fgetcsv($csv)) { if ($fields[0] !== NULL) { // Got one; figure out which field is an email address: foreach ($fields as $recipEmail) { // Take the email to purely lowercase for simplicity: $recipEmail = strtolower($recipEmail); // JKF Don't allow just usernames in CSV file! if (!preg_match($this->_dropbox->validEmailRegexp(), $recipEmail, $emailParts)) { continue; } $recipEmailDomain = $emailParts[2]; $recipEmail = $emailParts[1] . "@" . $emailParts[2]; // Look at the recipient's email domain; // un-authenticated users can only deliver to the dropbox's // domain: if (!$this->_dropbox->authorizedUser() && !$this->_dropbox->checkRecipientDomain($recipEmail)) { return $smarty->getConfigVariable('ErrorWillNotSend'); } // $recipients[] = array(( $recipName ? $recipName : "" ),$recipEmail); $recipients[] = array("", $recipEmail); } } } fclose($csv); } else { return $smarty->getConfigVariable('ErrorBadRecipientsFile'); } //$fileCount = count( array_keys($_FILES) ) - 1; //} else { // //$fileCount = count( array_keys($_FILES) ); // $fileCount = numberOfFiles(); } // If it's in response to a request, and the recipient override // is set, then zap the first recipient and replace with ours. $reqRecipient = $this->_dropbox->reqRecipient(); if ($req != '' && $reqRecipient != '') { $recipients[0][1] = $reqRecipient; } // Reduce the list of recipients to those with unique email addresses uniqueifyRecipients($recipients); // Confirm that all fields are present and accounted for: $fileCount = $this->numberOfFiles(); if ($fileCount == 0) { return $smarty->getConfigVariable('ErrorNoFiles'); } // Now make sure each file was uploaded successfully, isn't too large, // and that the total size of the upload isn't over capacity: $i = 1; $totalBytes = 0.0; $totalFiles = 0; // while ( $i <= $fileCount ) { while ($i <= $this->maxFilesKey) { $key = "file_" . $i; if (array_key_exists('file_select_' . $i, $_POST) && $_POST['file_select_' . $i] != "-1") { $totalFiles++; } elseif ($_FILES[$key]['name']) { if ($_FILES[$key]['error'] != UPLOAD_ERR_OK) { $error = sprintf($smarty->getConfigVariable('ErrorWhileUploading'), $_FILES[$key]['name']); switch ($_FILES[$key]['error']) { case UPLOAD_ERR_INI_SIZE: $error .= $smarty->getConfigVariable('ErrorTooBigForPHP'); break; case UPLOAD_ERR_FORM_SIZE: $error .= sprintf($smarty->getConfigVariable('ErrorFileTooBig'), $this->_dropbox->maxBytesForFile()); break; case UPLOAD_ERR_PARTIAL: $error .= $smarty->getConfigVariable('ErrorPartialUpload'); break; case UPLOAD_ERR_NO_FILE: $error .= $smarty->getConfigVariable('ErrorNoFile'); break; case UPLOAD_ERR_NO_TMP_DIR: $error .= $smarty->getConfigVariable('ErrorNoTemp'); break; case UPLOAD_ERR_CANT_WRITE: $error .= $smarty->getConfigVariable('ErrorBadTemp'); break; } return $error; } if (($bytes = $_FILES[$key]['size']) < 0) { // Grrr...stupid 32-bit nonsense. Convert to the positive // value float-wise: $bytes = ($bytes & 0x7fffffff) + 2147483648.0; } if ($bytes > $this->_dropbox->maxBytesForFile()) { return sprintf($smarty->getConfigVariable('ErrorNamedFileTooBig'), $_FILES[$key]['name'], NSSFormattedMemSize($this->_dropbox->maxBytesForFile())); } if (($totalBytes += $bytes) > $this->_dropbox->maxBytesForDropoff()) { return sprintf($smarty->getConfigVariable('ErrorDropoffTooBig'), $_FILES[$key]['name'], NSSFormattedMemSize($this->_dropbox->maxBytesForDropoff())); } // MyZendTo: If they don't have enough quota left, disallow it if (preg_match('/^[yYtT1]/', MYZENDTO)) { $QuotaLeft = $this->_dropbox->database->DBRemainingQuota($this->_dropbox->authorizedUser()); if ($totalBytes > $QuotaLeft) { return sprintf($smarty->getConfigVariable('ErrorDropoffQuota'), NSSFormattedMemSize($totalBytes - $QuotaLeft)); } } $totalFiles++; } $i++; } //if ( $totalBytes == 0 ) { if ($totalFiles == 0) { return $smarty->getConfigVariable('ErrorNoFiles'); } // JKF Start // // Call clamdscan on all the files, fail if they are infected // If the name of the scanner is set to '' or 'DISABLED' then skip this. $clamdscancmd = $this->_dropbox->clamdscan(); if ($clamdscancmd != 'DISABLED') { $ccfilecount = 1; $ccfilelist = ''; $foundsometoscan = FALSE; while ($ccfilecount <= $this->maxFilesKey) { // For every possible file, we only add it to the list of clamd // targets if it's not a library file (assumed clean), but it is // an uploaded file, and that file-slot in the form was used. $filekey = "file_" . $ccfilecount; $selectkey = "file_select_" . $ccfilecount; if (!(array_key_exists($selectkey, $_POST) && $_POST[$selectkey] != "-1") && array_key_exists($filekey, $_FILES) && array_key_exists('tmp_name', $_FILES[$filekey]) && $_FILES[$filekey]['tmp_name'] !== '') { // and is not blank $ccfilelist .= ' ' . $_FILES[$filekey]['tmp_name']; $foundsometoscan = TRUE; } $ccfilecount++; } if ($foundsometoscan) { // Don't do any of this if they uploaded nothing exec("/bin/chmod go+r " . $ccfilelist); // Need clamd to read them! $clamdinfected = 0; $clamdoutput = array(); $clamcmd = exec($clamdscancmd . $ccfilelist, $clamdoutput, $clamdinfected); if ($clamdinfected == 1) { return $smarty->getConfigVariable('ErrorVirusFound'); } if ($clamdinfected == 2) { return $smarty->getConfigVariable('ErrorVirusFailed'); } } } // // JKF End if (!$senderName) { return $smarty->getConfigVariable('ErrorSenderName'); } if (!$senderEmail) { return $smarty->getConfigVariable('ErrorSenderEmail'); } if (!preg_match($this->_dropbox->validEmailRegexp(), $senderEmail, $emailParts)) { return $smarty->getConfigVariable('ErrorSenderBadEmail'); } $senderEmail = $emailParts[1] . "@" . $emailParts[2]; // Invent a passcode and claim ID: $claimPasscode = NSSGenerateCode(); $claimID = NULL; $claimDir = NULL; if (!$this->_dropbox->directoryForDropoff($claimID, $claimDir)) { return $smarty->getConfigVariable('ErrorUniqueDir'); } // Insert into database: if ($this->_dropbox->database->DBStartTran()) { if ($dropoffID = $this->_dropbox->database->DBAddDropoff($claimID, $claimPasscode, $this->_dropbox->authorizedUser(), $senderName, $senderOrganization, $senderEmail, $_SERVER['REMOTE_ADDR'], $confirmDelivery, timestampForTime(time()), $note)) { // Add recipients: if (!$this->_dropbox->database->DBAddRecipients($recipients, $dropoffID)) { $this->_dropbox->database->DBRollbackTran(); return $smarty->getConfigVariable('ErrorStoreRecipients'); } // Process the files: $i = 1; $realFileCount = 0; $tplFiles = array(); // These are the file hashes we process in tpl. //while ( $i <= $fileCount ) { while ($i <= $this->maxFilesKey) { $key = "file_" . $i; $selectkey = 'file_select_' . $i; if (array_key_exists($selectkey, $_POST) && $_POST[$selectkey] != "-1") { // It's a library file. // Get the name of the library file they want (safely) // by removing all "../" elements and things like it $libraryfile = preg_replace('/\\.\\.[:\\/\\\\]/', '', $_POST[$selectkey]); $libraryfile = paramPrepare($libraryfile); // Generate a random filename (collisions are very unlikely) $tmpname = mt_rand(10000000, 99999999); // Link in the library file symlink($this->_dropbox->libraryDirectory() . '/' . $libraryfile, $claimDir . '/' . $tmpname); // Now strip off the possible subdirectory name as we only // want it in the symlink and not after that. $libraryfilesize = filesize($this->_dropbox->libraryDirectory() . '/' . $libraryfile); $libraryfile = trim(preg_replace('/^.*\\//', '', $libraryfile)); // We use this a few times $librarydesc = paramPrepare(trim($_POST["desc_" . $i])); // Add to database: if (!$this->_dropbox->database->DBAddFile1($dropoffID, $tmpname, $libraryfile, $libraryfilesize, "application/octet-stream", $librarydesc)) { // Exit gracefully -- dump database changes and remove the dropoff // directory: $this->_dropbox->writeToLog("error while adding dropoff library file to database for {$claimID}"); if (!rmdir_r($claimDir)) { $this->_dropbox->writeToLog("unable to remove {$claimDir} -- orphaned!!"); } if (!$this->_dropbox->database->DBRollbackTran()) { $this->_dropbox->writeToLog("failed to ROLLBACK after botched dropoff: {$claimID}"); $this->_dropbox->writeToLog("there may be orphans"); } return sprintf($smarty->getConfigVariable('ErrorNamedStore'), $libraryfile); } // That's right, one more file! $tplFiles[$realFileCount] = array(); $tplFiles[$realFileCount]['name'] = $libraryfile; $tplFiles[$realFileCount]['type'] = 'Library'; $tplFiles[$realFileCount]['size'] = NSSFormattedMemSize($libraryfilesize); $tplFiles[$realFileCount]['description'] = $librarydesc; $realFileCount++; // Update the description in the library index $this->_dropbox->database()->DBUpdateLibraryDescription($libraryfile, $librarydesc); } elseif ($_FILES[$key]['name']) { // It's an uploaded file $tmpname = basename($_FILES[$key]['tmp_name']); // Get file size from local copy, not what browser told us $bytes = filesize($_FILES[$key]['tmp_name']); if (!move_uploaded_file($_FILES[$key]['tmp_name'], $claimDir . "/" . $tmpname)) { // Exit gracefully -- dump database changes and remove the dropoff // directory: $this->_dropbox->writeToLog("error while storing dropoff files for {$claimID}"); if (!rmdir_r($claimDir)) { $this->_dropbox->writeToLog("unable to remove {$claimDir} -- orphaned!!"); } if (!$this->_dropbox->database->DBRollbackTran()) { $this->_dropbox->writeToLog("failed to ROLLBACK after botched dropoff: {$claimID}"); $this->_dropbox->writeToLog("there may be orphans"); } return sprintf($smarty->getConfigVariable('ErrorNamedDrop'), $_FILES[$key]['name']); } //if ( ($bytes = $_FILES[$key]['size']) < 0 ) { // // Grrr...stupid 32-bit nonsense. Convert to the positive // // value float-wise: // $bytes = ($bytes & 0x7FFFFFFF) + 2147483648.0; //} // Add to database: if (!$this->_dropbox->database->DBAddFile1($dropoffID, $tmpname, paramPrepare($_FILES[$key]['name']), $bytes, $_FILES[$key]['type'] ? $_FILES[$key]['type'] : "application/octet-stream", paramPrepare($_POST["desc_" . $i]))) { // Exit gracefully -- dump database changes and remove the dropoff // directory: $this->_dropbox->writeToLog("error while adding dropoff file to database for {$claimID}"); if (!rmdir_r($claimDir)) { $this->_dropbox->writeToLog("unable to remove {$claimDir} -- orphaned!!"); } if (!$this->_dropbox->database->DBRollbackTran()) { $this->_dropbox->writeToLog("failed to ROLLBACK after botched dropoff: {$claimID}"); $this->_dropbox->writeToLog("there may be orphans"); } return sprintf($smarty->getConfigVariable('ErrorNamedStore'), $_FILES[$key]['name']); } // That's right, one more file! $tplFiles[$realFileCount] = array(); $tplFiles[$realFileCount]['name'] = paramPrepare($_FILES[$key]['name']); $tplFiles[$realFileCount]['type'] = $_FILES[$key]['type']; // Get filesize from local copy, not browser $tplFiles[$i]['size'] = NSSFormattedMemSize($_FILES[$key]['size']); $tplFiles[$realFileCount]['size'] = NSSFormattedMemSize($bytes); $tplFiles[$realFileCount]['description'] = paramPrepare($_POST["desc_" . $i]); $realFileCount++; } $i++; } // Once we get here, it's time to commit the stuff to the database: $this->_dropbox->database->DBCommitTran(); $this->_dropoffID = $dropoffID; // At long last, fill-in the fields: $this->_claimID = $claimID; $this->_claimPasscode = $claimPasscode; $this->_claimDir = $claimDir; $this->_authorizedUser = $this->_dropbox->authorizedUser(); $this->_note = $note; $this->_senderName = $senderName; $this->_senderOrganization = $senderOrganization; $this->_senderEmail = $senderEmail; $this->_senderIP = $_SERVER['REMOTE_ADDR']; $senderIP = $_SERVER['REMOTE_ADDR']; $senderHost = gethostbyaddr($_SERVER['REMOTE_ADDR']); if ($senderHost != '') { $senderHost = '(' . $senderHost . ')'; } $this->_confirmDelivery = $confirmDelivery; $this->_informRecipients = $informRecipients; $this->_created = getdate(); $this->_recipients = $recipients; // This Drop-off request has been fulfilled, so kill the keys // to stop playback attacks. if ($req) { $this->_dropbox->DeleteReqData($req); } if ($auth) { $this->_dropbox->DeleteAuthData($auth); } // Work out the real email subject line. if ($reqSubject != '') { $emailSubject = $reqSubject; } else { if ($realFileCount == 1) { $emailSubject = sprintf($smarty->getConfigVariable('DropoffEmailSubject1'), $senderName); } else { $emailSubject = sprintf($smarty->getConfigVariable('DropoffEmailSubject2'), $senderName); } } // Construct the email notification and deliver: $smarty->assign('senderName', $senderName); $smarty->assign('senderOrg', $senderOrganization); $smarty->assign('senderEmail', $senderEmail); $smarty->assign('senderIP', $senderIP); $smarty->assign('senderHost', $senderHost); $smarty->assign('note', trim($note)); $smarty->assign('subject', $emailSubject); $smarty->assign('now', timestampForTime(time())); $smarty->assign('claimID', $claimID); $smarty->assign('claimPasscode', $claimPasscode); $smarty->assign('fileCount', $realFileCount); $smarty->assign('retainDays', $this->_dropbox->retainDays()); $smarty->assignByRef('files', $tplFiles); $emailTemplate = $smarty->fetch('dropoff_email.tpl'); // Update the address book entries for this user $this->_dropbox->updateAddressbook($recipients); // Inform all the recipients by email if they want me to if ($informRecipients) { // Do we want to Bcc the sender as well? $emailBcc = ''; if ($this->_dropbox->bccSender()) { // and don't forget to encode it if there are intl chars in it if (preg_match('/[^\\x00-\\x7f]/', $senderEmail)) { $emailBcc = "Bcc: =?UTF-8?B?" . base64_encode(html_entity_decode($senderEmail)) . "?=" . PHP_EOL; } else { $emailBcc = "Bcc: {$senderEmail}" . PHP_EOL; } } // Make the mail come from the sender, not ZendTo foreach ($recipients as $recipient) { // In MyZendTo, don't send email to myself if (preg_match('/^[yYtT1]/', MYZENDTO) && $senderEmail != $recipient[1] || preg_match('/^[^yYtT1]/', MYZENDTO)) { $emailContent = preg_replace('/__EMAILADDR__/', urlencode($recipient[1]), $emailTemplate); $success = $this->_dropbox->deliverEmail($recipient[1], $senderEmail, $emailSubject, $emailContent, $emailBcc); $emailBcc = ''; // Only Bcc the sender on the first email out if (!$success) { $this->_dropbox->writeToLog(sprintf("notification email not delivered successfully to %s for claimID {$claimID}", $recipient[1])); } else { $this->_dropbox->writeToLog(sprintf("notification email delivered successfully to %s for claimID {$claimID}", $recipient[1])); } } } } // Log our success: $this->_dropbox->writeToLog(sprintf("{$senderName} <{$senderEmail}> => {$claimID} [%s]", $realFileCount == 1 ? "1 file" : "{$realFileCount} files")); } else { return $smarty->getConfigVariable('ErrorAddDropoff'); } } else { return $smarty->getConfigVariable('ErrorBeginTransaction'); } return NULL; }