summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Lofgren <alofgren@op5.com>2014-05-15 14:48:26 +0200
committerLorenz Kästle <lorenz.kaestle@netways.de>2022-01-14 15:34:12 +0100
commitecf3f468905dc2b8e8470eb5288ce8b9f845c26f (patch)
tree292016afc6114a6aed2a6334059b07f8961a4ebb
parent4433c7554337b6bc54a3dc548b75746f9dbc2d86 (diff)
downloadmonitoring-plugins-ecf3f468905dc2b8e8470eb5288ce8b9f845c26f.tar.gz
check_ssh: Handle non-alpha software versions
This patch fixes a bug where we would reject version control strings that do not contain letters, because the assumption is made that they always do. This is not required by the RFC however, and there exist implementations that do not contain letters. I've also added a few references to the RFC to make the process of parsing the control string more apparent. This fixes op5#8716 (https://bugs.op5.com/view.php?id=8716) Signed-off-by: Anton Lofgren <alofgren@op5.com>
-rw-r--r--plugins/check_ssh.c26
-rw-r--r--plugins/t/check_ssh.t76
2 files changed, 70 insertions, 32 deletions
diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c
index 8a3abb03..b4bfab45 100644
--- a/plugins/check_ssh.c
+++ b/plugins/check_ssh.c
@@ -278,11 +278,35 @@ ssh_connect (char *haddr, int hport, char *remote_version, char *remote_protocol
278 printf("SSH CRITICAL - No version control string received"); 278 printf("SSH CRITICAL - No version control string received");
279 exit(STATE_CRITICAL); 279 exit(STATE_CRITICAL);
280 } 280 }
281 /*
282 * "When the connection has been established, both sides MUST send an
283 * identification string. This identification string MUST be
284 *
285 * SSH-protoversion-softwareversion SP comments CR LF"
286 * - RFC 4253:4.2
287 */
281 strip (version_control_string); 288 strip (version_control_string);
282 if (verbose) 289 if (verbose)
283 printf ("%s\n", version_control_string); 290 printf ("%s\n", version_control_string);
284 ssh_proto = version_control_string + 4; 291 ssh_proto = version_control_string + 4;
285 ssh_server = ssh_proto + strspn (ssh_proto, "-0123456789."); 292
293 /*
294 * We assume the protoversion is of the form Major.Minor, although
295 * this is not _strictly_ required. See
296 *
297 * "Both the 'protoversion' and 'softwareversion' strings MUST consist of
298 * printable US-ASCII characters, with the exception of whitespace
299 * characters and the minus sign (-)"
300 * - RFC 4253:4.2
301 * and,
302 *
303 * "As stated earlier, the 'protoversion' specified for this protocol is
304 * "2.0". Earlier versions of this protocol have not been formally
305 * documented, but it is widely known that they use 'protoversion' of
306 * "1.x" (e.g., "1.5" or "1.3")."
307 * - RFC 4253:5
308 */
309 ssh_server = ssh_proto + strspn (ssh_proto, "0123456789.") + 1; /* (+1 for the '-' separating protoversion from softwareversion) */
286 310
287 /* If there's a space in the version string, whatever's after the space is a comment 311 /* If there's a space in the version string, whatever's after the space is a comment
288 * (which is NOT part of the server name/version)*/ 312 * (which is NOT part of the server name/version)*/
diff --git a/plugins/t/check_ssh.t b/plugins/t/check_ssh.t
index 3e1824df..7df62651 100644
--- a/plugins/t/check_ssh.t
+++ b/plugins/t/check_ssh.t
@@ -8,10 +8,13 @@ use strict;
8use Test::More; 8use Test::More;
9use NPTest; 9use NPTest;
10 10
11my $res;
12
11# Required parameters 13# Required parameters
12my $ssh_host = getTestParameter("NP_SSH_HOST", 14my $ssh_host = getTestParameter("NP_SSH_HOST",
13 "A host providing SSH service", 15 "A host providing SSH service",
14 "localhost"); 16 "localhost");
17
15my $host_nonresponsive = getTestParameter("NP_HOST_NONRESPONSIVE", 18my $host_nonresponsive = getTestParameter("NP_HOST_NONRESPONSIVE",
16 "The hostname of system not responsive to network requests", 19 "The hostname of system not responsive to network requests",
17 "10.0.0.1" ); 20 "10.0.0.1" );
@@ -20,13 +23,37 @@ my $hostname_invalid = getTestParameter("NP_HOSTNAME_INVALID",
20 "An invalid (not known to DNS) hostname", 23 "An invalid (not known to DNS) hostname",
21 "nosuchhost" ); 24 "nosuchhost" );
22 25
23my $res;
24 26
27plan tests => 14 + 6;
25 28
26plan tests => 18;
27SKIP: { 29SKIP: {
30 skip "SSH_HOST must be defined", 6 unless $ssh_host;
31 my $result = NPTest->testCmd(
32 "./check_ssh -H $ssh_host"
33 );
34 cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)");
35 like($result->output, '/^SSH OK - /', "Status text if command returned none (OK)");
28 36
29 skip "No netcat available", 12 unless (system("which nc > /dev/null") == 0); 37
38 $result = NPTest->testCmd(
39 "./check_ssh -H $host_nonresponsive -t 2"
40 );
41 cmp_ok($result->return_code, '==', 2, "Exit with return code 0 (OK)");
42 like($result->output, '/^CRITICAL - Socket timeout after 2 seconds/', "Status text if command returned none (OK)");
43
44
45
46 $result = NPTest->testCmd(
47 "./check_ssh -H $hostname_invalid -t 2"
48 );
49 cmp_ok($result->return_code, '==', 3, "Exit with return code 0 (OK)");
50 like($result->output, '/^check_ssh: Invalid hostname/', "Status text if command returned none (OK)");
51
52
53}
54SKIP: {
55
56 skip "No netcat available", 14 unless (system("which nc > /dev/null") == 0);
30 57
31 my $nc_flags = "-l 5003 -i 1"; 58 my $nc_flags = "-l 5003 -i 1";
32 #A valid protocol version control string has the form 59 #A valid protocol version control string has the form
@@ -41,6 +68,13 @@ SKIP: {
41 like( $res->output, '/^SSH OK - nagiosplug.ssh.0.1 \(protocol 2.0\)/', "Output OK"); 68 like( $res->output, '/^SSH OK - nagiosplug.ssh.0.1 \(protocol 2.0\)/', "Output OK");
42 close NC; 69 close NC;
43 70
71 open(NC, "echo 'SSH-2.0-3.2.9.1' | nc ${nc_flags}|");
72 sleep 1;
73 $res = NPTest->testCmd( "./check_ssh -H localhost -p 5003" );
74 cmp_ok( $res->return_code, "==", 0, "Got SSH protocol version control string with non-alpha softwareversion string");
75 like( $res->output, '/^SSH OK - 3.2.9.1 \(protocol 2.0\)/', "Output OK for non-alpha softwareversion string");
76 close NC;
77
44 open(NC, "echo 'SSH-2.0-nagiosplug.ssh.0.1 this is a comment' | nc ${nc_flags} |"); 78 open(NC, "echo 'SSH-2.0-nagiosplug.ssh.0.1 this is a comment' | nc ${nc_flags} |");
45 sleep 1; 79 sleep 1;
46 $res = NPTest->testCmd( "./check_ssh -H localhost -p 5003 -r nagiosplug.ssh.0.1" ); 80 $res = NPTest->testCmd( "./check_ssh -H localhost -p 5003 -r nagiosplug.ssh.0.1" );
@@ -48,7 +82,6 @@ SKIP: {
48 like( $res->output, '/^SSH OK - nagiosplug.ssh.0.1 \(protocol 2.0\)/', "Output OK"); 82 like( $res->output, '/^SSH OK - nagiosplug.ssh.0.1 \(protocol 2.0\)/', "Output OK");
49 close NC; 83 close NC;
50 84
51
52 open(NC, "echo 'SSH-' | nc ${nc_flags}|"); 85 open(NC, "echo 'SSH-' | nc ${nc_flags}|");
53 sleep 1; 86 sleep 1;
54 $res = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ); 87 $res = NPTest->testCmd( "./check_ssh -H localhost -p 5003" );
@@ -72,36 +105,17 @@ SKIP: {
72 105
73 106
74 #RFC 4253 permits servers to send any number of data lines prior to sending the protocol version control string 107 #RFC 4253 permits servers to send any number of data lines prior to sending the protocol version control string
75 open(NC, "echo 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n 108 open(NC, "{ echo 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; sleep 1;
76 BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n 109 echo 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'; sleep 1;
77 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n 110 echo 'CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC'; sleep 1;
78 DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD\n 111 echo 'DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD'; sleep 1;
79 Some\nPrepended\nData\nLines\nSSH-2.0-nagiosplug.ssh.0.2' | nc ${nc_flags}|"); 112 printf 'EEEEEEEEEEEEEEEEEE'; sleep 1;
113 printf 'EEEEEEEEEEEEEEEEEE\n'; sleep 1;
114 echo 'Some\nPrepended\nData\nLines\n'; sleep 1;
115 echo 'SSH-2.0-nagiosplug.ssh.0.2';} | nc ${nc_flags}|");
80 sleep 1; 116 sleep 1;
81 $res = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ); 117 $res = NPTest->testCmd( "./check_ssh -H localhost -p 5003" );
82 cmp_ok( $res->return_code, '==', 0, "Got delayed SSH protocol version control string"); 118 cmp_ok( $res->return_code, '==', 0, "Got delayed SSH protocol version control string");
83 like( $res->output, '/^SSH OK - nagiosplug.ssh.0.2 \(protocol 2.0\)/', "Output OK"); 119 like( $res->output, '/^SSH OK - nagiosplug.ssh.0.2 \(protocol 2.0\)/', "Output OK");
84 close NC; 120 close NC;
85} 121}
86
87SKIP {
88 skip "SSH_HOST must be defined", 6 unless $ssh_host;
89 $res = NPTest->testCmd(
90 "./check_ssh -H $ssh_host"
91 );
92 cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)");
93 like($result->output, '/^SSH OK - /', "Status text if command returned none (OK)");
94
95 $res = NPTest->testCmd(
96 "./check_ssh -H $host_nonresponsive -t 2"
97 );
98 cmp_ok($result->return_code, '==', 2, "Exit with return code 2 (CRITICAL)");
99 like($result->output, '/^CRITICAL - Socket timeout after 2 seconds/', "Status text if command returned none (OK)");
100
101 $res = NPTest->testCmd(
102 "./check_ssh -H $hostname_invalid -t 2"
103 );
104 cmp_ok($result->return_code, '==', 3, "Exit with return code 3 (UNKNOWN)");
105 like($result->output, '/^check_ssh: Invalid hostname/', "Status text if command returned none (OK)");
106
107}