summaryrefslogtreecommitdiffstats
path: root/plugins/check_ssh.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_ssh.c')
-rw-r--r--plugins/check_ssh.c122
1 files changed, 85 insertions, 37 deletions
diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c
index 8ccbd5a..8a3abb0 100644
--- a/plugins/check_ssh.c
+++ b/plugins/check_ssh.c
@@ -215,8 +215,13 @@ ssh_connect (char *haddr, int hport, char *remote_version, char *remote_protocol
215{ 215{
216 int sd; 216 int sd;
217 int result; 217 int result;
218 int len = 0;
219 ssize_t byte_offset = 0;
220 ssize_t recv_ret = 0;
221 char *version_control_string = NULL;
218 char *output = NULL; 222 char *output = NULL;
219 char *buffer = NULL; 223 char *buffer = NULL;
224 char *tmp= NULL, *saveptr = NULL;
220 char *ssh_proto = NULL; 225 char *ssh_proto = NULL;
221 char *ssh_server = NULL; 226 char *ssh_server = NULL;
222 static char *rev_no = VERSION; 227 static char *rev_no = VERSION;
@@ -231,51 +236,94 @@ ssh_connect (char *haddr, int hport, char *remote_version, char *remote_protocol
231 return result; 236 return result;
232 237
233 output = (char *) malloc (BUFF_SZ + 1); 238 output = (char *) malloc (BUFF_SZ + 1);
234 memset (output, 0, BUFF_SZ + 1); 239 memset(output, 0, BUFF_SZ+1);
235 recv (sd, output, BUFF_SZ, 0); 240 while (!version_control_string && (recv_ret = recv(sd, output+byte_offset, BUFF_SZ - byte_offset, 0)) > 0) {
236 if (strncmp (output, "SSH", 3)) { 241 if (strchr(output, '\n')) { /* we've got at least one full line, start parsing*/
237 printf (_("Server answer: %s"), output); 242 byte_offset = 0;
238 close(sd); 243 while (strchr(output+byte_offset, '\n') != NULL) {
244 /*Partition the buffer so that this line is a separate string,
245 * by replacing the newline with NUL*/
246 output[(strchr(output+byte_offset, '\n')-output)]= '\0';
247 len = strlen(output+byte_offset);
248 if (len >= 4) {
249 /*if the string starts with SSH-, this _should_ be a valid version control string*/
250 if (strncmp (output+byte_offset, "SSH-", 4) == 0) {
251 version_control_string = output+byte_offset;
252 break;
253 }
254 }
255
256 /*the start of the next line (if one exists) will be after the current one (+ NUL)*/
257 byte_offset+=len+1;
258 }
259 if(!version_control_string) {
260 /* move unconsumed data to beginning of buffer, null rest */
261 memmove((void *)output, (void *)output+byte_offset+1, BUFF_SZ - len+1);
262 memset(output+byte_offset+1, 0, BUFF_SZ-byte_offset+1);
263
264 /*start reading from end of current line chunk on next recv*/
265 byte_offset = strlen(output);
266 }
267 }
268 else {
269 byte_offset += recv_ret;
270 }
271 }
272 tmp = NULL;
273 if (recv_ret < 0) {
274 printf("SSH CRITICAL - %s", strerror(errno));
275 exit(STATE_CRITICAL);
276 }
277 if (!version_control_string) {
278 printf("SSH CRITICAL - No version control string received");
279 exit(STATE_CRITICAL);
280 }
281 strip (version_control_string);
282 if (verbose)
283 printf ("%s\n", version_control_string);
284 ssh_proto = version_control_string + 4;
285 ssh_server = ssh_proto + strspn (ssh_proto, "-0123456789.");
286
287 /* 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)*/
289 tmp = strchr(ssh_server, ' ');
290 if (tmp) {
291 ssh_server[tmp - ssh_server] = '\0';
292 }
293 if (strlen(ssh_proto) == 0 || strlen(ssh_server) == 0) {
294 printf(_("SSH CRITICAL - Invalid protocol version control string %s\n"), version_control_string);
239 exit (STATE_CRITICAL); 295 exit (STATE_CRITICAL);
240 } 296 }
241 else { 297 ssh_proto[strspn (ssh_proto, "0123456789. ")] = 0;
242 strip (output);
243 if (verbose)
244 printf ("%s\n", output);
245 ssh_proto = output + 4;
246 ssh_server = ssh_proto + strspn (ssh_proto, "-0123456789. ");
247 ssh_proto[strspn (ssh_proto, "0123456789. ")] = 0;
248
249 xasprintf (&buffer, "SSH-%s-check_ssh_%s\r\n", ssh_proto, rev_no);
250 send (sd, buffer, strlen (buffer), MSG_DONTWAIT);
251 if (verbose)
252 printf ("%s\n", buffer);
253
254 if (remote_version && strcmp(remote_version, ssh_server)) {
255 printf
256 (_("SSH CRITICAL - %s (protocol %s) version mismatch, expected '%s'\n"),
257 ssh_server, ssh_proto, remote_version);
258 close(sd);
259 exit (STATE_CRITICAL);
260 }
261 298
262 if (remote_protocol && strcmp(remote_protocol, ssh_proto)) { 299 xasprintf (&buffer, "SSH-%s-check_ssh_%s\r\n", ssh_proto, rev_no);
263 printf 300 send (sd, buffer, strlen (buffer), MSG_DONTWAIT);
264 (_("SSH CRITICAL - %s (protocol %s) protocol version mismatch, expected '%s'\n"), 301 if (verbose)
265 ssh_server, ssh_proto, remote_protocol); 302 printf ("%s\n", buffer);
266 close(sd);
267 exit (STATE_CRITICAL);
268 }
269 303
270 elapsed_time = (double)deltime(tv) / 1.0e6; 304 if (remote_version && strcmp(remote_version, ssh_server)) {
305 printf
306 (_("SSH CRITICAL - %s (protocol %s) version mismatch, expected '%s'\n"),
307 ssh_server, ssh_proto, remote_version);
308 close(sd);
309 exit (STATE_CRITICAL);
310 }
271 311
312 if (remote_protocol && strcmp(remote_protocol, ssh_proto)) {
272 printf 313 printf
273 (_("SSH OK - %s (protocol %s) | %s\n"), 314 (_("SSH CRITICAL - %s (protocol %s) protocol version mismatch, expected '%s'\n"),
274 ssh_server, ssh_proto, fperfdata("time", elapsed_time, "s", 315 ssh_server, ssh_proto, remote_protocol);
275 FALSE, 0, FALSE, 0, TRUE, 0, TRUE, (int)socket_timeout));
276 close(sd); 316 close(sd);
277 exit (STATE_OK); 317 exit (STATE_CRITICAL);
278 } 318 }
319 elapsed_time = (double)deltime(tv) / 1.0e6;
320
321 printf
322 (_("SSH OK - %s (protocol %s) | %s\n"),
323 ssh_server, ssh_proto, fperfdata("time", elapsed_time, "s",
324 FALSE, 0, FALSE, 0, TRUE, 0, TRUE, (int)socket_timeout));
325 close(sd);
326 exit (STATE_OK);
279} 327}
280 328
281 329