Merge branch 'main' into use-https-for-verification-links

This commit is contained in:
Jan Dittberner 2024-05-20 10:46:16 +00:00
commit c61f0c4519
5 changed files with 93 additions and 22 deletions

View file

@ -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.");
?><p><?= _("I didn't receive a valid Certificate Request, hit the back button and try again."); ?></p>
<p><?= _("You did not select any email address and did not check the SSO option."); ?></p><?
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)

View file

@ -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;

View file

@ -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)
{

View file

@ -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);

View file

@ -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)
{