Example #1
0
/**
 * Will verify the input against a set of criteria:
 * is every field supplied, does verify password match,
 * does current password validate, ..
 * These criteria are (for now) backend-independent.
 *
 * @return array Array with zero or more error messages.
 */
function cpw_check_input()
{
    global $cpw_pass_min_length, $cpw_pass_max_length;
    // formdata
    sqgetGlobalVar('cpw_curpass', $currentpw, SQ_POST);
    sqgetGlobalVar('cpw_newpass', $newpw, SQ_POST);
    sqgetGlobalVar('cpw_verify', $verifypw, SQ_POST);
    // for decrypting current password
    sqgetGlobalVar('key', $key, SQ_COOKIE);
    sqgetGlobalVar('onetimepad', $onetimepad, SQ_SESSION);
    $msg = array();
    if (!$newpw) {
        $msg[] = _("You must type in a new password.");
    }
    if (!$verifypw) {
        $msg[] = _("You must also type in your new password in the verify box.");
    } elseif ($verifypw != $newpw) {
        $msg[] = _("Your new password does not match the verify password.");
    }
    $orig_pw = OneTimePadDecrypt($key, $onetimepad);
    if (!$currentpw) {
        $msg[] = _("You must type in your current password.");
    } elseif ($currentpw != $orig_pw) {
        $msg[] = _("Your current password is not correct.");
    }
    if ($newpw && (strlen($newpw) < $cpw_pass_min_length || strlen($newpw) > $cpw_pass_max_length)) {
        $msg[] = sprintf(_("Your new password should be %s to %s characters long."), $cpw_pass_min_length, $cpw_pass_max_length);
    }
    // do we need to do checks that are backend-specific and should
    // be handled by a hook? I know of none now, bnd those checks can
    // also be done in the backend dochange() function. If there turns
    // out to be a need for it we can add a hook for that here.
    return $msg;
}
function sqimap_login($username, $password, $imap_server_address, $imap_port, $hide)
{
    global $color, $squirrelmail_language, $onetimepad, $use_imap_tls, $imap_auth_mech;
    if (!isset($onetimepad) || empty($onetimepad)) {
        sqgetglobalvar('onetimepad', $onetimepad, SQ_SESSION);
    }
    $imap_server_address = sqimap_get_user_server($imap_server_address, $username);
    $host = $imap_server_address;
    if ($use_imap_tls == true and check_php_version(4, 3) and extension_loaded('openssl')) {
        /* Use TLS by prefixing "tls://" to the hostname */
        $imap_server_address = 'tls://' . $imap_server_address;
    }
    $imap_stream = fsockopen($imap_server_address, $imap_port, $error_number, $error_string, 15);
    /* Do some error correction */
    if (!$imap_stream) {
        if (!$hide) {
            set_up_language($squirrelmail_language, true);
            require_once SM_PATH . 'functions/display_messages.php';
            $string = sprintf(_("Error connecting to IMAP server: %s.") . "<br>\r\n", $imap_server_address) . "{$error_number} : {$error_string}<br>\r\n";
            logout_error($string, $color);
        }
        exit;
    }
    $server_info = fgets($imap_stream, 1024);
    /* Decrypt the password */
    $password = OneTimePadDecrypt($password, $onetimepad);
    if ($imap_auth_mech == 'cram-md5' or $imap_auth_mech == 'digest-md5') {
        // We're using some sort of authentication OTHER than plain or login
        $tag = sqimap_session_id(false);
        if ($imap_auth_mech == 'digest-md5') {
            $query = $tag . " AUTHENTICATE DIGEST-MD5\r\n";
        } elseif ($imap_auth_mech == 'cram-md5') {
            $query = $tag . " AUTHENTICATE CRAM-MD5\r\n";
        }
        fputs($imap_stream, $query);
        $answer = sqimap_fgets($imap_stream);
        // Trim the "+ " off the front
        $response = explode(" ", $answer, 3);
        if ($response[0] == '+') {
            // Got a challenge back
            $challenge = $response[1];
            if ($imap_auth_mech == 'digest-md5') {
                $reply = digest_md5_response($username, $password, $challenge, 'imap', $host);
            } elseif ($imap_auth_mech == 'cram-md5') {
                $reply = cram_md5_response($username, $password, $challenge);
            }
            fputs($imap_stream, $reply);
            $read = sqimap_fgets($imap_stream);
            if ($imap_auth_mech == 'digest-md5') {
                // DIGEST-MD5 has an extra step..
                if (substr($read, 0, 1) == '+') {
                    // OK so far..
                    fputs($imap_stream, "\r\n");
                    $read = sqimap_fgets($imap_stream);
                }
            }
            $results = explode(" ", $read, 3);
            $response = $results[1];
            $message = $results[2];
        } else {
            // Fake the response, so the error trap at the bottom will work
            $response = "BAD";
            $message = 'IMAP server does not appear to support the authentication method selected.';
            $message .= '  Please contact your system administrator.';
        }
    } elseif ($imap_auth_mech == 'login') {
        // Original IMAP login code
        $query = 'LOGIN "' . quoteimap($username) . '" "' . quoteimap($password) . '"';
        $read = sqimap_run_command($imap_stream, $query, false, $response, $message);
    } elseif ($imap_auth_mech == 'plain') {
        /* Replace this with SASL PLAIN if it ever gets implemented */
        $response = "BAD";
        $message = 'SquirrelMail does not support SASL PLAIN yet. Rerun conf.pl and use login instead.';
    } else {
        $response = "BAD";
        $message = "Internal SquirrelMail error - unknown IMAP authentication method chosen.  Please contact the developers.";
    }
    /* If the connection was not successful, lets see why */
    if ($response != 'OK') {
        if (!$hide) {
            if ($response != 'NO') {
                /* "BAD" and anything else gets reported here. */
                $message = htmlspecialchars($message);
                set_up_language($squirrelmail_language, true);
                require_once SM_PATH . 'functions/display_messages.php';
                if ($response == 'BAD') {
                    $string = sprintf(_("Bad request: %s") . "<br>\r\n", $message);
                } else {
                    $string = sprintf(_("Unknown error: %s") . "<br>\n", $message);
                }
                if (isset($read) && is_array($read)) {
                    $string .= '<br>' . _("Read data:") . "<br>\n";
                    foreach ($read as $line) {
                        $string .= htmlspecialchars($line) . "<br>\n";
                    }
                }
                error_box($string, $color);
                exit;
            } else {
                /*
                 * If the user does not log in with the correct
                 * username and password it is not possible to get the
                 * correct locale from the user's preferences.
                 * Therefore, apply the same hack as on the login
                 * screen.
                 *
                 * $squirrelmail_language is set by a cookie when
                 * the user selects language and logs out
                 */
                set_up_language($squirrelmail_language, true);
                include_once SM_PATH . 'functions/display_messages.php';
                sqsession_destroy();
                logout_error(_("Unknown user or password incorrect."));
                exit;
            }
        } else {
            exit;
        }
    }
    return $imap_stream;
}
Example #3
0
 function sqauth_read_password()
 {
     sqgetGlobalVar('key', $key, SQ_COOKIE);
     sqgetGlobalVar('onetimepad', $onetimepad, SQ_SESSION);
     return OneTimePadDecrypt($key, $onetimepad);
 }
Example #4
0
/**
 * Fillin user and password based on SMTP auth settings.
 *
 * @param string $user Reference to SMTP username
 * @param string $pass Reference to SMTP password (unencrypted)
 */
function get_smtp_user(&$user, &$pass)
{
    global $username, $smtp_auth_mech, $smtp_sitewide_user, $smtp_sitewide_pass;
    if ($smtp_auth_mech == 'none') {
        $user = '';
        $pass = '';
    } elseif (isset($smtp_sitewide_user) && isset($smtp_sitewide_pass)) {
        $user = $smtp_sitewide_user;
        $pass = $smtp_sitewide_pass;
    } else {
        global $key, $onetimepad;
        $user = $username;
        $pass = OneTimePadDecrypt($key, $onetimepad);
    }
}
/**
 * Writes user dictionary into the $username.words file, then changes mask
 * to 0600. If encryption is needed -- does that, too.
 *
 * @param  $words The contents of the ".words" file to write.
 * @return        void
 * @since 1.5.1 (sqspell 0.5)
 * @deprecated
 */
function sqspell_writeWords_old($words)
{
    global $SQSPELL_WORDS_FILE, $SQSPELL_CRYPTO;
    /**
     * if $words is empty, create a template entry by calling the
     * sqspell_makeDummy() function.
     */
    if (!$words) {
        $words = sqspell_makeDummy();
    }
    if ($SQSPELL_CRYPTO) {
        /**
         * User wants to encrypt the file. So be it.
         * Get the user's password to use as a key.
         */
        sqgetGlobalVar('key', $key, SQ_COOKIE);
        sqgetGlobalVar('onetimepad', $onetimepad, SQ_SESSION);
        $clear_key = OneTimePadDecrypt($key, $onetimepad);
        /**
         * Try encrypting it. If fails, scream bloody hell.
         */
        $save_words = sqspell_crypto("encrypt", $clear_key, $words);
        if ($save_words == 'PANIC') {
            /**
             * AAAAAAAAH! I'm not handling this yet, since obviously
             * the admin of the site forgot to compile the MCRYPT support in
             * when upgrading an existing PHP installation.
             * I will add a handler for this case later, when I can come up
             * with some work-around... Right now, do nothing. Let the Admin's
             * head hurt.. ;)))
             */
            /** save some hairs on admin's head and store error message in logs */
            error_log('SquirrelSpell: php does not have mcrypt support');
        }
    } else {
        $save_words = $words;
    }
    /**
     * Do the actual writing.
     */
    $fp = fopen($SQSPELL_WORDS_FILE, "w");
    fwrite($fp, $save_words);
    fclose($fp);
    chmod($SQSPELL_WORDS_FILE, 0600);
}
echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"' . "\n" . '  "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">' . "\n<head>\n<meta name=\"robots\" content=\"noindex,nofollow\">\n" . "</head><body>";
if (sqgetGlobalVar('submit', $submit, SQ_POST)) {
    $continue = TRUE;
    if (!sqgetGlobalVar('secret', $secret, SQ_POST) || empty($secret)) {
        $continue = FALSE;
        echo "<p>You must enter an encryption key.</p>\n";
    }
    if (!sqgetGlobalVar('enc_string', $enc_string, SQ_POST) || empty($enc_string)) {
        $continue = FALSE;
        echo "<p>You must enter an encrypted string.</p>\n";
    }
    if ($continue) {
        if (isset($enc_string) && !base64_decode($enc_string)) {
            echo "<p>Encrypted string should be BASE64 encoded.<br />\n" . "Please enter all characters that are listed after header name.</p>\n";
        } elseif (isset($secret)) {
            $string = OneTimePadDecrypt($enc_string, base64_encode($secret));
            if (sqgetGlobalVar('ip_addr', $is_addr, SQ_POST)) {
                $string = hex2ip($string);
            }
            echo "<p>Decoded string: " . htmlspecialchars($string) . "</p>\n";
        }
    }
    echo "<hr />";
}
?>
<form action="" method="post">
<p>
Secret key: <input type="password" name="secret"><br />
Encrypted string: <input type="text" name="enc_string"><br />
<label for="ip_addr">Check here if you are decoding an address string (FromHash/ProxyHash): </label><input type="checkbox" name="ip_addr" id="ip_addr" /><br />
<button type="submit" name="submit" value="submit">Submit</button>
Example #7
0
function retrieve_external_userdata()
{
    global $data_dir, $username, $password;
    include "../plugins/retrieveuserdata/config.php";
    include "../plugins/retrieveuserdata/{$retrieve_data_from}";
    $cleartext_password = OneTimePadDecrypt($password, $onetimepad);
    $userdata = retrieve_data($username, $cleartext_password);
    if (!$userdata["error"]) {
        set_userdata($userdata["common_name"], $userdata["mail_address"]);
        set_userdata_backup($userdata["common_name"], $userdata["mail_address"]);
        setPref($data_dir, $username, "got_external_userdata", 1);
    }
}
Example #8
0
    <td align="right" nowrap><?php 
    echo _("Repeat password: "******"left"><input type="password" name="rptpass" size="12"></td></tr>
  <tr>
    <td colspan="2" align="center"><input type="submit" name="mkpass" value="<?php 
    echo _("Change my password &gt;&gt;");
    ?>
"></td></tr>
  </table>
  </div>
<?php 
} else {
    /** This means that the form was submitted **/
    $v_key = OneTimePadDecrypt($key, $onetimepad);
    /** These checks are self-explanatory **/
    if ($oldpass != $v_key) {
        sayError("Old password did not match.");
    }
    if ($newpass == $v_key) {
        sayError("New password is the same as old");
    }
    if ($newpass != $rptpass) {
        sayError("New password and repeat password did not match");
    }
    if (strlen($newpass) < 4) {
        sayError("Password too short. Passwords must be between 4 and 16 characters in length.");
    }
    if (strlen($newpass) > 16) {
        sayError("Password too long. Passwords must be between 4 and 16 characters in length.");
Example #9
0
function SendMDN($mailbox, $passed_id, $sender, $message, $imapConnection)
{
    global $username, $attachment_dir, $color, $version, $attachments, $squirrelmail_language, $default_charset, $languages, $useSendmail, $domain, $sent_folder, $popuser, $data_dir, $username;
    sqgetGlobalVar('SERVER_NAME', $SERVER_NAME, SQ_SERVER);
    $header = $message->rfc822_header;
    $hashed_attachment_dir = getHashedDir($username, $attachment_dir);
    $rfc822_header = new Rfc822Header();
    $content_type = new ContentType('multipart/report');
    $content_type->properties['report-type'] = 'disposition-notification';
    set_my_charset();
    if ($default_charset) {
        $content_type->properties['charset'] = $default_charset;
    }
    $rfc822_header->content_type = $content_type;
    $rfc822_header->to[] = $header->dnt;
    $rfc822_header->subject = _("Read:") . ' ' . encodeHeader($header->subject);
    // FIX ME, use identity.php from SM 1.5. Change this also in compose.php
    $reply_to = '';
    if (isset($identity) && $identity != 'default') {
        $from_mail = getPref($data_dir, $username, 'email_address' . $identity);
        $full_name = getPref($data_dir, $username, 'full_name' . $identity);
        $from_addr = '"' . $full_name . '" <' . $from_mail . '>';
        $reply_to = getPref($data_dir, $username, 'reply_to' . $identity);
    } else {
        $from_mail = getPref($data_dir, $username, 'email_address');
        $full_name = getPref($data_dir, $username, 'full_name');
        $from_addr = '"' . $full_name . '" <' . $from_mail . '>';
        $reply_to = getPref($data_dir, $username, 'reply_to');
    }
    // Patch #793504 Return Receipt Failing with <@> from Tim Craig (burny_md)
    // This merely comes from compose.php and only happens when there is no
    // email_addr specified in user's identity (which is the startup config)
    if (ereg("^([^@%/]+)[@%/](.+)\$", $username, $usernamedata)) {
        $popuser = $usernamedata[1];
        $domain = $usernamedata[2];
        unset($usernamedata);
    } else {
        $popuser = $username;
    }
    if (!$from_mail) {
        $from_mail = "{$popuser}@{$domain}";
        $from_addr = $from_mail;
    }
    $rfc822_header->from = $rfc822_header->parseAddress($from_addr, true);
    if ($reply_to) {
        $rfc822_header->reply_to = $rfc822_header->parseAddress($reply_to, true);
    }
    // part 1 (RFC2298)
    $senton = getLongDateString($header->date, $header->date_unparsed);
    $to_array = $header->to;
    $to = '';
    foreach ($to_array as $line) {
        $to .= ' ' . $line->getAddress();
    }
    $now = getLongDateString(time());
    set_my_charset();
    $body = _("Your message") . "\r\n\r\n" . "\t" . _("To") . ': ' . decodeHeader($to, false, false, true) . "\r\n" . "\t" . _("Subject") . ': ' . decodeHeader($header->subject, false, false, true) . "\r\n" . "\t" . _("Sent") . ': ' . $senton . "\r\n" . "\r\n" . sprintf(_("Was displayed on %s"), $now);
    $special_encoding = '';
    if (isset($languages[$squirrelmail_language]['XTRA_CODE']) && function_exists($languages[$squirrelmail_language]['XTRA_CODE'])) {
        $body = $languages[$squirrelmail_language]['XTRA_CODE']('encode', $body);
        if (strtolower($default_charset) == 'iso-2022-jp') {
            if (mb_detect_encoding($body) == 'ASCII') {
                $special_encoding = '8bit';
            } else {
                $body = mb_convert_encoding($body, 'JIS');
                $special_encoding = '7bit';
            }
        }
    } elseif (sq_is8bit($body)) {
        // detect 8bit symbols added by translations
        $special_encoding = '8bit';
    }
    $part1 = new Message();
    $part1->setBody($body);
    $mime_header = new MessageHeader();
    $mime_header->type0 = 'text';
    $mime_header->type1 = 'plain';
    if ($special_encoding) {
        $mime_header->encoding = $special_encoding;
    } else {
        $mime_header->encoding = 'us-ascii';
    }
    if ($default_charset) {
        $mime_header->parameters['charset'] = $default_charset;
    }
    $part1->mime_header = $mime_header;
    // part2  (RFC2298)
    $original_recipient = $to;
    $original_message_id = $header->message_id;
    $report = "Reporting-UA : {$SERVER_NAME} ; SquirrelMail (version {$version}) \r\n";
    if ($original_recipient != '') {
        $report .= "Original-Recipient : {$original_recipient}\r\n";
    }
    $final_recipient = $sender;
    $report .= "Final-Recipient: rfc822; {$final_recipient}\r\n" . "Original-Message-ID : {$original_message_id}\r\n" . "Disposition: manual-action/MDN-sent-manually; displayed\r\n";
    $part2 = new Message();
    $part2->setBody($report);
    $mime_header = new MessageHeader();
    $mime_header->type0 = 'message';
    $mime_header->type1 = 'disposition-notification';
    $mime_header->encoding = 'us-ascii';
    $part2->mime_header = $mime_header;
    $composeMessage = new Message();
    $composeMessage->rfc822_header = $rfc822_header;
    $composeMessage->addEntity($part1);
    $composeMessage->addEntity($part2);
    if ($useSendmail) {
        require_once SM_PATH . 'class/deliver/Deliver_SendMail.class.php';
        global $sendmail_path, $sendmail_args;
        // Check for outdated configuration
        if (!isset($sendmail_args)) {
            if ($sendmail_path == '/var/qmail/bin/qmail-inject') {
                $sendmail_args = '';
            } else {
                $sendmail_args = '-i -t';
            }
        }
        $deliver = new Deliver_SendMail(array('sendmail_args' => $sendmail_args));
        $stream = $deliver->initStream($composeMessage, $sendmail_path);
    } else {
        require_once SM_PATH . 'class/deliver/Deliver_SMTP.class.php';
        $deliver = new Deliver_SMTP();
        global $smtpServerAddress, $smtpPort, $smtp_auth_mech, $pop_before_smtp;
        if ($smtp_auth_mech == 'none') {
            $user = '';
            $pass = '';
        } else {
            global $key, $onetimepad;
            $user = $username;
            $pass = OneTimePadDecrypt($key, $onetimepad);
        }
        $authPop = isset($pop_before_smtp) && $pop_before_smtp ? true : false;
        $stream = $deliver->initStream($composeMessage, $domain, 0, $smtpServerAddress, $smtpPort, $user, $pass, $authPop);
    }
    $success = false;
    if ($stream) {
        $length = $deliver->mail($composeMessage, $stream);
        $success = $deliver->finalizeStream($stream);
    }
    if (!$success) {
        $msg = _("Message not sent.") . ' ' . _("Server replied:") . "\n<blockquote>\n" . $deliver->dlv_msg . '<br />' . $deliver->dlv_ret_nr . ' ' . $deliver->dlv_server_msg . "</blockquote>\n\n";
        require_once SM_PATH . 'functions/display_messages.php';
        plain_error_message($msg, $color);
    } else {
        unset($deliver);
        if (sqimap_mailbox_exists($imapConnection, $sent_folder)) {
            sqimap_append($imapConnection, $sent_folder, $length);
            require_once SM_PATH . 'class/deliver/Deliver_IMAP.class.php';
            $imap_deliver = new Deliver_IMAP();
            $imap_deliver->mail($composeMessage, $imapConnection);
            sqimap_append_done($imapConnection);
            unset($imap_deliver);
        }
    }
    return $success;
}
Example #10
0
/**
 * temporary function to make use of the deliver class.
 * In the future the responsible backend should be automaticly loaded
 * and conf.pl should show a list of available backends.
 * The message also should be constructed by the message class.
 */
function deliverMessage($composeMessage, $draft = false)
{
    global $send_to, $send_to_cc, $send_to_bcc, $mailprio, $subject, $body, $username, $popuser, $usernamedata, $identity, $idents, $data_dir, $request_mdn, $request_dr, $default_charset, $color, $useSendmail, $domain, $action, $default_move_to_sent, $move_to_sent;
    global $imapServerAddress, $imapPort, $sent_folder, $key;
    $rfc822_header = $composeMessage->rfc822_header;
    $abook = addressbook_init(false, true);
    $rfc822_header->to = $rfc822_header->parseAddress($send_to, true, array(), '', $domain, array(&$abook, 'lookup'));
    $rfc822_header->cc = $rfc822_header->parseAddress($send_to_cc, true, array(), '', $domain, array(&$abook, 'lookup'));
    $rfc822_header->bcc = $rfc822_header->parseAddress($send_to_bcc, true, array(), '', $domain, array(&$abook, 'lookup'));
    $rfc822_header->priority = $mailprio;
    $rfc822_header->subject = $subject;
    $special_encoding = '';
    if (strtolower($default_charset) == 'iso-2022-jp') {
        if (mb_detect_encoding($body) == 'ASCII') {
            $special_encoding = '8bit';
        } else {
            $body = mb_convert_encoding($body, 'JIS');
            $special_encoding = '7bit';
        }
    }
    $composeMessage->setBody($body);
    if (ereg("^([^@%/]+)[@%/](.+)\$", $username, $usernamedata)) {
        $popuser = $usernamedata[1];
        $domain = $usernamedata[2];
        unset($usernamedata);
    } else {
        $popuser = $username;
    }
    $reply_to = '';
    $from_mail = $idents[$identity]['email_address'];
    $full_name = $idents[$identity]['full_name'];
    $reply_to = $idents[$identity]['reply_to'];
    if (!$from_mail) {
        $from_mail = "{$popuser}@{$domain}";
    }
    $rfc822_header->from = $rfc822_header->parseAddress($from_mail, true);
    if ($full_name) {
        $from = $rfc822_header->from[0];
        if (!$from->host) {
            $from->host = $domain;
        }
        $full_name_encoded = encodeHeader($full_name);
        if ($full_name_encoded != $full_name) {
            $from_addr = $full_name_encoded . ' <' . $from->mailbox . '@' . $from->host . '>';
        } else {
            $from_addr = '"' . $full_name . '" <' . $from->mailbox . '@' . $from->host . '>';
        }
        $rfc822_header->from = $rfc822_header->parseAddress($from_addr, true);
    }
    if ($reply_to) {
        $rfc822_header->reply_to = $rfc822_header->parseAddress($reply_to, true);
    }
    /* Receipt: On Read */
    if (isset($request_mdn) && $request_mdn) {
        $rfc822_header->dnt = $rfc822_header->parseAddress($from_mail, true);
    }
    /* Receipt: On Delivery */
    if (isset($request_dr) && $request_dr) {
        $rfc822_header->more_headers['Return-Receipt-To'] = $from_mail;
    }
    /* multipart messages */
    if (count($composeMessage->entities)) {
        $message_body = new Message();
        $message_body->body_part = $composeMessage->body_part;
        $composeMessage->body_part = '';
        $mime_header = new MessageHeader();
        $mime_header->type0 = 'text';
        $mime_header->type1 = 'plain';
        if ($special_encoding) {
            $mime_header->encoding = $special_encoding;
        } else {
            $mime_header->encoding = '8bit';
        }
        if ($default_charset) {
            $mime_header->parameters['charset'] = $default_charset;
        }
        $message_body->mime_header = $mime_header;
        array_unshift($composeMessage->entities, $message_body);
        $content_type = new ContentType('multipart/mixed');
    } else {
        $content_type = new ContentType('text/plain');
        if ($special_encoding) {
            $rfc822_header->encoding = $special_encoding;
        } else {
            $rfc822_header->encoding = '8bit';
        }
        if ($default_charset) {
            $content_type->properties['charset'] = $default_charset;
        }
    }
    $rfc822_header->content_type = $content_type;
    $composeMessage->rfc822_header = $rfc822_header;
    /* Here you can modify the message structure just before we hand
       it over to deliver */
    $hookReturn = do_hook('compose_send', $composeMessage);
    /* Get any changes made by plugins to $composeMessage. */
    if (is_object($hookReturn[1])) {
        $composeMessage = $hookReturn[1];
    }
    if (!$useSendmail && !$draft) {
        require_once SM_PATH . 'class/deliver/Deliver_SMTP.class.php';
        $deliver = new Deliver_SMTP();
        global $smtpServerAddress, $smtpPort, $pop_before_smtp, $smtp_auth_mech;
        $authPop = isset($pop_before_smtp) && $pop_before_smtp ? true : false;
        if ($smtp_auth_mech == 'none' && !$authPop) {
            $user = '';
            $pass = '';
        } else {
            global $key, $onetimepad;
            $user = $username;
            $pass = OneTimePadDecrypt($key, $onetimepad);
        }
        $stream = $deliver->initStream($composeMessage, $domain, 0, $smtpServerAddress, $smtpPort, $user, $pass, $authPop);
    } elseif (!$draft) {
        require_once SM_PATH . 'class/deliver/Deliver_SendMail.class.php';
        global $sendmail_path, $sendmail_args;
        // Check for outdated configuration
        if (!isset($sendmail_args)) {
            if ($sendmail_path == '/var/qmail/bin/qmail-inject') {
                $sendmail_args = '';
            } else {
                $sendmail_args = '-i -t';
            }
        }
        $deliver = new Deliver_SendMail(array('sendmail_args' => $sendmail_args));
        $stream = $deliver->initStream($composeMessage, $sendmail_path);
    } elseif ($draft) {
        global $draft_folder;
        require_once SM_PATH . 'class/deliver/Deliver_IMAP.class.php';
        $imap_stream = sqimap_login($username, $key, $imapServerAddress, $imapPort, 0);
        if (sqimap_mailbox_exists($imap_stream, $draft_folder)) {
            require_once SM_PATH . 'class/deliver/Deliver_IMAP.class.php';
            $imap_deliver = new Deliver_IMAP();
            $length = $imap_deliver->mail($composeMessage);
            sqimap_append($imap_stream, $draft_folder, $length);
            $imap_deliver->mail($composeMessage, $imap_stream);
            sqimap_append_done($imap_stream, $draft_folder);
            sqimap_logout($imap_stream);
            unset($imap_deliver);
            $composeMessage->purgeAttachments();
            return $length;
        } else {
            $msg = '<br />' . sprintf(_("Error: Draft folder %s does not exist."), htmlspecialchars($draft_folder));
            plain_error_message($msg, $color);
            return false;
        }
    }
    $succes = false;
    if ($stream) {
        $length = $deliver->mail($composeMessage, $stream);
        $succes = $deliver->finalizeStream($stream);
    }
    if (!$succes) {
        $msg = _("Message not sent.") . ' ' . _("Server replied:") . "\n<blockquote>\n" . $deliver->dlv_msg . '<br />' . $deliver->dlv_ret_nr . ' ' . $deliver->dlv_server_msg . "</blockquote>\n\n";
        plain_error_message($msg, $color);
    } else {
        unset($deliver);
        $move_to_sent = getPref($data_dir, $username, 'move_to_sent');
        $imap_stream = sqimap_login($username, $key, $imapServerAddress, $imapPort, 0);
        /* Move to sent code */
        if (isset($default_move_to_sent) && $default_move_to_sent != 0) {
            $svr_allow_sent = true;
        } else {
            $svr_allow_sent = false;
        }
        if (isset($sent_folder) && ($sent_folder != '' || $sent_folder != 'none') && sqimap_mailbox_exists($imap_stream, $sent_folder)) {
            $fld_sent = true;
        } else {
            $fld_sent = false;
        }
        if (isset($move_to_sent) && $move_to_sent != 0 || !isset($move_to_sent)) {
            $lcl_allow_sent = true;
        } else {
            $lcl_allow_sent = false;
        }
        if ($fld_sent && $svr_allow_sent && !$lcl_allow_sent || $fld_sent && $lcl_allow_sent) {
            sqimap_append($imap_stream, $sent_folder, $length);
            require_once SM_PATH . 'class/deliver/Deliver_IMAP.class.php';
            $imap_deliver = new Deliver_IMAP();
            $imap_deliver->mail($composeMessage, $imap_stream);
            sqimap_append_done($imap_stream, $sent_folder);
            unset($imap_deliver);
        }
        global $passed_id, $mailbox, $action;
        $composeMessage->purgeAttachments();
        if ($action == 'reply' || $action == 'reply_all') {
            sqimap_mailbox_select($imap_stream, $mailbox);
            sqimap_messages_flag($imap_stream, $passed_id, $passed_id, 'Answered', false);
        }
        sqimap_logout($imap_stream);
    }
    return $succes;
}
Example #11
0
/**
 * Logs the user into the IMAP server.  If $hide is set, no error messages
 * will be displayed (if set to 1, just exits, if set to 2, returns FALSE).
 * This function returns the IMAP connection handle.
 * @param string $username user name
 * @param string $password password encrypted with onetimepad. Since 1.5.2
 *  function can use internal password functions, if parameter is set to
 *  boolean false.
 * @param string $imap_server_address address of imap server
 * @param integer $imap_port port of imap server
 * @param int $hide controls display connection errors:
 *                  0 = do not hide
 *                  1 = show no errors (just exit)
 *                  2 = show no errors (return FALSE)
 *                  3 = show no errors (return error string)
 * @param array $stream_options Stream context options, see config_local.php
 *                           for more details (OPTIONAL)
 * @return mixed The IMAP connection stream, or if the connection fails,
 *               FALSE if $hide is set to 2 or an error string if $hide
 *               is set to 3.
 */
function sqimap_login($username, $password, $imap_server_address, $imap_port, $hide, $stream_options = array())
{
    global $color, $squirrelmail_language, $onetimepad, $use_imap_tls, $imap_auth_mech, $sqimap_capabilities, $display_imap_login_error;
    // Note/TODO: This hack grabs the $authz argument from the session. In the short future,
    // a new argument in function sqimap_login() will be used instead.
    $authz = '';
    global $authz;
    sqgetglobalvar('authz', $authz, SQ_SESSION);
    if (!empty($authz)) {
        /* authz plugin - specific:
         * Get proxy login parameters from authz plugin configuration. If they
         * exist, they will override the current ones.
         * This is useful if we want to use different SASL authentication mechanism
         * and/or different TLS settings for proxy logins. */
        global $authz_imap_auth_mech, $authz_use_imap_tls, $authz_imapPort_tls;
        $imap_auth_mech = !empty($authz_imap_auth_mech) ? strtolower($authz_imap_auth_mech) : $imap_auth_mech;
        $use_imap_tls = !empty($authz_use_imap_tls) ? $authz_use_imap_tls : $use_imap_tls;
        $imap_port = !empty($authz_use_imap_tls) ? $authz_imapPort_tls : $imap_port;
        if ($imap_auth_mech == 'login' || $imap_auth_mech == 'cram-md5') {
            logout_error("Misconfigured Plugin (authz or equivalent):<br/>" . "The LOGIN and CRAM-MD5 authentication mechanisms cannot be used when attempting proxy login.");
            exit;
        }
    }
    /* get imap login password */
    if ($password === false) {
        /* standard functions */
        $password = sqauth_read_password();
    } else {
        /* old way. $key must be extracted from cookie */
        if (!isset($onetimepad) || empty($onetimepad)) {
            sqgetglobalvar('onetimepad', $onetimepad, SQ_SESSION);
        }
        /* Decrypt the password */
        $password = OneTimePadDecrypt($password, $onetimepad);
    }
    if (!isset($sqimap_capabilities)) {
        sqgetglobalvar('sqimap_capabilities', $sqimap_capabilities, SQ_SESSION);
    }
    $host = $imap_server_address;
    $imap_server_address = sqimap_get_user_server($imap_server_address, $username);
    $imap_stream = sqimap_create_stream($imap_server_address, $imap_port, $use_imap_tls, $stream_options);
    if ($imap_auth_mech == 'cram-md5' or $imap_auth_mech == 'digest-md5') {
        // We're using some sort of authentication OTHER than plain or login
        $tag = sqimap_session_id(false);
        if ($imap_auth_mech == 'digest-md5') {
            $query = $tag . " AUTHENTICATE DIGEST-MD5\r\n";
        } elseif ($imap_auth_mech == 'cram-md5') {
            $query = $tag . " AUTHENTICATE CRAM-MD5\r\n";
        }
        fputs($imap_stream, $query);
        $answer = sqimap_fgets($imap_stream);
        // Trim the "+ " off the front
        $response = explode(" ", $answer, 3);
        if ($response[0] == '+') {
            // Got a challenge back
            $challenge = $response[1];
            if ($imap_auth_mech == 'digest-md5') {
                $reply = digest_md5_response($username, $password, $challenge, 'imap', $host, $authz);
            } elseif ($imap_auth_mech == 'cram-md5') {
                $reply = cram_md5_response($username, $password, $challenge);
            }
            fputs($imap_stream, $reply);
            $read = sqimap_fgets($imap_stream);
            if ($imap_auth_mech == 'digest-md5') {
                // DIGEST-MD5 has an extra step..
                if (substr($read, 0, 1) == '+') {
                    // OK so far..
                    fputs($imap_stream, "\r\n");
                    $read = sqimap_fgets($imap_stream);
                }
            }
            $results = explode(" ", $read, 3);
            $response = $results[1];
            $message = $results[2];
        } else {
            // Fake the response, so the error trap at the bottom will work
            $response = "BAD";
            $message = 'IMAP server does not appear to support the authentication method selected.';
            $message .= '  Please contact your system administrator.';
        }
    } elseif ($imap_auth_mech == 'login') {
        // Original IMAP login code
        $query = 'LOGIN "' . quoteimap($username) . '" "' . quoteimap($password) . '"';
        $read = sqimap_run_command($imap_stream, $query, false, $response, $message);
    } elseif ($imap_auth_mech == 'plain') {
        /***
         * SASL PLAIN, RFC 4616 (updates 2595)
         *
         * The mechanism consists of a single message, a string of [UTF-8]
         * encoded [Unicode] characters, from the client to the server.  The
         * client presents the authorization identity (identity to act as),
         * followed by a NUL (U+0000) character, followed by the authentication
         * identity (identity whose password will be used), followed by a NUL
         * (U+0000) character, followed by the clear-text password.  As with
         * other SASL mechanisms, the client does not provide an authorization
         * identity when it wishes the server to derive an identity from the
         * credentials and use that as the authorization identity.
         */
        $tag = sqimap_session_id(false);
        $sasl = isset($sqimap_capabilities['SASL-IR']) && $sqimap_capabilities['SASL-IR'] ? true : false;
        if (!empty($authz)) {
            $auth = base64_encode("{$username}{$authz}{$password}");
        } else {
            $auth = base64_encode("{$username}{$username}{$password}");
        }
        if ($sasl) {
            // IMAP Extension for SASL Initial Client Response
            // <draft-siemborski-imap-sasl-initial-response-01b.txt>
            $query = $tag . " AUTHENTICATE PLAIN {$auth}\r\n";
            fputs($imap_stream, $query);
            $read = sqimap_fgets($imap_stream);
        } else {
            $query = $tag . " AUTHENTICATE PLAIN\r\n";
            fputs($imap_stream, $query);
            $read = sqimap_fgets($imap_stream);
            if (substr($read, 0, 1) == '+') {
                // OK so far..
                fputs($imap_stream, "{$auth}\r\n");
                $read = sqimap_fgets($imap_stream);
            }
        }
        $results = explode(" ", $read, 3);
        $response = $results[1];
        $message = $results[2];
    } else {
        $response = "BAD";
        $message = "Internal SquirrelMail error - unknown IMAP authentication method chosen.  Please contact the developers.";
    }
    /* If the connection was not successful, lets see why */
    if ($response != 'OK') {
        if (!$hide || $hide == 3) {
            //FIXME: UUURG... We don't want HTML in error messages, should also do html sanitizing of error messages elsewhere; should't assume output is destined for an HTML browser here
            if ($response != 'NO') {
                /* "BAD" and anything else gets reported here. */
                $message = sm_encode_html_special_chars($message);
                set_up_language($squirrelmail_language, true);
                if ($response == 'BAD') {
                    if ($hide == 3) {
                        return sprintf(_("Bad request: %s"), $message);
                    }
                    $string = sprintf(_("Bad request: %s") . "<br />\r\n", $message);
                } else {
                    if ($hide == 3) {
                        return sprintf(_("Unknown error: %s"), $message);
                    }
                    $string = sprintf(_("Unknown error: %s") . "<br />\n", $message);
                }
                if (isset($read) && is_array($read)) {
                    $string .= '<br />' . _("Read data:") . "<br />\n";
                    foreach ($read as $line) {
                        $string .= sm_encode_html_special_chars($line) . "<br />\n";
                    }
                }
                error_box($string);
                exit;
            } else {
                /*
                 * If the user does not log in with the correct
                 * username and password it is not possible to get the
                 * correct locale from the user's preferences.
                 * Therefore, apply the same hack as on the login
                 * screen.
                 *
                 * $squirrelmail_language is set by a cookie when
                 * the user selects language and logs out
                 */
                set_up_language($squirrelmail_language, true);
                sqsession_destroy();
                /* terminate the session nicely */
                sqimap_logout($imap_stream);
                // determine what error message to use
                //
                $fail_msg = _("Unknown user or password incorrect.");
                if ($display_imap_login_error) {
                    // See if there is an error message from the server
                    // Skip any rfc5530 response code: '[something]' at the
                    // start of the message
                    if (!empty($message) && $message[0] == '[' && ($end = strstr($message, ']')) && $end != ']') {
                        $message = substr($end, 1);
                    }
                    // Remove surrounding spaces and if there
                    // is anything left, display that as the
                    // error message:
                    $message = trim($message);
                    if (strlen($message)) {
                        $fail_msg = _($message);
                    }
                }
                if ($hide == 3) {
                    return $fail_msg;
                }
                logout_error($fail_msg);
                exit;
            }
        } else {
            if ($hide == 2) {
                return FALSE;
            }
            exit;
        }
    }
    /* Special error case:
     * Login referrals. The server returns:
     * ? OK [REFERRAL <imap url>]
     * Check RFC 2221 for details. Since we do not support login referrals yet
     * we log the user out.
     */
    if (stristr($message, 'REFERRAL imap') === TRUE) {
        sqimap_logout($imap_stream);
        set_up_language($squirrelmail_language, true);
        sqsession_destroy();
        logout_error(_("Your mailbox is not located at this server. Try a different server or consult your system administrator"));
        exit;
    }
    return $imap_stream;
}
Example #12
0
/**
 * Reads and decodes stored user password information
 *
 * Direct access to password information is deprecated.
 * @return string password in plain text
 * @since 1.5.1
 */
function sqauth_read_password()
{
    global $currentHookName;
    if ($currentHookName == 'login_verified') {
        global $key;
    }
    sqgetGlobalVar('key', $key, SQ_COOKIE);
    sqgetGlobalVar('onetimepad', $onetimepad, SQ_SESSION);
    return OneTimePadDecrypt($key, $onetimepad);
}