From 95c8cf48f9bd72da5371aa01a03a070885411dbf Mon Sep 17 00:00:00 2001 From: Evgeny Yurchenko Date: Thu, 23 Jun 2011 19:02:34 -0400 Subject: [PATCH 1/8] Intermediate CAs and openssl_xxx() error checking in CA management. --- etc/inc/certs.inc | 42 +++++++++++++++++++ usr/local/www/system_camanager.php | 67 ++++++++++++++++++++++++++++-- 2 files changed, 105 insertions(+), 4 deletions(-) diff --git a/etc/inc/certs.inc b/etc/inc/certs.inc index 3595f45cae..67a35402cd 100644 --- a/etc/inc/certs.inc +++ b/etc/inc/certs.inc @@ -186,6 +186,48 @@ function ca_create(& $ca, $keylen, $lifetime, $dn) { return true; } +function ca_inter_create(& $ca, $keylen, $lifetime, $dn, $caref) { + // Create Intermediate Certificate Authority + $signing_ca =& lookup_ca($caref); + if (!$signing_ca) + return false; + + $signing_ca_res_crt = openssl_x509_read(base64_decode($signing_ca['crt'])); + $signing_ca_res_key = openssl_pkey_get_private(array(0 => base64_decode($signing_ca['prv']) , 1 => "")); + if (!$signing_ca_res_crt || !$signing_ca_res_key) return false; + $signing_ca_serial = ++$signing_ca['serial']; + + $args = array( + "digest_alg" => "sha1", + "private_key_bits" => (int)$keylen, + "private_key_type" => OPENSSL_KEYTYPE_RSA, + "encrypt_key" => false); + + // generate a new key pair + $res_key = openssl_pkey_new($args); + if (!$res_key) return false; + + // generate a certificate signing request + $res_csr = openssl_csr_new($dn, $res_key, $args); + if (!$res_csr) return false; + + // Sign the certificate + $res_crt = openssl_csr_sign($res_csr, $signing_ca_res_crt, $signing_ca_res_key, $lifetime, $args, $signing_ca_serial); + if (!$res_crt) return false; + + // export our certificate data + if (!openssl_pkey_export($res_key, $str_key) || + !openssl_x509_export($res_crt, $str_crt)) + return false; + + // return our ca information + $ca['crt'] = base64_encode($str_crt); + $ca['prv'] = base64_encode($str_key); + $ca['serial'] = 0; + + return true; +} + function cert_import(& $cert, $crt_str, $key_str) { $cert['crt'] = base64_encode($crt_str); diff --git a/usr/local/www/system_camanager.php b/usr/local/www/system_camanager.php index a4b60af5a2..92a129ac24 100644 --- a/usr/local/www/system_camanager.php +++ b/usr/local/www/system_camanager.php @@ -42,7 +42,8 @@ require_once("certs.inc"); $ca_methods = array( "existing" => gettext("Import an existing Certificate Authority"), - "internal" => gettext("Create an internal Certificate Authority")); + "internal" => gettext("Create an internal Certificate Authority"), + "intermediate" => gettext("Create an intermediate Certificate Authority")); $ca_keylens = array( "512", "1024", "2048", "4096"); @@ -154,7 +155,7 @@ if ($act == "expkey") { if ($_POST) { - $input_errors = array(); + unset($input_errors); $pconfig = $_POST; /* input validation */ @@ -183,6 +184,22 @@ if ($_POST) { gettext("Distinguished name Email Address"), gettext("Distinguished name Common Name")); } + if ($pconfig['method'] == "intermediate") { + $reqdfields = explode(" ", + "descr caref keylen lifetime dn_country dn_state dn_city ". + "dn_organization dn_email dn_commonname"); + $reqdfieldsn = array( + gettext("Descriptive name"), + gettext("Signing Certificate Authority"), + gettext("Key length"), + gettext("Lifetime"), + gettext("Distinguished name Country Code"), + gettext("Distinguished name State or Province"), + gettext("Distinguished name City"), + gettext("Distinguished name Organization"), + gettext("Distinguished name Email Address"), + gettext("Distinguished name Common Name")); + } do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); if ($pconfig['method'] != "existing") @@ -229,7 +246,7 @@ if ($_POST) { if ($pconfig['method'] == "existing") ca_import($ca, $pconfig['cert'], $pconfig['key'], $pconfig['serial']); - if ($pconfig['method'] == "internal") { + else if ($pconfig['method'] == "internal") { $dn = array( 'countryName' => $pconfig['dn_country'], 'stateOrProvinceName' => $pconfig['dn_state'], @@ -239,6 +256,23 @@ if ($_POST) { 'commonName' => $pconfig['dn_commonname']); ca_create($ca, $pconfig['keylen'], $pconfig['lifetime'], $dn); } + else if ($pconfig['method'] == "intermediate") { + $dn = array( + 'countryName' => $pconfig['dn_country'], + 'stateOrProvinceName' => $pconfig['dn_state'], + 'localityName' => $pconfig['dn_city'], + 'organizationName' => $pconfig['dn_organization'], + 'emailAddress' => $pconfig['dn_email'], + 'commonName' => $pconfig['dn_commonname']); + $old_err_level = error_reporting(0); /* otherwise openssl_ functions throw warings directly to a page screwing menu tab */ + if (!ca_inter_create($ca, $pconfig['keylen'], $pconfig['lifetime'], $dn, $pconfig['caref'])){ + while($ssl_err = openssl_error_string()){ + $input_errors = array(); + array_push($input_errors, "openssl library returns: " . $ssl_err); + } + } + error_reporting($old_err_level); + } } if (isset($id) && $a_ca[$id]) @@ -246,7 +280,8 @@ if ($_POST) { else $a_ca[] = $ca; - write_config(); + if (!$input_errors) + write_config(); // pfSenseHeader("system_camanager.php"); } @@ -268,10 +303,17 @@ function method_change() { case 0: document.getElementById("existing").style.display=""; document.getElementById("internal").style.display="none"; + document.getElementById("intermediate").style.display="none"; break; case 1: document.getElementById("existing").style.display="none"; document.getElementById("internal").style.display=""; + document.getElementById("intermediate").style.display="none"; + break; + case 2: + document.getElementById("existing").style.display="none"; + document.getElementById("internal").style.display=""; + document.getElementById("intermediate").style.display=""; break; } } @@ -385,6 +427,23 @@ function method_change() { + + + + + + From 1b6d9fa59cdc3a284497abb0bfa415741c258d10 Mon Sep 17 00:00:00 2001 From: Evgeny Yurchenko Date: Thu, 23 Jun 2011 20:05:35 -0400 Subject: [PATCH 2/8] Internal CA creation error handling added. --- etc/inc/certs.inc | 8 ++++++-- usr/local/www/system_camanager.php | 11 ++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/etc/inc/certs.inc b/etc/inc/certs.inc index 67a35402cd..b1203cfc1b 100644 --- a/etc/inc/certs.inc +++ b/etc/inc/certs.inc @@ -167,16 +167,20 @@ function ca_create(& $ca, $keylen, $lifetime, $dn) { // generate a new key pair $res_key = openssl_pkey_new($args); + if (!$res_key) return false; // generate a certificate signing request $res_csr = openssl_csr_new($dn, $res_key, $args); + if (!$res_csr) return false; // self sign the certificate $res_crt = openssl_csr_sign($res_csr, null, $res_key, $lifetime, $args); + if (!$res_crt) return false; // export our certificate data - openssl_pkey_export($res_key, $str_key); - openssl_x509_export($res_crt, $str_crt); + if (!openssl_pkey_export($res_key, $str_key) || + !openssl_x509_export($res_crt, $str_crt)) + return false; // return our ca information $ca['crt'] = base64_encode($str_crt); diff --git a/usr/local/www/system_camanager.php b/usr/local/www/system_camanager.php index 92a129ac24..9a18c87208 100644 --- a/usr/local/www/system_camanager.php +++ b/usr/local/www/system_camanager.php @@ -243,6 +243,7 @@ if ($_POST) { if (!empty($pconfig['key'])) $ca['prv'] = base64_encode($pconfig['key']); } else { + $old_err_level = error_reporting(0); /* otherwise openssl_ functions throw warings directly to a page screwing menu tab */ if ($pconfig['method'] == "existing") ca_import($ca, $pconfig['cert'], $pconfig['key'], $pconfig['serial']); @@ -254,7 +255,12 @@ if ($_POST) { 'organizationName' => $pconfig['dn_organization'], 'emailAddress' => $pconfig['dn_email'], 'commonName' => $pconfig['dn_commonname']); - ca_create($ca, $pconfig['keylen'], $pconfig['lifetime'], $dn); + if (!ca_create($ca, $pconfig['keylen'], $pconfig['lifetime'], $dn)){ + while($ssl_err = openssl_error_string()){ + $input_errors = array(); + array_push($input_errors, "openssl library returns: " . $ssl_err); + } + } } else if ($pconfig['method'] == "intermediate") { $dn = array( @@ -264,15 +270,14 @@ if ($_POST) { 'organizationName' => $pconfig['dn_organization'], 'emailAddress' => $pconfig['dn_email'], 'commonName' => $pconfig['dn_commonname']); - $old_err_level = error_reporting(0); /* otherwise openssl_ functions throw warings directly to a page screwing menu tab */ if (!ca_inter_create($ca, $pconfig['keylen'], $pconfig['lifetime'], $dn, $pconfig['caref'])){ while($ssl_err = openssl_error_string()){ $input_errors = array(); array_push($input_errors, "openssl library returns: " . $ssl_err); } } - error_reporting($old_err_level); } + error_reporting($old_err_level); } if (isset($id) && $a_ca[$id]) From 22b380aa6f4b7401b887945262a2e595d03dac26 Mon Sep 17 00:00:00 2001 From: Evgeny Yurchenko Date: Thu, 23 Jun 2011 20:28:31 -0400 Subject: [PATCH 3/8] Internal cert and CSR creation error handling added. --- etc/inc/certs.inc | 16 ++++++++++++---- usr/local/www/system_certmanager.php | 23 +++++++++++++++++++---- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/etc/inc/certs.inc b/etc/inc/certs.inc index b1203cfc1b..6ab448b3eb 100644 --- a/etc/inc/certs.inc +++ b/etc/inc/certs.inc @@ -259,6 +259,7 @@ function cert_create(& $cert, $caref, $keylen, $lifetime, $dn) { $ca_str_key = base64_decode($ca['prv']); $ca_res_crt = openssl_x509_read($ca_str_crt); $ca_res_key = openssl_pkey_get_private(array(0 => $ca_str_key, 1 => "")); + if(!$ca_res_key) return false; $ca_serial = ++$ca['serial']; $args = array( @@ -269,17 +270,21 @@ function cert_create(& $cert, $caref, $keylen, $lifetime, $dn) { // generate a new key pair $res_key = openssl_pkey_new($args); + if(!$res_key) return false; // generate a certificate signing request $res_csr = openssl_csr_new($dn, $res_key, $args); + if(!$res_csr) return false; // self sign the certificate $res_crt = openssl_csr_sign($res_csr, $ca_res_crt, $ca_res_key, $lifetime, $args, $ca_serial); + if(!$res_crt) return false; // export our certificate data - openssl_pkey_export($res_key, $str_key); - openssl_x509_export($res_crt, $str_crt); + if (!openssl_pkey_export($res_key, $str_key) || + !openssl_x509_export($res_crt, $str_crt)) + return false; // return our certificate information $cert['caref'] = $caref; @@ -299,13 +304,16 @@ function csr_generate(& $cert, $keylen, $dn) { // generate a new key pair $res_key = openssl_pkey_new($args); + if(!$res_key) return false; // generate a certificate signing request $res_csr = openssl_csr_new($dn, $res_key, $args); + if(!$res_csr) return false; // export our request data - openssl_pkey_export($res_key, $str_key); - openssl_csr_export($res_csr, $str_csr); + if (!openssl_pkey_export($res_key, $str_key) || + !openssl_csr_export($res_csr, $str_csr)) + return false; // return our request information $cert['csr'] = base64_encode($str_csr); diff --git a/usr/local/www/system_certmanager.php b/usr/local/www/system_certmanager.php index 87b8d9119e..355621b09a 100644 --- a/usr/local/www/system_certmanager.php +++ b/usr/local/www/system_certmanager.php @@ -240,6 +240,8 @@ if ($_POST) { $cert['descr'] = $pconfig['descr']; + $old_err_level = error_reporting(0); /* otherwise openssl_ functions throw warings directly to a page screwing menu tab */ + if ($pconfig['method'] == "import") cert_import($cert, $pconfig['cert'], $pconfig['key']); @@ -252,8 +254,13 @@ if ($_POST) { 'emailAddress' => $pconfig['dn_email'], 'commonName' => $pconfig['dn_commonname']); - cert_create($cert, $pconfig['caref'], $pconfig['keylen'], - $pconfig['lifetime'], $dn); + if (!cert_create($cert, $pconfig['caref'], $pconfig['keylen'], + $pconfig['lifetime'], $dn)){ + while($ssl_err = openssl_error_string()){ + $input_errors = array(); + array_push($input_errors, "openssl library returns: " . $ssl_err); + } + } } if ($pconfig['method'] == "external") { @@ -265,8 +272,15 @@ if ($_POST) { 'emailAddress' => $pconfig['csr_dn_email'], 'commonName' => $pconfig['csr_dn_commonname']); - csr_generate($cert, $pconfig['csr_keylen'], $dn); + if(!csr_generate($cert, $pconfig['csr_keylen'], $dn)){ + while($ssl_err = openssl_error_string()){ + $input_errors = array(); + array_push($input_errors, "openssl library returns: " . $ssl_err); + } + } } + error_reporting($old_err_level); + if (isset($id) && $a_cert[$id]) $a_cert[$id] = $cert; else @@ -275,7 +289,8 @@ if ($_POST) { $a_user[$userid]['cert'][] = $cert['refid']; } - write_config(); + if (!$input_errors) + write_config(); if ($userid) pfSenseHeader("system_usermanager.php?act=edit&id={$userid}"); From 5ca13f69b79ab1e461e7a689d7d02a8c2c0794eb Mon Sep 17 00:00:00 2001 From: Ermal Date: Fri, 24 Jun 2011 12:10:51 +0000 Subject: [PATCH 4/8] Import error handling to avoid errors. --- etc/inc/certs.inc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/etc/inc/certs.inc b/etc/inc/certs.inc index 6ab448b3eb..3f655b1d99 100644 --- a/etc/inc/certs.inc +++ b/etc/inc/certs.inc @@ -338,7 +338,7 @@ function csr_get_subject($str_crt, $decode = true) { $components = openssl_csr_get_subject($str_crt); - if (!is_array($components)) + if (empty($components) || !is_array($components)) return "unknown"; ksort($components); @@ -360,7 +360,7 @@ function cert_get_subject($str_crt, $decode = true) { $inf_crt = openssl_x509_parse($str_crt); $components = $inf_crt['subject']; - if (!is_array($components)) + if (empty($components) || !is_array($components)) return "unknown"; ksort($components); @@ -410,9 +410,10 @@ function cert_get_issuer($str_crt, $decode = true) { $inf_crt = openssl_x509_parse($str_crt); $components = $inf_crt['issuer']; - ksort($components); - if (!is_array($components)) + if (empty($components) || !is_array($components)) return "unknown"; + + ksort($components); foreach ($components as $a => $v) { if (!strlen($issuer)) $issuer = "{$a}={$v}"; From 506514e77bf9823f965e70f6a1c9d8cdefd6413b Mon Sep 17 00:00:00 2001 From: jim-p Date: Fri, 24 Jun 2011 10:52:28 -0400 Subject: [PATCH 5/8] Add LB monitor types to config during upgrade, or they will be missing from boxes upgraded from 1.2.3. --- etc/inc/upgrade_config.inc | 40 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/etc/inc/upgrade_config.inc b/etc/inc/upgrade_config.inc index 29f0ac02d3..9b349d30f4 100644 --- a/etc/inc/upgrade_config.inc +++ b/etc/inc/upgrade_config.inc @@ -842,6 +842,46 @@ function upgrade_044_to_045() { function upgrade_045_to_046() { global $config; + /* Load up monitors that are in the default config for 2.0 but not in 1.2.3 + thus wouldn't be in an upgraded config. */ + $config['load_balancer']['monitor_type'] = array ( + array ( 'name' => 'ICMP', + 'type' => 'icmp', + 'descr' => 'ICMP', + 'options' => '', + ), + array ( 'name' => 'TCP', + 'type' => 'tcp', + 'descr' => 'Generic TCP', + 'options' => '', + ), + array ( 'name' => 'HTTP', + 'type' => 'http', + 'descr' => 'Generic HTTP', + 'options' => + array ( 'path' => '/', + 'host' => '', + 'code' => '200', + ), + ), + array ( 'name' => 'HTTPS', + 'type' => 'https', + 'descr' => 'Generic HTTPS', + 'options' => + array ( 'path' => '/', + 'host' => '', + 'code' => '200', + ), + ), + array ( 'name' => 'SMTP', + 'type' => 'send', + 'descr' => 'Generic SMTP', + 'options' => + array ( 'send' => 'EHLO nosuchhost', + 'expect' => '250-', + ), + ), + ); /* Upgrade load balancer from slb to relayd */ if (is_array($config['load_balancer']['virtual_server']) && count($config['load_balancer']['virtual_server'])) { $vs_a = &$config['load_balancer']['virtual_server']; From 01599e5e95cdc329ccb062fe0837b216af67b2cc Mon Sep 17 00:00:00 2001 From: Ermal Date: Fri, 24 Jun 2011 19:05:58 +0000 Subject: [PATCH 6/8] Remove nohup from the calling for check_reload_status since it may cause issues to the processes that get forked from it. --- etc/rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/rc b/etc/rc index b5a143f201..f8194ac674 100755 --- a/etc/rc +++ b/etc/rc @@ -365,7 +365,7 @@ if [ -f /etc/rc.custom_boot_early ]; then echo "Done" fi -nohup /usr/bin/nice -n20 /usr/local/sbin/check_reload_status +/usr/bin/nice -n20 /usr/local/sbin/check_reload_status # let the PHP-based configuration subsystem set up the system now echo -n "Launching the init system..." From 5a7cc1f9e9a94c0bf479cd498e5a51b8fce27511 Mon Sep 17 00:00:00 2001 From: Ermal Date: Fri, 24 Jun 2011 19:09:07 +0000 Subject: [PATCH 7/8] No need to use nohup when using mwexec_bg since it calls nohup itself. Also use fullpath to executables. --- etc/inc/openvpn.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/etc/inc/openvpn.inc b/etc/inc/openvpn.inc index edd22bed3e..5e4dd1e493 100644 --- a/etc/inc/openvpn.inc +++ b/etc/inc/openvpn.inc @@ -161,7 +161,7 @@ function openvpn_port_next($prot) { function openvpn_get_cipherlist() { $ciphers = array(); - $cipher_out = shell_exec('openvpn --show-ciphers | grep "default key" | awk \'{print $1, "(" $2 "-" $3 ")";}\''); + $cipher_out = shell_exec('/usr/local/sbin/openvpn --show-ciphers | /usr/bin/grep "default key" | /usr/bin/awk \'{print $1, "(" $2 "-" $3 ")";}\''); $cipher_lines = explode("\n", trim($cipher_out)); sort($cipher_lines); foreach ($cipher_lines as $line) { @@ -606,7 +606,7 @@ function openvpn_restart($mode, $settings) { /* start the new process */ $fpath = $g['varetc_path']."/openvpn/{$mode_id}.conf"; - mwexec_bg("nohup openvpn --config {$fpath}"); + mwexec_bg("/usr/local/sbin/openvpn --config {$fpath}"); if (!$g['booting']) send_event("filter reload"); From 0da02ef5d99de2c04846934b0cd7504e9e880eec Mon Sep 17 00:00:00 2001 From: Evgeny Yurchenko Date: Sun, 26 Jun 2011 00:36:40 -0400 Subject: [PATCH 8/8] Bug #1615. Half-fix. --- usr/local/www/status_rrd_graph.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/www/status_rrd_graph.php b/usr/local/www/status_rrd_graph.php index 4505a0231a..e548530dd8 100755 --- a/usr/local/www/status_rrd_graph.php +++ b/usr/local/www/status_rrd_graph.php @@ -607,7 +607,7 @@ function get_dates($curperiod, $graph) { } /* generate update events utilizing prototype $('') feature */ echo "\n"; - echo "\t\t\$('{$graph}-{$curoption}-{$curdatabase}').src='status_rrd_graph_img.php?start={$start}&end={$end}&graph={$graph}&database={$curdatabase}&style={$curstyle}&tmp=' + randomid;\n"; + echo "\t\t\$('{$graph}-{$curoption}-{$curdatabase}').src='status_rrd_graph_img.php?start={$start}&graph={$graph}&database={$curdatabase}&style={$curstyle}&tmp=' + randomid;\n"; } } ?>