From 98558d2faa913d7c47ae9d8f58f07e8d81bc1768 Mon Sep 17 00:00:00 2001 From: Ross Williams Date: Fri, 17 Feb 2017 21:53:02 -0500 Subject: [PATCH 01/13] MVP of trusted roots At each boot, /etc/ssl/certs is created and populated with all CA certificates configured in the web GUI. --- src/etc/inc/certs.inc | 6 ++++++ src/etc/inc/system.inc | 30 ++++++++++++++++++++++++++++++ src/etc/pfSense-rc | 4 ++++ src/etc/rc.bootup | 3 +++ 4 files changed, 43 insertions(+) diff --git a/src/etc/inc/certs.inc b/src/etc/inc/certs.inc index 248019e94ce..3d64d66bacf 100644 --- a/src/etc/inc/certs.inc +++ b/src/etc/inc/certs.inc @@ -513,6 +513,12 @@ function cert_get_subject_hash($crt) { return $inf_crt['subject']; } +function cert_get_hash($crt) { + $str_crt = base64_decode($crt); + $inf_crt = openssl_x509_parse($str_crt); + return $inf_crt['hash']; +} + function cert_get_issuer($str_crt, $decode = true) { if ($decode) { diff --git a/src/etc/inc/system.inc b/src/etc/inc/system.inc index 028583b3e67..c63aeddb4d7 100644 --- a/src/etc/inc/system.inc +++ b/src/etc/inc/system.inc @@ -568,6 +568,36 @@ function system_hosts_generate() { return 0; } +function system_trustedcerts_generate() { + global $config, $g; + if (isset($config['system']['developerspew'])) { + $mt = microtime(); + echo "system_trustedcerts_generate() being called $mt\n"; + } + + if (is_array($config['ca'])) { + mwexec("/bin/mkdir -p {$g['etc_path']}/ssl/certs"); + foreach ($config['ca'] as & $ca) { + $ca_hash = cert_get_hash($ca['crt']); + $ca_certfile = "{$g['etc_path']}/ssl/certs/{$ca_hash}.0"; + + unlink_if_exists($ca_certfile); + $fd = fopen($ca_certfile, "w"); + if (!$fd) { + log_error(gettext( + "Error: cannot open {$g['etc_path']}/ssl/certs/{$ca_hash}.0 file in system_trustedcerts_generate()." + )); + return 1; + } + + fwrite($fd, base64_decode($ca['crt'])); + fclose($fd); + } + } + + return 0; +} + function system_dhcpleases_configure() { global $config, $g; diff --git a/src/etc/pfSense-rc b/src/etc/pfSense-rc index 4b9990d345a..03c209105da 100755 --- a/src/etc/pfSense-rc +++ b/src/etc/pfSense-rc @@ -340,6 +340,10 @@ mkdir -p /usr/local/openssl >/dev/null 2>&1 ln -sf /etc/ssl/openssl.cnf \ /usr/local/openssl/openssl.cnf +# Add environment variable to custom CA trusted roots directory +# Use SSL_CA_CERT_PATH environment variable per man fetch(3) +export SSL_CA_CERT_PATH=/etc/ssl/certs + # Run the php.ini setup file and populate # /usr/local/etc/php.ini /etc/rc.php_ini_setup 2>/tmp/php_errors.txt diff --git a/src/etc/rc.bootup b/src/etc/rc.bootup index e4a3a20d5b9..f7f289fe3a9 100755 --- a/src/etc/rc.bootup +++ b/src/etc/rc.bootup @@ -227,6 +227,9 @@ if (!$debugging) { /* re-make hosts file after configuring interfaces */ system_hosts_generate(); +/* add configured trusted CA certificates to /etc/ssl/certs */ +system_trustedcerts_generate(); + /* start OpenVPN server & clients */ echo "Syncing OpenVPN settings..."; openvpn_resync_all(); From 4ecbbac22e941359570e255756a46473186f2a1a Mon Sep 17 00:00:00 2001 From: Ross Williams Date: Sat, 18 Feb 2017 18:13:12 -0500 Subject: [PATCH 02/13] Add 'trusted' option to CA manager Is checked when regenerating trusted CAs. --- src/etc/inc/system.inc | 28 ++++++++++++++------------ src/usr/local/www/system_camanager.php | 17 ++++++++++++++++ 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/etc/inc/system.inc b/src/etc/inc/system.inc index c63aeddb4d7..b5add7ad021 100644 --- a/src/etc/inc/system.inc +++ b/src/etc/inc/system.inc @@ -578,20 +578,22 @@ function system_trustedcerts_generate() { if (is_array($config['ca'])) { mwexec("/bin/mkdir -p {$g['etc_path']}/ssl/certs"); foreach ($config['ca'] as & $ca) { - $ca_hash = cert_get_hash($ca['crt']); - $ca_certfile = "{$g['etc_path']}/ssl/certs/{$ca_hash}.0"; - - unlink_if_exists($ca_certfile); - $fd = fopen($ca_certfile, "w"); - if (!$fd) { - log_error(gettext( - "Error: cannot open {$g['etc_path']}/ssl/certs/{$ca_hash}.0 file in system_trustedcerts_generate()." - )); - return 1; - } + if ($ca['trusted']) { + $ca_hash = cert_get_hash($ca['crt']); + $ca_certfile = "{$g['etc_path']}/ssl/certs/{$ca_hash}.0"; + + unlink_if_exists($ca_certfile); + $fd = fopen($ca_certfile, "w"); + if (!$fd) { + log_error(gettext( + "Error: cannot open {$g['etc_path']}/ssl/certs/{$ca_hash}.0 file in system_trustedcerts_generate()." + )); + return 1; + } - fwrite($fd, base64_decode($ca['crt'])); - fclose($fd); + fwrite($fd, base64_decode($ca['crt'])); + fclose($fd); + } } } diff --git a/src/usr/local/www/system_camanager.php b/src/usr/local/www/system_camanager.php index 33c31fd7e00..c2b9a824510 100644 --- a/src/usr/local/www/system_camanager.php +++ b/src/usr/local/www/system_camanager.php @@ -107,6 +107,7 @@ if (!empty($a_ca[$id]['prv'])) { $pconfig['key'] = base64_decode($a_ca[$id]['prv']); } + $pconfig['trusted'] = $a_ca[$id]['trusted']; } if ($act == "new") { @@ -115,6 +116,7 @@ $pconfig['digest_alg'] = "sha256"; $pconfig['lifetime'] = "3650"; $pconfig['dn_commonname'] = "internal-ca"; + $pconfig['trusted'] = false; } if ($act == "exp") { @@ -250,6 +252,12 @@ $ca['descr'] = $pconfig['descr']; + if (!isset($pconfig['trusted']) || empty($pconfig['trusted'])) { + $ca['trusted'] = false; + } else { + $ca['trusted'] = $pconfig['trusted']; + } + if ($act == "edit") { $ca['descr'] = $pconfig['descr']; $ca['refid'] = $pconfig['refid']; @@ -359,6 +367,7 @@ + @@ -402,6 +411,7 @@ "> + "> @@ -483,6 +493,13 @@ $pconfig['descr'] )); +$section->addInput(new Form_Checkbox( + 'trusted', + 'Trust', + 'Trust this CA\'s certificates', + $pconfig['trusted'] +))->setHelp('Trust certificates generated by this CA when pfSense accesses HTTPS/FTPS servers (e.g. updates, firewall URL aliases).'); + if (!isset($id) || $act == "edit") { $section->addInput(new Form_Select( 'method', From 3a701ee144ac271f4de9ecd4e0ca8902c7206ad5 Mon Sep 17 00:00:00 2001 From: Ross Williams Date: Sat, 18 Feb 2017 18:28:48 -0500 Subject: [PATCH 03/13] Be sure to delete any previously trusted certfiles. --- src/etc/inc/system.inc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/etc/inc/system.inc b/src/etc/inc/system.inc index b5add7ad021..54831b6d27d 100644 --- a/src/etc/inc/system.inc +++ b/src/etc/inc/system.inc @@ -578,11 +578,12 @@ function system_trustedcerts_generate() { if (is_array($config['ca'])) { mwexec("/bin/mkdir -p {$g['etc_path']}/ssl/certs"); foreach ($config['ca'] as & $ca) { - if ($ca['trusted']) { - $ca_hash = cert_get_hash($ca['crt']); - $ca_certfile = "{$g['etc_path']}/ssl/certs/{$ca_hash}.0"; + $ca_hash = cert_get_hash($ca['crt']); + $ca_certfile = "{$g['etc_path']}/ssl/certs/{$ca_hash}.0"; - unlink_if_exists($ca_certfile); + /* Unlink before checking if the CA is trusted, so we delete any formerly trusted CA certfiles */ + unlink_if_exists($ca_certfile); + if ($ca['trusted']) { $fd = fopen($ca_certfile, "w"); if (!$fd) { log_error(gettext( From b60a90ce9a30eaca29dcc3846ced41c89a169dc3 Mon Sep 17 00:00:00 2001 From: Ross Williams Date: Sat, 18 Feb 2017 18:38:03 -0500 Subject: [PATCH 04/13] Get more aggressive about removing untrusted certs Instead of removing specific untrusted certs, delete all files in /etc/ssl/certs BUT leave symlinks in place for power users or for testing. --- src/etc/inc/system.inc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/etc/inc/system.inc b/src/etc/inc/system.inc index 54831b6d27d..8cc2d5cf395 100644 --- a/src/etc/inc/system.inc +++ b/src/etc/inc/system.inc @@ -577,13 +577,13 @@ function system_trustedcerts_generate() { if (is_array($config['ca'])) { mwexec("/bin/mkdir -p {$g['etc_path']}/ssl/certs"); + /* Remove all certs in the directory (but leave symlinks in place to allow power users to add trusted certs outside the Certificate Manager) */ + mwexec("/usr/bin/find {$g['etc_path']}/ssl/certs -type f -exec /bin/rm '{}' ';'"); foreach ($config['ca'] as & $ca) { - $ca_hash = cert_get_hash($ca['crt']); - $ca_certfile = "{$g['etc_path']}/ssl/certs/{$ca_hash}.0"; - - /* Unlink before checking if the CA is trusted, so we delete any formerly trusted CA certfiles */ - unlink_if_exists($ca_certfile); if ($ca['trusted']) { + $ca_hash = cert_get_hash($ca['crt']); + $ca_certfile = "{$g['etc_path']}/ssl/certs/{$ca_hash}.0"; + $fd = fopen($ca_certfile, "w"); if (!$fd) { log_error(gettext( From e7ecd5667f48999bda464ad5b3c0203385fbf1ee Mon Sep 17 00:00:00 2001 From: Ross Williams Date: Sat, 18 Feb 2017 18:49:39 -0500 Subject: [PATCH 05/13] Moved trusted CA cert generation to certs.inc Moved out of system.inc so it can be accessed by system_camanager.php to refresh /etc/ssl/certs on changes to the CA list. --- src/etc/inc/certs.inc | 33 +++++++++++++++++++++++++++++++++ src/etc/inc/system.inc | 33 --------------------------------- src/etc/rc.bootup | 4 +++- 3 files changed, 36 insertions(+), 34 deletions(-) diff --git a/src/etc/inc/certs.inc b/src/etc/inc/certs.inc index 3d64d66bacf..cefc91b722e 100644 --- a/src/etc/inc/certs.inc +++ b/src/etc/inc/certs.inc @@ -281,6 +281,39 @@ function ca_inter_create(& $ca, $keylen, $lifetime, $dn, $caref, $digest_alg = " return true; } +function ca_trustedcerts_generate() { + global $config, $g; + if (isset($config['system']['developerspew'])) { + $mt = microtime(); + echo "ca_trustedcerts_generate() being called $mt\n"; + } + + if (is_array($config['ca'])) { + mwexec("/bin/mkdir -p {$g['etc_path']}/ssl/certs"); + /* Remove all certs in the directory (but leave symlinks in place to allow power users to add trusted certs outside the Certificate Manager) */ + mwexec("/usr/bin/find {$g['etc_path']}/ssl/certs -type f -exec /bin/rm '{}' ';'"); + foreach ($config['ca'] as & $ca) { + if ($ca['trusted']) { + $ca_hash = cert_get_hash($ca['crt']); + $ca_certfile = "{$g['etc_path']}/ssl/certs/{$ca_hash}.0"; + + $fd = fopen($ca_certfile, "w"); + if (!$fd) { + log_error(gettext( + "Error: cannot open {$g['etc_path']}/ssl/certs/{$ca_hash}.0 file in ca_trustedcerts_generate()." + )); + return 1; + } + + fwrite($fd, base64_decode($ca['crt'])); + fclose($fd); + } + } + } + + return 0; +} + function cert_import(& $cert, $crt_str, $key_str) { $cert['crt'] = base64_encode($crt_str); diff --git a/src/etc/inc/system.inc b/src/etc/inc/system.inc index 8cc2d5cf395..028583b3e67 100644 --- a/src/etc/inc/system.inc +++ b/src/etc/inc/system.inc @@ -568,39 +568,6 @@ function system_hosts_generate() { return 0; } -function system_trustedcerts_generate() { - global $config, $g; - if (isset($config['system']['developerspew'])) { - $mt = microtime(); - echo "system_trustedcerts_generate() being called $mt\n"; - } - - if (is_array($config['ca'])) { - mwexec("/bin/mkdir -p {$g['etc_path']}/ssl/certs"); - /* Remove all certs in the directory (but leave symlinks in place to allow power users to add trusted certs outside the Certificate Manager) */ - mwexec("/usr/bin/find {$g['etc_path']}/ssl/certs -type f -exec /bin/rm '{}' ';'"); - foreach ($config['ca'] as & $ca) { - if ($ca['trusted']) { - $ca_hash = cert_get_hash($ca['crt']); - $ca_certfile = "{$g['etc_path']}/ssl/certs/{$ca_hash}.0"; - - $fd = fopen($ca_certfile, "w"); - if (!$fd) { - log_error(gettext( - "Error: cannot open {$g['etc_path']}/ssl/certs/{$ca_hash}.0 file in system_trustedcerts_generate()." - )); - return 1; - } - - fwrite($fd, base64_decode($ca['crt'])); - fclose($fd); - } - } - } - - return 0; -} - function system_dhcpleases_configure() { global $config, $g; diff --git a/src/etc/rc.bootup b/src/etc/rc.bootup index f7f289fe3a9..40c334d947c 100755 --- a/src/etc/rc.bootup +++ b/src/etc/rc.bootup @@ -54,6 +54,8 @@ require_once("/etc/inc/filter.inc"); echo "."; require_once("/etc/inc/shaper.inc"); echo "."; +require_once("/etc/inc/certs.inc"); +echo "."; require_once("/etc/inc/ipsec.inc"); echo "."; require_once("/etc/inc/vpn.inc"); @@ -228,7 +230,7 @@ if (!$debugging) { system_hosts_generate(); /* add configured trusted CA certificates to /etc/ssl/certs */ -system_trustedcerts_generate(); +ca_trustedcerts_generate(); /* start OpenVPN server & clients */ echo "Syncing OpenVPN settings..."; From e4303c1262d5be08e346511de92723d40c9c76a0 Mon Sep 17 00:00:00 2001 From: Ross Williams Date: Sun, 19 Feb 2017 09:35:49 -0500 Subject: [PATCH 06/13] Re-generate trusted roots when saving/deleting CAs Call ca_trustedcerts_generate() after write_config() in system_camanager.php --- src/usr/local/www/system_camanager.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/usr/local/www/system_camanager.php b/src/usr/local/www/system_camanager.php index c2b9a824510..93b19f7f538 100644 --- a/src/usr/local/www/system_camanager.php +++ b/src/usr/local/www/system_camanager.php @@ -90,6 +90,7 @@ $name = $a_ca[$id]['descr']; unset($a_ca[$id]); write_config(); + ca_trustedcerts_generate(); $savemsg = sprintf(gettext("Certificate Authority %s and its CRLs (if any) successfully deleted."), htmlspecialchars($name)); pfSenseHeader("system_camanager.php"); exit; @@ -316,6 +317,7 @@ if (!$input_errors) { write_config(); + ca_trustedcerts_generate(); } pfSenseHeader("system_camanager.php"); From 15619ae102638eb09594a4f7b5c7af5153a201fb Mon Sep 17 00:00:00 2001 From: Ross Williams Date: Sun, 19 Feb 2017 09:46:11 -0500 Subject: [PATCH 07/13] Clean up trusted certs even when no CAs configured Previously was cleaning out directory only if CAs were configured, so deleting last CA left an orphan, trusted certificate in /etc/ssl/certs --- src/etc/inc/certs.inc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/etc/inc/certs.inc b/src/etc/inc/certs.inc index cefc91b722e..7ab04b2e04e 100644 --- a/src/etc/inc/certs.inc +++ b/src/etc/inc/certs.inc @@ -288,10 +288,11 @@ function ca_trustedcerts_generate() { echo "ca_trustedcerts_generate() being called $mt\n"; } + mwexec("/bin/mkdir -p {$g['etc_path']}/ssl/certs"); + /* Remove all certs in the directory (but leave symlinks in place to allow power users to add trusted certs outside the Certificate Manager) */ + mwexec("/usr/bin/find {$g['etc_path']}/ssl/certs -type f -exec /bin/rm '{}' ';'"); + if (is_array($config['ca'])) { - mwexec("/bin/mkdir -p {$g['etc_path']}/ssl/certs"); - /* Remove all certs in the directory (but leave symlinks in place to allow power users to add trusted certs outside the Certificate Manager) */ - mwexec("/usr/bin/find {$g['etc_path']}/ssl/certs -type f -exec /bin/rm '{}' ';'"); foreach ($config['ca'] as & $ca) { if ($ca['trusted']) { $ca_hash = cert_get_hash($ca['crt']); From 3c79ee768c4d77542bc7a66abdc5a64a933fdc05 Mon Sep 17 00:00:00 2001 From: Ross Williams Date: Sun, 19 Feb 2017 10:06:26 -0500 Subject: [PATCH 08/13] Also set the OpenSSL SSL_CERT_DIR env var --- src/etc/pfSense-rc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/etc/pfSense-rc b/src/etc/pfSense-rc index 03c209105da..2cc1e9c69d1 100755 --- a/src/etc/pfSense-rc +++ b/src/etc/pfSense-rc @@ -343,6 +343,8 @@ ln -sf /etc/ssl/openssl.cnf \ # Add environment variable to custom CA trusted roots directory # Use SSL_CA_CERT_PATH environment variable per man fetch(3) export SSL_CA_CERT_PATH=/etc/ssl/certs +# Use SSL_CERT_DIR environment variable per man SSL_CTX_load_verify_locations(3) +export SSL_CERT_DIR=/etc/ssl/certs # Run the php.ini setup file and populate # /usr/local/etc/php.ini From 268580acd6c4344775dacafeff4205b33bb6da5c Mon Sep 17 00:00:00 2001 From: Ross Williams Date: Sun, 19 Feb 2017 10:08:42 -0500 Subject: [PATCH 09/13] Unlink certfile before creating Prevents any possible hash name collision between symlinked certs and pfSense-created cert files --- src/etc/inc/certs.inc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/etc/inc/certs.inc b/src/etc/inc/certs.inc index 7ab04b2e04e..8ef851780c7 100644 --- a/src/etc/inc/certs.inc +++ b/src/etc/inc/certs.inc @@ -298,6 +298,8 @@ function ca_trustedcerts_generate() { $ca_hash = cert_get_hash($ca['crt']); $ca_certfile = "{$g['etc_path']}/ssl/certs/{$ca_hash}.0"; + /* Try again to unlink the specific cert file just in case a non-regular file (e.g. symlink) with the same hash exists */ + unlink_if_exists($ca_certfile); $fd = fopen($ca_certfile, "w"); if (!$fd) { log_error(gettext( From 32cd3f1acf21734987244165365dea35638c1575 Mon Sep 17 00:00:00 2001 From: Ross Williams Date: Tue, 21 Feb 2017 17:17:05 -0500 Subject: [PATCH 10/13] Changes requsted in PR Handling isset() more consistently Removed calls to shell commands in place of PHP functions --- src/etc/inc/certs.inc | 9 ++++----- src/usr/local/www/system_camanager.php | 11 +++-------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/etc/inc/certs.inc b/src/etc/inc/certs.inc index 8ef851780c7..124111da5f1 100644 --- a/src/etc/inc/certs.inc +++ b/src/etc/inc/certs.inc @@ -288,13 +288,13 @@ function ca_trustedcerts_generate() { echo "ca_trustedcerts_generate() being called $mt\n"; } - mwexec("/bin/mkdir -p {$g['etc_path']}/ssl/certs"); + safe_mkdir("{$g['etc_path']}/ssl/certs"); /* Remove all certs in the directory (but leave symlinks in place to allow power users to add trusted certs outside the Certificate Manager) */ - mwexec("/usr/bin/find {$g['etc_path']}/ssl/certs -type f -exec /bin/rm '{}' ';'"); + array_map('unlink', array_filter('is_file',glob("{$g['etc_path']}/ssl/certs/*"))); if (is_array($config['ca'])) { foreach ($config['ca'] as & $ca) { - if ($ca['trusted']) { + if (isset($ca['trusted'])) { $ca_hash = cert_get_hash($ca['crt']); $ca_certfile = "{$g['etc_path']}/ssl/certs/{$ca_hash}.0"; @@ -550,8 +550,7 @@ function cert_get_subject_hash($crt) { } function cert_get_hash($crt) { - $str_crt = base64_decode($crt); - $inf_crt = openssl_x509_parse($str_crt); + $inf_crt = openssl_x509_parse(base64_decode($crt)); return $inf_crt['hash']; } diff --git a/src/usr/local/www/system_camanager.php b/src/usr/local/www/system_camanager.php index 93b19f7f538..838d6188b56 100644 --- a/src/usr/local/www/system_camanager.php +++ b/src/usr/local/www/system_camanager.php @@ -108,7 +108,7 @@ if (!empty($a_ca[$id]['prv'])) { $pconfig['key'] = base64_decode($a_ca[$id]['prv']); } - $pconfig['trusted'] = $a_ca[$id]['trusted']; + $pconfig['trusted'] = isset($a_ca[$id]['trusted']); } if ($act == "new") { @@ -117,7 +117,6 @@ $pconfig['digest_alg'] = "sha256"; $pconfig['lifetime'] = "3650"; $pconfig['dn_commonname'] = "internal-ca"; - $pconfig['trusted'] = false; } if ($act == "exp") { @@ -253,11 +252,7 @@ $ca['descr'] = $pconfig['descr']; - if (!isset($pconfig['trusted']) || empty($pconfig['trusted'])) { - $ca['trusted'] = false; - } else { - $ca['trusted'] = $pconfig['trusted']; - } + $ca['trusted'] = isset($pconfig['trusted']); if ($act == "edit") { $ca['descr'] = $pconfig['descr']; @@ -413,7 +408,7 @@ "> - "> + "> From 7cea2b1a4ee9d07084e30ce781a46d633da3df04 Mon Sep 17 00:00:00 2001 From: Ross Williams Date: Tue, 28 Feb 2017 12:19:16 -0500 Subject: [PATCH 11/13] Moved default cURL config to get_curl_handle() Refactored calls to curl_setopt() in various modules to a common function in pfsense-utils.inc. Did not modify curl_* calls in simplepie.inc, as it is an upstream library. --- src/etc/inc/pfsense-utils.inc | 61 ++++++++++++---------------- src/etc/inc/services.inc | 8 ++-- src/usr/local/www/crash_reporter.php | 8 +--- 3 files changed, 30 insertions(+), 47 deletions(-) diff --git a/src/etc/inc/pfsense-utils.inc b/src/etc/inc/pfsense-utils.inc index e5dfc052c8c..e32895297dd 100644 --- a/src/etc/inc/pfsense-utils.inc +++ b/src/etc/inc/pfsense-utils.inc @@ -1810,24 +1810,19 @@ function get_freebsd_version() { return $version[0]; } -function download_file($url, $destination, $verify_ssl = true, $connect_timeout = 5, $timeout = 0) { +function get_curl_handle($url, $connect_timeout = 5, $timeout = 0, $verify_ssl = true, $follow_location = true, $verbose = false) { global $config, $g; - $fp = fopen($destination, "wb"); - - if (!$fp) { - return false; - } - $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $follow_location); + curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $connect_timeout); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $verify_ssl); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $verify_ssl); - curl_setopt($ch, CURLOPT_FILE, $fp); - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $connect_timeout); - curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); - curl_setopt($ch, CURLOPT_HEADER, false); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($ch, CURLOPT_VERBOSE, $verbose); + if (!isset($config['system']['do_not_send_host_uuid'])) { curl_setopt($ch, CURLOPT_USERAGENT, $g['product_name'] . '/' . $g['product_version'] . ' : ' . get_single_sysctl('kern.hostuuid')); } else { @@ -1845,6 +1840,22 @@ function download_file($url, $destination, $verify_ssl = true, $connect_timeout } } + return $ch; +} + +function download_file($url, $destination, $verify_ssl = true, $connect_timeout = 5, $timeout = 0) { + global $config, $g; + + $fp = fopen($destination, "wb"); + + if (!$fp) { + return false; + } + + $ch = get_curl_handle($url); + curl_setopt($ch, CURLOPT_FILE, $fp); + curl_setopt($ch, CURLOPT_HEADER, false); + @curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); fclose($fp); @@ -1874,32 +1885,10 @@ function download_file_with_progress_bar($url, $destination, $verify_ssl = true, * Originally by Author: Keyvan Minoukadeh * Modified by Scott Ullrich to return Content-Length size */ - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $verify_ssl); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $verify_ssl); + $ch = get_curl_handle($url); curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'read_header'); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_WRITEFUNCTION, $readbody); - curl_setopt($ch, CURLOPT_NOPROGRESS, '1'); - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $connect_timeout); - curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); - if (!isset($config['system']['do_not_send_host_uuid'])) { - curl_setopt($ch, CURLOPT_USERAGENT, $g['product_name'] . '/' . $g['product_version'] . ' : ' . get_single_sysctl('kern.hostuuid')); - } else { - curl_setopt($ch, CURLOPT_USERAGENT, $g['product_name'] . '/' . $g['product_version']); - } - - if (!empty($config['system']['proxyurl'])) { - curl_setopt($ch, CURLOPT_PROXY, $config['system']['proxyurl']); - if (!empty($config['system']['proxyport'])) { - curl_setopt($ch, CURLOPT_PROXYPORT, $config['system']['proxyport']); - } - if (!empty($config['system']['proxyuser']) && !empty($config['system']['proxypass'])) { - @curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_ANY | CURLAUTH_ANYSAFE); - curl_setopt($ch, CURLOPT_PROXYUSERPWD, "{$config['system']['proxyuser']}:{$config['system']['proxypass']}"); - } - } + curl_setopt($ch, CURLOPT_NOPROGRESS, true); @curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); diff --git a/src/etc/inc/services.inc b/src/etc/inc/services.inc index 021fb7e5620..df1936512df 100644 --- a/src/etc/inc/services.inc +++ b/src/etc/inc/services.inc @@ -23,6 +23,8 @@ * limitations under the License. */ +require_once('pfsense-utils.inc'); + define('DYNDNS_PROVIDER_VALUES', 'all-inkl citynetwork cloudflare cloudflare-v6 custom custom-v6 dnsexit dnsimple dnsmadeeasy dnsomatic duiadns duiadns-v6 dyndns dyndns-custom dyndns-static dyns easydns eurodns freedns freedns-v6 glesys googledomains gratisdns he-net he-net-v6 he-net-tunnelbroker loopia namecheap noip noip-free ods opendns ovh-dynhost route53 selfhost spdyn spdyn-v6 zoneedit'); define('DYNDNS_PROVIDER_DESCRIPTIONS', 'All-Inkl.com,City Network,CloudFlare,CloudFlare (v6),Custom,Custom (v6),DNSexit,DNSimple,DNS Made Easy,DNS-O-Matic,DuiaDns.net,DuiaDns.net (v6),DynDNS (dynamic),DynDNS (custom),DynDNS (static),DyNS,easyDNS,Euro Dns,freeDNS,freeDNS (v6),GleSYS,Google Domains,GratisDNS,HE.net,HE.net (v6),HE.net Tunnelbroker,Loopia,Namecheap,No-IP,No-IP (free),ODS.org,OpenDNS,OVH DynHOST,Route 53,SelfHost,SPDYN,SPDYN (v6),ZoneEdit'); @@ -2032,12 +2034,8 @@ function dyndnsCheckIP($int) { } $hosttocheck = $url; - $ip_ch = curl_init($hosttocheck); - curl_setopt($ip_ch, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($ip_ch, CURLOPT_SSL_VERIFYPEER, $verifysslpeer); + $ip_ch = get_curl_handle($hosttocheck, 30, 120, $verifysslpeer); curl_setopt($ip_ch, CURLOPT_INTERFACE, 'host!' . $ip_address); - curl_setopt($ip_ch, CURLOPT_CONNECTTIMEOUT, '30'); - curl_setopt($ip_ch, CURLOPT_TIMEOUT, 120); curl_setopt($ip_ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); curl_setopt($ip_ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY); curl_setopt($ip_ch, CURLOPT_USERPWD, "{$username}:{$password}"); diff --git a/src/usr/local/www/crash_reporter.php b/src/usr/local/www/crash_reporter.php index 101939f4fdc..803cea2fdef 100644 --- a/src/usr/local/www/crash_reporter.php +++ b/src/usr/local/www/crash_reporter.php @@ -40,13 +40,9 @@ function upload_crash_report($files) { $post["file{$counter}"] = "@{$file}"; $counter++; } - $ch = curl_init(); - curl_setopt($ch, CURLOPT_HEADER, 0); - curl_setopt($ch, CURLOPT_VERBOSE, 0); + $ch = get_curl_handle($g['crashreporterurl']); + curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_USERAGENT, $g['product_name'] . '/' . $g['product_version']); - curl_setopt($ch, CURLOPT_URL, $g['crashreporterurl']); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $post); $response = curl_exec($ch); From b5aa0efb25608928b2f216ddc713910185acbcd3 Mon Sep 17 00:00:00 2001 From: Ross Williams Date: Tue, 28 Feb 2017 12:24:47 -0500 Subject: [PATCH 12/13] Added CURLOPT_CAPATH to get_curl_handle() --- src/etc/inc/pfsense-utils.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/etc/inc/pfsense-utils.inc b/src/etc/inc/pfsense-utils.inc index e32895297dd..4e1fabae72c 100644 --- a/src/etc/inc/pfsense-utils.inc +++ b/src/etc/inc/pfsense-utils.inc @@ -1821,6 +1821,7 @@ function get_curl_handle($url, $connect_timeout = 5, $timeout = 0, $verify_ssl = curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $verify_ssl); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $verify_ssl); + curl_setopt($ch, CURLOPT_CAPATH, "{$g['etc_path']}/ssl/certs"); curl_setopt($ch, CURLOPT_VERBOSE, $verbose); if (!isset($config['system']['do_not_send_host_uuid'])) { From 2b69f26c48b987428a598ff93b56a63436c6d0a5 Mon Sep 17 00:00:00 2001 From: Ross Williams Date: Tue, 28 Feb 2017 12:36:26 -0500 Subject: [PATCH 13/13] Fixed array_filter that unlinks cert files in /etc/ssl/certs --- src/etc/inc/certs.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/etc/inc/certs.inc b/src/etc/inc/certs.inc index 124111da5f1..2dab288dc59 100644 --- a/src/etc/inc/certs.inc +++ b/src/etc/inc/certs.inc @@ -290,7 +290,7 @@ function ca_trustedcerts_generate() { safe_mkdir("{$g['etc_path']}/ssl/certs"); /* Remove all certs in the directory (but leave symlinks in place to allow power users to add trusted certs outside the Certificate Manager) */ - array_map('unlink', array_filter('is_file',glob("{$g['etc_path']}/ssl/certs/*"))); + array_map('unlink', array_filter(glob("{$g['etc_path']}/ssl/certs/*"),function($x) { return is_file($x) && !is_link($x); })); if (is_array($config['ca'])) { foreach ($config['ca'] as & $ca) {