diff --git a/controllers/certificate.php b/controllers/certificate.php index e235475..1186b85 100644 --- a/controllers/certificate.php +++ b/controllers/certificate.php @@ -7,9 +7,9 @@ * @package lets-encrypt * @subpackage controllers * @author eGloo - * @copyright 2017 Marc Laporte + * @copyright 2017-2018 Marc Laporte * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License version 3 or later - * @link https://github.com/eglooca/app-lets-encrypt + * @link https://github.com/WikiSuite/app-lets-encrypt */ /////////////////////////////////////////////////////////////////////////////// @@ -40,9 +40,9 @@ * @package lets-encrypt * @subpackage controllers * @author eGloo - * @copyright 2017 Marc Laporte + * @copyright 2017-2018 Marc Laporte * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License version 3 or later - * @link https://github.com/eglooca/app-lets-encrypt + * @link https://github.com/WikiSuite/app-lets-encrypt */ class Certificate extends ClearOS_Controller @@ -59,13 +59,13 @@ function index() //------------------ $this->lang->load('lets_encrypt'); - $this->load->library('lets_encrypt/Lets_Encrypt'); + $this->load->library('lets_encrypt/Certificates_Class'); // Load view data //--------------- try { - $data['certificates'] = $this->lets_encrypt->get_certificates(); + $data['certificates'] = $this->certificates_class->listing(); } catch (Engine_Engine_Exception $e) { $this->page->view_exception($e); return; @@ -89,14 +89,15 @@ function add() //------------------ $this->lang->load('lets_encrypt'); - $this->load->library('lets_encrypt/Lets_Encrypt'); + $this->load->library('lets_encrypt/Certificates_Class'); + $this->load->library('lets_encrypt/Lets_Encrypt_Class'); // Set validation rules //--------------------- - $this->form_validation->set_policy('email', 'lets_encrypt/Lets_Encrypt', 'validate_email', TRUE); - $this->form_validation->set_policy('domain', 'lets_encrypt/Lets_Encrypt', 'validate_domain', TRUE); - $this->form_validation->set_policy('domains', 'lets_encrypt/Lets_Encrypt', 'validate_domains'); + $this->form_validation->set_policy('email', 'lets_encrypt/Certificates_Class', 'validate_email', TRUE); + $this->form_validation->set_policy('domain', 'lets_encrypt/Certificates_Class', 'validate_domain', TRUE); + $this->form_validation->set_policy('domains', 'lets_encrypt/Certificates_Class', 'validate_domains'); $form_ok = $this->form_validation->run(); // Handle form submit @@ -121,7 +122,7 @@ function add() //--------------- try { - $data['email'] = $this->lets_encrypt->get_email(); + $data['email'] = $this->lets_encrypt_class->get_email(); } catch (Engine_Engine_Exception $e) { $this->page->view_exception($e); return; @@ -145,12 +146,12 @@ function add_ajax() //------------------ $this->lang->load('lets_encrypt'); - $this->load->library('lets_encrypt/Lets_Encrypt'); + $this->load->library('lets_encrypt/Certificates_Class'); // Add certificate //---------------- - $error = $this->lets_encrypt->add( + $error = $this->certificates_class->create( $this->input->post('email'), $this->input->post('domain'), $this->input->post('domains') @@ -191,13 +192,13 @@ function destroy($certificate) // Load libraries //--------------- - $this->load->library('Lets_Encrypt'); + $this->load->library('Certificates_Class'); // Handle form submit //------------------- try { - $this->lets_encrypt->delete($certificate); + $this->lets_encrypt_class->delete($certificate); $this->page->set_status_deleted(); redirect('/lets_encrypt'); @@ -222,8 +223,8 @@ function view($certificate, $is_new = FALSE) //------------------ $this->lang->load('lets_encrypt'); - $this->load->library('lets_encrypt/Lets_Encrypt'); - $this->load->library('certificate_manager/Certificate_Manager'); + $this->load->library('lets_encrypt/Certificates_Class'); + $this->load->library('certificate_manager/Certificate_Store'); // Load view data //--------------- @@ -234,15 +235,15 @@ function view($certificate, $is_new = FALSE) if ($form_type === 'add') { } else { - $attributes = $this->lets_encrypt->get_certificate_attributes($certificate); + $attributes = $this->certificates_class->get($certificate); - $data['issued'] = $attributes['issued']; - $data['expires'] = $attributes['expires']; - $data['key_size'] = $attributes['key_size']; - $data['domains'] = $attributes['domains']; - $data['details'] = $attributes['details']; + $data['issued'] = $attributes['certificate']['issued']; + $data['expires'] = $attributes['certificate']['expires']; + $data['key_size'] = $attributes['certificate']['key_size']; + $data['domains'] = $attributes['certificate']['domains']; + $data['details'] = $attributes['certificate']['details']; - $data['state'] = $this->certificate_manager->get_state($certificate); + $data['state'] = $this->certificate_store->get_state($certificate); $data['is_new'] = $is_new; } } catch (Exception $e) { @@ -269,13 +270,13 @@ function download($certificate) // Load dependencies //------------------ - $this->load->library('lets_encrypt/Lets_Encrypt'); + $this->load->library('lets_encrypt/Certificates_Class'); // Load view data //--------------- try { - $attributes = $this->lets_encrypt->get_certificate_attributes($certificate); + $attributes = $this->lets_encrypt_class->get_certificate_attributes($certificate); } catch (Engine_Exception $e) { $this->page->view_exception($e); return; @@ -307,7 +308,7 @@ function get_log($certificate) // Load dependencies //------------------ - $this->load->library('lets_encrypt/Lets_Encrypt'); + $this->load->library('lets_encrypt/Certificates_Class'); // Grab data //---------- diff --git a/controllers/settings.php b/controllers/settings.php index 8c737f6..0482817 100644 --- a/controllers/settings.php +++ b/controllers/settings.php @@ -7,9 +7,9 @@ * @package lets-encrypt * @subpackage controllers * @author eGloo - * @copyright 2017 Marc Laporte + * @copyright 2017-2018 Marc Laporte * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License version 3 or later - * @link https://github.com/eglooca/app-lets-encrypt + * @link https://github.com/WikiSuite/app-lets-encrypt */ /////////////////////////////////////////////////////////////////////////////// @@ -40,9 +40,9 @@ * @package lets-encrypt * @subpackage controllers * @author eGloo - * @copyright 2017 Marc Laporte + * @copyright 2017-2018 Marc Laporte * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License version 3 or later - * @link https://github.com/eglooca/app-lets-encrypt + * @link https://github.com/WikiSuite/app-lets-encrypt */ class Settings extends ClearOS_Controller @@ -94,12 +94,12 @@ function _common($form_type) //------------------ $this->lang->load('lets_encrypt'); - $this->load->library('lets_encrypt/Lets_Encrypt'); + $this->load->library('lets_encrypt/Lets_Encrypt_Class'); // Set validation rules //--------------------- - $this->form_validation->set_policy('email', 'lets_encrypt/Lets_Encrypt', 'validate_email', TRUE); + $this->form_validation->set_policy('email', 'lets_encrypt/Lets_Encrypt_Class', 'validate_email', TRUE); $form_ok = $this->form_validation->run(); // Handle form submit @@ -107,7 +107,7 @@ function _common($form_type) if ($this->input->post('submit') && $form_ok) { try { - $this->lets_encrypt->set_email($this->input->post('email')); + $this->lets_encrypt_class->set_email($this->input->post('email')); $this->page->set_status_updated(); redirect('/lets_encrypt/settings'); @@ -122,7 +122,7 @@ function _common($form_type) try { $data['form_type'] = $form_type; - $data['email'] = $this->lets_encrypt->get_email(); + $data['email'] = $this->lets_encrypt_class->get_email(); } catch (Exception $e) { $this->page->view_exception($e); return; diff --git a/deploy/info.php b/deploy/info.php index 7723c99..1ebd2c7 100644 --- a/deploy/info.php +++ b/deploy/info.php @@ -46,7 +46,7 @@ $app['core_requires'] = array( 'app-network-core', - 'app-certificate-manager-core >= 1:2.4.10', + 'app-certificate-manager-core >= 1:2.5.10', 'app-events-core', 'app-tasks-core', 'certbot >= 0.21.0' diff --git a/htdocs/lets_encrypt.js.php b/htdocs/lets_encrypt.js.php index aa4a621..9911400 100644 --- a/htdocs/lets_encrypt.js.php +++ b/htdocs/lets_encrypt.js.php @@ -7,9 +7,9 @@ * @package lets-encrypt * @subpackage javascript * @author eGloo - * @copyright 2017 Marc Laporte + * @copyright 2017-2018 Marc Laporte * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License version 3 or later - * @link https://github.com/eglooca/app-lets-encrypt + * @link https://github.com/WikiSuite/app-lets-encrypt */ /////////////////////////////////////////////////////////////////////////////// @@ -83,4 +83,3 @@ function showLog(payload) { }); // vim: ts=4 syntax=javascript - diff --git a/libraries/Certificates_Class.php b/libraries/Certificates_Class.php new file mode 100644 index 0000000..bdde531 --- /dev/null +++ b/libraries/Certificates_Class.php @@ -0,0 +1,405 @@ + + * @copyright 2017-2018 Marc Laporte + * @license http://www.gnu.org/copyleft/lgpl.html GNU Lesser General Public License version 3 or later + * @link https://github.com/WikiSuite/app-lets-encrypt + */ + +/////////////////////////////////////////////////////////////////////////////// +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// N A M E S P A C E +/////////////////////////////////////////////////////////////////////////////// + +namespace clearos\apps\lets_encrypt; + +/////////////////////////////////////////////////////////////////////////////// +// B O O T S T R A P +/////////////////////////////////////////////////////////////////////////////// + +$bootstrap = getenv('CLEAROS_BOOTSTRAP') ? getenv('CLEAROS_BOOTSTRAP') : '/usr/clearos/framework/shared'; +require_once $bootstrap . '/bootstrap.php'; + +/////////////////////////////////////////////////////////////////////////////// +// T R A N S L A T I O N S +/////////////////////////////////////////////////////////////////////////////// + +clearos_load_language('lets_encrypt'); +clearos_load_language('certificate_manager'); +clearos_load_language('network'); + +/////////////////////////////////////////////////////////////////////////////// +// D E P E N D E N C I E S +/////////////////////////////////////////////////////////////////////////////// + +// Classes +//-------- + +use \clearos\apps\base\Engine as Engine; +use \clearos\apps\base\File as File; +use \clearos\apps\base\Folder as Folder; +use \clearos\apps\base\Shell as Shell; +use \clearos\apps\certificate_manager\SSL as SSL; +use \clearos\apps\lets_encrypt\Lets_Encrypt_Class as Lets_Encrypt_Class; +use \clearos\apps\network\Network_Utils as Network_Utils; + +clearos_load_library('base/Engine'); +clearos_load_library('base/File'); +clearos_load_library('base/Folder'); +clearos_load_library('base/Shell'); +clearos_load_library('certificate_manager/SSL'); +clearos_load_library('lets_encrypt/Lets_Encrypt_Class'); +clearos_load_library('network/Network_Utils'); + +// Exceptions +//----------- + +use \Exception as Exception; +use \clearos\apps\base\Not_Found_Exception as Not_Found_Exception; +use \clearos\apps\base\Validation_Exception as Validation_Exception; + +clearos_load_library('base/Not_Found_Exception'); +clearos_load_library('base/Validation_Exception'); + +/////////////////////////////////////////////////////////////////////////////// +// C L A S S +/////////////////////////////////////////////////////////////////////////////// + +/** + * Let's Encrypt certificates class. + * + * @category apps + * @package lets-encrypt + * @subpackage controllers + * @author eGloo + * @copyright 2017-2018 Marc Laporte + * @license http://www.gnu.org/copyleft/lgpl.html GNU Lesser General Public License version 3 or later + * @link https://github.com/WikiSuite/app-lets-encrypt + */ + +class Certificates_Class extends Engine +{ + /////////////////////////////////////////////////////////////////////////////// + // M E T H O D S + /////////////////////////////////////////////////////////////////////////////// + + /** + * Let's Encrypt certificates constructor. + */ + + public function __construct() + { + clearos_profile(__METHOD__, __LINE__); + } + + /** + * Adds a certificate. + * + * @param string $email e-mail address to register for updates + * @param string $domain primary domain + * @param array $domains list of other domains + * + * @return array error entries if an error occurred. + */ + + public function create($email, $domain, $domains) + { + clearos_profile(__METHOD__, __LINE__); + + Validation_Exception::is_valid($this->validate_email($email)); + Validation_Exception::is_valid($this->validate_domain($domain)); + if (!empty($domains)) + Validation_Exception::is_valid($this->validate_domains($domains)); + + // Delete old log output file + //--------------------------- + + $log_basename = Lets_Encrypt_Class::FILE_LOG_PREFIX . $domain . '.log'; + + $log = new File(CLEAROS_TEMP_DIR . '/' . $log_basename, TRUE); + if ($log->exists()) + $log->delete(); + + // Generate domain list + //--------------------- + + $domains = preg_replace('/,/', ' ', $domains); // Strip commas, re-add below + $raw_domains = trim($domain) . ' ' . trim($domains); + $domain_param = preg_replace('/\s+/', ',', trim($raw_domains)); + + // Manage daemons and firewall on port 80 + //--------------------------------------- + + $lets_encrypt = new Lets_Encrypt_Class(); + + $daemon_states = $lets_encrypt->_disengage_daemons(); + $incoming_state = $lets_encrypt->_disengage_incoming_firewall(); + $forwarding_rules = $lets_encrypt->_disengage_port_forwarding(); + + // Run certbot + //------------ + + try { + $options['log'] = $log_basename; + $options['validate_exit_code'] = FALSE; + $options['env'] = 'LANG=en_US'; + + $shell = new Shell(); + + $test_cert = ''; + + // Devel environments run on port 1501. Default to test mode. + if (!empty($_SERVER['SERVER_PORT']) && ($_SERVER['SERVER_PORT'] == 1501)) + $test_cert = '--test-cert'; + + $exit_code = $shell->execute( + Lets_Encrypt_Class::COMMAND_CERTBOT, + $test_cert . ' --standalone --agree-tos -n -m ' . $email . ' -d "' . $domain_param . '" certonly', + TRUE, + $options + ); + } catch (Exception $e) { + $exit_code = 1; + } + + // Manage daemons and firewall on port 80 + //--------------------------------------- + + $lets_encrypt->_engage_incoming_firewall($incoming_state); + $lets_encrypt->_engage_port_forwarding($forwarding_rules); + $lets_encrypt->_engage_daemons($daemon_states); + + // Return + //------- + + if ($exit_code === 0) { + $log_entries = []; + } else { + $log_entries = $this->get_log($domain); + + foreach ($log_entries as $log) { + if (preg_match('/Connection refused/', $log)) { + array_unshift($log_entries, lang('lets_encrypt_connection_refused_warning'), '', ''); + return $log_entries; + } + } + } + + return $log_entries; + } + + /** + * Deletes a certificate. + * + * @param string $name ceritificate domain name + * + * @return void + */ + + public function delete($name) + { + clearos_profile(__METHOD__, __LINE__); + + Validation_Exception::is_valid($this->validate_certificate_name($name)); + + $shell = new Shell(); + $shell->execute(Lets_Encrypt_Class::COMMAND_CERTBOT, 'delete --cert-name ' . $name, TRUE); + } + + /** + * Returns certificate details. + * + * @param string $name certificate domain name + * + * @return array certificate details + * @throws Certificate_Not_Found_Exception, Engine_Exception + */ + + public function get($name) + { + clearos_profile(__METHOD__, __LINE__); + + Validation_Exception::is_valid($this->validate_certificate_name($name)); + + $listing = $this->listing(); + + if (!array_key_exists($name, $listing)) + throw new Not_Found_Exception(); + + return $listing[$name]; + } + + /** + * Returns array of log lines. + * + * @param string $certificate certificate name + * + * @return array log lines + * @throws Engine_Exception + */ + + public function get_log($name) + { + clearos_profile(__METHOD__, __LINE__); + + $log_basename = Lets_Encrypt_Class::FILE_LOG_PREFIX . $name . '.log'; + + $log = new File(CLEAROS_TEMP_DIR . '/' . $log_basename); + if (!$log->exists()) + return []; + + $lines = $log->get_contents_as_array(); + + $important = []; + $important_found = FALSE; + + foreach ($lines as $line) { + // KLUDGE: trying to extract only the good stuff + if ($important_found) + $important[] = $line; + + if (preg_match('/IMPORTANT NOTES:/', $line)) + $important_found = TRUE; + } + + if (empty($important)) + $important = $lines; + + return $important; + } + + /** + * Returns a list of certificates. + * + * @return array a list of certificates + */ + + public function listing() + { + clearos_profile(__METHOD__, __LINE__); + + $folder = new Folder(Lets_Encrypt_Class::PATH_CERTIFICATES, TRUE); + + if (!$folder->exists()) + return []; + + $certificate_list = $folder->get_listing(); + + $ssl = new SSL(); + + $certs = []; + + foreach ($certificate_list as $certificate) { + $base_path = Lets_Encrypt_Class::PATH_CERTIFICATES . '/' . $certificate . '/'; + + $certs[$certificate]['certificate'] = $ssl->get_certificate_attributes($base_path . 'cert.pem'); + $certs[$certificate]['certificate']['filename'] = $base_path . 'cert.pem'; + $certs[$certificate]['key']['filename'] = $base_path . 'privkey.pem'; + $certs[$certificate]['intermediate']['filename'] = $base_path . 'chain.pem'; + $certs[$certificate]['fullchain']['filename'] = $base_path . 'fullchain.pem'; + } + + return $certs; + } + + /////////////////////////////////////////////////////////////////////////////// + // V A L I D A T I O N M E T H O D S + /////////////////////////////////////////////////////////////////////////////// + + /** + * Validation routine for ceritificates. + * + * @param string $name certificate name + * + * @return string error message if certificate is invalid + */ + + public function validate_certificate_name($name) + { + clearos_profile(__METHOD__, __LINE__); + + $certificates = $this->listing(); + + if (! array_key_exists($name, $certificates)) + return lang('certificate_manager_certificate_invalid'); + } + + /** + * Validation routine for primary domain. + * + * @param string $domain primary domain + * + * @return string error message if primary domain is invalid + */ + + public function validate_domain($domain) + { + clearos_profile(__METHOD__, __LINE__); + + if (!Network_Utils::is_valid_domain($domain)) + return lang('network_domain_invalid'); + } + + /** + * Validation routine for domain list. + * + * @param string $domains domain list + * + * @return string error message domain list is invalid + */ + + public function validate_domains($domains) + { + clearos_profile(__METHOD__, __LINE__); + + $domains = preg_replace('/,/', ' ', $domains); + $domain_list = preg_split('/\s+/', $domains); + $valid = TRUE; + + foreach ($domain_list as $domain) { + if ($this->validate_domain($domain)) + $valid = FALSE; + } + + if (!$valid) + return lang('lets_encrypt_domain_list_invalid'); + } + + /** + * Validation routine for the admin e-mail address. + * + * @param string $email e-mail address + * + * @return string error message if e-mail address is invalid + */ + + public function validate_email($email) + { + clearos_profile(__METHOD__, __LINE__); + + if (!preg_match("/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/", $email)) + return lang('base_email_address_invalid'); + } +} diff --git a/libraries/Lets_Encrypt.php b/libraries/Lets_Encrypt_Class.php similarity index 63% rename from libraries/Lets_Encrypt.php rename to libraries/Lets_Encrypt_Class.php index 10336af..e9e0749 100644 --- a/libraries/Lets_Encrypt.php +++ b/libraries/Lets_Encrypt_Class.php @@ -7,8 +7,8 @@ * @package lets-encrypt * @subpackage controllers * @author eGloo - * @copyright 2017 Marc Laporte - * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License version 3 or later + * @copyright 2017-2018 Marc Laporte + * @license http://www.gnu.org/copyleft/lgpl.html GNU Lesser General Public License version 3 or later * @link https://github.com/eglooca/app-lets-encrypt */ @@ -100,12 +100,12 @@ * @package lets-encrypt * @subpackage controllers * @author eGloo - * @copyright 2017 Marc Laporte - * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License version 3 or later + * @copyright 2017-2018 Marc Laporte + * @license http://www.gnu.org/copyleft/lgpl.html GNU Lesser General Public License version 3 or later * @link https://github.com/eglooca/app-lets-encrypt */ -class Lets_Encrypt extends Software +class Lets_Encrypt_Class extends Software { /////////////////////////////////////////////////////////////////////////////// // C O N S T A N T S @@ -113,7 +113,6 @@ class Lets_Encrypt extends Software const PATH_CERTIFICATES = '/etc/letsencrypt/live'; const COMMAND_CERTBOT = '/usr/bin/certbot'; - const FILE_CERT = 'cert.pem'; const FILE_LOG_PREFIX = 'lets-encrypt-'; const FILE_APP_CONFIG = '/etc/clearos/lets_encrypt.conf'; @@ -124,7 +123,7 @@ class Lets_Encrypt extends Software protected $is_loaded = FALSE; protected $config = array(); protected $max_logs = 200; - protected $daemon_list = ['httpd', 'nginx']; + public $daemon_list = ['httpd', 'nginx']; /////////////////////////////////////////////////////////////////////////////// // M E T H O D S @@ -142,121 +141,12 @@ public function __construct() } /** - * Deletes a certificate. + * Returns auto-renew state. * - * @param string $email e-mail address to register for updates - * @param string $domain primary domain - * @param array $domains list of other domains + * By default, auto renewals are enabled. However, this behavior can + * be changed via configuration file. * - * @return array error entries if an error occurred. - */ - - public function add($email, $domain, $domains) - { - clearos_profile(__METHOD__, __LINE__); - - Validation_Exception::is_valid($this->validate_email($email)); - Validation_Exception::is_valid($this->validate_domain($domain)); - if (!empty($domains)) - Validation_Exception::is_valid($this->validate_domains($domains)); - - // Delete old log output file - //--------------------------- - - $log_basename = self::FILE_LOG_PREFIX . $domain . '.log'; - - $log = new File(CLEAROS_TEMP_DIR . '/' . $log_basename, TRUE); - if ($log->exists()) - $log->delete(); - - // Generate domain list - //--------------------- - - $domains = preg_replace('/,/', ' ', $domains); // Strip commas, re-add below - $raw_domains = trim($domain) . ' ' . trim($domains); - $domain_param = preg_replace('/\s+/', ',', trim($raw_domains)); - - // Manage daemons and firewall on port 80 - //--------------------------------------- - - $daemon_states = $this->_disengage_daemons(); - $incoming_state = $this->_disengage_incoming_firewall(); - $forwarding_rules = $this->_disengage_port_forwarding(); - - // Run certbot - //------------ - - try { - $options['log'] = $log_basename; - $options['validate_exit_code'] = FALSE; - $options['env'] = 'LANG=en_US'; - - $shell = new Shell(); - - $test_cert = ''; - - // Devel environments run on port 1501. Default to test mode. - if (!empty($_SERVER['SERVER_PORT']) && ($_SERVER['SERVER_PORT'] == 1501)) - $test_cert = '--test-cert'; - - $exit_code = $shell->execute( - self::COMMAND_CERTBOT, - $test_cert . ' --standalone --agree-tos -n -m ' . $email . ' -d "' . $domain_param . '" certonly', - TRUE, - $options - ); - } catch (Exception $e) { - $exit_code = 1; - } - - // Manage daemons and firewall on port 80 - //--------------------------------------- - - $this->_engage_incoming_firewall($incoming_state); - $this->_engage_port_forwarding($forwarding_rules); - $this->_engage_daemons($daemon_states); - - // Return - //------- - - if ($exit_code === 0) { - $log_entries = []; - } else { - $log_entries = $this->get_log($domain); - - foreach ($log_entries as $log) { - if (preg_match('/Connection refused/', $log)) { - array_unshift($log_entries, lang('lets_encrypt_connection_refused_warning'), '', ''); - return $log_entries; - } - } - } - - return $log_entries; - } - - /** - * Deletes a certificate. - * - * @param string $name ceritificate name - * - * @return void - */ - - public function delete($name) - { - clearos_profile(__METHOD__, __LINE__); - - Validation_Exception::is_valid($this->validate_certificate_name($name)); - - $shell = new Shell(); - $shell->execute(self::COMMAND_CERTBOT, 'delete --cert-name ' . $name, TRUE); - } - - /** - * Returns auto-configure state. - * - * @return boolean state of auto-configure mode + * @return boolean state of auto-renew state */ public function get_auto_renew_state() @@ -280,82 +170,6 @@ public function get_auto_renew_state() return FALSE; } - /** - * Returns a list of certificates. - * - * @return array a list of certificates - */ - - public function get_certificates() - { - clearos_profile(__METHOD__, __LINE__); - - $folder = new Folder(self::PATH_CERTIFICATES, TRUE); - - if (!$folder->exists()) - return []; - - $certificate_list = $folder->get_listing(); - - $ssl = new SSL(); - - $certs = []; - - foreach ($certificate_list as $certificate) - $certs[$certificate] = $ssl->get_certificate_attributes(self::PATH_CERTIFICATES . '/' . $certificate . '/' . self::FILE_CERT); - - return $certs; - } - - /** - * Returns a list of certificates. - * - * @return array a list of certificates - */ - - public function get_certificate_files() - { - clearos_profile(__METHOD__, __LINE__); - - $folder = new Folder(self::PATH_CERTIFICATES, TRUE); - - if (!$folder->exists()) - return []; - - $certificate_list = $folder->get_listing(); - - $cert_files = []; - - foreach ($certificate_list as $certificate) { - $base_path = self::PATH_CERTIFICATES . '/' . $certificate . '/'; - $cert_files[$certificate]['certificate-filename'] = $base_path . 'cert.pem'; - $cert_files[$certificate]['key-filename'] = $base_path . 'privkey.pem'; - $cert_files[$certificate]['intermediate-filename'] = $base_path . 'chain.pem'; - $cert_files[$certificate]['fullchain-filename'] = $base_path . 'fullchain.pem'; - } - - return $cert_files; - } - - /** - * Returns certificate attributes. - * - * @param string $certificate certificate basename - * - * @return array list of certificate attributes - * @throws Certificate_Not_Found_Exception, Engine_Exception - */ - - - public function get_certificate_attributes($certificate) - { - clearos_profile(__METHOD__, __LINE__); - - $ssl = new SSL(); - - return $ssl->get_certificate_attributes(self::PATH_CERTIFICATES . '/' . $certificate . '/' . self::FILE_CERT); - } - /** * Returns the admin e-mail address. * @@ -374,70 +188,13 @@ public function get_email() return $email; } - /** - * Returns array of log lines. - * - * @param string $certificate certificate basename - * - * @return array log lines - * @throws Engine_Exception - */ - - public function get_log($certificate) - { - clearos_profile(__METHOD__, __LINE__); - - $log_basename = self::FILE_LOG_PREFIX . $certificate . '.log'; - - $log = new File(CLEAROS_TEMP_DIR . '/' . $log_basename); - if (!$log->exists()) - return []; - - $lines = $log->get_contents_as_array(); - - $important = []; - $important_found = FALSE; - - foreach ($lines as $line) { - // KLUDGE: trying to extract only the good stuff - if ($important_found) - $important[] = $line; - - if (preg_match('/IMPORTANT NOTES:/', $line)) - $important_found = TRUE; - } - - if (empty($important)) - $important = $lines; - - return $important; - } - - /** - * Sets the admin e-mail address. - * - * @param string $email admin e-mail address - * - * @return void - * @throws Engine_Exception - */ - - public function set_email($email) - { - clearos_profile(__METHOD__, __LINE__); - - Validation_Exception::is_valid($this->validate_email($email)); - - $this->_set_parameter('email', $email); - } - /** * Renews certificates. * * The basically runs "certbot renew" but does some firewall, * Apache, and NGINX checks. * - * @param boolean $auto flag is renew is called automatically via cron + * @param boolean $auto flag is set if called via default cron * * @return void * @throws Engine_Exception @@ -530,68 +287,27 @@ public function renew_required() return TRUE; } - /////////////////////////////////////////////////////////////////////////////// - // V A L I D A T I O N M E T H O D S - /////////////////////////////////////////////////////////////////////////////// - /** - * Validation routine for ceritificates. + * Sets the admin e-mail address. * - * @param string $name certificate name + * @param string $email admin e-mail address * - * @return string error message if certificate is invalid + * @return void + * @throws Engine_Exception */ - public function validate_certificate_name($name) + public function set_email($email) { clearos_profile(__METHOD__, __LINE__); - $certificates = $this->get_certificates(); - - if (! array_key_exists($name, $certificates)) - return lang('certificate_manager_certificate_invalid'); - } - - /** - * Validation routine for primary domain. - * - * @param string $domain primary domain - * - * @return string error message if primary domain is invalid - */ - - public function validate_domain($domain) - { - clearos_profile(__METHOD__, __LINE__); + Validation_Exception::is_valid($this->validate_email($email)); - if (!Network_Utils::is_valid_domain($domain)) - return lang('network_domain_invalid'); + $this->_set_parameter('email', $email); } - /** - * Validation routine for domain list. - * - * @param string $domains domain list - * - * @return string error message domain list is invalid - */ - - public function validate_domains($domains) - { - clearos_profile(__METHOD__, __LINE__); - - $domains = preg_replace('/,/', ' ', $domains); - $domain_list = preg_split('/\s+/', $domains); - $valid = TRUE; - - foreach ($domain_list as $domain) { - if ($this->validate_domain($domain)) - $valid = FALSE; - } - - if (!$valid) - return lang('lets_encrypt_domain_list_invalid'); - } + /////////////////////////////////////////////////////////////////////////////// + // V A L I D A T I O N M E T H O D S + /////////////////////////////////////////////////////////////////////////////// /** * Validation routine for the admin e-mail address. @@ -621,7 +337,7 @@ public function validate_email($email) * @throws Engine_Exception */ - protected function _disengage_daemons() + public function _disengage_daemons() { clearos_profile(__METHOD__, __LINE__); @@ -648,7 +364,7 @@ protected function _disengage_daemons() * @throws Engine_Exception */ - protected function _disengage_incoming_firewall() + public function _disengage_incoming_firewall() { clearos_profile(__METHOD__, __LINE__); @@ -679,7 +395,7 @@ protected function _disengage_incoming_firewall() * @throws Engine_Exception */ - protected function _disengage_port_forwarding() + public function _disengage_port_forwarding() { clearos_profile(__METHOD__, __LINE__); @@ -715,7 +431,7 @@ protected function _disengage_port_forwarding() * @throws Engine_Exception */ - protected function _engage_daemons($states) + public function _engage_daemons($states) { clearos_profile(__METHOD__, __LINE__); @@ -741,7 +457,7 @@ protected function _engage_daemons($states) * @throws Engine_Exception */ - protected function _engage_incoming_firewall($state) + public function _engage_incoming_firewall($state) { clearos_profile(__METHOD__, __LINE__); @@ -765,7 +481,7 @@ protected function _engage_incoming_firewall($state) * @throws Engine_Exception */ - protected function _engage_port_forwarding($rules) + public function _engage_port_forwarding($rules) { clearos_profile(__METHOD__, __LINE__); diff --git a/packaging/app-lets-encrypt.spec b/packaging/app-lets-encrypt.spec index 1bd1403..aec2517 100644 --- a/packaging/app-lets-encrypt.spec +++ b/packaging/app-lets-encrypt.spec @@ -23,7 +23,7 @@ License: LGPLv3 Group: Applications/API Requires: app-base-core Requires: app-network-core -Requires: app-certificate-manager-core >= 1:2.4.10 +Requires: app-certificate-manager-core >= 1:2.5.10 Requires: app-events-core Requires: app-tasks-core Requires: certbot >= 0.21.0 @@ -91,6 +91,7 @@ exit 0 %dir /var/clearos/lets_encrypt/backup /usr/clearos/apps/lets_encrypt/deploy /usr/clearos/apps/lets_encrypt/language +/usr/clearos/apps/lets_encrypt/api /usr/clearos/apps/lets_encrypt/libraries /etc/cron.d/app-lets-encrypt /var/clearos/events/lets_encrypt/lets_encrypt