// sanity check if (!isset($stamp) || $stamp <= NULL_DATE) { return $stamp; } // time in surfer time zone $stamp = mktime(intval(substr($stamp, 11, 2)), intval(substr($stamp, 14, 2)), intval(substr($stamp, 17, 2)), intval(substr($stamp, 5, 2)), intval(substr($stamp, 8, 2)), intval(substr($stamp, 0, 4))); // shift to UTC time zone return strftime('%Y-%m-%d %H:%M:%S', $stamp - Surfer::get_gmt_offset() * 3600); } } // we don't want to use url rewriting, but only cookies (exclusive with 'use.cookies' and 'use_trans_sid') if (isset($_SERVER['REMOTE_ADDR'])) { Safe::ini_set('session.use_cookies', '1'); Safe::ini_set('session.use_only_cookies', '1'); //Safe::ini_set('session.use_trans_sid', '0'); -- don't uncomment !!! Safe::ini_set('url_rewriter.tags', ''); } // set the permanent cookie on the transaction that follows the login, in case a redirection would have happened if (isset($_SESSION['surfer_token'])) { // set it Surfer::set_cookie('screening', $_SESSION['surfer_token']); // don't do that again unset($_SESSION['surfer_token']); } // retrieve session data, but not if run from the command line, and not from robot nor spider if (isset($_SERVER['REMOTE_ADDR']) && !Surfer::is_crawler() && !headers_sent()) { // permanent identification has been selected if (isset($context['users_with_permanent_authentication']) && $context['users_with_permanent_authentication'] != 'N') { // use cookie to identify user -- user id, time of login, gmt offset, salt if (!Surfer::is_logged() && isset($_COOKIE['screening']) && ($nouns = explode('|', $_COOKIE['screening'], 4)) && count($nouns) == 4) { // get user by id
/** * connect to the mail server * * This function opens a network connection to the server, authenticate if required to do so, * and set $context['mail_handle'] to be used for actual transmissions. * * If parameter $context['mail_variant'] is set to 'smtp', a SMTP connection is * established with the computer specified in $context['mail_server']. If some credentials * are provided in $context['mail_account'] and $context['mail_password'], they are * transmitted to the server as per protocol extension. CRAM-MD5, LOGIN and PLAIN authentication * schemes have been implemented. * * @link http://tools.ietf.org/rfc/rfc2104.txt HMAC * @link http://www.fehcom.de/qmail/smtpauth.html * * If parameter $context['mail_variant'] is set to 'pop3', and if credentials have been * set in $context['mail_account'] and in $context['mail_password'], a POP3 connection * is made to the mail server just to authenticate, and then a SMTP connection * is established to actually transmit messages. If a secured communication has been * configured for SMTP, then a secured POP3 communication is performed on port 995. Else * a vanilla POP3 transaction is done on regular port 110. * * For any other value of $context['mail_variant'], or if the parameter is not set, * the function relies on the PHP mail() function to do the job. If the parameter * $context['mail_server'] is set, it overloads php.ini settings. Therefore you can change * the SMTP server used for transmission without the needs to edit the php.ini file. * * The parameter $context['mail_server'] can call for SSL/TLS support, or use a specific * port number, as in the following examples: * * [snippet] * ssl://mail.server.com * mail.server.com:234 * [/snippet] * * @return mixed the socket handle itself, of FALSE on error * * @see control/configure.php */ private static function connect() { global $context; // we already have an open handle if (isset($context['mail_handle'])) { return $context['mail_handle']; } // email services have to be activated if (!isset($context['with_email']) || $context['with_email'] != 'Y') { Logger::error(i18n::s('E-mail has not been enabled on this system.')); return FALSE; } // define target smtp server $port = 25; if (isset($context['mail_server'])) { $server = $context['mail_server']; // use alternate port if required to do so if (preg_match('/^(.+):([0-9]+)$/', $server, $matches)) { $server = $matches[1]; $port = intval($matches[2]); } } // ensure that we can support tls communications if (isset($server) && !strncmp($server, 'ssl://', 6) && is_callable('extension_loaded') && !extension_loaded('openssl')) { logger::remember('shared/mailer.php: Load the OpenSSL extension to support secured transmissions to mail server ' . $server); return FALSE; } // go for POP authentication if (isset($server) && isset($context['mail_variant']) && $context['mail_variant'] == 'pop3') { // authenticate to a pop3 server if (isset($context['mail_account']) && isset($context['mail_password'])) { // select which port to use if (strncmp($server, 'ssl://', 6)) { $pop3_port = 110; } else { $pop3_port = 995; } // open a network connection if (!($handle = Safe::fsockopen($server, $pop3_port, $errno, $errstr, 10))) { if ($context['debug_mail'] == 'Y') { Logger::remember('shared/mailer.php: fsockopen:', $errstr . ' (' . $errno . ')', 'debug'); } Logger::remember('shared/mailer.php: ' . sprintf('Impossible to connect to %s', $server . ':' . $pop3_port)); return FALSE; } // ensure enough execution time Safe::set_time_limit(30); // get server banner if (($reply = fgets($handle)) === FALSE) { Logger::remember('shared/mailer.php: Impossible to get banner of ' . $server); fclose($handle); return FALSE; } if ($context['debug_mail'] == 'Y') { Logger::remember('shared/mailer.php: POP <-', $reply, 'debug'); } // expecting an OK if (strncmp($reply, '+OK', 3)) { Logger::remember('shared/mailer.php: Mail service is closed at ' . $server, $reply); fclose($handle); return FALSE; } // send user name $request = 'USER ' . $context['mail_account']; fputs($handle, $request . CRLF); if ($context['debug_mail'] == 'Y') { Logger::remember('shared/mailer.php: POP ->', $request, 'debug'); } // expecting an OK if (($reply = fgets($handle)) === FALSE) { Logger::remember('shared/mailer.php: No reply to USER command at ' . $server); fclose($handle); return FALSE; } if ($context['debug_mail'] == 'Y') { Logger::remember('shared/mailer.php: POP <-', $reply, 'debug'); } if (strncmp($reply, '+OK', 3)) { Logger::remember('shared/mailer.php: Unknown account ' . $context['mail_account'] . ' at ' . $server, $reply); fclose($handle); return FALSE; } // send password $request = 'PASS ' . $context['mail_password']; fputs($handle, $request . CRLF); if ($context['debug_mail'] == 'Y') { Logger::remember('shared/mailer.php: POP ->', $request, 'debug'); } // expecting an OK if (($reply = fgets($handle)) === FALSE) { Logger::remember('shared/mailer.php: No reply to PASS command at ' . $server); fclose($handle); return FALSE; } if ($context['debug_mail'] == 'Y') { Logger::remember('shared/mailer.php: POP <-', $reply, 'debug'); } if (strncmp($reply, '+OK', 3)) { Logger::remember('shared/mailer.php: Invalid password for account ' . $account . ' at ' . $server, $reply); fclose($handle); return FALSE; } // we just wanted to authenticate fclose($handle); } } // we manage directly the SMTP transaction if (isset($server) && isset($context['mail_variant']) && ($context['mail_variant'] == 'pop3' || $context['mail_variant'] == 'smtp')) { // open a network connection if (!($handle = Safe::fsockopen($server, $port, $errno, $errstr, 10))) { if ($context['debug_mail'] == 'Y') { Logger::remember('shared/mailer.php: fsockopen:', $errstr . ' (' . $errno . ')', 'debug'); } Logger::remember('shared/mailer.php: ' . sprintf('Impossible to connect to %s', $server . ':' . $port)); return FALSE; } // ensure enough execution time Safe::set_time_limit(30); // get server banner if (($response = Mailer::parse_response($handle, 220)) === FALSE) { Logger::remember('shared/mailer.php: Impossible to get banner of ' . $server); fclose($handle); return FALSE; } // provide our logical name if (strpos($response, 'ESMTP')) { $request = 'EHLO ' . $context['host_name']; } else { $request = 'HELO ' . $context['host_name']; } fputs($handle, $request . CRLF); if ($context['debug_mail'] == 'Y') { Logger::remember('shared/mailer.php: SMTP ->', $request, 'debug'); } // expecting a welcome message if (($response = Mailer::parse_response($handle, 250)) === FALSE) { Logger::remember('shared/mailer.php: Command EHLO has been rejected at ' . $server); fclose($handle); return FALSE; } // authenticate as per SMTP protocol extension if (isset($context['mail_account']) && isset($context['mail_password']) && preg_match('/^AUTH (.+)$/m', $response, $matches)) { // CRAM-MD5 -- the preferred method if (strpos($matches[1], 'CRAM-MD5') !== FALSE) { // get the challenge $request = 'AUTH CRAM-MD5'; fputs($handle, $request . CRLF); if ($context['debug_mail'] == 'Y') { Logger::remember('shared/mailer.php: SMTP ->', $request, 'debug'); } if (($response = Mailer::parse_response($handle, 334)) === FALSE) { Logger::remember('shared/mailer.php: Command AUTH has been rejected at ' . $server); fclose($handle); return FALSE; } $challenge = base64_decode($response); // from password to a 64 bytes block if (strlen($context['mail_password']) < 64) { $key = str_pad($context['mail_password'], 64, chr(0)); } elseif (strlen($context['mail_password']) > 64) { $key = str_pad(pack('H32', md5($context['mail_password'])), 64, chr(0)); } else { $key = $context['mail_password']; } // compute HMAC-MD5 $inner = $key ^ str_repeat(chr(0x36), 64); $outer = $key ^ str_repeat(chr(0x5c), 64); $digest = md5($outer . pack('H32', md5($inner . $challenge))); // answer the challenge $request = base64_encode($context['mail_account'] . ' ' . $digest); fputs($handle, $request . CRLF); if ($context['debug_mail'] == 'Y') { Logger::remember('shared/mailer.php: SMTP ->', $request, 'debug'); } // LOGIN } elseif (strpos($matches[1], 'LOGIN') !== FALSE) { $request = 'AUTH LOGIN'; fputs($handle, $request . CRLF); if ($context['debug_mail'] == 'Y') { Logger::remember('shared/mailer.php: SMTP ->', $request, 'debug'); } if (Mailer::parse_response($handle, 334) === FALSE) { Logger::remember('shared/mailer.php: Command AUTH has been rejected at ' . $server); fclose($handle); return FALSE; } $request = base64_encode($context['mail_account']); fputs($handle, $request . CRLF); if ($context['debug_mail'] == 'Y') { Logger::remember('shared/mailer.php: SMTP ->', $request, 'debug'); } if (Mailer::parse_response($handle, 334) === FALSE) { Logger::remember('shared/mailer.php: Command AUTH has been rejected at ' . $server); fclose($handle); return FALSE; } $request = base64_encode($context['mail_password']); fputs($handle, $request . CRLF); if ($context['debug_mail'] == 'Y') { Logger::remember('shared/mailer.php: SMTP ->', $request, 'debug'); } // PLAIN } elseif (strpos($matches[1], 'PLAIN') !== FALSE) { $request = 'AUTH PLAIN ' . base64_encode("" . $context['mail_account'] . "" . $context['mail_password']); fputs($handle, $request . CRLF); if ($context['debug_mail'] == 'Y') { Logger::remember('shared/mailer.php: SMTP ->', $request, 'debug'); } } // expecting an OK if (Mailer::parse_response($handle, 235) === FALSE) { Logger::remember('shared/mailer.php: Command AUTH has been rejected at ' . $server); fclose($handle); return FALSE; } } // ready to submit messages $context['mail_handle'] = $handle; return $handle; // rely on system settings and PHP } elseif (is_callable('mail')) { // set the SMTP server if ($server) { Safe::ini_set('SMTP', $server); } // set the SMTP sender if (isset($context['mail_from']) && $context['mail_from']) { Safe::ini_set('sendmail_from', $context['mail_from']); } // ready to submit messages $context['mail_handle'] = TRUE; return TRUE; } // no SMTP configuration return FALSE; }