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; }
/** * Logs the user into the imap server. If $hide is set, no error messages * will be displayed. This function returns the imap connection handle. */ function sqimap_login($username, $password, $imap_server_address, $imap_port, $hide) { global $color, $squirrelmail_language, $onetimepad, $use_imap_tls, $imap_auth_mech, $sqimap_capabilities; if (!isset($onetimepad) || empty($onetimepad)) { sqgetglobalvar('onetimepad', $onetimepad, SQ_SESSION); } if (!isset($sqimap_capabilities)) { sqgetglobalvar('sqimap_capabilities', $capability, 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); /* 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') { /*** * SASL PLAIN * * RFC 2595 Chapter 6 * * The mechanism consists of a single message from the client to the * server. The client sends the authorization identity (identity to * login as), followed by a US-ASCII NUL character, followed by the * authentication identity (identity whose password will be used), * followed by a US-ASCII NUL character, followed by the clear-text * password. The client may leave the authorization identity empty to * indicate that it is the same as the authentication identity. * **/ $tag = sqimap_session_id(false); $sasl = isset($capability['SASL-IR']) && $capability['SASL-IR'] ? true : false; $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) { 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(); /* terminate the session nicely */ sqimap_logout($imap_stream); logout_error(_("Unknown user or password incorrect.")); exit; } } else { exit; } } return $imap_stream; }
/** * Creates and runs the IMAP command to filter messages * @param string $imap_stream TODO: Document this parameter * @param string $where Which part of the message to search (TO, CC, SUBJECT, etc...) * @param string $what String to search for * @param string $where_to Folder it will move to * @param string $user_scan Whether to search all or just unseen * @param string $should_expunge * @access private */ function filter_search_and_delete($imap_stream, $where, $what, $where_to, $user_scan, $should_expunge) { global $languages, $squirrelmail_language, $allow_charset_search, $imap_server_type; //TODO: make use of new mailbox cache. See mailbox_display.phpinfo if (strtolower($where_to) == 'inbox') { return array(); } if ($user_scan == 'new') { $category = 'UNSEEN'; } else { $category = 'ALL'; } $category .= ' UNDELETED'; if ($allow_charset_search && isset($languages[$squirrelmail_language]['CHARSET']) && $languages[$squirrelmail_language]['CHARSET']) { $search_str = 'SEARCH CHARSET ' . strtoupper($languages[$squirrelmail_language]['CHARSET']) . ' ' . $category; } else { $search_str = 'SEARCH CHARSET US-ASCII ' . $category; } if ($where == 'Header') { $what = explode(':', $what); $where = strtoupper($where); $where = trim($where . ' ' . $what[0]); $what = addslashes(trim($what[1])); } // see comments in squirrelmail sqimap_search function if ($imap_server_type == 'macosx' || $imap_server_type == 'hmailserver') { $search_str .= ' ' . $where . ' ' . $what; /* read data back from IMAP */ $read = sqimap_run_command($imap_stream, $search_str, true, $response, $message, TRUE); } else { $search_str .= ' ' . $where . ' {' . strlen($what) . "}"; $sid = sqimap_session_id(true); fputs($imap_stream, $sid . ' ' . $search_str . "\r\n"); $read2 = sqimap_fgets($imap_stream); # server should respond with Ready for argument, then we will send search text #echo "RR2 $read2<br>"; fputs($imap_stream, "{$what}\r\n"); #echo "SS $what<br>"; $read2 = sqimap_fgets($imap_stream); #echo "RR2 $read2<br>"; $read[] = $read2; $read3 = sqimap_fgets($imap_stream); #echo "RR3 $read3<br>"; list($rtag, $response, $message) = explode(' ', $read3, 3); ## $read2 = sqimap_retrieve_imap_response($imap_stream, $sid, true, ## $response, $message, $search_str, false, true, false); #echo "RR2 $read2 / RESPONSE $response<br>"; } if (isset($read[0])) { $ids = array(); for ($i = 0, $iCnt = count($read); $i < $iCnt; ++$i) { if (preg_match("/^\\* SEARCH (.+)\$/", $read[$i], $regs)) { $ids += explode(' ', trim($regs[1])); } } if ($response == 'OK' && count($ids)) { if (sqimap_mailbox_exists($imap_stream, $where_to)) { if (!sqimap_msgs_list_move($imap_stream, $ids, $where_to, false)) { // if errors occurred, don't try to filter again during this session sqsession_register(TRUE, 'filters_error'); global $color; error_box(_("A problem occurred filtering messages. Check filter settings and account quota if applicable. Filtering is disabled for the remainder of this login session."), $color); } // expunge even in the case of errors, in case some // messages were filtered before the error happened $should_expunge = true; } } elseif ($response != 'OK') { $query = $search_str . "\r\n" . $what . "\r\n"; if ($response == 'NO') { if (strpos($message, 'BADCHARSET') !== false || strpos($message, 'character') !== false) { sqm_trigger_imap_error('SQM_IMAP_BADCHARSET', $query, $response, $message); } else { sqm_trigger_imap_error('SQM_IMAP_ERROR', $query, $response, $message); } } else { sqm_trigger_imap_error('SQM_IMAP_ERROR', $query, $response, $message); } } } return $should_expunge; }
/** * 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; }
function sqimap_read_data_list($imap_stream, $tag_uid, $handle_errors, &$response, &$message, $query = '', $filter = false, $outputstream = false, $no_return = false) { $read = ''; $tag_uid_a = explode(' ', trim($tag_uid)); $tag = $tag_uid_a[0]; $resultlist = array(); $data = array(); $read = sqimap_fgets($imap_stream); $i = 0; while ($read) { $char = substr($read, 0, 1); switch ($char) { case '+': default: $read = sqimap_fgets($imap_stream); break; case substr($tag, 0, 1): /* get the command */ $arg = ''; $i = strlen($tag) + 1; $s = substr($read, $i); if (($j = strpos($s, ' ')) || ($j = strpos($s, "\n"))) { $arg = substr($s, 0, $j); } $found_tag = substr($read, 0, $i - 1); if ($arg && $found_tag == $tag) { switch ($arg) { case 'OK': case 'BAD': case 'NO': case 'BYE': case 'PREAUTH': $response = $arg; $message = trim(substr($read, $i + strlen($arg))); break 3; /* switch switch while */ /* switch switch while */ default: /* this shouldn't happen */ $response = $arg; $message = trim(substr($read, $i + strlen($arg))); break 3; /* switch switch while */ } } elseif ($found_tag !== $tag) { /* reset data array because we do not need this reponse */ $data = array(); $read = sqimap_fgets($imap_stream); break; } // end case substr($tag, 0, 1) // end case substr($tag, 0, 1) case '*': if (preg_match('/^\\*\\s\\d+\\sFETCH/', $read)) { /* check for literal */ $s = substr($read, -3); $fetch_data = array(); do { /* outer loop, continue until next untagged fetch or tagged reponse */ do { /* innerloop for fetching literals. with this loop we prohibid that literal responses appear in the outer loop so we can trust the untagged and tagged info provided by $read */ if ($s === "}\r\n") { $j = strrpos($read, '{'); $iLit = substr($read, $j + 1, -3); $fetch_data[] = $read; $sLiteral = sqimap_fread($imap_stream, $iLit, $filter, $outputstream, $no_return); if ($sLiteral === false) { /* error */ break 4; /* while while switch while */ } /* backwards compattibility */ $aLiteral = explode("\n", $sLiteral); /* release not neaded data */ unset($sLiteral); foreach ($aLiteral as $line) { $fetch_data[] = $line . "\n"; } /* release not neaded data */ unset($aLiteral); /* next fgets belongs to this fetch because we just got the exact literalsize and there must follow data to complete the response */ $read = sqimap_fgets($imap_stream); if ($read === false) { /* error */ break 4; /* while while switch while */ } $fetch_data[] = $read; } else { $fetch_data[] = $read; } /* retrieve next line and check in the while statements if it belongs to this fetch response */ $read = sqimap_fgets($imap_stream); if ($read === false) { /* error */ break 4; /* while while switch while */ } /* check for next untagged reponse and break */ if (substr($read, 0, 1) == '*') { break 2; } $s = substr($read, -3); } while ($s === "}\r\n"); $s = substr($read, -3); } while (substr($read, 0, 1) !== '*' && substr($read, 0, strlen($tag)) !== $tag); $resultlist[] = $fetch_data; /* release not neaded data */ unset($fetch_data); } else { $s = substr($read, -3); do { if ($s === "}\r\n") { $j = strrpos($read, '{'); $iLit = substr($read, $j + 1, -3); $data[] = $read; $sLiteral = fread($imap_stream, $iLit); if ($sLiteral === false) { /* error */ $read = false; break 3; /* while switch while */ } $data[] = $sLiteral; $data[] = sqimap_fgets($imap_stream); } else { $data[] = $read; } $read = sqimap_fgets($imap_stream); if ($read === false) { break 3; /* while switch while */ } elseif (substr($read, 0, 1) == '*') { break; } $s = substr($read, -3); } while ($s === "}\r\n"); break 1; } break; // end case '*' } // end switch } // end while /* error processing in case $read is false */ if ($read === false) { unset($data); echo date("d.m.Y @ G:i:s") . ": ERROR: Connection dropped by IMAP server.\n"; exit; } /* Set $resultlist array */ if (!empty($data)) { $resultlist[] = $data; } elseif (empty($resultlist)) { $resultlist[] = array(); } /* Return result or handle errors */ if ($handle_errors == false) { return $resultlist; } switch ($response) { case 'OK': return $resultlist; break; case 'NO': /* ignore this error from M$ exchange, it is not fatal (aka bug) */ if (strstr($message, 'command resulted in') === false) { echo date("d.m.Y @ G:i:s") . ": ERROR: Could not complete request.\n"; exit; } break; case 'BAD': echo date("d.m.Y @ G:i:s") . ": ERROR: Bad or malformed request.\n"; exit; case 'BYE': echo date("d.m.Y @ G:i:s") . ": ERROR: IMAP server closed the connection.\n"; exit; default: echo date("d.m.Y @ G:i:s") . ": ERROR: Unknown IMAP response.\n"; return $resultlist; break; } }