summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Wiese <tobias@tobiaswiese.com>2021-05-23 01:39:15 +0200
committerwaja <waja@users.noreply.github.com>2022-01-30 12:25:56 +0100
commit31bdbfce92de2dc7717fe13a8d1ca8e7dbf850d4 (patch)
tree27c5416f0096e89f168c1baaa1909537fb453223
parent986b2479465648c49a7eefc3fbf4df8860e3e4b7 (diff)
downloadmonitoring-plugins-31bdbfce92de2dc7717fe13a8d1ca8e7dbf850d4.tar.gz
sslutils: use chain from client certificates
sslutils used to load only the first certificate when it was given a client certificate file. Added tests for check_http to connect to a http server that expects a client certificate (simple and with chain). Signed-off-by: Tobias Wiese <tobias@tobiaswiese.com>
-rw-r--r--plugins/sslutils.c2
-rw-r--r--plugins/tests/certs/.gitignore2
-rw-r--r--plugins/tests/certs/client-cert.pem22
-rw-r--r--plugins/tests/certs/client-key.pem28
-rw-r--r--plugins/tests/certs/clientca-cert.pem25
-rw-r--r--plugins/tests/certs/clientca-key.pem28
-rw-r--r--plugins/tests/certs/clientchain-cert.pem45
-rw-r--r--plugins/tests/certs/clientchain-key.pem28
-rw-r--r--plugins/tests/certs/clientintermediate-cert.pem23
-rw-r--r--plugins/tests/certs/clientintermediate-key.pem28
-rw-r--r--plugins/tests/certs/expired-cert.pem32
-rw-r--r--plugins/tests/certs/expired-key.pem52
-rw-r--r--plugins/tests/certs/ext.cnf2
-rwxr-xr-xplugins/tests/certs/generate-certs.sh63
-rw-r--r--plugins/tests/certs/server-cert.pem44
-rw-r--r--plugins/tests/certs/server-key.pem52
-rwxr-xr-xplugins/tests/check_curl.t10
-rwxr-xr-xplugins/tests/check_http.t256
18 files changed, 538 insertions, 204 deletions
diff --git a/plugins/sslutils.c b/plugins/sslutils.c
index 14f6579d..286273f6 100644
--- a/plugins/sslutils.c
+++ b/plugins/sslutils.c
@@ -134,7 +134,7 @@ int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int
134 return STATE_CRITICAL; 134 return STATE_CRITICAL;
135 } 135 }
136 if (cert && privkey) { 136 if (cert && privkey) {
137 SSL_CTX_use_certificate_file(c, cert, SSL_FILETYPE_PEM); 137 SSL_CTX_use_certificate_chain_file(c, cert);
138 SSL_CTX_use_PrivateKey_file(c, privkey, SSL_FILETYPE_PEM); 138 SSL_CTX_use_PrivateKey_file(c, privkey, SSL_FILETYPE_PEM);
139#ifdef USE_OPENSSL 139#ifdef USE_OPENSSL
140 if (!SSL_CTX_check_private_key(c)) { 140 if (!SSL_CTX_check_private_key(c)) {
diff --git a/plugins/tests/certs/.gitignore b/plugins/tests/certs/.gitignore
new file mode 100644
index 00000000..79acaaa5
--- /dev/null
+++ b/plugins/tests/certs/.gitignore
@@ -0,0 +1,2 @@
1/*.csr
2/*.srl
diff --git a/plugins/tests/certs/client-cert.pem b/plugins/tests/certs/client-cert.pem
new file mode 100644
index 00000000..5709750d
--- /dev/null
+++ b/plugins/tests/certs/client-cert.pem
@@ -0,0 +1,22 @@
1-----BEGIN CERTIFICATE-----
2MIIDtDCCApwCAQIwDQYJKoZIhvcNAQELBQAwgaAxCzAJBgNVBAYTAkRFMRAwDgYD
3VQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZNdW5pY2gxGzAZBgNVBAoMEk1vbml0b3Jp
4bmcgUGx1Z2luczEkMCIGA1UEAwwbTW9uaXRvcmluZyBQbHVnaW5zIENsaWVudENB
5MSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5nLXBsdWdpbnMub3JnMB4X
6DTIxMDIyODIxMDIxMloXDTMwMTEyODIxMDIxMlowgZ4xCzAJBgNVBAYTAkRFMRAw
7DgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZNdW5pY2gxGzAZBgNVBAoMEk1vbml0
8b3JpbmcgUGx1Z2luczEiMCAGA1UEAwwZTW9uaXRvcmluZyBQbHVnaW5zIENsaWVu
9dDErMCkGCSqGSIb3DQEJARYcZGV2ZWxAbW9uaXRvcmluZy1wbHVnaW5zLm9yZzCC
10ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM3EiqfFPomm5dZQPGYG5SrF
11rPvyqseXTzCkwUIUzGf+Sfm3s13zx7e3ije/04yKhTXgK59EQ793q7E2aWhSOz3s
12hwKKdylFkOIyc5jgbAfF1/pLZMK209rLt/mMRksXCRXYrHdTjRMx1ev4C2407+8Y
138qkf77DuYQmUqCQe7DPOvqLeagdw9JcLGmQNTKHg3fl6wyRl5K1Bsy+qXu2XvEjZ
140Ng7n8LHjOUkTqUEJndOxci9gL5cHU5ttul/GW34dKOtTuMU/pQX6/ywYusOGVOx
15RYI76OolRqj5BqbNctDIB/obe2RLo+UVx74/0jAxtH4XS23pYjO7NUpJcytsVG8C
16AwEAATANBgkqhkiG9w0BAQsFAAOCAQEAYfaY5n4pCq0NWPCdeVVRr4nr+GAfv1TC
17/PKcGuEoJZKt7TQT+OOA5yeZMZb53OvtA49D1r9aoJzWe946KElWOEBqxDRi5Cdr
18wkqpwGcPT2RfAqA3/cvQZ1XsquboXrCf7ajdl5OC64bs2jkqCFh9gnxuI140g8Ar
19Njol8BFxRPaYWOnwuQwmh/2t0FJqr3WSD85HrNqtxUSNGbTdSsvCfgF0v7QVkvLG
203/cbx6z5hxzj2JUjhMnCvn+EbasoJt4xyBFvg67Q2229SMwu9YNqS63GVoKUqhCB
214Gl5v31qx8dAFKuRvnez3ze/6oohwmakZkst4hcQdgZocHhzesvKlg==
22-----END CERTIFICATE-----
diff --git a/plugins/tests/certs/client-key.pem b/plugins/tests/certs/client-key.pem
new file mode 100644
index 00000000..09b6761d
--- /dev/null
+++ b/plugins/tests/certs/client-key.pem
@@ -0,0 +1,28 @@
1-----BEGIN PRIVATE KEY-----
2MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDNxIqnxT6JpuXW
3UDxmBuUqxaz78qrHl08wpMFCFMxn/kn5t7Nd88e3t4o3v9OMioU14CufREO/d6ux
4NmloUjs97IcCincpRZDiMnOY4GwHxdf6S2TCttPay7f5jEZLFwkV2Kx3U40TMdXr
5+AtuNO/vGPKpH++w7mEJlKgkHuwzzr6i3moHcPSXCxpkDUyh4N35esMkZeStQbMv
6ql7tl7xI2dDYO5/Cx4zlJE6lBCZ3TsXIvYC+XB1Obbbpfxlt+HSjrU7jFP6UF+v8
7sGLrDhlTsUWCO+jqJUao+QamzXLQyAf6G3tkS6PlFce+P9IwMbR+F0tt6WIzuzVK
8SXMrbFRvAgMBAAECggEBALtc2pB3p0E6KpAiEU0pvCRdSO1FgsIpAd+eNadRPur2
9fi+XWQkUwGeGBaJL1npja3aqP65PP40pj7nWfNaUAgOZyznCEU0QXiPJor6yo0vU
10l5v+aKpwRao107i0RRF80TYGTMx+1LeEqnCqNOZN56gERHlBbkTiWpOZvBzf1143
11oegTcyM6+Ee6+FYNhHaDyIYD0md1S2wGR+IBPet6HwWiakLNKahFPa7lOLIKfmmD
12iTtifcbf4724wSe44a0uTeP4JrquZSeIKakm8MEmffmYqpycnaakYefd0Xc5UEsH
13+VbhKpOWGY3d8FKHqUsTa+6QyXb2uFPo6A+yWm0pdJECgYEA7Prd5sbWACvXOcHT
14ONDBAgyfAVDQwOXi3D4dk6D5mg+/jxl5ZQY5slszJrwsLFtoEzXtYpNfTy3cpNOp
15JLbBDZYnqty+5tD8t3/Zv2IBXCAgvuk5CgfJWP5FNAfiyUEE6Vbp6J/5/vAnODsa
16fxZryN5UsH0X8ew7AlbfcVNyj4kCgYEA3khetIgn+GR6sv9jFRdCT6aJbp0xMsms
176F4v3L5FG4Kp+SwDHL1bVOhieJ5g8odYp9hDbgTEEqbJfNmyCOu9+OQmZ/mztku7
186reU8HhYBIvi+hFeJmvqKpdIgU0Zveg4Bst5QordmhPk8AHjBC4xvQ++uh7rwYKd
19WVsS08bGDjcCgYEAlAuNARUKsASzakOqHv5a9VrJIttH7povBYRQmd+gzxwzgcRa
20UEB5XvEWnYZE2lkoRYgVCtYiXqa6BsasDmGVbVV25okNQckhd8mJUMR7MQBpNJsi
21pR+EK/J9bSnYBf52gQdpDYiTdy60ca6KuQZaw5wRsEgV426+1pFK+dM16HECgYBY
22cTsdYb9lmbUoW201CxgbUQwFsw3MQ2pE2pT4o8wjcg3nUpe6a61XT08+5uV0Gl4w
23CmBp+gN52Fr7DjNEUWg5C64sWLIkqmWOspTUSU3cITyiex6W8wEtCRyUNfU0Fp2U
24Nol87HvXvmqtBFMraqXnr8gXjg4H5MxurUoEcWaEaQKBgCT4iIGZwW0Qf2rkFC7B
25xObzVGefivVVbaf8/c/LRO8TMLdnExkShMOmCzHeHV4mMEZDLbMOusHCI7xm10EX
26l3L1I1Kyqnhm1RH3e7TVWgkTmIDW3V5Fgrhm1jx5Iz6et4sb4Uh+bZq9tTLyqfZY
278s0yJUrfpjRggfk7eUs5s7aY
28-----END PRIVATE KEY-----
diff --git a/plugins/tests/certs/clientca-cert.pem b/plugins/tests/certs/clientca-cert.pem
new file mode 100644
index 00000000..9ce7cd7d
--- /dev/null
+++ b/plugins/tests/certs/clientca-cert.pem
@@ -0,0 +1,25 @@
1-----BEGIN CERTIFICATE-----
2MIIEIzCCAwugAwIBAgIUL9Jfp5zv5B29NgDsNEFU2OM/UHswDQYJKoZIhvcNAQEL
3BQAwgaAxCzAJBgNVBAYTAkRFMRAwDgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZN
4dW5pY2gxGzAZBgNVBAoMEk1vbml0b3JpbmcgUGx1Z2luczEkMCIGA1UEAwwbTW9u
5aXRvcmluZyBQbHVnaW5zIENsaWVudENBMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBt
6b25pdG9yaW5nLXBsdWdpbnMub3JnMB4XDTIxMDIyODIxMDIxMVoXDTMwMTEyODIx
7MDIxMVowgaAxCzAJBgNVBAYTAkRFMRAwDgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQH
8DAZNdW5pY2gxGzAZBgNVBAoMEk1vbml0b3JpbmcgUGx1Z2luczEkMCIGA1UEAwwb
9TW9uaXRvcmluZyBQbHVnaW5zIENsaWVudENBMSswKQYJKoZIhvcNAQkBFhxkZXZl
10bEBtb25pdG9yaW5nLXBsdWdpbnMub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
11MIIBCgKCAQEAyxiWsGrsJFHw3VR0pqHviXUfbfKMw8LaCxI5EQZfInsMVkBIGWEW
12tFW6qDuAOsMdzsrKOnQRNNt852ts/0Uz++z8zysoauAGpc4JnCZuM5A1DU5CFXBx
13w6Ax+1ft3UsTt8C6kfLfs8mPCbtNVqAHrMrIqDxsNSRRxQSqkzp1vD8rwSKcbB1h
14u2+lut1bEqMe7dp89jKOtc6G/1tHUFQuLAGFoX/qk9yPscmQNzL6YbLP4m9r/416
15PsxWsAfyY97hmoYo6mSCue5LmeanOsjf4Kzq90hIJRwrpiUGmxGjW+tPLEhQBZw6
16C2wHyN74YIJYX2xREz2ijT0mgsqdhO5ZxwIDAQABo1MwUTAdBgNVHQ4EFgQUtsP9
17Z3fKkhmFp97Kh/cW/UqHMIMwHwYDVR0jBBgwFoAUtsP9Z3fKkhmFp97Kh/cW/UqH
18MIMwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEApO5o+YECwTEv
19s+elDJZQ20UYwDSiU9Lpf4EcdnRv6FAb5UlhfRTH3ZdKCc/HX7kcKuy3PsF+b8Pw
20EusoKito9OlNEOF5HYAI9/J54/qceqn+SC0INsISeE19PvT0dma7lBSj4OvBv0IS
21GYbdztVaKLWqYgYs0mcEzteUc4MZcy1/C+Ru1i1Kp2s9/vIeAw2PV2+kpWtw88Pb
22FRJomGngP/hQdwniayCltG/Q1smS4iFEHNI5ayLZj1qJGMHwzqGiRr4KknJKfHzv
23fl4NQaFyMY31s1FRIS6QVIRFHVzUAlKZTdzwqEJygg3fUS9n9uDBnyDI/sW7DQuj
24yjSmYRS1hw==
25-----END CERTIFICATE-----
diff --git a/plugins/tests/certs/clientca-key.pem b/plugins/tests/certs/clientca-key.pem
new file mode 100644
index 00000000..a939f035
--- /dev/null
+++ b/plugins/tests/certs/clientca-key.pem
@@ -0,0 +1,28 @@
1-----BEGIN PRIVATE KEY-----
2MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDLGJawauwkUfDd
3VHSmoe+JdR9t8ozDwtoLEjkRBl8iewxWQEgZYRa0VbqoO4A6wx3Oyso6dBE023zn
4a2z/RTP77PzPKyhq4AalzgmcJm4zkDUNTkIVcHHDoDH7V+3dSxO3wLqR8t+zyY8J
5u01WoAesysioPGw1JFHFBKqTOnW8PyvBIpxsHWG7b6W63VsSox7t2nz2Mo61zob/
6W0dQVC4sAYWhf+qT3I+xyZA3Mvphss/ib2v/jXo+zFawB/Jj3uGahijqZIK57kuZ
75qc6yN/grOr3SEglHCumJQabEaNb608sSFAFnDoLbAfI3vhgglhfbFETPaKNPSaC
8yp2E7lnHAgMBAAECggEAJqAWiJbNMlsjI/Tb+pTxqYLM52wpuVFlhpWApOxBS517
9SywOikUcvE9RoI0wZfyVvq5yp4tLenID3z9fC21t5Yu8yOm8VhclLINy8G+epc/X
10RyCLEOjBuiLNXq/qXRvaNChDU16NjPPYcFFe9AqbaxFl+BkFu1Wc94tbpYSIv7Qt
11L6iBxUTXdgvLM5doa9AazIQzJx+jUsVCgRVQQf3zsLqtp9hH0Pfq+KWFIy5TA+bG
120NFmYyQndRjtT0ihWGuNU7D8AXa+z7abzk+HydIlx4D//vGgdNq92QYPdnu2BBya
135Fs6LkmkUonX/I8FbkLbRKkQWNPMt+Ks21t3xcVBgQKBgQDn4HuHVCPwxgU6Mv+5
140sHJXYBq1fDzrUt0+iTtYkRqViX+9Mp4sUpYgXext/wXFLcKzQQp5B0g1dLYLSRS
15KwhsdiN0J7ZcoP1GMStw8zsayRTf8C3WRU6aACqyFiylYbyh56XomfYgwhja/7l9
16pzpVJD9ecG+mLVAyAkJtK2JolQKBgQDgOZfvrQj0L4QG+9E5VmFc3PE+6k3g+zDO
17MWqTSh0fOHqdTEyet4bMC4DogXGVsvw0/UKwbrGHOk0+ltA5VyKUtK/whSutr/+S
18nhCHljhV0XUN/I3OFcvezFjM3g0oC4uy1cL30hoM4IfeHM1d3EYse9N1Y/Op+mR6
19Sx+fEku16wKBgQC0KQ7RjuZ95N2a4pUe5En9EtD8MU4Nhs/iC5k1d+yAUn8jIT9P
20lzCUo8NEKheMN2Qg2Dor8jlPkdNIc4qM7TKWUxQo49IlFlCzgPCnydRac3HsrMhw
21e1ke/pIt3FzEArR1d27I0xcRTL3TKm4M2ynPjWJPFj0peHue33KNL/A+IQKBgEpL
22awd0Sxo1wEZcG9gmwf32C01wbzuTn3lCsHB7Ryj4GtCR3nVclCJ50U24zjzu4Fhi
23bj1tgA8xhzSs3fOR5phlQkKsrWtQfJtFGm8CnEn7LBDlVMsrN7Dr/qRrEuro4HHy
24GDbq+8y2fO5glr955BqLMOadprf0imRnDeQ0OLffAoGBAJio+X+xpglgMOC4BeH9
259LcYi9nUEw8MDJNGo9/3e0XKA7spd3HShLDvt8YZhFJ2m168qBpGfezuw0+jpWxy
26PV9q0dokAgDx4pvCzIKaptZ1D30CWXJZHq25VK1tA41PCUIOh8JD5+R0MpxA5rn2
27DbqL4Vq7K7K0imGENYhHdyM+
28-----END PRIVATE KEY-----
diff --git a/plugins/tests/certs/clientchain-cert.pem b/plugins/tests/certs/clientchain-cert.pem
new file mode 100644
index 00000000..acd1e3e8
--- /dev/null
+++ b/plugins/tests/certs/clientchain-cert.pem
@@ -0,0 +1,45 @@
1-----BEGIN CERTIFICATE-----
2MIIDuTCCAqECAQQwDQYJKoZIhvcNAQELBQAwgaAxCzAJBgNVBAYTAkRFMRAwDgYD
3VQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZNdW5pY2gxGzAZBgNVBAoMEk1vbml0b3Jp
4bmcgUGx1Z2luczEkMCIGA1UEAwwbTW9uaXRvcmluZyBQbHVnaW5zIENsaWVudENB
5MSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5nLXBsdWdpbnMub3JnMB4X
6DTIxMDIyODIxMDIxMloXDTMwMTEyODIxMDIxMlowgaMxCzAJBgNVBAYTAkRFMRAw
7DgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZNdW5pY2gxGzAZBgNVBAoMEk1vbml0
8b3JpbmcgUGx1Z2luczEnMCUGA1UEAwweTW9uaXRvcmluZyBQbHVnaW5zIENsaWVu
9dENoYWluMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5nLXBsdWdpbnMu
10b3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAphvoJBbi/rDvm3+X
118xok0sLCJvCRuUpSbU5wEmREQlkoOGmWK4l6r1JyOphKRBo8+n2MxPiCMvAmTrqx
12VlBmkcmyrwWj392Nga+2SLWTziASk5nFrrhV6U79PkgXnETV2Wk1/FNVIFkB8N+B
13undsTce8LLiCs7hfA5CK7ctJg8fqsAsmgKBNGzBRWwkbvxZPd6xlY6foIJeD7PQ2
14elvTmrD6WXSZq7GshFpDEkL3AifqrPMdsTnbBpyGgJ/fBM1b2dx9k53e25mgEQmn
15iSuYQxn08BsUT0FOvav8ksZLBQz859fuqCtwhikpODO635fD9zK5YkBPlVl+/5xo
16SvKOywIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBh4zeSKjENfY+VDLtPssaNQz2a
17R1ioY40lZ0WoihDSrfG32dqTK/R2YsLKBABjJ7uRYS1NIBMrtS2OktK8BWD5IUTF
18FuGuWilu6IWiTKZrLiZh1rsilNDVqwhorRPxDnbF+qVt9EMIvzKnKdJLGF+CWHN9
19yYJDeTD8MK5uR7zUJR3PsgW4ve5pFTi7z2UJ/xRvgOds6bmeeQnvaWDEL7k2+hrr
200G899A086NL3htzaOnIllg0xo2D1o4ToncAJn+cUQVJmHZSg9HYiD4Lg3z8uXPAl
21rt/MX7dBm4dnImLXbSg7N3e8FdUtz+kZT9z+beKAeIe9JTbpxtsVUTzUZBBA
22-----END CERTIFICATE-----
23-----BEGIN CERTIFICATE-----
24MIID2jCCAsKgAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBoDELMAkGA1UEBhMCREUx
25EDAOBgNVBAgMB0JhdmFyaWExDzANBgNVBAcMBk11bmljaDEbMBkGA1UECgwSTW9u
26aXRvcmluZyBQbHVnaW5zMSQwIgYDVQQDDBtNb25pdG9yaW5nIFBsdWdpbnMgQ2xp
27ZW50Q0ExKzApBgkqhkiG9w0BCQEWHGRldmVsQG1vbml0b3JpbmctcGx1Z2lucy5v
28cmcwHhcNMjEwMjI4MjEwMjEyWhcNMzAxMTI4MjEwMjEyWjCBqjELMAkGA1UEBhMC
29REUxEDAOBgNVBAgMB0JhdmFyaWExDzANBgNVBAcMBk11bmljaDEbMBkGA1UECgwS
30TW9uaXRvcmluZyBQbHVnaW5zMS4wLAYDVQQDDCVNb25pdG9yaW5nIFBsdWdpbnMg
31Q2xpZW50SW50ZXJtZWRpYXRlMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9y
32aW5nLXBsdWdpbnMub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
336rUgOZ9pAOxrcgeeOT3Vmu1YmY2O/C9tXhpKzDzjTaWUzcdDg00KdsjXfgbDzSiV
34uvMzjX63aKpmqeFG+05D2VzQGit3knqerUgl10FnTotiJGF5CU5/gY1aPxTJ7rj2
35tD6LINBkJcPTyQ4MoJT19pssvCax9erY1RxoXxLblJ+31C+VvrftdmBP4nVKXK26
364anb1oUQhkgpXpJimJBmF+v7NbDs1Wh21Be80KXUh9SKgePhSQblr2QlRcA7jLgJ
374PMjZ+KYF+da+4RB7s+DvTXVDMn9AL84E1w5Ut1E8XZV+u4RjWPvNdhK/7GnuxOR
38C9SdxonqkPQ8hiI7thP9bQIDAQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
39SIb3DQEBCwUAA4IBAQDKQeiDbyr0/7sEhX33MmTDv84GeWgKl9qqHecx+d/0vImb
40c8XHK0PDa4lVqo/BW4P1hjKzpt2DW35kbOhuqGqM0lasIczef43aCDDEBLwstAe6
41qMoyWGVGoAQbpwT3li2pMrsIYoPwMvoSGNUphjrkdpviff2POkLly7a5RrR1X3qt
42Dai6eYbeMCr9NdgW7AZ5++/sKlFoe+zVk/Ed31s4D2lh3awrApZhVgcoquPmEwpt
43gm+OgRmHw50U4SF3ZaJPwDyLMbx+clH/bgUg0+Za9e53Br1NtGKmw7hh/7CG/hy0
44yxeLd930pH4vZu7s0XM56N/ckkfUzRkAH8dSmhH4
45-----END CERTIFICATE-----
diff --git a/plugins/tests/certs/clientchain-key.pem b/plugins/tests/certs/clientchain-key.pem
new file mode 100644
index 00000000..0263604f
--- /dev/null
+++ b/plugins/tests/certs/clientchain-key.pem
@@ -0,0 +1,28 @@
1-----BEGIN PRIVATE KEY-----
2MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCmG+gkFuL+sO+b
3f5fzGiTSwsIm8JG5SlJtTnASZERCWSg4aZYriXqvUnI6mEpEGjz6fYzE+IIy8CZO
4urFWUGaRybKvBaPf3Y2Br7ZItZPOIBKTmcWuuFXpTv0+SBecRNXZaTX8U1UgWQHw
534G6d2xNx7wsuIKzuF8DkIrty0mDx+qwCyaAoE0bMFFbCRu/Fk93rGVjp+ggl4Ps
69DZ6W9OasPpZdJmrsayEWkMSQvcCJ+qs8x2xOdsGnIaAn98EzVvZ3H2Tnd7bmaAR
7CaeJK5hDGfTwGxRPQU69q/ySxksFDPzn1+6oK3CGKSk4M7rfl8P3MrliQE+VWX7/
8nGhK8o7LAgMBAAECggEAAfTqMyKh4eYrrGVAYPi53lG0/8htrwUVG3yFDXJo628p
9biCwSCsCavZJqi8JEOxOM5UvB1L2FauGh/7i/+VKkAUUOcOTPpvZguGTACBDcXYn
10Qd3Z2kkJmgn4Kbenr4uQCVOX8zT4F710rGW1nYCyoefsa4pw37UYSW52dH6kiwzW
119k4X251nDMl/twBdOcjZbL768IEa5l4nySLpUNwfrVbSb1NzBoH0dVioh3DTLjt6
12gaShW4eIpaKczht1U97n6/7WNLl6vHX/mR99k/py8OhzhR1ccYpd2IfSHAWyQT0M
13K8BoNnkjICrr9oc0FCr2BVJa3IzKHlhukF4GTZiGYQKBgQDWCHTwAmwL4FFEBVhj
14pZne/sjaZc8TzPPxA8SkmxwDIZrM7tSu7qUuYgWTM432jZbLILWTyGfXf2PpqyF6
15wOpoBJj1ETkre8ZfRmYvsSvS5vtjF3Drszol+XvZnOclfB5VG3m5P2vYkQ8wI9OE
16Y5jUBgDj0RsCNd8QnrC1u54U/wKBgQDGrd5y8S9kUT0P0lkZit7bYjSPJExtClXt
17V7YNTjELrVCdc0jranxBWaub8NP3e6TGTi9HiQWvk2eOAS2qyccqlK4+YAK5XO3D
18EpFUNNcClq8CErw2POuCAKajrPuSp6vd6q8h4lTzDExVctQS4R9fRKKFBKkPUV5G
19UiKFllnKNQKBgQDBGIQXfLfpxwjKK2BhFihKDOc8UhmOrZtvV4zzTJTrJkg4l0f+
20QoN34ytQcHSleXwP6oSmvWkh/GYxjBj6XE2eZndwsYc4ecSwdB0A7gCxl345Gg7g
21NqRBWmGoJGxNXzsmYVFiFZvAmK5xKgFMMWbR8lCfOCn7xopmviSC8K9gFQKBgFRb
22KmH/SbH8VELNews/TVQ0pEBKlzCM/OLjJOcNVgGxOtM/Say677sHibeST0168AFK
233QQwh3t+yK8gjPVA6xGHQ1w0g7OUY1c6IP5x2QC+XdwxfDxDLXNrN1WzcrVX/78f
24j/CBGrR/ekGlmanSb/GRQLfdvLJGSBLveLzjk4gpAoGBANN9RUm/aRz3dDBWex46
25kJ15xKJfLZiUeyDvY5+5d7YF4/tw5LU4XmKQNhiojHecykrTzPUMaGyMrbMPNn32
26WFW9CKMjuBEwWpMDJJb1/5NLEvpwu++sr7bUPZkQl76ot6OqgNHodbP8ATqrNr80
275b8FrEN1LyfkTbabxNyAWcA0
28-----END PRIVATE KEY-----
diff --git a/plugins/tests/certs/clientintermediate-cert.pem b/plugins/tests/certs/clientintermediate-cert.pem
new file mode 100644
index 00000000..608a8fa2
--- /dev/null
+++ b/plugins/tests/certs/clientintermediate-cert.pem
@@ -0,0 +1,23 @@
1-----BEGIN CERTIFICATE-----
2MIID2jCCAsKgAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBoDELMAkGA1UEBhMCREUx
3EDAOBgNVBAgMB0JhdmFyaWExDzANBgNVBAcMBk11bmljaDEbMBkGA1UECgwSTW9u
4aXRvcmluZyBQbHVnaW5zMSQwIgYDVQQDDBtNb25pdG9yaW5nIFBsdWdpbnMgQ2xp
5ZW50Q0ExKzApBgkqhkiG9w0BCQEWHGRldmVsQG1vbml0b3JpbmctcGx1Z2lucy5v
6cmcwHhcNMjEwMjI4MjEwMjEyWhcNMzAxMTI4MjEwMjEyWjCBqjELMAkGA1UEBhMC
7REUxEDAOBgNVBAgMB0JhdmFyaWExDzANBgNVBAcMBk11bmljaDEbMBkGA1UECgwS
8TW9uaXRvcmluZyBQbHVnaW5zMS4wLAYDVQQDDCVNb25pdG9yaW5nIFBsdWdpbnMg
9Q2xpZW50SW50ZXJtZWRpYXRlMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9y
10aW5nLXBsdWdpbnMub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
116rUgOZ9pAOxrcgeeOT3Vmu1YmY2O/C9tXhpKzDzjTaWUzcdDg00KdsjXfgbDzSiV
12uvMzjX63aKpmqeFG+05D2VzQGit3knqerUgl10FnTotiJGF5CU5/gY1aPxTJ7rj2
13tD6LINBkJcPTyQ4MoJT19pssvCax9erY1RxoXxLblJ+31C+VvrftdmBP4nVKXK26
144anb1oUQhkgpXpJimJBmF+v7NbDs1Wh21Be80KXUh9SKgePhSQblr2QlRcA7jLgJ
154PMjZ+KYF+da+4RB7s+DvTXVDMn9AL84E1w5Ut1E8XZV+u4RjWPvNdhK/7GnuxOR
16C9SdxonqkPQ8hiI7thP9bQIDAQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
17SIb3DQEBCwUAA4IBAQDKQeiDbyr0/7sEhX33MmTDv84GeWgKl9qqHecx+d/0vImb
18c8XHK0PDa4lVqo/BW4P1hjKzpt2DW35kbOhuqGqM0lasIczef43aCDDEBLwstAe6
19qMoyWGVGoAQbpwT3li2pMrsIYoPwMvoSGNUphjrkdpviff2POkLly7a5RrR1X3qt
20Dai6eYbeMCr9NdgW7AZ5++/sKlFoe+zVk/Ed31s4D2lh3awrApZhVgcoquPmEwpt
21gm+OgRmHw50U4SF3ZaJPwDyLMbx+clH/bgUg0+Za9e53Br1NtGKmw7hh/7CG/hy0
22yxeLd930pH4vZu7s0XM56N/ckkfUzRkAH8dSmhH4
23-----END CERTIFICATE-----
diff --git a/plugins/tests/certs/clientintermediate-key.pem b/plugins/tests/certs/clientintermediate-key.pem
new file mode 100644
index 00000000..13f68874
--- /dev/null
+++ b/plugins/tests/certs/clientintermediate-key.pem
@@ -0,0 +1,28 @@
1-----BEGIN PRIVATE KEY-----
2MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDqtSA5n2kA7Gty
3B545PdWa7ViZjY78L21eGkrMPONNpZTNx0ODTQp2yNd+BsPNKJW68zONfrdoqmap
44Ub7TkPZXNAaK3eSep6tSCXXQWdOi2IkYXkJTn+BjVo/FMnuuPa0Posg0GQlw9PJ
5DgyglPX2myy8JrH16tjVHGhfEtuUn7fUL5W+t+12YE/idUpcrbrhqdvWhRCGSCle
6kmKYkGYX6/s1sOzVaHbUF7zQpdSH1IqB4+FJBuWvZCVFwDuMuAng8yNn4pgX51r7
7hEHuz4O9NdUMyf0AvzgTXDlS3UTxdlX67hGNY+812Er/sae7E5EL1J3GieqQ9DyG
8Iju2E/1tAgMBAAECggEACyYJXtNUoIeaXvM/r8ZhJBfMEpcnyJDUKBklnmfyABky
9ZUfmzBDXw2as3b6ihFc+LYAp3bm8KouVjtI1lfBUxrli5StVZa7PZLm9mmjv6Eo0
10ojfDEQ8afWPieoaZRO6iQVOLNkbPyv9vSuiQ7vvEZy9dw54u69h47j6IMqPprDiG
11ropUNeGAvTnh1Vf9/8aCHEvHUNHcc4zjzGiQ+E60JgnbpGVeJKoeiMgrQE0yjweo
12KyKA47Y6vqP6+AxAaPplXtmrx2UCbMjktHNvLvg42+2UlLS5roiwmJYEN9c6iT6t
13y82MJrjEFGZyLG2u6ZQANSJiIWaCnOyT1o2deJ8NoQKBgQD7UxivDTuljQD0so+E
14JX9UaFZ9PgS+8LC9v56PciL4XQ7bcCVP5vVgZZPABiQ9i989Wq7qI042Jrfu5qtE
15SthlOAu80GvAQV+Oujwo7ZzM6ciQtjMsj63r2uayWXnmQ07QcIg7x7y161Pt9Bqr
16LIDrqHziIj/lzT7+6QKZaQwFaQKBgQDvEuSC14CBlMhy2jji71kB/3Ya3c+8dP+A
17kQZL9wEWK4a4dm8IaTS8jl1/luhQUzFRMyh2rWaTqqigSe3dvs5DRblhE5NPwTSI
189TO7t1EnzjW3R8LxZZsySyiSFnZ/8mR0empxq0Mov37OdXBj0tXuuzREf/hwijWh
19WuLxJUSjZQKBgAIDZ2Y3l+u6lnBfYdDwL/XwJAk6zvTsnq3WdCG4C1mr/St62YGr
20WvnbtnRKWE356d7m9BHCGKVMaBrM1EBmzRb6fPWVQde3blmJWmQFi0UE9mtaWkyY
21Fg+WoFR7bQOQNHhs/lpkPjnC2dhFJVWLtLiuj9mL5rEjlMab/T5XXhZJAoGBAMEP
22FZ8fXbPGrTQqSwPfWpZFcF9zvbynEmkFM/uGRMddcNZnNXSqWJ7nrFNLTuEGvW2g
23DU4A6zPV/YQrDz4hRjmHBZOCFlSyZbUvpY4yFAQ7/p66AY+kiHZNwT5vi1P5Luvs
24qyaNsZcnRMR+i7rg2EeHv0aNvNdMlNBvL5KikNINAoGAU2P/phdwJOUcqgHavQcQ
25ureTEyZ5i5AeNomNeHSj0slG24V9nxOqEL7D00JKln7oAPovYBUWocEnF39uBJe0
26p0Hy7fCCK6EI8/0QyiQuuZmJfDEEvjQqE6irONNH63r2UwDEpDNGFvGsZNuWHLZc
27SXADu5oSNu6o6IydiyOx528=
28-----END PRIVATE KEY-----
diff --git a/plugins/tests/certs/expired-cert.pem b/plugins/tests/certs/expired-cert.pem
index 77a9166e..87fc8e47 100644
--- a/plugins/tests/certs/expired-cert.pem
+++ b/plugins/tests/certs/expired-cert.pem
@@ -1,24 +1,24 @@
1-----BEGIN CERTIFICATE----- 1-----BEGIN CERTIFICATE-----
2MIIEETCCAvmgAwIBAgIUFDsP6WnV/uqeQMpD/DYSqouE13kwDQYJKoZIhvcNAQEL 2MIIEETCCAvmgAwIBAgIUVDKkhcUoYFnjYCw12tScPIqQzqIwDQYJKoZIhvcNAQEL
3BQAwgZcxCzAJBgNVBAYTAkRFMRAwDgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZN 3BQAwgZcxCzAJBgNVBAYTAkRFMRAwDgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZN
4dW5pY2gxGzAZBgNVBAoMEk1vbml0b3JpbmcgUGx1Z2luczEbMBkGA1UEAwwSTW9u 4dW5pY2gxGzAZBgNVBAoMEk1vbml0b3JpbmcgUGx1Z2luczEbMBkGA1UEAwwSTW9u
5aXRvcmluZyBQbHVnaW5zMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5n 5aXRvcmluZyBQbHVnaW5zMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5n
6LXBsdWdpbnMub3JnMB4XDTA4MDEwMTExMDAyNloXDTA4MDEwMjExMDAyNlowgZcx 6LXBsdWdpbnMub3JnMB4XDTA4MDEwMTEyMDAwMFoXDTA4MDEwMjEyMDAwMFowgZcx
7CzAJBgNVBAYTAkRFMRAwDgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZNdW5pY2gx 7CzAJBgNVBAYTAkRFMRAwDgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZNdW5pY2gx
8GzAZBgNVBAoMEk1vbml0b3JpbmcgUGx1Z2luczEbMBkGA1UEAwwSTW9uaXRvcmlu 8GzAZBgNVBAoMEk1vbml0b3JpbmcgUGx1Z2luczEbMBkGA1UEAwwSTW9uaXRvcmlu
9ZyBQbHVnaW5zMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5nLXBsdWdp 9ZyBQbHVnaW5zMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5nLXBsdWdp
10bnMub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyeHKwKFjJWUX 10bnMub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwg1dmGT3rVqM
11YHKsisypUf9dHlIPQAISyGP1BX6UL26ZLvE6kKbx3LFQ9W2POGoQWlzFiB1soGeV 11beVWWLy8EAiq9re07AF8sTERy9oIYF5EUq9f0xO53mwwqIWV77O9mF99/kDFGQuQ
12WDd0U0JtWdCKmOXWdcXpupQlTSUtRCMDQkfqLN8GR5TBTd73rezp5mz08nMfLwu0 12NOnICMSHXNtMXEXzfBaMighw0uyCh1o/VCejNQ5x/HU8aLh930g5DIcOJQ3fZ4v9
13p5VQ191Ui8JHFgrAOalAn8Uw5De8vj4VmTXmU5NJ2UFoC0ddU/Th/lwRCayHc1cn 138kBaie7+aPgRMVDM1vIrILfedq9Kt56zvPizkXhDeqxjKyIZdrdoBlX5zAfftWtY
14MVq2F7c/uhMUUQYNBmJy0pxoHawp+j9NKl/xIYsjgQNgahQyNuswuGHjaEwhPu+7 14HpQ+lkThSSXqQnchN6S2JFejmRtsNnceDVOBBdvlzmH0NlfwjynLK3/EJooTsINy
15G03XsW4ehu+H1898M/MkSln6LQAU1syoJ8ypPM8tV+zgx4uwj7udnZ2hceN95uW7 15i9dXD8/Oe8r+UA+nokWvnWC2IAUJjpxW+XAyTG/NofGwX+PwquT0YD5cSlODIwZA
160PWg5DQyUwIDAQABo1MwUTAdBgNVHQ4EFgQUt9ps3KJ1XiMuy/ijFBjMzf6jgwkw 16WAimygWLqQIDAQABo1MwUTAdBgNVHQ4EFgQUsKyJAwR9OXWEcSZMQz73GfpxCJIw
17HwYDVR0jBBgwFoAUt9ps3KJ1XiMuy/ijFBjMzf6jgwkwDwYDVR0TAQH/BAUwAwEB 17HwYDVR0jBBgwFoAUsKyJAwR9OXWEcSZMQz73GfpxCJIwDwYDVR0TAQH/BAUwAwEB
18/zANBgkqhkiG9w0BAQsFAAOCAQEAVPBZwMHbrnHFbmhbcPuvYd5cxk0uSVNAUzsl 18/zANBgkqhkiG9w0BAQsFAAOCAQEAYKFGX7J3Fc/T9s278w61E2dSsY4DS/mjSDik
192biCq5P+ZHo10VHGygXtdV4utqk/IrAt2u5qSxycWPStCtAgTd3Q8ncfjOkaHM4z 19fMWvod6eKw0fE3wJOnkWxjEH3VywTY6CmHd/oiJOaD8lr/Vk+BJfYNVBaVNmguyg
202bxTkhLyQeU8NWPuDBqDszo2GOaFTv+lm36LEKiAfqB1tjQVePSkycdrWIhkamBV 204LXoWz9Benx0bAIeuDbNAhOvA4H4aIz8UrD9lKFvKdRp42gPMLtMEbzbLcBdT95D
21EgMe6uHLdU7QQk1ajQfrBdakN1beqki/dKieA6gm+XF/QS4SSYINmsHB/2X5cT9U 216BX7EhYm7vTnpitLPgFxVCsJ1JFqv2AQfUm+IkqQkezPs5x0tWLyrvCDNRGJ0kfv
22b/KMB8xurCnuJQuk1P4VsSkJCOSeHjWZgK9pKNdsIJZr4wDVfhjQgU0XT6xakSf7 22UuowpUZXDOh3k1vB+xaSOFviieLaCW8TSdd5FZgI2HQj4e6vCKsMGuKKZXrMUTI/
23eCaHtO0VKsbLZoiTmpxidjsdYiXyeKYIQNtUpTjyJ5V/cZsq9w== 23qtrFlUfsOuwourfC5LMHtCyYo5B3uvAWT1eTXxhrGqyleSlxJQ==
24-----END CERTIFICATE----- 24-----END CERTIFICATE-----
diff --git a/plugins/tests/certs/expired-key.pem b/plugins/tests/certs/expired-key.pem
index c1510b2d..c5bba569 100644
--- a/plugins/tests/certs/expired-key.pem
+++ b/plugins/tests/certs/expired-key.pem
@@ -1,28 +1,28 @@
1-----BEGIN PRIVATE KEY----- 1-----BEGIN PRIVATE KEY-----
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
27xH3OV8KV4UiTEVxS7ksmGzY= 27pm5Btrq/NZqtVXovS+UhGLvJ
28-----END PRIVATE KEY----- 28-----END PRIVATE KEY-----
diff --git a/plugins/tests/certs/ext.cnf b/plugins/tests/certs/ext.cnf
new file mode 100644
index 00000000..d09cee13
--- /dev/null
+++ b/plugins/tests/certs/ext.cnf
@@ -0,0 +1,2 @@
1[ client_ca ]
2basicConstraints = critical, CA:true
diff --git a/plugins/tests/certs/generate-certs.sh b/plugins/tests/certs/generate-certs.sh
new file mode 100755
index 00000000..78660a26
--- /dev/null
+++ b/plugins/tests/certs/generate-certs.sh
@@ -0,0 +1,63 @@
1#!/bin/sh -e
2#
3# Recreates the https server certificates
4#
5# Set the GEN_EXPIRED environment variable to also regenerate
6# the expired certificate.
7
8cd "$(dirname "$0")"
9trap 'rm -f *.csr; rm -f clientca-cert.srl' EXIT
10
11subj() {
12 c="DE"
13 st="Bavaria"
14 l="Munich"
15 o="Monitoring Plugins"
16 cn="Monitoring Plugins"
17 emailAddress="devel@monitoring-plugins.org"
18
19 if [ -n "$1" ]; then
20 # Add to CN
21 cn="$cn $1"
22 fi
23
24 printf "/C=%s/ST=%s/L=%s/O=%s/CN=%s/emailAddress=%s" \
25 "$c" "$st" "$l" "$o" "$cn" "$emailAddress"
26}
27
28# server
29openssl req -new -x509 -days 3560 -nodes \
30 -keyout server-key.pem -out server-cert.pem \
31 -subj "$(subj)"
32# server, expired
33# there is generally no need to regenerate this, as it will stay epxired
34[ -n "$GEN_EXPIRED" ] && TZ=UTC faketime -f '2008-01-01 12:00:00' \
35 openssl req -new -x509 -days 1 -nodes \
36 -keyout expired-key.pem -out expired-cert.pem \
37 -subj "$(subj)"
38
39# client, ca
40openssl req -new -x509 -days 3560 -nodes \
41 -keyout clientca-key.pem -out clientca-cert.pem \
42 -subj "$(subj ClientCA)"
43echo "01" >clientca-cert.srl
44# client
45openssl req -new -nodes \
46 -keyout client-key.pem -out client-cert.csr \
47 -subj "$(subj Client)"
48openssl x509 -days 3560 -req -CA clientca-cert.pem -CAkey clientca-key.pem \
49 -in client-cert.csr -out client-cert.pem
50# client, intermediate
51openssl req -new -nodes \
52 -keyout clientintermediate-key.pem -out clientintermediate-cert.csr \
53 -subj "$(subj ClientIntermediate)"
54openssl x509 -days 3560 -req -CA clientca-cert.pem -CAkey clientca-key.pem \
55 -extfile ext.cnf -extensions client_ca \
56 -in clientintermediate-cert.csr -out clientintermediate-cert.pem
57# client, chain
58openssl req -new -nodes \
59 -keyout clientchain-key.pem -out clientchain-cert.csr \
60 -subj "$(subj ClientChain)"
61openssl x509 -days 3560 -req -CA clientca-cert.pem -CAkey clientca-key.pem \
62 -in clientchain-cert.csr -out clientchain-cert.pem
63cat clientintermediate-cert.pem >>clientchain-cert.pem
diff --git a/plugins/tests/certs/server-cert.pem b/plugins/tests/certs/server-cert.pem
index b84b91d2..d1249ef1 100644
--- a/plugins/tests/certs/server-cert.pem
+++ b/plugins/tests/certs/server-cert.pem
@@ -1,24 +1,24 @@
1-----BEGIN CERTIFICATE----- 1-----BEGIN CERTIFICATE-----
2MIIEBjCCAu6gAwIBAgIJANbQ5QQrKhUGMA0GCSqGSIb3DQEBCwUAMIGXMQswCQYD 2MIIEETCCAvmgAwIBAgIUZwOhY4myaCUaPek3NM+MxbLG9vwwDQYJKoZIhvcNAQEL
3VQQGEwJERTEQMA4GA1UECAwHQmF2YXJpYTEPMA0GA1UEBwwGTXVuaWNoMRswGQYD 3BQAwgZcxCzAJBgNVBAYTAkRFMRAwDgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZN
4VQQKDBJNb25pdG9yaW5nIFBsdWdpbnMxGzAZBgNVBAMMEk1vbml0b3JpbmcgUGx1 4dW5pY2gxGzAZBgNVBAoMEk1vbml0b3JpbmcgUGx1Z2luczEbMBkGA1UEAwwSTW9u
5Z2luczErMCkGCSqGSIb3DQEJARYcZGV2ZWxAbW9uaXRvcmluZy1wbHVnaW5zLm9y 5aXRvcmluZyBQbHVnaW5zMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5n
6ZzAeFw0xOTAyMTkxNTMxNDRaFw0yOTAyMTYxNTMxNDRaMIGXMQswCQYDVQQGEwJE 6LXBsdWdpbnMub3JnMB4XDTIxMDIyODIxMDIxMVoXDTMwMTEyODIxMDIxMVowgZcx
7RTEQMA4GA1UECAwHQmF2YXJpYTEPMA0GA1UEBwwGTXVuaWNoMRswGQYDVQQKDBJN 7CzAJBgNVBAYTAkRFMRAwDgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZNdW5pY2gx
8b25pdG9yaW5nIFBsdWdpbnMxGzAZBgNVBAMMEk1vbml0b3JpbmcgUGx1Z2luczEr 8GzAZBgNVBAoMEk1vbml0b3JpbmcgUGx1Z2luczEbMBkGA1UEAwwSTW9uaXRvcmlu
9MCkGCSqGSIb3DQEJARYcZGV2ZWxAbW9uaXRvcmluZy1wbHVnaW5zLm9yZzCCASIw 9ZyBQbHVnaW5zMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5nLXBsdWdp
10DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKgV2yp8pQvJuN+aJGdAe6Hd0tja 10bnMub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2/3eBA4WG6xz
11uteCPcNIcM92WLOF69TLTSYon1XDon4tHTh4Z5d4lD8bfsGzFVBmDSgWidhAUf+v 11LfM6xcWywxThb1Rp7XAW3ewQd9/PdoWXEe8BJWlLfyYi1drLMcsDywhLkKmW4Vp9
12EqEXwbp293ej/Frc0pXCvmrz6kI1tWrLtQhL/VdbxFYxhV7JjKb+PY3SxGFpSLPe 121R4PAkiljjrB/ZaUMDLJ1ri3dwX4RvXG7crsU3QWFWCBOrf5V2FTRQ2m/H/KyB/6
13PQ/5SwVndv7rZIwcjseL22K5Uy2TIrkgzzm2pRs/IvoxRybYr/+LGoHyrtJC6AO8 13rVZANsU47HqTFSPiUm2j7P3wx/wtHeYC+qmNG7zZTjAYPYxfKiod0lytTSmb+h54
14ylp8A/etL0gwtUvRnrnZeTQ2pA1uZ5QN3anTL8JP/ZRZYNegIkaawqMtTKbhM6pi 146lxn3+VPEXZAQZlLvPnm/58JnXGrUv7B2yocf5MhKkLJOrGxH2hfwKISfaj2gpOV
15u3/4a3Uppvt0y7vmGfQlYejxCpICnMrvHMpw8L58zv/98AbCGjDU3UwCt6MCAwEA 15m4PUVYiDzCSpq1fPvwbUxIvdO27xprx+mrGOFM6f2UCEOc35w8FSmYiR2yQTnEJK
16AaNTMFEwHQYDVR0OBBYEFG/UH6nGYPlVcM75UXzXBF5GZyrcMB8GA1UdIwQYMBaA 16pbSQD6t1jQIDAQABo1MwUTAdBgNVHQ4EFgQUMeYgglT2aWDlF8KEeF2376AlTGYw
17FG/UH6nGYPlVcM75UXzXBF5GZyrcMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN 17HwYDVR0jBBgwFoAUMeYgglT2aWDlF8KEeF2376AlTGYwDwYDVR0TAQH/BAUwAwEB
18AQELBQADggEBAGwitJPOnlIKLndNf+iCLMIs0dxsl8kAaejFcjoT0n4ja7Y6Zrqz 18/zANBgkqhkiG9w0BAQsFAAOCAQEAFcEg83rTJdgkp7JLYqK0j8JogSHNlDYchr/r
19VSIidzz9vQWvy24xKJpAOdj/iLRHCUOG+Pf5fA6+/FiuqXr6gE2/lm0eC58BNONr 19VxKBgQwfnjSp5A8d5+uTQ9s3QDabw8v7YeSrzYXbbjuWZ61mnl84tzOQ8LMeESnC
20E5OzjQ/VoQ8RX4hDntgu6FYbaVa/vhwn16igt9qmdNGGZXf2/+DM3JADwyaA4EK8 20CBXRCxB8Ow22WsVTVJq279SGYT+cZrdsmqGVWDi1A0C5kH+XTLAioG5CZmmxemD/
21vm7KdofX9zkxXecHPNvf3jiVLPiDDt6tkGpHPEsyP/yc+RUdltUeZvHfliV0cCuC 21S92ZoRxGyYfg33r+3X6EMcEYtHKGxCUa3EPcPOL4dq2F3nOnyjiWPZm3786H3NY2
22jJX+Fm9ysjSpHIFFr+jUMuMHibWoOD8iy3eYxfCDoWsH488pCbj8MNuAq6vd6DBk 22nsYwrEhAdUFtbYSsV5O0c/Zlc33fmTfh654ab35io1DtwmFo7q8J532dUE007EN0
23bOZxDz43vjWuYMkwXJTxJQh7Pne6kK0vE1g= 23mIQmhdrjNJJHIftgSt0fuN5m48oLOnX7vvkz+X0WLWfVTtMr0w==
24-----END CERTIFICATE----- 24-----END CERTIFICATE-----
diff --git a/plugins/tests/certs/server-key.pem b/plugins/tests/certs/server-key.pem
index 11947555..0de63f8f 100644
--- a/plugins/tests/certs/server-key.pem
+++ b/plugins/tests/certs/server-key.pem
@@ -1,28 +1,28 @@
1-----BEGIN PRIVATE KEY----- 1-----BEGIN PRIVATE KEY-----
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
27N0wdmCAqlQwHR13+F1zrAD7V 27nYGB5/QXYr5WGV9YhAkRsFJYgA==
28-----END PRIVATE KEY----- 28-----END PRIVATE KEY-----
diff --git a/plugins/tests/check_curl.t b/plugins/tests/check_curl.t
index 29cb03f2..aa72ef67 100755
--- a/plugins/tests/check_curl.t
+++ b/plugins/tests/check_curl.t
@@ -228,23 +228,25 @@ SKIP: {
228 skip "HTTP::Daemon::SSL not installed", $common_tests + $ssl_only_tests if ! exists $servers->{https}; 228 skip "HTTP::Daemon::SSL not installed", $common_tests + $ssl_only_tests if ! exists $servers->{https};
229 run_common_tests( { command => "$command -p $port_https", ssl => 1 } ); 229 run_common_tests( { command => "$command -p $port_https", ssl => 1 } );
230 230
231 my $expiry = "Thu Nov 28 21:02:11 2030 +0000";
232
231 $result = NPTest->testCmd( "$command -p $port_https -S -C 14" ); 233 $result = NPTest->testCmd( "$command -p $port_https -S -C 14" );
232 is( $result->return_code, 0, "$command -p $port_https -S -C 14" ); 234 is( $result->return_code, 0, "$command -p $port_https -S -C 14" );
233 is( $result->output, "OK - Certificate 'Monitoring Plugins' will expire on Fri Feb 16 15:31:44 2029 +0000.", "output ok" ); 235 is( $result->output, "OK - Certificate 'Monitoring Plugins' will expire on $expiry.", "output ok" );
234 236
235 $result = NPTest->testCmd( "$command -p $port_https -S -C 14000" ); 237 $result = NPTest->testCmd( "$command -p $port_https -S -C 14000" );
236 is( $result->return_code, 1, "$command -p $port_https -S -C 14000" ); 238 is( $result->return_code, 1, "$command -p $port_https -S -C 14000" );
237 like( $result->output, '/WARNING - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(Fri Feb 16 15:31:44 2029 \+0000\)./', "output ok" ); 239 like( $result->output, '/WARNING - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(' . quotemeta($expiry) . '\)./', "output ok" );
238 240
239 # Expired cert tests 241 # Expired cert tests
240 $result = NPTest->testCmd( "$command -p $port_https -S -C 13960,14000" ); 242 $result = NPTest->testCmd( "$command -p $port_https -S -C 13960,14000" );
241 is( $result->return_code, 2, "$command -p $port_https -S -C 13960,14000" ); 243 is( $result->return_code, 2, "$command -p $port_https -S -C 13960,14000" );
242 like( $result->output, '/CRITICAL - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(Fri Feb 16 15:31:44 2029 \+0000\)./', "output ok" ); 244 like( $result->output, '/CRITICAL - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(' . quotemeta($expiry) . '\)./', "output ok" );
243 245
244 $result = NPTest->testCmd( "$command -p $port_https_expired -S -C 7" ); 246 $result = NPTest->testCmd( "$command -p $port_https_expired -S -C 7" );
245 is( $result->return_code, 2, "$command -p $port_https_expired -S -C 7" ); 247 is( $result->return_code, 2, "$command -p $port_https_expired -S -C 7" );
246 is( $result->output, 248 is( $result->output,
247 'CRITICAL - Certificate \'Monitoring Plugins\' expired on Wed Jan 2 11:00:26 2008 +0000.', 249 'CRITICAL - Certificate \'Monitoring Plugins\' expired on Wed Jan 2 12:00:00 2008 +0000.',
248 "output ok" ); 250 "output ok" );
249 251
250} 252}
diff --git a/plugins/tests/check_http.t b/plugins/tests/check_http.t
index 188f5e75..ea11b2ac 100755
--- a/plugins/tests/check_http.t
+++ b/plugins/tests/check_http.t
@@ -3,16 +3,7 @@
3# Test check_http by having an actual HTTP server running 3# Test check_http by having an actual HTTP server running
4# 4#
5# To create the https server certificate: 5# To create the https server certificate:
6# openssl req -new -x509 -keyout server-key.pem -out server-cert.pem -days 3650 -nodes 6# ./certs/generate-certs.sh
7# to create a new expired certificate:
8# faketime '2008-01-01 12:00:00' openssl req -new -x509 -keyout expired-key.pem -out expired-cert.pem -days 1 -nodes
9# Country Name (2 letter code) [AU]:DE
10# State or Province Name (full name) [Some-State]:Bavaria
11# Locality Name (eg, city) []:Munich
12# Organization Name (eg, company) [Internet Widgits Pty Ltd]:Monitoring Plugins
13# Organizational Unit Name (eg, section) []:
14# Common Name (e.g. server FQDN or YOUR name) []:Monitoring Plugins
15# Email Address []:devel@monitoring-plugins.org
16 7
17use strict; 8use strict;
18use Test::More; 9use Test::More;
@@ -23,7 +14,7 @@ $ENV{'LC_TIME'} = "C";
23 14
24my $common_tests = 70; 15my $common_tests = 70;
25my $virtual_port_tests = 8; 16my $virtual_port_tests = 8;
26my $ssl_only_tests = 8; 17my $ssl_only_tests = 12;
27# Check that all dependent modules are available 18# Check that all dependent modules are available
28eval "use HTTP::Daemon 6.01;"; 19eval "use HTTP::Daemon 6.01;";
29plan skip_all => 'HTTP::Daemon >= 6.01 required' if $@; 20plan skip_all => 'HTTP::Daemon >= 6.01 required' if $@;
@@ -59,61 +50,87 @@ $HTTP::Daemon::VERSION = "1.00";
59my $port_http = 50000 + int(rand(1000)); 50my $port_http = 50000 + int(rand(1000));
60my $port_https = $port_http + 1; 51my $port_https = $port_http + 1;
61my $port_https_expired = $port_http + 2; 52my $port_https_expired = $port_http + 2;
53my $port_https_clientcert = $port_http + 3;
62 54
63# This array keeps sockets around for implementing timeouts 55# This array keeps sockets around for implementing timeouts
64my @persist; 56my @persist;
65 57
66# Start up all servers 58# Start up all servers
67my @pids; 59my @pids;
68my $pid = fork(); 60# Fork a HTTP server
69if ($pid) { 61my $pid = fork;
70 # Parent 62defined $pid or die "Failed to fork";
71 push @pids, $pid; 63if (!$pid) {
72 if (exists $servers->{https}) { 64 undef @pids;
73 # Fork a normal HTTPS server
74 $pid = fork();
75 if ($pid) {
76 # Parent
77 push @pids, $pid;
78 # Fork an expired cert server
79 $pid = fork();
80 if ($pid) {
81 push @pids, $pid;
82 } else {
83 my $d = HTTP::Daemon::SSL->new(
84 LocalPort => $port_https_expired,
85 LocalAddr => "127.0.0.1",
86 SSL_cert_file => "$Bin/certs/expired-cert.pem",
87 SSL_key_file => "$Bin/certs/expired-key.pem",
88 ) || die;
89 print "Please contact https expired at: <URL:", $d->url, ">\n";
90 run_server( $d );
91 exit;
92 }
93 } else {
94 # closing the connection after -C cert checks make the daemon exit with a sigpipe otherwise
95 local $SIG{'PIPE'} = 'IGNORE';
96 my $d = HTTP::Daemon::SSL->new(
97 LocalPort => $port_https,
98 LocalAddr => "127.0.0.1",
99 SSL_cert_file => "$Bin/certs/server-cert.pem",
100 SSL_key_file => "$Bin/certs/server-key.pem",
101 ) || die;
102 print "Please contact https at: <URL:", $d->url, ">\n";
103 run_server( $d );
104 exit;
105 }
106 }
107} else {
108 # Child
109 #print "child\n";
110 my $d = HTTP::Daemon->new( 65 my $d = HTTP::Daemon->new(
111 LocalPort => $port_http, 66 LocalPort => $port_http,
112 LocalAddr => "127.0.0.1", 67 LocalAddr => "127.0.0.1",
113 ) || die; 68 ) || die;
114 print "Please contact http at: <URL:", $d->url, ">\n"; 69 print "Please contact http at: <URL:", $d->url, ">\n";
115 run_server( $d ); 70 run_server( $d );
116 exit; 71 die "webserver stopped";
72}
73push @pids, $pid;
74
75if (exists $servers->{https}) {
76 # Fork a normal HTTPS server
77 $pid = fork;
78 defined $pid or die "Failed to fork";
79 if (!$pid) {
80 undef @pids;
81 # closing the connection after -C cert checks make the daemon exit with a sigpipe otherwise
82 local $SIG{'PIPE'} = 'IGNORE';
83 my $d = HTTP::Daemon::SSL->new(
84 LocalPort => $port_https,
85 LocalAddr => "127.0.0.1",
86 SSL_cert_file => "$Bin/certs/server-cert.pem",
87 SSL_key_file => "$Bin/certs/server-key.pem",
88 ) || die;
89 print "Please contact https at: <URL:", $d->url, ">\n";
90 run_server( $d );
91 die "webserver stopped";
92 }
93 push @pids, $pid;
94
95 # Fork an expired cert server
96 $pid = fork;
97 defined $pid or die "Failed to fork";
98 if (!$pid) {
99 undef @pids;
100 # closing the connection after -C cert checks make the daemon exit with a sigpipe otherwise
101 local $SIG{'PIPE'} = 'IGNORE';
102 my $d = HTTP::Daemon::SSL->new(
103 LocalPort => $port_https_expired,
104 LocalAddr => "127.0.0.1",
105 SSL_cert_file => "$Bin/certs/expired-cert.pem",
106 SSL_key_file => "$Bin/certs/expired-key.pem",
107 ) || die;
108 print "Please contact https expired at: <URL:", $d->url, ">\n";
109 run_server( $d );
110 die "webserver stopped";
111 }
112 push @pids, $pid;
113
114 # Fork an client cert expecting server
115 $pid = fork;
116 defined $pid or die "Failed to fork";
117 if (!$pid) {
118 undef @pids;
119 # closing the connection after -C cert checks make the daemon exit with a sigpipe otherwise
120 local $SIG{'PIPE'} = 'IGNORE';
121 my $d = HTTP::Daemon::SSL->new(
122 LocalPort => $port_https_clientcert,
123 LocalAddr => "127.0.0.1",
124 SSL_cert_file => "$Bin/certs/server-cert.pem",
125 SSL_key_file => "$Bin/certs/server-key.pem",
126 SSL_verify_mode => IO::Socket::SSL->SSL_VERIFY_PEER | IO::Socket::SSL->SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
127 SSL_ca_file => "$Bin/certs/clientca-cert.pem",
128 ) || die;
129 print "Please contact https client cert at: <URL:", $d->url, ">\n";
130 run_server( $d );
131 die "webserver stopped";
132 }
133 push @pids, $pid;
117} 134}
118 135
119# give our webservers some time to startup 136# give our webservers some time to startup
@@ -122,60 +139,62 @@ sleep(3);
122# Run the same server on http and https 139# Run the same server on http and https
123sub run_server { 140sub run_server {
124 my $d = shift; 141 my $d = shift;
125 MAINLOOP: while (my $c = $d->accept ) { 142 while (1) {
126 while (my $r = $c->get_request) { 143 MAINLOOP: while (my $c = $d->accept) {
127 if ($r->method eq "GET" and $r->url->path =~ m^/statuscode/(\d+)^) { 144 while (my $r = $c->get_request) {
128 $c->send_basic_header($1); 145 if ($r->method eq "GET" and $r->url->path =~ m^/statuscode/(\d+)^) {
129 $c->send_crlf; 146 $c->send_basic_header($1);
130 } elsif ($r->method eq "GET" and $r->url->path =~ m^/file/(.*)^) { 147 $c->send_crlf;
131 $c->send_basic_header; 148 } elsif ($r->method eq "GET" and $r->url->path =~ m^/file/(.*)^) {
132 $c->send_crlf; 149 $c->send_basic_header;
133 $c->send_file_response("$Bin/var/$1"); 150 $c->send_crlf;
134 } elsif ($r->method eq "GET" and $r->url->path eq "/slow") { 151 $c->send_file_response("$Bin/var/$1");
135 $c->send_basic_header; 152 } elsif ($r->method eq "GET" and $r->url->path eq "/slow") {
136 $c->send_crlf; 153 $c->send_basic_header;
137 sleep 1; 154 $c->send_crlf;
138 $c->send_response("slow"); 155 sleep 1;
139 } elsif ($r->url->path eq "/method") { 156 $c->send_response("slow");
140 if ($r->method eq "DELETE") { 157 } elsif ($r->url->path eq "/method") {
141 $c->send_error(HTTP::Status->RC_METHOD_NOT_ALLOWED); 158 if ($r->method eq "DELETE") {
142 } elsif ($r->method eq "foo") { 159 $c->send_error(HTTP::Status->RC_METHOD_NOT_ALLOWED);
143 $c->send_error(HTTP::Status->RC_NOT_IMPLEMENTED); 160 } elsif ($r->method eq "foo") {
161 $c->send_error(HTTP::Status->RC_NOT_IMPLEMENTED);
162 } else {
163 $c->send_status_line(200, $r->method);
164 }
165 } elsif ($r->url->path eq "/postdata") {
166 $c->send_basic_header;
167 $c->send_crlf;
168 $c->send_response($r->method.":".$r->content);
169 } elsif ($r->url->path eq "/redirect") {
170 $c->send_redirect( "/redirect2" );
171 } elsif ($r->url->path eq "/redir_external") {
172 $c->send_redirect(($d->isa('HTTP::Daemon::SSL') ? "https" : "http") . "://169.254.169.254/redirect2" );
173 } elsif ($r->url->path eq "/redirect2") {
174 $c->send_basic_header;
175 $c->send_crlf;
176 $c->send_response(HTTP::Response->new( 200, 'OK', undef, 'redirected' ));
177 } elsif ($r->url->path eq "/redir_timeout") {
178 $c->send_redirect( "/timeout" );
179 } elsif ($r->url->path eq "/timeout") {
180 # Keep $c from being destroyed, but prevent severe leaks
181 unshift @persist, $c;
182 delete($persist[1000]);
183 next MAINLOOP;
184 } elsif ($r->url->path eq "/header_check") {
185 $c->send_basic_header;
186 $c->send_header('foo');
187 $c->send_crlf;
188 } elsif ($r->url->path eq "/virtual_port") {
189 # return sent Host header
190 $c->send_basic_header;
191 $c->send_crlf;
192 $c->send_response(HTTP::Response->new( 200, 'OK', undef, $r->header ('Host')));
144 } else { 193 } else {
145 $c->send_status_line(200, $r->method); 194 $c->send_error(HTTP::Status->RC_FORBIDDEN);
146 } 195 }
147 } elsif ($r->url->path eq "/postdata") { 196 $c->close;
148 $c->send_basic_header;
149 $c->send_crlf;
150 $c->send_response($r->method.":".$r->content);
151 } elsif ($r->url->path eq "/redirect") {
152 $c->send_redirect( "/redirect2" );
153 } elsif ($r->url->path eq "/redir_external") {
154 $c->send_redirect(($d->isa('HTTP::Daemon::SSL') ? "https" : "http") . "://169.254.169.254/redirect2" );
155 } elsif ($r->url->path eq "/redirect2") {
156 $c->send_basic_header;
157 $c->send_crlf;
158 $c->send_response(HTTP::Response->new( 200, 'OK', undef, 'redirected' ));
159 } elsif ($r->url->path eq "/redir_timeout") {
160 $c->send_redirect( "/timeout" );
161 } elsif ($r->url->path eq "/timeout") {
162 # Keep $c from being destroyed, but prevent severe leaks
163 unshift @persist, $c;
164 delete($persist[1000]);
165 next MAINLOOP;
166 } elsif ($r->url->path eq "/header_check") {
167 $c->send_basic_header;
168 $c->send_header('foo');
169 $c->send_crlf;
170 } elsif ($r->url->path eq "/virtual_port") {
171 # return sent Host header
172 $c->send_basic_header;
173 $c->send_crlf;
174 $c->send_response(HTTP::Response->new( 200, 'OK', undef, $r->header ('Host')));
175 } else {
176 $c->send_error(HTTP::Status->RC_FORBIDDEN);
177 } 197 }
178 $c->close;
179 } 198 }
180 } 199 }
181} 200}
@@ -200,25 +219,44 @@ SKIP: {
200 skip "HTTP::Daemon::SSL not installed", $common_tests + $ssl_only_tests if ! exists $servers->{https}; 219 skip "HTTP::Daemon::SSL not installed", $common_tests + $ssl_only_tests if ! exists $servers->{https};
201 run_common_tests( { command => "$command -p $port_https", ssl => 1 } ); 220 run_common_tests( { command => "$command -p $port_https", ssl => 1 } );
202 221
222 my $expiry = "Thu Nov 28 21:02:11 2030 +0000";
223
203 $result = NPTest->testCmd( "$command -p $port_https -S -C 14" ); 224 $result = NPTest->testCmd( "$command -p $port_https -S -C 14" );
204 is( $result->return_code, 0, "$command -p $port_https -S -C 14" ); 225 is( $result->return_code, 0, "$command -p $port_https -S -C 14" );
205 is( $result->output, "OK - Certificate 'Monitoring Plugins' will expire on Fri Feb 16 15:31:44 2029 +0000.", "output ok" ); 226 is( $result->output, "OK - Certificate 'Monitoring Plugins' will expire on $expiry.", "output ok" );
206 227
207 $result = NPTest->testCmd( "$command -p $port_https -S -C 14000" ); 228 $result = NPTest->testCmd( "$command -p $port_https -S -C 14000" );
208 is( $result->return_code, 1, "$command -p $port_https -S -C 14000" ); 229 is( $result->return_code, 1, "$command -p $port_https -S -C 14000" );
209 like( $result->output, '/WARNING - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(Fri Feb 16 15:31:44 2029 \+0000\)./', "output ok" ); 230 like( $result->output, '/WARNING - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(' . quotemeta($expiry) . '\)./', "output ok" );
210 231
211 # Expired cert tests 232 # Expired cert tests
212 $result = NPTest->testCmd( "$command -p $port_https -S -C 13960,14000" ); 233 $result = NPTest->testCmd( "$command -p $port_https -S -C 13960,14000" );
213 is( $result->return_code, 2, "$command -p $port_https -S -C 13960,14000" ); 234 is( $result->return_code, 2, "$command -p $port_https -S -C 13960,14000" );
214 like( $result->output, '/CRITICAL - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(Fri Feb 16 15:31:44 2029 \+0000\)./', "output ok" ); 235 like( $result->output, '/CRITICAL - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(' . quotemeta($expiry) . '\)./', "output ok" );
215 236
216 $result = NPTest->testCmd( "$command -p $port_https_expired -S -C 7" ); 237 $result = NPTest->testCmd( "$command -p $port_https_expired -S -C 7" );
217 is( $result->return_code, 2, "$command -p $port_https_expired -S -C 7" ); 238 is( $result->return_code, 2, "$command -p $port_https_expired -S -C 7" );
218 is( $result->output, 239 is( $result->output,
219 'CRITICAL - Certificate \'Monitoring Plugins\' expired on Wed Jan 2 11:00:26 2008 +0000.', 240 'CRITICAL - Certificate \'Monitoring Plugins\' expired on Wed Jan 2 12:00:00 2008 +0000.',
220 "output ok" ); 241 "output ok" );
221 242
243 # client cert tests
244 my $cmd;
245 $cmd = "$command -p $port_https_clientcert"
246 . " -J \"$Bin/certs/client-cert.pem\""
247 . " -K \"$Bin/certs/client-key.pem\""
248 . " -u /statuscode/200";
249 $result = NPTest->testCmd($cmd);
250 is( $result->return_code, 0, $cmd);
251 like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output );
252
253 $cmd = "$command -p $port_https_clientcert"
254 . " -J \"$Bin/certs/clientchain-cert.pem\""
255 . " -K \"$Bin/certs/clientchain-key.pem\""
256 . " -u /statuscode/200";
257 $result = NPTest->testCmd($cmd);
258 is( $result->return_code, 0, $cmd);
259 like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output );
222} 260}
223 261
224my $cmd; 262my $cmd;