Added ssl cert expiration check

This commit is contained in:
TimZ99 2020-01-09 22:28:26 +01:00
parent ef3970cda9
commit e0b8bc1154
No known key found for this signature in database
GPG Key ID: 4D8268DC68E8339D
6 changed files with 73 additions and 7 deletions

View File

@ -247,6 +247,11 @@ $sm_lang = array(
'hour' => 'Hour',
'warning_threshold' => 'Warning threshold',
'warning_threshold_description' => 'Number of failed checks required before it is marked offline.',
'ssl_cert_expiry_days' => 'SSL Certificate Validity',
'ssl_cert_expiry_days_description' => 'The minimum remaining days the SSL certificate is still valid. Use 0 to
disable check.',
'ssl_cert_expired' => 'SSL certificate expired since',
'ssl_cert_expiring' => 'SSL certificate expiring:',
'chart_last_week' => 'Last week',
'chart_history' => 'History',
'chart_day_format' => '%Y-%m-%d',
@ -264,6 +269,8 @@ $sm_lang = array(
'error_server_ip_bad_website' => 'The website URL is not valid.',
'error_server_type_invalid' => 'The selected server type is invalid.',
'error_server_warning_threshold_invalid' => 'The warning threshold must be a valid integer greater than 0.',
'error_server_ssl_cert_expiry_days' => 'The remaining days for SSL certificate validity must be a valid integer
greater than or equal to 0.',
),
'config' => array(
'general' => 'General',

View File

@ -85,6 +85,8 @@ abstract class AbstractServerController extends AbstractController
`s`.`telegram`,
`s`.`warning_threshold`,
`s`.`warning_threshold_counter`,
`s`.`ssl_cert_expiry_days`,
`s`.`ssl_cert_expired_time`,
`s`.`timeout`,
`s`.`website_username`,
`s`.`website_password`,

View File

@ -208,6 +208,7 @@ class ServerController extends AbstractServerController
'edit_value_website_username' => $edit_server['website_username'],
'edit_value_website_password' => empty($edit_server['website_password']) ? '' :
sha1($edit_server['website_password']),
'edit_value_ssl_cert_expiry_days' => $edit_server['ssl_cert_expiry_days'],
'edit_type_selected_' . $edit_server['type'] => 'selected="selected"',
'edit_active_selected' => $edit_server['active'],
'edit_email_selected' => $edit_server['email'],
@ -281,6 +282,7 @@ class ServerController extends AbstractServerController
'header_name' => psm_POST('header_name', ''),
'header_value' => psm_POST('header_value', ''),
'warning_threshold' => intval(psm_POST('warning_threshold', 0)),
'ssl_cert_expiry_days' => intval(psm_POST('ssl_cert_expiry_days', 1)),
'active' => in_array($_POST['active'], array('yes', 'no')) ? $_POST['active'] : 'no',
'email' => in_array($_POST['email'], array('yes', 'no')) ? $_POST['email'] : 'no',
'sms' => in_array($_POST['sms'], array('yes', 'no')) ? $_POST['sms'] : 'no',
@ -325,6 +327,7 @@ class ServerController extends AbstractServerController
$server_validator->type($clean['type']);
$server_validator->ip($clean['ip'], $clean['type']);
$server_validator->warningThreshold($clean['warning_threshold']);
$server_validator->sslCertExpiryDays($clean['ssl_cert_expiry_days']);
} catch (\InvalidArgumentException $ex) {
$this->addMessage(psm_get_lang('servers', 'error_' . $ex->getMessage()), 'error');
return $this->executeEdit();
@ -558,6 +561,8 @@ class ServerController extends AbstractServerController
'label_users' => psm_get_lang('servers', 'users'),
'label_warning_threshold' => psm_get_lang('servers', 'warning_threshold'),
'label_warning_threshold_description' => psm_get_lang('servers', 'warning_threshold_description'),
'label_ssl_cert_expiry_days' => psm_get_lang('servers', 'ssl_cert_expiry_days'),
'label_ssl_cert_expiry_days_description' => psm_get_lang('servers', 'ssl_cert_expiry_days_description'),
'label_action' => psm_get_lang('system', 'action'),
'label_save' => psm_get_lang('system', 'save'),
'label_go_back' => psm_get_lang('system', 'go_back'),

View File

@ -154,4 +154,18 @@ class ServerValidator
}
return true;
}
/**
* Check SSL expiry days
* @param int $value
* @return boolean
* @throws \InvalidArgumentException
*/
public function sslCertExpiryDays($value)
{
if (!is_numeric($value) || $value < 0) {
throw new \InvalidArgumentException('server_ssl_cert_expiry_days');
}
return true;
}
}

View File

@ -41,6 +41,8 @@ class StatusUpdater
public $header = '';
public $curl_info = '';
public $rtime = 0;
public $status_new = false;
@ -86,6 +88,7 @@ class StatusUpdater
$this->server_id = $server_id;
$this->error = '';
$this->header = '';
$this->curl_info = '';
$this->rtime = '';
// get server info from db
@ -96,7 +99,7 @@ class StatusUpdater
'type', 'pattern', 'pattern_online', 'post_field',
'allow_http_status', 'redirect_check', 'header_name',
'header_value', 'status', 'active', 'warning_threshold',
'warning_threshold_counter', 'timeout', 'website_username',
'warning_threshold_counter', 'ssl_cert_expiry_days', 'ssl_cert_expired_time', 'timeout', 'website_username',
'website_password', 'last_offline'
));
if (empty($this->server)) {
@ -257,12 +260,13 @@ class StatusUpdater
$this->server['request_method'],
$this->server['post_field']
);
$this->header = $curl_result;
$this->header = $curl_result['exec'];
$this->curl_info = $curl_result['info'];
$this->rtime = (microtime(true) - $starttime);
// the first line would be the status code..
$status_code = strtok($curl_result, "\r\n");
$status_code = strtok($curl_result['exec'], "\r\n");
// keep it general
// $code[2][0] = status code
// $code[3][0] = name of status code
@ -293,7 +297,7 @@ class StatusUpdater
($this->server['pattern_online'] == 'yes') ==
!preg_match(
"/{$this->server['pattern']}/i",
$curl_result
$curl_result['exec']
)
) {
$this->error = "TEXT ERROR : Pattern '{$this->server['pattern']}' " .
@ -308,7 +312,7 @@ class StatusUpdater
$location_matches = array();
preg_match(
'/([Ll]ocation: )(https*:\/\/)(www.)?([a-zA-Z.:0-9]*)([\/][[:alnum:][:punct:]]*)/',
$curl_result,
$curl_result['exec'],
$location_matches
);
if (!empty($location_matches)) {
@ -329,7 +333,7 @@ class StatusUpdater
if ($this->server['header_name'] != '' && $this->server['header_value'] != '') {
$header_flag = false;
// Only get the header text if the result also includes the body
$header_text = substr($curl_result, 0, strpos($curl_result, "\r\n\r\n"));
$header_text = substr($curl_result['exec'], 0, strpos($curl_result['exec'], "\r\n\r\n"));
foreach (explode("\r\n", $header_text) as $i => $line) {
if ($i === 0 || strpos($line, ':') == false) {
continue; // We skip the status code & other non-header lines. Needed for proxy or redirects
@ -356,6 +360,9 @@ class StatusUpdater
}
}
// Check ssl cert
$this->checkSsl($this->server, $this->error, $result);
// check if server is available and rerun if asked.
if (!$result && $run < $max_runs) {
return $this->updateWebsite($max_runs, $run + 1);
@ -383,4 +390,33 @@ class StatusUpdater
{
return $this->rtime;
}
/**
* Check if a server speaks SSL and if the certificate is not expired.
* @param string $error
* @param bool $result
*/
private function checkSsl($server, &$error, &$result)
{
if (
!empty($this->curl_info['certinfo']) &&
$server['ssl_cert_expiry_days'] > 0
) {
$cert_expiration_date = strtotime($this->curl_info['certinfo'][0]['Expire date']);
$expiration_time = round((int)($cert_expiration_date - time()) / 86400);
$latest_time = time() + (86400 * $server['ssl_cert_expiry_days']);
if ($expiration_time >= 0) {
$this->header = psm_get_lang('servers', 'ssl_cert_expiring') . " " .
psm_date($this->curl_info['certinfo'][0]['Expire date']) .
"\n\n" . $this->header;
$save['ssl_cert_expired_time'] = null;
} else {
$error = psm_get_lang('servers', 'ssl_cert_expired') . " " .
psm_timespan($cert_expiration_date) . ".\n\n" .
$error;
$save['ssl_cert_expired_time'] = $expiration_time;
}
$this->db->save(PSM_DB_PREFIX . 'servers', $save, array('server_id' => $this->server_id));
}
}
}

View File

@ -46,7 +46,9 @@
</select>
</div>
<!-- Custom port -->
{{ macro.input_field("number", "port", "port types typeService", "port", label_custom_port, edit_value_port, null, "5") }}
{{ macro.input_field("number", "port", "port types typeService", "port", label_custom_port, edit_value_port, null, "5") }}
<!-- SSL Cert check -->
{{ macro.input_field("number", "ssl_cert_expiry_days", "types typeWebsite", "ssl_cert_expiry_days", label_ssl_cert_expiry_days, edit_value_ssl_cert_expiry_days, 0, "5", 'ssl_cert_help', label_ssl_cert_expiry_days_description) }}
<!-- Request method -->
<div class="form-group types typeWebsite">
<label for="popular_request_methods">{{ label_request_method }}</label>