Add Certificate checking

pull/494/head
av2k 2017-08-01 10:06:50 +02:00
parent 56d3a34784
commit 1743b6e3f9
15 changed files with 459 additions and 33 deletions

View File

@ -45,4 +45,4 @@ try {
// it that somehow also doesnt exist, we have a bit of an issue
// and we really have no reason catch it
$router->run(PSM_MODULE_DEFAULT);
}
}

View File

@ -92,4 +92,5 @@ if(!defined('PSM_INSTALL') || !PSM_INSTALL) {
}
$lang = psm_get_conf('language', 'en_US');
psm_load_lang($lang);
psm_load_lang($lang);

View File

@ -355,6 +355,21 @@ function psm_curl_get($href, $header = false, $body = true, $timeout = null, $ad
return $result;
}
/**
* Get SSL certificate information about the peer
*
* @param string $href
* @return array
*/
function psm_cert_info_get($href, $port) {
$host = parse_url($href, PHP_URL_HOST);
$stream_context = stream_context_create( array( "ssl" => array("capture_peer_cert" => TRUE ) ) );
$stream_client = stream_socket_client("ssl://" . $host . ":$port", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $stream_context );
$cert = stream_context_get_params( $stream_client );
$cert_info = openssl_x509_parse( $cert['options']['ssl']['peer_certificate'] );
return $cert_info;
}
/**
* Get a "nice" timespan message
*
@ -728,4 +743,4 @@ function psm_password_decrypt($key, $encryptedString)
);
return $decrypted;
}
}

View File

@ -155,6 +155,8 @@ $sm_lang = array(
'hour' => 'Stunde',
'warning_threshold' => 'Warnschwelle',
'warning_threshold_description' => 'Anzahl der fehlgeschlagenen Überprüfungen, bevor der Status als offline markiert wird.',
'ssl_cert_expiry_days' => 'Zertifikatsgültigkeit',
'ssl_cert_expiry_days_description' => 'Anzahl der Tage, die das SSL-Zertifikat noch gültig sein soll.',
'chart_last_week' => 'Letzte Woche',
'chart_history' => 'Historie',
// Charts date format according jqPlot date format http://www.jqplot.com/docs/files/plugins/jqplot-dateAxisRenderer-js.html
@ -172,6 +174,7 @@ $sm_lang = array(
'error_server_ip_bad_website' => 'Die eingegebene Webseiten-URL ist ungültig.',
'error_server_type_invalid' => 'Der gewählte Server-Typ ist ungültig.',
'error_server_warning_threshold_invalid' => 'Die Warnschwelle muss eine gültige ganze Zahl größer als 0 sein.',
'error_server_ssl_cert_expiry_days_invalid' => 'Die verbleibenden Tage des SSL-Zertifikats müssen eine gültige ganze Zahl größer oder gleich 0 sein.',
),
'config' => array(
'general' => 'Allgemein',

View File

@ -168,6 +168,8 @@ $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.',
'chart_last_week' => 'Last week',
'chart_history' => 'History',
// Charts date format according jqPlot date format http://www.jqplot.com/docs/files/plugins/jqplot-dateAxisRenderer-js.html
@ -185,6 +187,7 @@ $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',

327
src/lang/ja_JP.lang.php Normal file
View File

@ -0,0 +1,327 @@
<?php
/**
* PHP Server Monitor
* Monitor your servers and websites.
*
* This file is part of PHP Server Monitor.
* PHP Server Monitor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PHP Server Monitor 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
*
* @package phpservermon
* @author Pepijn Over <pep@mailbox.org>
* @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: v3.2.0
* @link http://www.phpservermonitor.org/
**/
$sm_lang = array(
'name' => '日本語 - Japanese',
'locale' => array('ja_JP.UTF-8', 'ja_JP', 'Japan', 'Japanese'),
'locale_tag' => 'ja',
'locale_dir' => 'ltr',
'system' => array(
'title' => 'サーバーモニター',
'install' => 'インストール',
'action' => 'アクション',
'save' => 'セーブ',
'edit' => '編集',
'delete' => '削除',
'date' => '日時',
'message' => 'メッセージ',
'yes' => 'はい',
'no' => 'いいえ',
'insert' => '挿入',
'add_new' => '新規に追加',
'update_available' => '新しいバージョン({version}) がリリースされています。ここから入手可能です: <a href="http://www.phpservermonitor.org" target="_blank">http://www.phpservermonitor.org</a>.',
'back_to_top' => 'トップに戻る',
'go_back' => '戻る',
'ok' => 'OK',
'cancel' => 'キャンセル',
// date/time format according the strftime php function format parameter http://php.net/manual/function.strftime.php
'short_day_format' => '%B %e',
'long_day_format' => '%B %e, %Y',
'yesterday_format' => '昨日の %k:%M',
'other_day_format' => '%A at %k:%M',
'never' => 'なし',
'hours_ago' => '%d 時間前',
'an_hour_ago' => '1時間くらい前',
'minutes_ago' => '%d 分前',
'a_minute_ago' => '1分くらい前',
'seconds_ago' => '%d 秒前',
'a_second_ago' => '1秒',
),
'menu' => array(
'config' => '設定',
'server' => 'サーバー',
'server_log' => 'ログ',
'server_status' => 'ステータス',
'server_update' => 'アップデート',
'user' => 'ユーザー',
'help' => 'ヘルプ',
),
'users' => array(
'user' => 'ユーザー',
'name' => '名前',
'user_name' => 'ユーザーネーム',
'password' => 'パスワード',
'password_repeat' => 'パスワードを繰り返す',
'password_leave_blank' => '空白のままにしておく',
'level' => 'レベル',
'level_10' => '管理者(Administrator)',
'level_20' => 'ユーザー(User)',
'level_description' => '<b>管理者(Administrators)</b> はフルアクセス権があります:サーバーの管理、 ユーザーとグローバル設定を変更できます。<br/><b>ユーザー(Users)</b>は、割り当てられたサーバーのアップデータのみを表示して実行できます。',
'mobile' => 'モバイル',
'email' => 'メールアドレス',
'pushover' => 'プッシュオーバー',
'pushover_description' => 'プッシュオーバーサービスは、リアルタイムで通知を受け取るのが簡単にできます。詳細についてはこちらをご覧ください: <a href="https://pushover.net/">https://pushover.net/</a>',
'pushover_key' => 'プッシュオーバーキー',
'pushover_device' => 'プッシュオーバーデバイス',
'pushover_device_description' => '指定したデバイスに送信します。空欄ですべてのデバイスに送信できます。',
'delete_title' => 'ユーザーを削除',
'delete_message' => '本当にユーザーを削除しますか?: \'%1\'?',
'deleted' => 'ユーザーを削除しました。',
'updated' => 'ユーザー情報を更新しました。',
'inserted' => 'ユーザーを追加しました。',
'profile' => 'プロフィール',
'profile_updated' => 'あなたのプロフィールは更新されました。',
'error_user_name_bad_length' => 'ユーザーネームは264文字以内で入力してください。',
'error_user_name_invalid' => 'ユーザー名は、アルファベット、数字とアンダーバーのみを含むことができます。',
'error_user_name_exists' => '登録しようとしたユーザー名は既にデータベースに登録されています。',
'error_user_email_bad_length' => 'メールアドレスは5255文字以内で入力してください。',
'error_user_email_invalid' => 'メールアドレスが無効です。',
'error_user_level_invalid' => '指定したレベルが無効です。',
'error_user_no_match' => 'このユーザー名は存在しません。',
'error_user_password_invalid' => 'パスワードが無効です。',
'error_user_password_no_match' => '確認のパスワードが一致しません。',
),
'log' => array(
'title' => 'ログエントリー',
'type' => 'タイプ',
'status' => 'ステータス',
'email' => 'メール',
'sms' => 'SMS',
'pushover' => 'プッシュオーバー',
'no_logs' => 'ログがありません',
),
'servers' => array(
'server' => 'サーバー',
'status' => 'ステータス',
'label' => 'ラベル',
'domain' => 'ドメイン/IP',
'timeout' => 'タイムアウト',
'timeout_description' => '指定した秒数、サーバーのレスポンスを待ちます。',
'authentication_settings' => '認証設定(オプション)',
'website_username' => 'ユーザー名',
'website_username_description' => 'ユーザー名でウェブサイトにアクセスします。 (サポートはApache認証のみです。)',
'website_password' => 'パスワード',
'website_password_description' => 'Password to access the site. The password is encrypted in the database.',
'fieldset_monitoring' => 'モニター',
'fieldset_permissions' => '権限',
'port' => 'ポート',
'custom_port' => 'カスタムポート',
'popular_ports' => '主要なポート',
'please_select' => '選択してください',
'type' => 'タイプ',
'type_website' => 'ウェブサイト',
'type_service' => 'サービス',
'type_ping' => 'Ping',
'pattern' => '文字列/パターンを検索',
'pattern_description' => '指定した文字列/パターンが存在しない場合は、「オフライン」としてマークされます。また、標準的な計算式は許可されています。',
'last_check' => '最後の確認',
'last_online' => '最後のオンライン',
'monitoring' => 'モニタリング',
'no_monitoring' => 'モニタリングなし',
'email' => 'メール',
'send_email' => 'メールを送信',
'sms' => 'SMS',
'send_sms' => 'SMSを送信',
'pushover' => 'プッシュオーバー',
'users' => 'ユーザー',
'delete_title' => 'サーバーを削除',
'delete_message' => '本当にこのサーバーを削除しますか?: \'%1\'?',
'deleted' => 'サーバーを削除しました。',
'updated' => 'サーバーを更新しました。',
'inserted' => 'サーバーを追加しました。',
'latency' => 'レイテンシ',
'latency_max' => 'レイテンシ(最大)',
'latency_min' => 'レイテンシ(最小)',
'latency_avg' => 'レイテンシ(アベレージ)',
'uptime' => '稼働時間',
'year' => '年',
'month' => '月',
'week' => '週間',
'day' => '日',
'hour' => '時間',
'warning_threshold' => '警告閾値',
'warning_threshold_description' => 'オフラインとしてマークされる前に失敗したチェックの数',
'chart_last_week' => '最後の週間',
'chart_history' => '履歴',
// Charts date format according jqPlot date format http://www.jqplot.com/docs/files/plugins/jqplot-dateAxisRenderer-js.html
'chart_day_format' => '%Y-%m-%d',
'chart_long_date_format' => '%Y-%m-%d %H:%M:%S',
'chart_short_date_format' => '%m/%d %H:%M',
'chart_short_time_format' => '%H:%M',
'warning_notifications_disabled_sms' => 'SMS 通知は無効です。',
'warning_notifications_disabled_email' => 'メール通知は無効です。',
'warning_notifications_disabled_pushover' => 'プッシュオーバー通知は無効です。',
'error_server_no_match' => 'サーバーが見つかりません',
'error_server_label_bad_length' => 'ラベルは1255文字以内で入力してください。',
'error_server_ip_bad_length' => 'ドメイン/IPは1255文字以内で入力してください。',
'error_server_ip_bad_service' => '無効なIPです。',
'error_server_ip_bad_website' => 'ウェブサイトのURLが無効です。',
'error_server_type_invalid' => '選択されたサーバータイプが無効です。',
'error_server_warning_threshold_invalid' => '警告のしきい値は、0より大きい有効な整数でなければなりません。',
),
'config' => array(
'general' => '基本',
'language' => '言語',
'show_update' => 'アップデートをチェックしますか?',
'password_encrypt_key' => '暗号鍵パスワード',
'password_encrypt_key_note' => 'このキーは、Webサイトにアクセスするためにサーバーに保存されているパスワードを暗号化するために使用されます。 キーが変更された場合、保存されたパスワードは無効です!',
'proxy' => 'プロキシを有効化する',
'proxy_url' => 'プロキシのURL',
'proxy_user' => 'プロキシのユーザー名',
'proxy_password' => 'プロキシのパスワード',
'email_status' => 'メールの送信を許可',
'email_from_email' => 'アドレスからのメール',
'email_from_name' => '名前からのメール',
'email_smtp' => 'SMTPを有効にしますか',
'email_smtp_host' => 'SMTPホスト',
'email_smtp_port' => 'SMTPポート',
'email_smtp_security' => 'SMTPセキュリティ',
'email_smtp_security_none' => 'なし',
'email_smtp_username' => 'SMTPのユーザー名',
'email_smtp_password' => 'SMTPのパスワード',
'email_smtp_noauth' => '空白で認証なしになります',
'sms_status' => 'テキストメッセージの送信を許可する',
'sms_gateway' => 'このゲートウェイは、メッセージの送信に使用されます。',
'sms_gateway_mosms' => 'Mosms',
'sms_gateway_mollie' => 'Mollie',
'sms_gateway_spryng' => 'Spryng',
'sms_gateway_inetworx' => 'Inetworx',
'sms_gateway_clickatell' => 'Clickatell',
'sms_gateway_textmarketer' => 'Textmarketer',
'sms_gateway_smsglobal' => 'SMSGlobal',
'sms_gateway_octopush' => 'Octopush',
'sms_gateway_smsit' => 'Smsit',
'sms_gateway_freevoipdeal' => 'FreeVoipDeal',
'sms_gateway_freemobilesms' => 'FreeMobileSMS',
'sms_gateway_clicksend' => 'ClickSend',
'sms_gateway_nexmo' => 'Nexmo',
'sms_gateway_smsgw' => 'SMSgw',
'sms_gateway_username' => 'ゲートウェイのユーザー名',
'sms_gateway_password' => 'ゲートウェイのパスワード',
'sms_from' => '送信者の電話番号:',
'pushover_status' => 'プッシュオーバーのメッセージを送信することを許可する',
'pushover_description' => 'プッシュオーバーは、リアルタイムの通知を簡単に取得できるサービスです。 詳細については、<a href="https://pushover.net/">ウェブサイト</a>をご覧ください。',
'pushover_clone_app' => 'クリックでプッシュオーバーアプリケーションを作成できます。',
'pushover_api_token' => 'プッシュオーバーアプリケーションのAPIトークン',
'pushover_api_token_description' => 'プッシュオーバーを使用するには、事前にウェブサイトで<a href="%1$s" target="_blank">アプリを登録</a>してApp APIトークンを入力する必要があります。',
'alert_type' => '通知するタイミングを選択',
'alert_type_description' => '<b>状態の変化:</b> '.
'サーバーのステータスが変更されたときに通知を受け取ります。 だからオンライン -> オフラインまたはオフライン -> オンライン。<br/>'.
'<br /><b>オフライン:</b> '.
'サーバーが*初めての間*オフラインになったときに通知を受け取ります。 例えば、'.
'あなたのcronの仕事は15分ごとです。あなたのサーバーは午前1時にダウンし、午前6時まで停止します。 '.
'午前1時に1つの通知が届きます。<br/>'.
'<br><b>常に:</b> '.
'サイトが数時間にわたってオフラインになっていても、スクリプトが実行され、サイトが停止するたびに通知を受け取ります。',
'alert_type_status' => '状況の変化',
'alert_type_offline' => 'オフライン',
'alert_type_always' => '常に',
'alert_proxy' => '有効にしても、プロキシはサービスに使用されません',
'alert_proxy_url' => '<b>フォーマット:</b> ホスト:ポート',
'log_status' => 'ログステータス',
'log_status_description' => 'ログステータスがTRUEに設定されている場合、モニターは通知設定が渡されるたびにイベントを記録します。',
'log_email' => 'スクリプトによって送信された電子メールを記録する',
'log_sms' => 'スクリプトによって送信されたテキストメッセージを記録する',
'log_pushover' => 'スクリプトによって送信されたプッシュオーバーメッセージを記録する',
'updated' => '設定は更新されました。',
'tab_email' => 'メール',
'tab_sms' => 'SMS',
'tab_pushover' => 'プッシュオーバー',
'settings_email' => 'メール設定',
'settings_sms' => 'テキストメッセージ設定',
'settings_pushover' => 'プッシュオーバー設定',
'settings_notification' => '通知設定',
'settings_log' => 'ログ設定',
'settings_proxy' => 'プロキシ設定',
'auto_refresh' => '自動更新',
'auto_refresh_servers' =>
'サーバーページを自動更新します。<br/>'.
'<span class="small">'.
'時間を秒で指定し、0に設定すると更新しません。'.
'</span>',
'seconds' => '秒',
'test' => 'テスト',
'test_email' => 'あなたのユーザープロフィールで指定されたアドレスに電子メールが送信されます。',
'test_sms' => 'あなたのユーザープロフィールで指定された電話番号にSMSが送信されます。',
'test_pushover' => 'あなたのユーザープロフィールで指定されたユーザー キー/デバイスにプッシュオーバーが送信されます。',
'send' => '送信',
'test_subject' => 'テスト',
'test_message' => 'これはテストメッセージです',
'email_sent' => 'メールが送信されました',
'email_error' => 'メールを送信中にエラーが発生しました',
'sms_sent' => 'SMSが送信されました',
'sms_error' => 'SMSを送信中にエラーが発生しました',
'sms_error_nomobile' => 'テストSMSの送信に失敗: あなたのプロフィールに有効な電話番号がありません',
'pushover_sent' => 'プッシュオーバー通知が送信されました',
'pushover_error' => 'プッシュオーバー通知を送信中にエラーが発生しました: %s',
'pushover_error_noapp' => 'テスト通知の送信に失敗しましたグローバル設定にAPIトークンがありません',
'pushover_error_nokey' => 'テスト通知の送信に失敗しました:あなたのプロフィールに有効なプッシュオーバーキーがありません',
'log_retention_period' => 'ログ保存期間',
'log_retention_period_description' => '通知のログおよびサーバー稼働時間のアーカイブを保持する日数。 ログのクリーンアップを無効にするには、0を入力します。',
'log_retention_days' => '日',
),
// for newlines in the email messages use <br/>
'notifications' => array(
'off_sms' => 'サーバー \'%LABEL%\' はダウンしています: ip=%IP%, ポート=%PORT%. エラー=%ERROR%',
'off_email_subject' => '重要: サーバー \'%LABEL%\' がダウンしています!',
'off_email_body' => "サーバーへの接続に失敗しました:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>ポート: %PORT%<br/>エラー: %ERROR%<br/>日時: %DATE%",
'off_pushover_title' => 'サーバー \'%LABEL%\' がダウンしています!',
'off_pushover_message' => "サーバーへの接続に失敗しました:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>ポート: %PORT%<br/>エラー: %ERROR%<br/>日時: %DATE%",
'on_sms' => 'サーアb- \'%LABEL%\' は動作しています: ip=%IP%, port=%PORT%',
'on_email_subject' => '重要: サーバー \'%LABEL%\' は動作しています',
'on_email_body' => "サーバー '%LABEL%' は動作中です:<br/><br/>サーバー: %LABEL%<br/>IP: %IP%<br/>ポート: %PORT%<br/>日時: %DATE%",
'on_pushover_title' => 'サーバー \'%LABEL%\' は動作しています',
'on_pushover_message' => "サーバー '%LABEL%' は動作中です:<br/><br/>サーバー: %LABEL%<br/>IP: %IP%<br/>ポート: %PORT%<br/>日時: %DATE%",
),
'login' => array(
'welcome_usermenu' => 'ようこそ、 %user_name%',
'title_sign_in' => 'サインインしてください。',
'title_forgot' => 'パスワードを忘れましたか?',
'title_reset' => 'パスワードをリセットする',
'submit' => '送信',
'remember_me' => 'ログイン状態を保持する',
'login' => 'ログイン',
'logout' => 'ログアウト',
'username' => 'ユーザー名',
'password' => 'パスワード',
'password_repeat' => 'パスワードを繰り返してください',
'password_forgot' => 'パスワードを忘れましたか?',
'password_reset' => 'パスワードをリセットする',
'password_reset_email_subject' => 'PHP Server Monitorのパスワードをリセットする',
'password_reset_email_body' => 'パスワードをリセットするには、次のリンクを使用してください。 1時間で期限切れになりますのでご注意ください。<br /><br /> %link%',
'error_user_incorrect' => '指定されたユーザー名が見つかりませんでした。',
'error_login_incorrect' => '情報が間違っています。',
'error_login_passwords_nomatch' => '指定されたパスワードが一致しません。',
'error_reset_invalid_link' => '指定したリセットリンクは無効です。',
'success_password_forgot' => 'パスワードをリセットする方法に関する情報が電子メールで送信されました。',
'success_password_reset' => 'パスワードは正常にリセットされました。ログインしてください。',
),
'error' => array(
'401_unauthorized' => '未認証',
'401_unauthorized_description' => 'このページを表示する権限がありません。',
),
);

View File

@ -43,4 +43,4 @@ class ErrorModule implements ModuleInterface {
);
}
}
}

View File

@ -77,6 +77,7 @@ abstract class AbstractServerController extends AbstractController {
`s`.`pushover`,
`s`.`warning_threshold`,
`s`.`warning_threshold_counter`,
`s`.`ssl_cert_expiry_days`,
`s`.`timeout`,
`s`.`website_username`,
`s`.`website_password`

View File

@ -203,6 +203,7 @@ class ServerController extends AbstractServerController {
'edit_value_warning_threshold' => $edit_server['warning_threshold'],
'edit_website_username' => $edit_server['website_username'],
'edit_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'] => 'selected="selected"',
'edit_email_selected_' . $edit_server['email'] => 'selected="selected"',
@ -268,6 +269,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', 0)),
'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',
@ -303,6 +305,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();
@ -482,6 +485,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

@ -237,6 +237,7 @@ class Installer {
`pushover` enum('yes','no') NOT NULL default 'yes',
`warning_threshold` mediumint(1) unsigned NOT NULL DEFAULT '1',
`warning_threshold_counter` mediumint(1) unsigned NOT NULL DEFAULT '0',
`ssl_cert_expiry_days` mediumint(1) unsigned NOT NULL DEFAULT '0',
`timeout` smallint(1) unsigned NULL DEFAULT NULL,
`website_username` varchar(255) DEFAULT NULL,
`website_password` varchar(255) DEFAULT NULL,
@ -321,7 +322,7 @@ class Installer {
$this->execSQL($queries);
}
/**
* Upgrade for v3.0.0 release
*/
@ -490,6 +491,7 @@ class Installer {
protected function upgrade321() {
$queries = array();
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "servers` ADD COLUMN `header_name` VARCHAR(255) AFTER `pattern`, ADD COLUMN `header_value` VARCHAR(255) AFTER `header_name`";
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "servers` ADD `ssl_cert_expiry_days` MEDIUMINT( 1 ) UNSIGNED NOT NULL DEFAULT '0' AFTER `warning_threshold_counter`";
$this->execSQL($queries);
}
}

View File

@ -52,49 +52,55 @@ class ArchiveManager {
*/
protected $retention_period;
public function __construct(\psm\Service\Database $db) {
public function __construct( \psm\Service\Database $db ) {
$this->db = $db;
$this->setRetentionPeriod(psm_get_conf('log_retention_period', 365));
$this->setRetentionPeriod( psm_get_conf( 'log_retention_period', 365 ) );
$this->archivers[] = new Archiver\UptimeArchiver($db);
$this->archivers[] = new Archiver\LogsArchiver($db);
$this->archivers[] = new Archiver\UptimeArchiver( $db );
$this->archivers[] = new Archiver\LogsArchiver( $db );
}
/**
* Archive one or more servers.
*
* @param int $server_id
*
* @return boolean
*/
public function archive($server_id = null) {
public function archive( $server_id = null ) {
$result = true;
foreach($this->archivers as $archiver) {
if(!$archiver->archive($server_id)) {
foreach ( $this->archivers as $archiver ) {
if ( ! $archiver->archive( $server_id ) ) {
$result = false;
}
}
return $result;
}
/**
* Cleanup old records for one or more servers
*
* @param int $server_id
*
* @return boolean
*/
public function cleanup($server_id = null) {
public function cleanup( $server_id = null ) {
$result = true;
if(!$this->retention_period) {
if ( ! $this->retention_period ) {
// cleanup is disabled
return $result;
}
$retdate = new \DateTime();
$retdate->sub($this->retention_period);
$retdate->sub( $this->retention_period );
foreach($this->archivers as $archiver) {
if(!$archiver->cleanup($retdate, $server_id)) {
foreach ( $this->archivers as $archiver ) {
if ( ! $archiver->cleanup( $retdate, $server_id ) ) {
$result = false;
}
}
return $result;
}
@ -102,18 +108,21 @@ class ArchiveManager {
* Set retention period for this archive run.
*
* Set period to 0 to disable cleanup altogether.
*
* @param \DateInterval|int $period \DateInterval object or number of days (int)
*
* @return \psm\Util\Server\ArchiveManager
*/
public function setRetentionPeriod($period) {
if(is_object($period) && $period instanceof \DateInterval) {
public function setRetentionPeriod( $period ) {
if ( is_object( $period ) && $period instanceof \DateInterval ) {
$this->retention_period = $period;
} elseif(intval($period) == 0) {
} elseif ( intval( $period ) == 0 ) {
// cleanup disabled
$this->retention_period = false;
} else {
$this->retention_period = new \DateInterval('P' . intval($period) . 'D');
$this->retention_period = new \DateInterval( 'P' . intval( $period ) . 'D' );
}
return $this;
}
}

View File

@ -40,7 +40,7 @@ class LogsArchiver implements ArchiverInterface {
*/
protected $db;
function __construct(Database $db) {
function __construct( Database $db ) {
$this->db = $db;
}
@ -48,23 +48,25 @@ class LogsArchiver implements ArchiverInterface {
* Currently there is not really a log archive.
*
* It stays in the log table until cleaned up.
*
* @param int $server_id
*/
public function archive($server_id = null) {
public function archive( $server_id = null ) {
return true;
}
public function cleanup(\DateTime $retention_date, $server_id = null) {
$sql_where_server = ($server_id !== null)
// this is obviously not the cleanest way to implement this when using paramter binding.. sorry.
? ' `server_id` = ' . intval($server_id) . ' AND '
: '';
public function cleanup( \DateTime $retention_date, $server_id = null ) {
$sql_where_server = ( $server_id !== null )
// this is obviously not the cleanest way to implement this when using paramter binding.. sorry.
? ' `server_id` = ' . intval( $server_id ) . ' AND '
: '';
$this->db->execute(
"DELETE FROM `".PSM_DB_PREFIX."log` WHERE {$sql_where_server} `datetime` < :latest_date",
array('latest_date' => $retention_date->format('Y-m-d 00:00:00')),
"DELETE FROM `" . PSM_DB_PREFIX . "log` WHERE {$sql_where_server} `datetime` < :latest_date",
array( 'latest_date' => $retention_date->format( 'Y-m-d 00:00:00' ) ),
false
);
return true;
}
}

View File

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

View File

@ -83,7 +83,7 @@ class StatusUpdater {
'server_id' => $server_id,
), array(
'server_id', 'ip', 'port', 'label', 'type', 'pattern', 'header_name', 'header_value', 'status', 'active', 'warning_threshold',
'warning_threshold_counter', 'timeout', 'website_username', 'website_password'
'warning_threshold_counter', 'ssl_cert_expiry_days', 'timeout', 'website_username', 'website_password'
));
if(empty($this->server)) {
return false;
@ -192,6 +192,8 @@ class StatusUpdater {
fclose($fp);
}
$this->check_ssl($this->server, $this->error, $status);
// check if server is available and rerun if asked.
if(!$status && $run < $max_runs) {
return $this->updateService($max_runs, $run + 1);
@ -207,6 +209,7 @@ class StatusUpdater {
* @return boolean
*/
protected function updateWebsite($max_runs, $run = 1) {
$result = '';
$starttime = microtime(true);
// We're only interested in the header, because that should tell us plenty!
@ -279,15 +282,51 @@ class StatusUpdater {
}
}
}
$this->check_ssl($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);
}
return $result;
}
/**
* Check if a server speaks SSL and if the certificate is not expired.
* @param string $error
* @param bool $result
*/
private function check_ssl($server, &$error, &$result) {
if(($ssl_cert_expiry_days = $server['ssl_cert_expiry_days']) > 0) {
$cert_info = psm_cert_info_get($server['ip'], $server['port']);
if( empty( $cert_info) ) {
$error = "SSL is disabled.";
$result = false;
} else {
$current_time = time();
$seconds_per_day = 86400;
$cert_valid_until = $cert_info['validTo_time_t'];
$latest_time = $current_time + $seconds_per_day*$ssl_cert_expiry_days;
if( $latest_time > $cert_valid_until ) {
$remaining_time = $cert_valid_until - $current_time;
$remaining_days = (int)( $remaining_time / $seconds_per_day );
if( $remaining_days >= 0 ) {
$error = "SSL certificate expiring: $remaining_days days left.";
} else {
$remaining_days *= -1;
$error = "SSL certificate expired since $remaining_days.";
}
$result = false;
}
}
}
}
/**
* Get the error returned by the update function
*

View File

@ -78,6 +78,12 @@
<input class="input-mini" type="text" id="warning_threshold" name="warning_threshold" value="{{ edit_value_warning_threshold }}" maxlength="5" data-toggle="tooltip" title="{{ label_warning_threshold_description }}" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="ssl_cert_expiry_days">{{ label_ssl_cert_expiry_days }}</label>
<div class="controls">
<input class="input-mini" type="text" id="ssl_cert_expiry_days" name="ssl_cert_expiry_days" value="{{ edit_value_ssl_cert_expiry_days }}" maxlength="5" data-toggle="tooltip" title="{{ label_ssl_cert_expiry_days_description }}" />
</div>
</div>
<div class="control-group types typeWebsite">
<label class="control-label" for="timeout">{{ label_timeout }}</label>
<div class="controls">