From 66f62dd336832702a1e4f60cbfc4258de2c931cf Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 27 Mar 2024 00:35:16 +0100 Subject: check_ssh: patches from op5 (#1738) * check_ssh: properly parse a delayed version control string This resolves an issue with SSH servers which do not respond with their version control string as the first thing in the SSH protocol version exchange phase after connection establishment. This patch also makes sure that we disregard a potential comment in the version exchange string to avoid nonsense mismatches. In the future, we might want to add the capability to match against a user specified comment. In addition, the patch largely improves the communication towards the server, which adds better protocol adherence. Of course, new test cases are added to support the trigger and guard against regressions of the bugs solved by this patch. This fixes op5#7945 (https://bugs.op5.com/view.php?id=7945) Signed-off-by: Anton Lofgren * check_ssh.t: Fix a few typos Signed-off-by: Anton Lofgren * 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 * check_ssh: Fix a typo in "remote-protocol parameter remote-protcol -> remote-protocol Signed-off-by: Anton Lofgren * Remove unused variable * Formating fixes * Update translations * Remove merge conflict artefact from previous merge * Set fixed include paths * Improve code style to be slightly more readable * Update test cases for different netcat behaviour and reduce sleep time --------- Signed-off-by: Anton Lofgren Co-authored-by: Anton Lofgren --- plugins/check_ssh.c | 188 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 132 insertions(+), 56 deletions(-) (limited to 'plugins/check_ssh.c') diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c index 4eb746cb..34ef37b7 100644 --- a/plugins/check_ssh.c +++ b/plugins/check_ssh.c @@ -1,39 +1,39 @@ /***************************************************************************** -* +* * Monitoring check_ssh plugin -* +* * License: GPL * Copyright (c) 2000-2007 Monitoring Plugins Development Team -* +* * Description: -* +* * This file contains the check_ssh plugin -* +* * Try to connect to an SSH server at specified server and port -* -* +* +* * This program 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. -* +* * 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 General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with this program. If not, see . -* -* +* +* *****************************************************************************/ const char *progname = "check_ssh"; const char *copyright = "2000-2007"; const char *email = "devel@monitoring-plugins.org"; -#include "common.h" -#include "netutils.h" +#include "./common.h" +#include "./netutils.h" #include "utils.h" #ifndef MSG_DONTWAIT @@ -105,7 +105,7 @@ process_arguments (int argc, char **argv) {"timeout", required_argument, 0, 't'}, {"verbose", no_argument, 0, 'v'}, {"remote-version", required_argument, 0, 'r'}, - {"remote-protcol", required_argument, 0, 'P'}, + {"remote-protocol", required_argument, 0, 'P'}, {0, 0, 0, 0} }; @@ -214,7 +214,9 @@ ssh_connect (char *haddr, int hport, char *remote_version, char *remote_protocol { int sd; int result; - char *output = NULL; + int len = 0; + ssize_t recv_ret = 0; + char *version_control_string = NULL; char *buffer = NULL; char *ssh_proto = NULL; char *ssh_server = NULL; @@ -229,52 +231,126 @@ ssh_connect (char *haddr, int hport, char *remote_version, char *remote_protocol if (result != STATE_OK) return result; - output = (char *) malloc (BUFF_SZ + 1); - memset (output, 0, BUFF_SZ + 1); - recv (sd, output, BUFF_SZ, 0); - if (strncmp (output, "SSH", 3)) { - printf (_("Server answer: %s"), output); - close(sd); + char *output = (char *) calloc (BUFF_SZ + 1, sizeof(char)); + + unsigned int iteration = 0; + ssize_t byte_offset = 0; + + while ((version_control_string == NULL) && (recv_ret = recv(sd, output+byte_offset, BUFF_SZ - byte_offset, 0) > 0)) { + + if (strchr(output, '\n')) { /* we've got at least one full line, start parsing*/ + byte_offset = 0; + + char *index = NULL; + while ((index = strchr(output+byte_offset, '\n')) != NULL) { + /*Partition the buffer so that this line is a separate string, + * by replacing the newline with NUL*/ + output[(index - output)] = '\0'; + len = strlen(output + byte_offset); + + if ((len >= 4) && (strncmp (output+byte_offset, "SSH-", 4) == 0)) { + /*if the string starts with SSH-, this _should_ be a valid version control string*/ + version_control_string = output+byte_offset; + break; + } + + /*the start of the next line (if one exists) will be after the current one (+ NUL)*/ + byte_offset += (len + 1); + } + + if(version_control_string == NULL) { + /* move unconsumed data to beginning of buffer, null rest */ + memmove((void *)output, (void *)output+byte_offset+1, BUFF_SZ - len+1); + memset(output+byte_offset+1, 0, BUFF_SZ-byte_offset+1); + + /*start reading from end of current line chunk on next recv*/ + byte_offset = strlen(output); + } + } else { + byte_offset += recv_ret; + } + } + + if (recv_ret < 0) { + printf("SSH CRITICAL - %s", strerror(errno)); + exit(STATE_CRITICAL); + } + + if (version_control_string == NULL) { + printf("SSH CRITICAL - No version control string received"); + exit(STATE_CRITICAL); + } + /* + * "When the connection has been established, both sides MUST send an + * identification string. This identification string MUST be + * + * SSH-protoversion-softwareversion SP comments CR LF" + * - RFC 4253:4.2 + */ + strip (version_control_string); + if (verbose) + printf ("%s\n", version_control_string); + ssh_proto = version_control_string + 4; + + /* + * We assume the protoversion is of the form Major.Minor, although + * this is not _strictly_ required. See + * + * "Both the 'protoversion' and 'softwareversion' strings MUST consist of + * printable US-ASCII characters, with the exception of whitespace + * characters and the minus sign (-)" + * - RFC 4253:4.2 + * and, + * + * "As stated earlier, the 'protoversion' specified for this protocol is + * "2.0". Earlier versions of this protocol have not been formally + * documented, but it is widely known that they use 'protoversion' of + * "1.x" (e.g., "1.5" or "1.3")." + * - RFC 4253:5 + */ + ssh_server = ssh_proto + strspn (ssh_proto, "0123456789.") + 1; /* (+1 for the '-' separating protoversion from softwareversion) */ + + /* If there's a space in the version string, whatever's after the space is a comment + * (which is NOT part of the server name/version)*/ + char *tmp = strchr(ssh_server, ' '); + if (tmp) { + ssh_server[tmp - ssh_server] = '\0'; + } + if (strlen(ssh_proto) == 0 || strlen(ssh_server) == 0) { + printf(_("SSH CRITICAL - Invalid protocol version control string %s\n"), version_control_string); exit (STATE_CRITICAL); } - else { - strip (output); - if (verbose) - printf ("%s\n", output); - ssh_proto = output + 4; - ssh_server = ssh_proto + strspn (ssh_proto, "-0123456789. "); - ssh_proto[strspn (ssh_proto, "0123456789. ")] = 0; - - xasprintf (&buffer, "SSH-%s-check_ssh_%s\r\n", ssh_proto, rev_no); - send (sd, buffer, strlen (buffer), MSG_DONTWAIT); - if (verbose) - printf ("%s\n", buffer); - - if (remote_version && strcmp(remote_version, ssh_server)) { - printf - (_("SSH CRITICAL - %s (protocol %s) version mismatch, expected '%s'\n"), - ssh_server, ssh_proto, remote_version); - close(sd); - exit (STATE_CRITICAL); - } + ssh_proto[strspn (ssh_proto, "0123456789. ")] = 0; - if (remote_protocol && strcmp(remote_protocol, ssh_proto)) { - printf - (_("SSH CRITICAL - %s (protocol %s) protocol version mismatch, expected '%s'\n"), - ssh_server, ssh_proto, remote_protocol); - close(sd); - exit (STATE_CRITICAL); - } + xasprintf (&buffer, "SSH-%s-check_ssh_%s\r\n", ssh_proto, rev_no); + send (sd, buffer, strlen (buffer), MSG_DONTWAIT); + if (verbose) + printf ("%s\n", buffer); - elapsed_time = (double)deltime(tv) / 1.0e6; + if (remote_version && strcmp(remote_version, ssh_server)) { + printf + (_("SSH CRITICAL - %s (protocol %s) version mismatch, expected '%s'\n"), + ssh_server, ssh_proto, remote_version); + close(sd); + exit (STATE_CRITICAL); + } + if (remote_protocol && strcmp(remote_protocol, ssh_proto)) { printf - (_("SSH OK - %s (protocol %s) | %s\n"), - ssh_server, ssh_proto, fperfdata("time", elapsed_time, "s", + (_("SSH CRITICAL - %s (protocol %s) protocol version mismatch, expected '%s' | %s\n"), + ssh_server, ssh_proto, remote_protocol, fperfdata("time", elapsed_time, "s", false, 0, false, 0, true, 0, true, (int)socket_timeout)); close(sd); - exit (STATE_OK); + exit (STATE_CRITICAL); } + elapsed_time = (double)deltime(tv) / 1.0e6; + + printf + (_("SSH OK - %s (protocol %s) | %s\n"), + ssh_server, ssh_proto, fperfdata("time", elapsed_time, "s", + false, 0, false, 0, true, 0, true, (int)socket_timeout)); + close(sd); + exit (STATE_OK); } @@ -292,7 +368,7 @@ print_help (void) printf ("%s\n", _("Try to connect to an SSH server at specified server and port")); - printf ("\n\n"); + printf ("\n\n"); print_usage (); @@ -306,10 +382,10 @@ print_help (void) printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); printf (" %s\n", "-r, --remote-version=STRING"); - printf (" %s\n", _("Alert if string doesn't match expected server version (ex: OpenSSH_3.9p1)")); + printf (" %s\n", _("Alert if string doesn't match expected server version (ex: OpenSSH_3.9p1)")); printf (" %s\n", "-P, --remote-protocol=STRING"); - printf (" %s\n", _("Alert if protocol doesn't match expected protocol version (ex: 2.0)")); + printf (" %s\n", _("Alert if protocol doesn't match expected protocol version (ex: 2.0)")); printf (UT_VERBOSE); @@ -321,7 +397,7 @@ print_help (void) void print_usage (void) { - printf ("%s\n", _("Usage:")); + printf ("%s\n", _("Usage:")); printf ("%s [-4|-6] [-t ] [-r ] [-p ] \n", progname); } -- cgit v1.2.3-74-g34f1 From 04115904adc237dbb2a4224728b0f5a49d617703 Mon Sep 17 00:00:00 2001 From: RincewindsHat <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 28 Aug 2024 23:39:57 +0200 Subject: check_ssh: Always initialize elapsed_time --- plugins/check_ssh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins/check_ssh.c') diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c index 34ef37b7..3c1a594d 100644 --- a/plugins/check_ssh.c +++ b/plugins/check_ssh.c @@ -222,7 +222,7 @@ ssh_connect (char *haddr, int hport, char *remote_version, char *remote_protocol char *ssh_server = NULL; static char *rev_no = VERSION; struct timeval tv; - double elapsed_time; + double elapsed_time = 0; gettimeofday(&tv, NULL); -- cgit v1.2.3-74-g34f1 From 829ec76f00f33f7015936dcccca60661ca459252 Mon Sep 17 00:00:00 2001 From: RincewindsHat <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 28 Aug 2024 23:40:22 +0200 Subject: check_ssh: Remove unused variable iteration --- plugins/check_ssh.c | 1 - 1 file changed, 1 deletion(-) (limited to 'plugins/check_ssh.c') diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c index 3c1a594d..a3b5358c 100644 --- a/plugins/check_ssh.c +++ b/plugins/check_ssh.c @@ -233,7 +233,6 @@ ssh_connect (char *haddr, int hport, char *remote_version, char *remote_protocol char *output = (char *) calloc (BUFF_SZ + 1, sizeof(char)); - unsigned int iteration = 0; ssize_t byte_offset = 0; while ((version_control_string == NULL) && (recv_ret = recv(sd, output+byte_offset, BUFF_SZ - byte_offset, 0) > 0)) { -- cgit v1.2.3-74-g34f1 From 0fd0421052fed1972ecbdfdabecba5a616eaa109 Mon Sep 17 00:00:00 2001 From: RincewindsHat <12514511+RincewindsHat@users.noreply.github.com> Date: Fri, 6 Sep 2024 01:53:47 +0200 Subject: check_ssh: set elapsed time properly Previous to this commit, `elapsed_time` was only set after being read, which was quite likely wrong and a bug. This commit actually set the value before it is being read again. --- plugins/check_ssh.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'plugins/check_ssh.c') diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c index a3b5358c..d162e42f 100644 --- a/plugins/check_ssh.c +++ b/plugins/check_ssh.c @@ -222,7 +222,6 @@ ssh_connect (char *haddr, int hport, char *remote_version, char *remote_protocol char *ssh_server = NULL; static char *rev_no = VERSION; struct timeval tv; - double elapsed_time = 0; gettimeofday(&tv, NULL); @@ -334,6 +333,7 @@ ssh_connect (char *haddr, int hport, char *remote_version, char *remote_protocol exit (STATE_CRITICAL); } + double elapsed_time = (double)deltime(tv) / 1.0e6; if (remote_protocol && strcmp(remote_protocol, ssh_proto)) { printf (_("SSH CRITICAL - %s (protocol %s) protocol version mismatch, expected '%s' | %s\n"), @@ -342,7 +342,6 @@ ssh_connect (char *haddr, int hport, char *remote_version, char *remote_protocol close(sd); exit (STATE_CRITICAL); } - elapsed_time = (double)deltime(tv) / 1.0e6; printf (_("SSH OK - %s (protocol %s) | %s\n"), -- cgit v1.2.3-74-g34f1 From 611b33a30e0369168a0cddfa1a8b5f9479f52056 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 31 Oct 2024 14:47:49 +0100 Subject: check_ssh: update copyright --- plugins/check_ssh.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins/check_ssh.c') diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c index 34ef37b7..e9c55ad7 100644 --- a/plugins/check_ssh.c +++ b/plugins/check_ssh.c @@ -3,7 +3,7 @@ * Monitoring check_ssh plugin * * License: GPL -* Copyright (c) 2000-2007 Monitoring Plugins Development Team +* Copyright (c) 2000-2024 Monitoring Plugins Development Team * * Description: * @@ -29,7 +29,7 @@ *****************************************************************************/ const char *progname = "check_ssh"; -const char *copyright = "2000-2007"; +const char *copyright = "2000-2024"; const char *email = "devel@monitoring-plugins.org"; #include "./common.h" -- cgit v1.2.3-74-g34f1 From 6410ef8acbc1445fd49da5c199febb5c2930ad65 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 31 Oct 2024 15:55:04 +0100 Subject: check_ssh: clang-format --- plugins/check_ssh.c | 330 ++++++++++++++++++++++++---------------------------- 1 file changed, 149 insertions(+), 181 deletions(-) (limited to 'plugins/check_ssh.c') diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c index 8e29fa98..9f805db4 100644 --- a/plugins/check_ssh.c +++ b/plugins/check_ssh.c @@ -1,32 +1,32 @@ /***************************************************************************** -* -* Monitoring check_ssh plugin -* -* License: GPL -* Copyright (c) 2000-2024 Monitoring Plugins Development Team -* -* Description: -* -* This file contains the check_ssh plugin -* -* Try to connect to an SSH server at specified server and port -* -* -* This program 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. -* -* 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 General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* -*****************************************************************************/ + * + * Monitoring check_ssh plugin + * + * License: GPL + * Copyright (c) 2000-2024 Monitoring Plugins Development Team + * + * Description: + * + * This file contains the check_ssh plugin + * + * Try to connect to an SSH server at specified server and port + * + * + * This program 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. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * + *****************************************************************************/ const char *progname = "check_ssh"; const char *copyright = "2000-2024"; @@ -37,11 +37,11 @@ const char *email = "devel@monitoring-plugins.org"; #include "utils.h" #ifndef MSG_DONTWAIT -#define MSG_DONTWAIT 0 +# define MSG_DONTWAIT 0 #endif -#define SSH_DFL_PORT 22 -#define BUFF_SZ 256 +#define SSH_DFL_PORT 22 +#define BUFF_SZ 256 int port = -1; char *server_name = NULL; @@ -49,96 +49,87 @@ char *remote_version = NULL; char *remote_protocol = NULL; bool verbose = false; -int process_arguments (int, char **); -int validate_arguments (void); -void print_help (void); -void print_usage (void); +int process_arguments(int, char **); +int validate_arguments(void); +void print_help(void); +void print_usage(void); -int ssh_connect (char *haddr, int hport, char *remote_version, char *remote_protocol); +int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_protocol); - -int -main (int argc, char **argv) -{ +int main(int argc, char **argv) { int result = STATE_UNKNOWN; - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); /* Parse extra opts if any */ - argv=np_extra_opts (&argc, argv, progname); + argv = np_extra_opts(&argc, argv, progname); - if (process_arguments (argc, argv) == ERROR) - usage4 (_("Could not parse arguments")); + if (process_arguments(argc, argv) == ERROR) + usage4(_("Could not parse arguments")); /* initialize alarm signal handling */ - signal (SIGALRM, socket_timeout_alarm_handler); + signal(SIGALRM, socket_timeout_alarm_handler); - alarm (socket_timeout); + alarm(socket_timeout); /* ssh_connect exits if error is found */ - result = ssh_connect (server_name, port, remote_version, remote_protocol); + result = ssh_connect(server_name, port, remote_version, remote_protocol); - alarm (0); + alarm(0); return (result); } - - /* process command-line arguments */ -int -process_arguments (int argc, char **argv) -{ +int process_arguments(int argc, char **argv) { int c; int option = 0; - static struct option longopts[] = { - {"help", no_argument, 0, 'h'}, - {"version", no_argument, 0, 'V'}, - {"host", required_argument, 0, 'H'}, /* backward compatibility */ - {"hostname", required_argument, 0, 'H'}, - {"port", required_argument, 0, 'p'}, - {"use-ipv4", no_argument, 0, '4'}, - {"use-ipv6", no_argument, 0, '6'}, - {"timeout", required_argument, 0, 't'}, - {"verbose", no_argument, 0, 'v'}, - {"remote-version", required_argument, 0, 'r'}, - {"remote-protocol", required_argument, 0, 'P'}, - {0, 0, 0, 0} - }; + static struct option longopts[] = {{"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"host", required_argument, 0, 'H'}, /* backward compatibility */ + {"hostname", required_argument, 0, 'H'}, + {"port", required_argument, 0, 'p'}, + {"use-ipv4", no_argument, 0, '4'}, + {"use-ipv6", no_argument, 0, '6'}, + {"timeout", required_argument, 0, 't'}, + {"verbose", no_argument, 0, 'v'}, + {"remote-version", required_argument, 0, 'r'}, + {"remote-protocol", required_argument, 0, 'P'}, + {0, 0, 0, 0}}; if (argc < 2) return ERROR; for (c = 1; c < argc; c++) - if (strcmp ("-to", argv[c]) == 0) - strcpy (argv[c], "-t"); + if (strcmp("-to", argv[c]) == 0) + strcpy(argv[c], "-t"); while (1) { - c = getopt_long (argc, argv, "+Vhv46t:r:H:p:P:", longopts, &option); + c = getopt_long(argc, argv, "+Vhv46t:r:H:p:P:", longopts, &option); if (c == -1 || c == EOF) break; switch (c) { - case '?': /* help */ - usage5 (); - case 'V': /* version */ - print_revision (progname, NP_VERSION); - exit (STATE_UNKNOWN); - case 'h': /* help */ - print_help (); - exit (STATE_UNKNOWN); - case 'v': /* verbose */ + case '?': /* help */ + usage5(); + case 'V': /* version */ + print_revision(progname, NP_VERSION); + exit(STATE_UNKNOWN); + case 'h': /* help */ + print_help(); + exit(STATE_UNKNOWN); + case 'v': /* verbose */ verbose = true; break; - case 't': /* timeout period */ - if (!is_integer (optarg)) - usage2 (_("Timeout interval must be a positive integer"), optarg); + case 't': /* timeout period */ + if (!is_integer(optarg)) + usage2(_("Timeout interval must be a positive integer"), optarg); else - socket_timeout = atoi (optarg); + socket_timeout = atoi(optarg); break; case '4': address_family = AF_INET; @@ -147,71 +138,63 @@ process_arguments (int argc, char **argv) #ifdef USE_IPV6 address_family = AF_INET6; #else - usage4 (_("IPv6 support not available")); + usage4(_("IPv6 support not available")); #endif break; - case 'r': /* remote version */ + case 'r': /* remote version */ remote_version = optarg; break; - case 'P': /* remote version */ + case 'P': /* remote version */ remote_protocol = optarg; break; - case 'H': /* host */ - if (!is_host (optarg)) - usage2 (_("Invalid hostname/address"), optarg); + case 'H': /* host */ + if (!is_host(optarg)) + usage2(_("Invalid hostname/address"), optarg); server_name = optarg; break; - case 'p': /* port */ - if (is_intpos (optarg)) { - port = atoi (optarg); - } - else { - usage2 (_("Port number must be a positive integer"), optarg); + case 'p': /* port */ + if (is_intpos(optarg)) { + port = atoi(optarg); + } else { + usage2(_("Port number must be a positive integer"), optarg); } } } c = optind; if (server_name == NULL && c < argc) { - if (is_host (argv[c])) { + if (is_host(argv[c])) { server_name = argv[c++]; } } if (port == -1 && c < argc) { - if (is_intpos (argv[c])) { - port = atoi (argv[c++]); - } - else { - print_usage (); - exit (STATE_UNKNOWN); + if (is_intpos(argv[c])) { + port = atoi(argv[c++]); + } else { + print_usage(); + exit(STATE_UNKNOWN); } } - return validate_arguments (); + return validate_arguments(); } -int -validate_arguments (void) -{ +int validate_arguments(void) { if (server_name == NULL) return ERROR; - if (port == -1) /* funky, but allows -p to override stray integer in args */ + if (port == -1) /* funky, but allows -p to override stray integer in args */ port = SSH_DFL_PORT; return OK; } - /************************************************************************ -* -* Try to connect to SSH server at specified server and port -* -*-----------------------------------------------------------------------*/ - + * + * Try to connect to SSH server at specified server and port + * + *-----------------------------------------------------------------------*/ -int -ssh_connect (char *haddr, int hport, char *remote_version, char *remote_protocol) -{ +int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_protocol) { int sd; int result; int len = 0; @@ -225,41 +208,41 @@ ssh_connect (char *haddr, int hport, char *remote_version, char *remote_protocol gettimeofday(&tv, NULL); - result = my_tcp_connect (haddr, hport, &sd); + result = my_tcp_connect(haddr, hport, &sd); if (result != STATE_OK) return result; - char *output = (char *) calloc (BUFF_SZ + 1, sizeof(char)); + char *output = (char *)calloc(BUFF_SZ + 1, sizeof(char)); ssize_t byte_offset = 0; - while ((version_control_string == NULL) && (recv_ret = recv(sd, output+byte_offset, BUFF_SZ - byte_offset, 0) > 0)) { + while ((version_control_string == NULL) && (recv_ret = recv(sd, output + byte_offset, BUFF_SZ - byte_offset, 0) > 0)) { if (strchr(output, '\n')) { /* we've got at least one full line, start parsing*/ byte_offset = 0; char *index = NULL; - while ((index = strchr(output+byte_offset, '\n')) != NULL) { + while ((index = strchr(output + byte_offset, '\n')) != NULL) { /*Partition the buffer so that this line is a separate string, * by replacing the newline with NUL*/ output[(index - output)] = '\0'; len = strlen(output + byte_offset); - if ((len >= 4) && (strncmp (output+byte_offset, "SSH-", 4) == 0)) { + if ((len >= 4) && (strncmp(output + byte_offset, "SSH-", 4) == 0)) { /*if the string starts with SSH-, this _should_ be a valid version control string*/ - version_control_string = output+byte_offset; - break; + version_control_string = output + byte_offset; + break; } /*the start of the next line (if one exists) will be after the current one (+ NUL)*/ byte_offset += (len + 1); } - if(version_control_string == NULL) { + if (version_control_string == NULL) { /* move unconsumed data to beginning of buffer, null rest */ - memmove((void *)output, (void *)output+byte_offset+1, BUFF_SZ - len+1); - memset(output+byte_offset+1, 0, BUFF_SZ-byte_offset+1); + memmove((void *)output, (void *)output + byte_offset + 1, BUFF_SZ - len + 1); + memset(output + byte_offset + 1, 0, BUFF_SZ - byte_offset + 1); /*start reading from end of current line chunk on next recv*/ byte_offset = strlen(output); @@ -285,9 +268,9 @@ ssh_connect (char *haddr, int hport, char *remote_version, char *remote_protocol * SSH-protoversion-softwareversion SP comments CR LF" * - RFC 4253:4.2 */ - strip (version_control_string); + strip(version_control_string); if (verbose) - printf ("%s\n", version_control_string); + printf("%s\n", version_control_string); ssh_proto = version_control_string + 4; /* @@ -306,7 +289,7 @@ ssh_connect (char *haddr, int hport, char *remote_version, char *remote_protocol * "1.x" (e.g., "1.5" or "1.3")." * - RFC 4253:5 */ - ssh_server = ssh_proto + strspn (ssh_proto, "0123456789.") + 1; /* (+1 for the '-' separating protoversion from softwareversion) */ + ssh_server = ssh_proto + strspn(ssh_proto, "0123456789.") + 1; /* (+1 for the '-' separating protoversion from softwareversion) */ /* If there's a space in the version string, whatever's after the space is a comment * (which is NOT part of the server name/version)*/ @@ -316,86 +299,71 @@ ssh_connect (char *haddr, int hport, char *remote_version, char *remote_protocol } if (strlen(ssh_proto) == 0 || strlen(ssh_server) == 0) { printf(_("SSH CRITICAL - Invalid protocol version control string %s\n"), version_control_string); - exit (STATE_CRITICAL); + exit(STATE_CRITICAL); } - ssh_proto[strspn (ssh_proto, "0123456789. ")] = 0; + ssh_proto[strspn(ssh_proto, "0123456789. ")] = 0; - xasprintf (&buffer, "SSH-%s-check_ssh_%s\r\n", ssh_proto, rev_no); - send (sd, buffer, strlen (buffer), MSG_DONTWAIT); + xasprintf(&buffer, "SSH-%s-check_ssh_%s\r\n", ssh_proto, rev_no); + send(sd, buffer, strlen(buffer), MSG_DONTWAIT); if (verbose) - printf ("%s\n", buffer); + printf("%s\n", buffer); if (remote_version && strcmp(remote_version, ssh_server)) { - printf - (_("SSH CRITICAL - %s (protocol %s) version mismatch, expected '%s'\n"), - ssh_server, ssh_proto, remote_version); + printf(_("SSH CRITICAL - %s (protocol %s) version mismatch, expected '%s'\n"), ssh_server, ssh_proto, remote_version); close(sd); - exit (STATE_CRITICAL); + exit(STATE_CRITICAL); } double elapsed_time = (double)deltime(tv) / 1.0e6; if (remote_protocol && strcmp(remote_protocol, ssh_proto)) { - printf - (_("SSH CRITICAL - %s (protocol %s) protocol version mismatch, expected '%s' | %s\n"), - ssh_server, ssh_proto, remote_protocol, fperfdata("time", elapsed_time, "s", - false, 0, false, 0, true, 0, true, (int)socket_timeout)); + printf(_("SSH CRITICAL - %s (protocol %s) protocol version mismatch, expected '%s' | %s\n"), ssh_server, ssh_proto, remote_protocol, + fperfdata("time", elapsed_time, "s", false, 0, false, 0, true, 0, true, (int)socket_timeout)); close(sd); - exit (STATE_CRITICAL); + exit(STATE_CRITICAL); } - printf - (_("SSH OK - %s (protocol %s) | %s\n"), - ssh_server, ssh_proto, fperfdata("time", elapsed_time, "s", - false, 0, false, 0, true, 0, true, (int)socket_timeout)); + printf(_("SSH OK - %s (protocol %s) | %s\n"), ssh_server, ssh_proto, + fperfdata("time", elapsed_time, "s", false, 0, false, 0, true, 0, true, (int)socket_timeout)); close(sd); - exit (STATE_OK); + exit(STATE_OK); } - - -void -print_help (void) -{ +void print_help(void) { char *myport; - xasprintf (&myport, "%d", SSH_DFL_PORT); + xasprintf(&myport, "%d", SSH_DFL_PORT); - print_revision (progname, NP_VERSION); + print_revision(progname, NP_VERSION); - printf ("Copyright (c) 1999 Remi Paulmier \n"); - printf (COPYRIGHT, copyright, email); + printf("Copyright (c) 1999 Remi Paulmier \n"); + printf(COPYRIGHT, copyright, email); - printf ("%s\n", _("Try to connect to an SSH server at specified server and port")); + printf("%s\n", _("Try to connect to an SSH server at specified server and port")); - printf ("\n\n"); + printf("\n\n"); - print_usage (); + print_usage(); - printf (UT_HELP_VRSN); - printf (UT_EXTRA_OPTS); + printf(UT_HELP_VRSN); + printf(UT_EXTRA_OPTS); - printf (UT_HOST_PORT, 'p', myport); + printf(UT_HOST_PORT, 'p', myport); - printf (UT_IPv46); + printf(UT_IPv46); - printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); + printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); - printf (" %s\n", "-r, --remote-version=STRING"); - printf (" %s\n", _("Alert if string doesn't match expected server version (ex: OpenSSH_3.9p1)")); + printf(" %s\n", "-r, --remote-version=STRING"); + printf(" %s\n", _("Alert if string doesn't match expected server version (ex: OpenSSH_3.9p1)")); - printf (" %s\n", "-P, --remote-protocol=STRING"); - printf (" %s\n", _("Alert if protocol doesn't match expected protocol version (ex: 2.0)")); + printf(" %s\n", "-P, --remote-protocol=STRING"); + printf(" %s\n", _("Alert if protocol doesn't match expected protocol version (ex: 2.0)")); - printf (UT_VERBOSE); + printf(UT_VERBOSE); - printf (UT_SUPPORT); + printf(UT_SUPPORT); } - - -void -print_usage (void) -{ - printf ("%s\n", _("Usage:")); - printf ("%s [-4|-6] [-t ] [-r ] [-p ] \n", progname); +void print_usage(void) { + printf("%s\n", _("Usage:")); + printf("%s [-4|-6] [-t ] [-r ] [-p ] \n", progname); } - -- cgit v1.2.3-74-g34f1 From 78258c4cd0dff4197e0642e6eb39a15c97c88807 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 31 Oct 2024 15:55:40 +0100 Subject: check_ssh: do not export local variables --- plugins/check_ssh.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'plugins/check_ssh.c') diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c index 9f805db4..b12cda1d 100644 --- a/plugins/check_ssh.c +++ b/plugins/check_ssh.c @@ -43,18 +43,18 @@ const char *email = "devel@monitoring-plugins.org"; #define SSH_DFL_PORT 22 #define BUFF_SZ 256 -int port = -1; -char *server_name = NULL; -char *remote_version = NULL; -char *remote_protocol = NULL; -bool verbose = false; - -int process_arguments(int, char **); -int validate_arguments(void); -void print_help(void); +static int port = -1; +static char *server_name = NULL; +static char *remote_version = NULL; +static char *remote_protocol = NULL; +static bool verbose = false; + +static int process_arguments(int, char **); +static int validate_arguments(void); +static void print_help(void); void print_usage(void); -int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_protocol); +static int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_protocol); int main(int argc, char **argv) { int result = STATE_UNKNOWN; -- cgit v1.2.3-74-g34f1 From 42ef1fa2fa37d7d684b624a4559c479e763457d0 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 31 Oct 2024 16:00:41 +0100 Subject: check_ssh: linter + style fixes --- plugins/check_ssh.c | 76 ++++++++++++++++++++++++----------------------------- 1 file changed, 34 insertions(+), 42 deletions(-) (limited to 'plugins/check_ssh.c') diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c index b12cda1d..42a88cf9 100644 --- a/plugins/check_ssh.c +++ b/plugins/check_ssh.c @@ -49,7 +49,7 @@ static char *remote_version = NULL; static char *remote_protocol = NULL; static bool verbose = false; -static int process_arguments(int, char **); +static int process_arguments(int /*argc*/, char ** /*argv*/); static int validate_arguments(void); static void print_help(void); void print_usage(void); @@ -57,8 +57,6 @@ void print_usage(void); static int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_protocol); int main(int argc, char **argv) { - int result = STATE_UNKNOWN; - setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); @@ -75,7 +73,7 @@ int main(int argc, char **argv) { alarm(socket_timeout); /* ssh_connect exits if error is found */ - result = ssh_connect(server_name, port, remote_version, remote_protocol); + int result = ssh_connect(server_name, port, remote_version, remote_protocol); alarm(0); @@ -84,9 +82,6 @@ int main(int argc, char **argv) { /* process command-line arguments */ int process_arguments(int argc, char **argv) { - int c; - - int option = 0; static struct option longopts[] = {{"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, {"host", required_argument, 0, 'H'}, /* backward compatibility */ @@ -103,17 +98,19 @@ int process_arguments(int argc, char **argv) { if (argc < 2) return ERROR; - for (c = 1; c < argc; c++) - if (strcmp("-to", argv[c]) == 0) - strcpy(argv[c], "-t"); + for (int i = 1; i < argc; i++) + if (strcmp("-to", argv[i]) == 0) + strcpy(argv[i], "-t"); - while (1) { - c = getopt_long(argc, argv, "+Vhv46t:r:H:p:P:", longopts, &option); + int option_char; + while (true) { + int option = 0; + option_char = getopt_long(argc, argv, "+Vhv46t:r:H:p:P:", longopts, &option); - if (c == -1 || c == EOF) + if (option_char == -1 || option_char == EOF) break; - switch (c) { + switch (option_char) { case '?': /* help */ usage5(); case 'V': /* version */ @@ -161,16 +158,16 @@ int process_arguments(int argc, char **argv) { } } - c = optind; - if (server_name == NULL && c < argc) { - if (is_host(argv[c])) { - server_name = argv[c++]; + option_char = optind; + if (server_name == NULL && option_char < argc) { + if (is_host(argv[option_char])) { + server_name = argv[option_char++]; } } - if (port == -1 && c < argc) { - if (is_intpos(argv[c])) { - port = atoi(argv[c++]); + if (port == -1 && option_char < argc) { + if (is_intpos(argv[option_char])) { + port = atoi(argv[option_char++]); } else { print_usage(); exit(STATE_UNKNOWN); @@ -195,34 +192,27 @@ int validate_arguments(void) { *-----------------------------------------------------------------------*/ int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_protocol) { - int sd; - int result; - int len = 0; - ssize_t recv_ret = 0; - char *version_control_string = NULL; - char *buffer = NULL; - char *ssh_proto = NULL; - char *ssh_server = NULL; - static char *rev_no = VERSION; struct timeval tv; - gettimeofday(&tv, NULL); - result = my_tcp_connect(haddr, hport, &sd); + int socket; + int result = my_tcp_connect(haddr, hport, &socket); if (result != STATE_OK) return result; char *output = (char *)calloc(BUFF_SZ + 1, sizeof(char)); - + char *buffer = NULL; + ssize_t recv_ret = 0; + char *version_control_string = NULL; ssize_t byte_offset = 0; - - while ((version_control_string == NULL) && (recv_ret = recv(sd, output + byte_offset, BUFF_SZ - byte_offset, 0) > 0)) { + while ((version_control_string == NULL) && (recv_ret = recv(socket, output + byte_offset, BUFF_SZ - byte_offset, 0) > 0)) { if (strchr(output, '\n')) { /* we've got at least one full line, start parsing*/ byte_offset = 0; char *index = NULL; + int len = 0; while ((index = strchr(output + byte_offset, '\n')) != NULL) { /*Partition the buffer so that this line is a separate string, * by replacing the newline with NUL*/ @@ -241,7 +231,7 @@ int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_proto if (version_control_string == NULL) { /* move unconsumed data to beginning of buffer, null rest */ - memmove((void *)output, (void *)output + byte_offset + 1, BUFF_SZ - len + 1); + memmove((void *)output, (void *)(output + byte_offset + 1), BUFF_SZ - len + 1); memset(output + byte_offset + 1, 0, BUFF_SZ - byte_offset + 1); /*start reading from end of current line chunk on next recv*/ @@ -271,7 +261,8 @@ int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_proto strip(version_control_string); if (verbose) printf("%s\n", version_control_string); - ssh_proto = version_control_string + 4; + + char *ssh_proto = version_control_string + 4; /* * We assume the protoversion is of the form Major.Minor, although @@ -289,7 +280,7 @@ int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_proto * "1.x" (e.g., "1.5" or "1.3")." * - RFC 4253:5 */ - ssh_server = ssh_proto + strspn(ssh_proto, "0123456789.") + 1; /* (+1 for the '-' separating protoversion from softwareversion) */ + char *ssh_server = ssh_proto + strspn(ssh_proto, "0123456789.") + 1; /* (+1 for the '-' separating protoversion from softwareversion) */ /* If there's a space in the version string, whatever's after the space is a comment * (which is NOT part of the server name/version)*/ @@ -303,14 +294,15 @@ int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_proto } ssh_proto[strspn(ssh_proto, "0123456789. ")] = 0; + static char *rev_no = VERSION; xasprintf(&buffer, "SSH-%s-check_ssh_%s\r\n", ssh_proto, rev_no); - send(sd, buffer, strlen(buffer), MSG_DONTWAIT); + send(socket, buffer, strlen(buffer), MSG_DONTWAIT); if (verbose) printf("%s\n", buffer); if (remote_version && strcmp(remote_version, ssh_server)) { printf(_("SSH CRITICAL - %s (protocol %s) version mismatch, expected '%s'\n"), ssh_server, ssh_proto, remote_version); - close(sd); + close(socket); exit(STATE_CRITICAL); } @@ -318,13 +310,13 @@ int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_proto if (remote_protocol && strcmp(remote_protocol, ssh_proto)) { printf(_("SSH CRITICAL - %s (protocol %s) protocol version mismatch, expected '%s' | %s\n"), ssh_server, ssh_proto, remote_protocol, fperfdata("time", elapsed_time, "s", false, 0, false, 0, true, 0, true, (int)socket_timeout)); - close(sd); + close(socket); exit(STATE_CRITICAL); } printf(_("SSH OK - %s (protocol %s) | %s\n"), ssh_server, ssh_proto, fperfdata("time", elapsed_time, "s", false, 0, false, 0, true, 0, true, (int)socket_timeout)); - close(sd); + close(socket); exit(STATE_OK); } -- cgit v1.2.3-74-g34f1