From 5311adaaab76b5c1505cad347936db201c1f01d7 Mon Sep 17 00:00:00 2001 From: jim-p Date: Tue, 12 Sep 2017 13:49:55 -0400 Subject: Relax OpenVPN wizard cert validation to match that of the cert manager and encode values before using them. Fixes #7854 Also, CDATA escape these fields in config.xml since they will most likely contain characters which are invalid in XML. While here, fix a cert display issue where a SAN value could be reused from a previous entry in the cert list display. (cherry picked from commit 00d5594c737d475abab8e0361bb3ff7f93b98ac8) --- src/etc/inc/xmlparse.inc | 12 +++++++ src/usr/local/www/system_certmanager.php | 2 +- src/usr/local/www/wizards/openvpn_wizard.inc | 47 ++++++++++++++++------------ 3 files changed, 40 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/etc/inc/xmlparse.inc b/src/etc/inc/xmlparse.inc index 5d00d29..60028c3 100644 --- a/src/etc/inc/xmlparse.inc +++ b/src/etc/inc/xmlparse.inc @@ -244,6 +244,12 @@ function dump_xml_config_sub($arr, $indent) { } else if ((substr($ent, 0, 5) == "descr") || (substr($ent, 0, 6) == "detail") || (substr($ent, 0, 12) == "login_banner") || + (substr($ent, 0, 5) == "state") || + (substr($ent, 0, 4) == "city") || + (substr($ent, 0, 12) == "organization") || + (substr($ent, 0, 5) == "email") || + (substr($ent, 0, 6) == "certca") || + (substr($ent, 0, 8) == "certname") || (substr($ent, 0, 9) == "ldap_attr") || (substr($ent, 0, 9) == "ldap_bind") || (substr($ent, 0, 11) == "ldap_basedn") || @@ -275,6 +281,12 @@ function dump_xml_config_sub($arr, $indent) { if ((substr($ent, 0, 5) == "descr") || (substr($ent, 0, 6) == "detail") || (substr($ent, 0, 12) == "login_banner") || + (substr($ent, 0, 5) == "state") || + (substr($ent, 0, 4) == "city") || + (substr($ent, 0, 12) == "organization") || + (substr($ent, 0, 5) == "email") || + (substr($ent, 0, 6) == "certca") || + (substr($ent, 0, 8) == "certname") || (substr($ent, 0, 9) == "ldap_attr") || (substr($ent, 0, 9) == "ldap_bind") || (substr($ent, 0, 11) == "ldap_basedn") || diff --git a/src/usr/local/www/system_certmanager.php b/src/usr/local/www/system_certmanager.php index 0cc0dd0..6f83028 100644 --- a/src/usr/local/www/system_certmanager.php +++ b/src/usr/local/www/system_certmanager.php @@ -1133,7 +1133,7 @@ $certificates_used_by_packages = pkg_call_plugins('plugin_certificates', $plugin $i = 0; foreach ($a_cert as $i => $cert): $name = htmlspecialchars($cert['descr']); - + $sans = array(); if ($cert['crt']) { $subj = cert_get_subject($cert['crt']); $issuer = cert_get_issuer($cert['crt']); diff --git a/src/usr/local/www/wizards/openvpn_wizard.inc b/src/usr/local/www/wizards/openvpn_wizard.inc index 0b4cf16..653c309 100644 --- a/src/usr/local/www/wizards/openvpn_wizard.inc +++ b/src/usr/local/www/wizards/openvpn_wizard.inc @@ -25,8 +25,15 @@ require_once("config.inc"); require_once("openvpn.inc"); require_once("util.inc"); -function has_special_chars($text) { - return preg_match('/[^A-Za-z0-9 _-]/', $text); +// Load valid country codes +$dn_cc = array(); +if (file_exists("/etc/ca_countries")) { + $dn_cc_file=file("/etc/ca_countries"); + foreach ($dn_cc_file as $line) { + if (preg_match('/^(\S*)\s(.*)$/', $line, $matches)) { + $dn_cc[$matches[1]] = $matches[1]; + } + } } function step1_stepsubmitbeforesave() { @@ -190,7 +197,7 @@ function step6_submitphpaction() { } function step7_submitphpaction() { - global $input_errors, $stepid, $savemsg, $_POST, $config; + global $input_errors, $stepid, $savemsg, $_POST, $config, $dn_cc; $canames = array(); $cacns = array(); @@ -211,10 +218,9 @@ function step7_submitphpaction() { empty($_POST['organization']) || empty($_POST['email'])) { $stepid--; $savemsg = "Please enter all information for the new Certificate Authority."; - } elseif (has_special_chars($_POST['country']) || has_special_chars($_POST['state']) || - has_special_chars($_POST['city']) || has_special_chars($_POST['organization'])) { + } elseif (!array_key_exists($_POST['country'], $dn_cc)) { $stepid--; - $input_errors[] = "Please limit Certificate field names to only the following characters: A-Z, a-z, space, underscore, and dash."; + $input_errors[] = "Please enter a valid country code."; } elseif (in_array($_POST['descr'], $canames) || in_array($_POST['descr'], $cacns)) { $stepid--; $savemsg = "Please enter a different name for the Certificate Authority. A Certificate Authority with that name already exists."; @@ -293,7 +299,7 @@ function step9_stepbeforeformdisplay() { } function step9_submitphpaction() { - global $input_errors, $stepid, $savemsg, $_POST, $config; + global $input_errors, $stepid, $savemsg, $_POST, $config, $dn_cc; $certnames = array(); $certcns = array(); @@ -314,10 +320,9 @@ function step9_submitphpaction() { empty($_POST['organization']) || empty($_POST['email'])) { $stepid--; $savemsg = "Please enter all information for the new certificate."; - } elseif (has_special_chars($_POST['country']) || has_special_chars($_POST['state']) || - has_special_chars($_POST['city']) || has_special_chars($_POST['organization'])) { + } elseif (!array_key_exists($_POST['country'], $dn_cc)) { $stepid--; - $input_errors[] = "Please do not use special characters in Certificate field names."; + $input_errors[] = "Please enter a valid country code."; } elseif (in_array($_POST['descr'], $certnames) || in_array($_POST['descr'], $certcns)) { $stepid--; $savemsg = "Please enter a different name for the Certificate. A Certificate with that name/common name already exists."; @@ -504,11 +509,11 @@ function step12_submitphpaction() { $ca['descr'] = $pconfig['step6']['certca']; $dn = array( 'countryName' => $pconfig['step6']['country'], - 'stateOrProvinceName' => $pconfig['step6']['state'], - 'localityName' => $pconfig['step6']['city'], - 'organizationName' => $pconfig['step6']['organization'], - 'emailAddress' => $pconfig['step6']['email'], - 'commonName' => $pconfig['step6']['certca']); + 'stateOrProvinceName' => cert_escape_x509_chars($pconfig['step6']['state']), + 'localityName' => cert_escape_x509_chars($pconfig['step6']['city']), + 'organizationName' => cert_escape_x509_chars($pconfig['step6']['organization']), + 'emailAddress' => cert_escape_x509_chars($pconfig['step6']['email']), + 'commonName' => cert_escape_x509_chars($pconfig['step6']['certca'])); ca_create($ca, $pconfig['step6']['keylength'], $pconfig['step6']['lifetime'], $dn, "sha256"); if (!is_array($config['ca'])) @@ -531,11 +536,13 @@ function step12_submitphpaction() { $cert['descr'] = $pconfig['step9']['certname']; $dn = array( 'countryName' => $pconfig['step9']['country'], - 'stateOrProvinceName' => $pconfig['step9']['state'], - 'localityName' => $pconfig['step9']['city'], - 'organizationName' => $pconfig['step9']['organization'], - 'emailAddress' => $pconfig['step9']['email'], - 'commonName' => $pconfig['step9']['certname']); + 'stateOrProvinceName' => cert_escape_x509_chars($pconfig['step9']['state']), + 'localityName' => cert_escape_x509_chars($pconfig['step9']['city']), + 'organizationName' => cert_escape_x509_chars($pconfig['step9']['organization']), + 'emailAddress' => cert_escape_x509_chars($pconfig['step9']['email']), + 'commonName' => cert_escape_x509_chars($pconfig['step9']['certname']), + 'subjectAltName' => cert_add_altname_type($pconfig['step9']['certname']), + ); cert_create($cert, $ca['refid'], $pconfig['step9']['keylength'], $pconfig['step9']['lifetime'], $dn, 'server', "sha256"); if (!is_array($config['cert'])) -- cgit v1.1