diff --git a/includes/account.php b/includes/account.php index 5e7e77e..48f712b 100644 --- a/includes/account.php +++ b/includes/account.php @@ -253,7 +253,8 @@ function buildSubjectFromSession() { if(!(array_key_exists('addid',$_REQUEST) && is_array($_REQUEST['addid'])) && $_REQUEST['SSO'] != '1') { showheader(_("My CAcert.org Account!")); - echo _("I didn't receive a valid Certificate Request, hit the back button and try again."); + ?>
= _("I didn't receive a valid Certificate Request, hit the back button and try again."); ?>
+= _("You did not select any email address and did not check the SSO option."); ?>
showfooter(); exit; } @@ -495,8 +496,13 @@ function buildSubjectFromSession() { `disablelogin`='".($_SESSION['_config']['disablelogin']?1:0)."', `rootcert`='".intval($_SESSION['_config']['rootcert'])."', `md`='".mysql_real_escape_string($_SESSION['_config']['hash_alg'])."', - `description`='".mysql_real_escape_string($_SESSION['_config']['description'])."'"; - mysql_query($query); + `description`='".mysql_real_escape_string($_SESSION['_config']['description'])."', + `coll_found`=0"; + + if (!mysql_query($query)) { + trigger_error("Query failed: " . mysql_errno() . ": " . mysql_error(), E_USER_ERROR); + } + $emailid = mysql_insert_id(); if(is_array($addys)) foreach($addys as $addy) diff --git a/includes/lib/general.php b/includes/lib/general.php index 127c6b7..e7e54db 100644 --- a/includes/lib/general.php +++ b/includes/lib/general.php @@ -1,6 +1,6 @@ /* LibreSSL - CAcert web application - Copyright (C) 2004-2011 CAcert Inc. + Copyright (C) CAcert Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -16,32 +16,91 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +/** + * Walk through the email address environment variables that Apache httpd + * might have set and put them into an array. + * + * The function ensures that unique addresses are returned. + * + * @return array + */ +function get_email_addresses_from_client_cert() { + $addresses = array(); + $maxAddresses = 10; // implement a hard boundary to avoid endless loop + + // try SAN email addresses first + $envNameBase = "SSL_CLIENT_SAN_Email"; + for ($i = 0; $i <= $maxAddresses; $i++) { + $envName = sprintf("%s_%d", $envNameBase, $i); + if (!array_key_exists($envName, $_SERVER)) { + break; + } + $addresses[] = $_SERVER[$envName]; + } + + if (count($addresses) > 0) { + return array_unique($addresses); + } + + // fallback for older Apache httpd versions that do not support email SAN fields + $envNameBase = "SSL_CLIENT_S_DN_Email"; + + if (array_key_exists($envNameBase, $_SERVER)) { + $addresses[] = $_SERVER[$envNameBase]; + } + + for ($i = 1; $i <= $maxAddresses; $i++) { + $envName = sprintf("%s_%d", $envNameBase, $i); + if (array_key_exists($envName, $_SERVER)) { + $addresses[] = $_SERVER[$envName]; + } + } + + return array_unique($addresses); +} + /** * Checks if the user may log in and retrieve the user id * * Usually called with $_SERVER['SSL_CLIENT_M_SERIAL'] and - * $_SERVER['SSL_CLIENT_I_DN_CN'] + * $_SERVER['SSL_CLIENT_I_DN_CN'] * * @param $serial string - * usually $_SERVER['SSL_CLIENT_M_SERIAL'] + * usually $_SERVER['SSL_CLIENT_M_SERIAL'] * @param $issuer_cn string - * usually $_SERVER['SSL_CLIENT_I_DN_CN'] + * usually $_SERVER['SSL_CLIENT_I_DN_CN'] + * @param $addresses array + * list of email addresses from the certificate * @return int - * the user id, -1 in case of error + * the user id, -1 in case of error + * + * @see get_email_addresses_from_client_cert() */ -function get_user_id_from_cert($serial, $issuer_cn) -{ - $query = "select `memid` from `emailcerts` where - `serial`='".mysql_escape_string($serial)."' and - `rootcert`= (select `id` from `root_certs` where - `Cert_Text`='".mysql_escape_string($issuer_cn)."') and - `revoked`=0 and disablelogin=0 and - UNIX_TIMESTAMP(`expire`) - UNIX_TIMESTAMP() > 0"; +function get_user_id_from_cert($serial, $issuer_cn, $addresses) { + $addresses_for_sql = array_map('mysql_real_escape_string', $addresses); + + $query = sprintf("SELECT DISTINCT ec.`memid` +FROM `emailcerts` ec + JOIN root_certs r ON r.id = ec.rootcert + JOIN email e ON ec.memid = e.memid +WHERE ec.serial = '%s' + AND r.`Cert_Text` = '%s' + AND e.email IN ('%s') + AND ec.revoked = 0 + AND ec.disablelogin = 0 + AND UNIX_TIMESTAMP(ec.expire) > UNIX_TIMESTAMP()", mysql_real_escape_string($serial), + mysql_real_escape_string($issuer_cn), implode("', '", $addresses_for_sql)); + $res = mysql_query($query); - if(mysql_num_rows($res) > 0) - { - $row = mysql_fetch_assoc($res); - return intval($row['memid']); + if ($res === false) { + trigger_error(sprintf("MySQL error %d: %s", mysql_errno(), mysql_error())); + + return -1; + } + + if (mysql_num_rows($res) === 1) { + $row = mysql_fetch_row($res); + return intval($row[0]); } return -1; diff --git a/includes/loggedin.php b/includes/loggedin.php index c14f8c2..30c6b55 100644 --- a/includes/loggedin.php +++ b/includes/loggedin.php @@ -54,7 +54,7 @@ if($_SERVER['HTTP_HOST'] == $_SESSION['_config']['securehostname'] && ($_SESSION['profile']['id'] == 0 || $_SESSION['profile']['loggedin'] == 0)) { $user_id = get_user_id_from_cert($_SERVER['SSL_CLIENT_M_SERIAL'], - $_SERVER['SSL_CLIENT_I_DN_CN']); + $_SERVER['SSL_CLIENT_I_DN_CN'], get_email_addresses_from_client_cert()); if($user_id >= 0) { diff --git a/scripts/cron/removedead.php b/scripts/cron/removedead.php index f473788..a9a1943 100755 --- a/scripts/cron/removedead.php +++ b/scripts/cron/removedead.php @@ -39,6 +39,12 @@ (UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(`created`)) >= 172800"; mysql_query($query); + // removes entries that where introduced due to missing/wrong default value + // in MariaDB strict mode, see https://bugs.cacert.org/view.php?id=1543 + $query = "delete from `email` where `memid`=0 and + (UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(`created`)) >= 172800"; + mysql_query($query); + $query = "delete from `disputedomain` where `hash`!='' and (UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(`created`)) >= 21600"; mysql_query($query); diff --git a/www/index.php b/www/index.php index d0da580..6095d8a 100644 --- a/www/index.php +++ b/www/index.php @@ -153,7 +153,7 @@ require_once('../includes/notary.inc.php'); { include_once("../includes/lib/general.php"); $user_id = get_user_id_from_cert($_SERVER['SSL_CLIENT_M_SERIAL'], - $_SERVER['SSL_CLIENT_I_DN_CN']); + $_SERVER['SSL_CLIENT_I_DN_CN'], get_email_addresses_from_client_cert()); if($user_id >= 0) {