int ssh_connect (char *haddr, int hport, char *remote_version) { int sd; int result; char *output = NULL; char *buffer = NULL; char *ssh_proto = NULL; char *ssh_server = NULL; static char *rev_no = VERSION; struct timeval tv; double elapsed_time; gettimeofday(&tv, NULL); result = my_tcp_connect (haddr, hport, &sd); 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); 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 WARNING - %s (protocol %s) version mismatch, expected '%s'\n"), ssh_server, ssh_proto, remote_version); close(sd); exit (STATE_WARNING); } 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); } }
int main (int argc, char **argv) { short supports_tls=FALSE; int n = 0; double elapsed_time; long microsec; int result = STATE_UNKNOWN; char *cmd_str = NULL; char *helocmd = NULL; char *error_msg = ""; struct timeval tv; /* Catch pipe errors in read/write - sometimes occurs when writing QUIT */ (void) signal (SIGPIPE, SIG_IGN); setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); /* Parse extra opts if any */ argv=np_extra_opts (&argc, argv, progname); if (process_arguments (argc, argv) == ERROR) usage4 (_("Could not parse arguments")); /* If localhostname not set on command line, use gethostname to set */ if(! localhostname){ localhostname = malloc (HOST_MAX_BYTES); if(!localhostname){ printf(_("malloc() failed!\n")); return STATE_CRITICAL; } if(gethostname(localhostname, HOST_MAX_BYTES)){ printf(_("gethostname() failed!\n")); return STATE_CRITICAL; } } if(use_ehlo) xasprintf (&helocmd, "%s%s%s", SMTP_EHLO, localhostname, "\r\n"); else xasprintf (&helocmd, "%s%s%s", SMTP_HELO, localhostname, "\r\n"); if (verbose) printf("HELOCMD: %s", helocmd); /* initialize the MAIL command with optional FROM command */ xasprintf (&cmd_str, "%sFROM:<%s>%s", mail_command, from_arg, "\r\n"); if (verbose && send_mail_from) printf ("FROM CMD: %s", cmd_str); /* initialize alarm signal handling */ (void) signal (SIGALRM, socket_timeout_alarm_handler); /* set socket timeout */ (void) alarm (socket_timeout); /* start timer */ gettimeofday (&tv, NULL); /* try to connect to the host at the given port number */ result = my_tcp_connect (server_address, server_port, &sd); if (result == STATE_OK) { /* we connected */ /* watch for the SMTP connection string and */ /* return a WARNING status if we couldn't read any data */ if (recvlines(buffer, MAX_INPUT_BUFFER) <= 0) { printf (_("recv() failed\n")); return STATE_WARNING; } else { if (verbose) printf ("%s", buffer); /* strip the buffer of carriage returns */ strip (buffer); /* make sure we find the response we are looking for */ if (!strstr (buffer, server_expect)) { if (server_port == SMTP_PORT) printf (_("Invalid SMTP response received from host: %s\n"), buffer); else printf (_("Invalid SMTP response received from host on port %d: %s\n"), server_port, buffer); return STATE_WARNING; } } /* send the HELO/EHLO command */ send(sd, helocmd, strlen(helocmd), 0); /* allow for response to helo command to reach us */ if (recvlines(buffer, MAX_INPUT_BUFFER) <= 0) { printf (_("recv() failed\n")); return STATE_WARNING; } else if(use_ehlo){ if(strstr(buffer, "250 STARTTLS") != NULL || strstr(buffer, "250-STARTTLS") != NULL){ supports_tls=TRUE; } } if(use_ssl && ! supports_tls){ printf(_("WARNING - TLS not supported by server\n")); smtp_quit(); return STATE_WARNING; } #ifdef HAVE_SSL if(use_ssl) { /* send the STARTTLS command */ send(sd, SMTP_STARTTLS, strlen(SMTP_STARTTLS), 0); recvlines(buffer, MAX_INPUT_BUFFER); /* wait for it */ if (!strstr (buffer, server_expect)) { printf (_("Server does not support STARTTLS\n")); smtp_quit(); return STATE_UNKNOWN; } result = np_net_ssl_init(sd); if(result != STATE_OK) { printf (_("CRITICAL - Cannot create SSL context.\n")); np_net_ssl_cleanup(); close(sd); return STATE_CRITICAL; } else { ssl_established = 1; } /* * Resend the EHLO command. * * RFC 3207 (4.2) says: ``The client MUST discard any knowledge * obtained from the server, such as the list of SMTP service * extensions, which was not obtained from the TLS negotiation * itself. The client SHOULD send an EHLO command as the first * command after a successful TLS negotiation.'' For this * reason, some MTAs will not allow an AUTH LOGIN command before * we resent EHLO via TLS. */ if (my_send(helocmd, strlen(helocmd)) <= 0) { printf("%s\n", _("SMTP UNKNOWN - Cannot send EHLO command via TLS.")); my_close(); return STATE_UNKNOWN; } if (verbose) printf(_("sent %s"), helocmd); if ((n = recvlines(buffer, MAX_INPUT_BUFFER)) <= 0) { printf("%s\n", _("SMTP UNKNOWN - Cannot read EHLO response via TLS.")); my_close(); return STATE_UNKNOWN; } if (verbose) { printf("%s", buffer); } # ifdef USE_OPENSSL if ( check_cert ) { result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit); my_close(); return result; } # endif /* USE_OPENSSL */ } #endif if (send_mail_from) { my_send(cmd_str, strlen(cmd_str)); if (recvlines(buffer, MAX_INPUT_BUFFER) >= 1 && verbose) printf("%s", buffer); } while (n < ncommands) { xasprintf (&cmd_str, "%s%s", commands[n], "\r\n"); my_send(cmd_str, strlen(cmd_str)); if (recvlines(buffer, MAX_INPUT_BUFFER) >= 1 && verbose) printf("%s", buffer); strip (buffer); if (n < nresponses) { cflags |= REG_EXTENDED | REG_NOSUB | REG_NEWLINE; errcode = regcomp (&preg, responses[n], cflags); if (errcode != 0) { regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); printf (_("Could Not Compile Regular Expression")); return ERROR; } excode = regexec (&preg, buffer, 10, pmatch, eflags); if (excode == 0) { result = STATE_OK; } else if (excode == REG_NOMATCH) { result = STATE_WARNING; printf (_("SMTP %s - Invalid response '%s' to command '%s'\n"), state_text (result), buffer, commands[n]); } else { regerror (excode, &preg, errbuf, MAX_INPUT_BUFFER); printf (_("Execute Error: %s\n"), errbuf); result = STATE_UNKNOWN; } } n++; } if (authtype != NULL) { if (strcmp (authtype, "LOGIN") == 0) { char *abuf; int ret; do { if (authuser == NULL) { result = STATE_CRITICAL; xasprintf(&error_msg, _("no authuser specified, ")); break; } if (authpass == NULL) { result = STATE_CRITICAL; xasprintf(&error_msg, _("no authpass specified, ")); break; } /* send AUTH LOGIN */ my_send(SMTP_AUTH_LOGIN, strlen(SMTP_AUTH_LOGIN)); if (verbose) printf (_("sent %s\n"), "AUTH LOGIN"); if ((ret = recvlines(buffer, MAX_INPUT_BUFFER)) <= 0) { xasprintf(&error_msg, _("recv() failed after AUTH LOGIN, ")); result = STATE_WARNING; break; } if (verbose) printf (_("received %s\n"), buffer); if (strncmp (buffer, "334", 3) != 0) { result = STATE_CRITICAL; xasprintf(&error_msg, _("invalid response received after AUTH LOGIN, ")); break; } /* encode authuser with base64 */ base64_encode_alloc (authuser, strlen(authuser), &abuf); xasprintf(&abuf, "%s\r\n", abuf); my_send(abuf, strlen(abuf)); if (verbose) printf (_("sent %s\n"), abuf); if ((ret = recvlines(buffer, MAX_INPUT_BUFFER)) <= 0) { result = STATE_CRITICAL; xasprintf(&error_msg, _("recv() failed after sending authuser, ")); break; } if (verbose) { printf (_("received %s\n"), buffer); } if (strncmp (buffer, "334", 3) != 0) { result = STATE_CRITICAL; xasprintf(&error_msg, _("invalid response received after authuser, ")); break; } /* encode authpass with base64 */ base64_encode_alloc (authpass, strlen(authpass), &abuf); xasprintf(&abuf, "%s\r\n", abuf); my_send(abuf, strlen(abuf)); if (verbose) { printf (_("sent %s\n"), abuf); } if ((ret = recvlines(buffer, MAX_INPUT_BUFFER)) <= 0) { result = STATE_CRITICAL; xasprintf(&error_msg, _("recv() failed after sending authpass, ")); break; } if (verbose) { printf (_("received %s\n"), buffer); } if (strncmp (buffer, "235", 3) != 0) { result = STATE_CRITICAL; xasprintf(&error_msg, _("invalid response received after authpass, ")); break; } break; } while (0); } else { result = STATE_CRITICAL; xasprintf(&error_msg, _("only authtype LOGIN is supported, ")); } } /* tell the server we're done */ smtp_quit(); /* finally close the connection */ close (sd); } /* reset the alarm */ alarm (0); microsec = deltime (tv); elapsed_time = (double)microsec / 1.0e6; if (result == STATE_OK) { if (check_critical_time && elapsed_time > critical_time) result = STATE_CRITICAL; else if (check_warning_time && elapsed_time > warning_time) result = STATE_WARNING; } printf (_("SMTP %s - %s%.3f sec. response time%s%s|%s\n"), state_text (result), error_msg, elapsed_time, verbose?", ":"", verbose?buffer:"", fperfdata ("time", elapsed_time, "s", (int)check_warning_time, warning_time, (int)check_critical_time, critical_time, TRUE, 0, FALSE, 0)); return result; }
int main (int argc, char **argv) { int sd; int result = STATE_UNKNOWN; time_t conntime; setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); /* Parse extra opts if any */ argv=np_extra_opts (&argc, argv, progname); if (process_arguments (argc, argv) == ERROR) usage4 (_("Could not parse arguments")); /* initialize alarm signal handling */ signal (SIGALRM, socket_timeout_alarm_handler); /* set socket timeout */ alarm (socket_timeout); time (&start_time); /* try to connect to the host at the given port number */ if (use_udp) { result = my_udp_connect (server_address, server_port, &sd); } else { result = my_tcp_connect (server_address, server_port, &sd); } if (result != STATE_OK) { if (check_critical_time == TRUE) result = STATE_CRITICAL; else if (check_warning_time == TRUE) result = STATE_WARNING; else result = STATE_UNKNOWN; die (result, _("TIME UNKNOWN - could not connect to server %s, port %d\n"), server_address, server_port); } if (use_udp) { if (send (sd, "", 0, 0) < 0) { if (check_critical_time == TRUE) result = STATE_CRITICAL; else if (check_warning_time == TRUE) result = STATE_WARNING; else result = STATE_UNKNOWN; die (result, _("TIME UNKNOWN - could not send UDP request to server %s, port %d\n"), server_address, server_port); } } /* watch for the connection string */ result = recv (sd, (void *)&raw_server_time, sizeof (raw_server_time), 0); /* close the connection */ close (sd); /* reset the alarm */ time (&end_time); alarm (0); /* return a WARNING status if we couldn't read any data */ if (result <= 0) { if (check_critical_time == TRUE) result = STATE_CRITICAL; else if (check_warning_time == TRUE) result = STATE_WARNING; else result = STATE_UNKNOWN; die (result, _("TIME UNKNOWN - no data received from server %s, port %d\n"), server_address, server_port); } result = STATE_OK; conntime = (end_time - start_time); if (check_critical_time == TRUE && conntime > critical_time) result = STATE_CRITICAL; else if (check_warning_time == TRUE && conntime > warning_time) result = STATE_WARNING; if (result != STATE_OK) die (result, _("TIME %s - %d second response time|%s\n"), state_text (result), (int)conntime, perfdata ("time", (long)conntime, "s", check_warning_time, (long)warning_time, check_critical_time, (long)critical_time, TRUE, 0, FALSE, 0)); server_time = ntohl (raw_server_time) - UNIX_EPOCH; if (server_time > (unsigned long)end_time) diff_time = server_time - (unsigned long)end_time; else diff_time = (unsigned long)end_time - server_time; if (check_critical_diff == TRUE && diff_time > critical_diff) result = STATE_CRITICAL; else if (check_warning_diff == TRUE && diff_time > warning_diff) result = STATE_WARNING; printf (_("TIME %s - %lu second time difference|%s %s\n"), state_text (result), diff_time, perfdata ("time", (long)conntime, "s", check_warning_time, (long)warning_time, check_critical_time, (long)critical_time, TRUE, 0, FALSE, 0), perfdata ("offset", diff_time, "s", check_warning_diff, warning_diff, check_critical_diff, critical_diff, TRUE, 0, FALSE, 0)); return result; }
int get_http_status() { if (my_tcp_connect (server_address, server_port, &sd) == 0) { close(sd); if (DEBUG) { printf("connect host %s at %d\n", server_address, server_port); } return 0; } else { close(sd); return -1; if (DEBUG) { printf("cat't connect host %s at %d\n", server_address, server_port); } } int i = 0; int http_status; char *buf; char *full_page; char *page; char *status_line; char *status_code; size_t pagesize = 0; asprintf (&buf, "GET %s HTTP/1.0\r\nUser-Agent: check_http\r\n", URL); /* tell HTTP/1.1 servers not to keep the connection alive */ asprintf (&buf, "%sConnection: close\r\n", buf); if (server_address) { asprintf (&buf, "%sHost: %s:%d\r\n", buf, server_address, server_port); } asprintf (&buf, "%s%s", buf, CRLF); if (DEBUG) { printf ("send %s\n", buf); } my_send (buf, strlen (buf)); full_page = strdup(""); while ((i = my_recv (buffer, MAX_INPUT_BUFFER-1)) > 0) { buffer[i] = '\0'; asprintf (&full_page, "%s%s", full_page, buffer); pagesize += i; if (document_headers_done (full_page)) { i = 0; break; } } if (DEBUG) { printf("%s\n", full_page); } if (i < 0 && errno != ECONNRESET) { printf("HTTP CRITICAL - Error on receive\n"); } /* return a CRITICAL status if we couldn't read any data */ if (pagesize == (size_t) 0){ printf("HTTP CRITICAL - No data received from host\n"); } /* close the connect */ if (sd) { close(sd); } /* find status line and null-terminate it */ page = full_page; page += (size_t) strspn (page, "\r\n"); status_line = page; status_line[strcspn(status_line, "\r\n")] = 0; if (DEBUG) { printf ("STATUS: %s\n", status_line); } status_code = strchr (status_line, ' ') + sizeof (char); http_status = atoi (status_code); return http_status; }
int main (int argc, char **argv) { int sd; int result = STATE_UNKNOWN; char buffer[MAX_INPUT_BUFFER]; char *status_line = NULL; setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); if (process_arguments (argc, argv) == ERROR) usage4 (_("Could not parse arguments")); /* initialize alarm signal handling */ signal (SIGALRM, socket_timeout_alarm_handler); /* set socket timeout */ alarm (socket_timeout); time (&start_time); /* try to connect to the host at the given port number */ if (my_tcp_connect (server_address, server_port, &sd) != STATE_OK) die (STATE_CRITICAL, _("Unable to connect to %s on port %d\n"), server_address, server_port); /* Part I - Server Check */ /* send the OPTIONS request */ sprintf (buffer, "OPTIONS rtsp://%s:%d RTSP/1.0\r\n", host_name, server_port); result = send (sd, buffer, strlen (buffer), 0); /* send the header sync */ sprintf (buffer, "CSeq: 1\r\n"); result = send (sd, buffer, strlen (buffer), 0); /* send a newline so the server knows we're done with the request */ sprintf (buffer, "\r\n"); result = send (sd, buffer, strlen (buffer), 0); /* watch for the REAL connection string */ result = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0); /* return a CRITICAL status if we couldn't read any data */ if (result == -1) die (STATE_CRITICAL, _("No data received from %s\n"), host_name); /* make sure we find the response we are looking for */ if (!strstr (buffer, server_expect)) { if (server_port == PORT) printf ("%s\n", _("Invalid REAL response received from host")); else printf (_("Invalid REAL response received from host on port %d\n"), server_port); } else { /* else we got the REAL string, so check the return code */ time (&end_time); result = STATE_OK; status_line = (char *) strtok (buffer, "\n"); if (strstr (status_line, "200")) result = STATE_OK; /* client errors result in a warning state */ else if (strstr (status_line, "400")) result = STATE_WARNING; else if (strstr (status_line, "401")) result = STATE_WARNING; else if (strstr (status_line, "402")) result = STATE_WARNING; else if (strstr (status_line, "403")) result = STATE_WARNING; else if (strstr (status_line, "404")) result = STATE_WARNING; /* server errors result in a critical state */ else if (strstr (status_line, "500")) result = STATE_CRITICAL; else if (strstr (status_line, "501")) result = STATE_CRITICAL; else if (strstr (status_line, "502")) result = STATE_CRITICAL; else if (strstr (status_line, "503")) result = STATE_CRITICAL; else result = STATE_UNKNOWN; } /* Part II - Check stream exists and is ok */ if ((result == STATE_OK )&& (server_url != NULL) ) { /* Part I - Server Check */ /* send the OPTIONS request */ sprintf (buffer, "DESCRIBE rtsp://%s:%d%s RTSP/1.0\n", host_name, server_port, server_url); result = send (sd, buffer, strlen (buffer), 0); /* send the header sync */ sprintf (buffer, "CSeq: 2\n"); result = send (sd, buffer, strlen (buffer), 0); /* send a newline so the server knows we're done with the request */ sprintf (buffer, "\n"); result = send (sd, buffer, strlen (buffer), 0); /* watch for the REAL connection string */ result = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0); /* return a CRITICAL status if we couldn't read any data */ if (result == -1) { printf (_("No data received from host\n")); result = STATE_CRITICAL; } else { /* make sure we find the response we are looking for */ if (!strstr (buffer, server_expect)) { if (server_port == PORT) printf ("%s\n", _("Invalid REAL response received from host")); else printf (_("Invalid REAL response received from host on port %d\n"), server_port); } else { /* else we got the REAL string, so check the return code */ time (&end_time); result = STATE_OK; status_line = (char *) strtok (buffer, "\n"); if (strstr (status_line, "200")) result = STATE_OK; /* client errors result in a warning state */ else if (strstr (status_line, "400")) result = STATE_WARNING; else if (strstr (status_line, "401")) result = STATE_WARNING; else if (strstr (status_line, "402")) result = STATE_WARNING; else if (strstr (status_line, "403")) result = STATE_WARNING; else if (strstr (status_line, "404")) result = STATE_WARNING; /* server errors result in a critical state */ else if (strstr (status_line, "500")) result = STATE_CRITICAL; else if (strstr (status_line, "501")) result = STATE_CRITICAL; else if (strstr (status_line, "502")) result = STATE_CRITICAL; else if (strstr (status_line, "503")) result = STATE_CRITICAL; else result = STATE_UNKNOWN; } } } /* Return results */ if (result == STATE_OK) { if (check_critical_time == TRUE && (end_time - start_time) > critical_time) result = STATE_CRITICAL; else if (check_warning_time == TRUE && (end_time - start_time) > warning_time) result = STATE_WARNING; /* Put some HTML in here to create a dynamic link */ printf (_("REAL %s - %d second response time\n"), state_text (result), (int) (end_time - start_time)); } else printf ("%s\n", status_line); /* close the connection */ close (sd); /* reset the alarm */ alarm (0); return result; }
int main(int argc, char **argv) { int sd; int rc; int result; data_packet send_packet; int bytes_to_send; char input[MAX_INPUT_BUFFER]; char input_buffer[MAX_INPUT_BUFFER]; char *temp_ptr; char host_name[MAX_HOSTNAME_LENGTH]; char svc_description[MAX_DESCRIPTION_LENGTH]; char plugin_output[MAX_PLUGINOUTPUT_LENGTH]; int total_packets = 0; int16_t return_code; u_int32_t calculated_crc32; char *inputptr, *ptr1, *ptr2, *ptr3, *ptr4; /* process command-line arguments */ result = process_arguments(argc, argv); if (result != OK || show_help == TRUE || show_license == TRUE || show_version == TRUE) { if (result != OK) printf("Incorrect command line arguments supplied\n"); printf("\n"); printf("NSCA Client %s\n", PROGRAM_VERSION); printf("Copyright (c) 2010-2012 Icinga Development Team and Community Contributors (http://www.icinga.org)\n"); printf("Copyright (c) 2000-2007 Ethan Galstad (www.nagios.org)\n"); printf("Last Modified: %s\n", MODIFICATION_DATE); printf("License: GPL v2\n"); printf("Encryption Routines: "); #ifdef HAVE_LIBMCRYPT printf("AVAILABLE"); #else printf("NOT AVAILABLE"); #endif printf("\n"); printf("\n"); } if (result != OK || show_help == TRUE) { printf("Usage: %s -H <host_address> [-p port] [-to to_sec] [-d delim] [-c config_file]\n", argv[0]); printf("\n"); printf("Options:\n"); printf(" <host_address> = The IP address of the host running the NSCA daemon\n"); printf(" [port] = The port on which the daemon is running - default is %s\n", DEFAULT_SERVER_PORT); printf(" [to_sec] = Number of seconds before connection attempt times out.\n"); printf(" (default timeout is %d seconds)\n", DEFAULT_SOCKET_TIMEOUT); printf(" [delim] = Delimiter to use when parsing input (defaults to a tab)\n"); printf(" [config_file] = Name of config file to use\n"); printf("\n"); printf("Note:\n"); printf("This utility is used to send passive check results to the NSCA daemon. Host and\n"); printf("Service check data that is to be sent to the NSCA daemon is read from standard\n"); printf("input. Input should be provided in the following format (tab-delimited unless\n"); printf("overriden with -d command line argument, one entry per line):\n"); printf("\n"); printf("Service Checks:\n"); printf("<host_name>[tab]<svc_description>[tab]<return_code>[tab]<plugin_output>[newline]\n\n"); printf("Host Checks:\n"); printf("<host_name>[tab]<return_code>[tab]<plugin_output>[newline]\n\n"); printf("When submitting multiple simultaneous results, separate each set with the ETB\n"); printf("character (^W or 0x17)\n"); printf("\n"); } if (show_license == TRUE) display_license(); if (result != OK || show_help == TRUE || show_license == TRUE || show_version == TRUE) do_exit(STATE_UNKNOWN); /* read the config file */ result = read_config_file(config_file); /* exit if there are errors... */ if (result == ERROR) { printf("Error: Config file '%s' contained errors...\n", config_file); do_exit(STATE_CRITICAL); } /* generate the CRC 32 table */ generate_crc32_table(); /* initialize alarm signal handling */ signal(SIGALRM, alarm_handler); /* set socket timeout */ alarm(socket_timeout); time(&start_time); /* try to connect to the host at the given port number */ result = my_tcp_connect(server_name, server_port, &sd); /* we couldn't connect */ if (result != STATE_OK) { printf("Error: Could not connect to host %s on port %s\n", server_name, server_port); do_exit(STATE_CRITICAL); } #ifdef DEBUG printf("Connected okay...\n"); #endif /* read the initialization packet containing the IV and timestamp */ result = read_init_packet(sd); if (result != OK) { printf("Error: Could not read init packet from server\n"); close(sd); do_exit(STATE_CRITICAL); } #ifdef DEBUG printf("Got init packet from server\n"); #endif /* initialize encryption/decryption routines with the IV we received from the server */ if (encrypt_init(password, encryption_method, received_iv, &CI) != OK) { printf("Error: Failed to initialize encryption libraries for method %d\n", encryption_method); close(sd); do_exit(STATE_CRITICAL); } #ifdef DEBUG printf("Initialized encryption routines\n"); #endif /**** WE'RE CONNECTED AND READY TO SEND ****/ /* read all data from STDIN until there isn't anymore */ while (!feof(stdin)) { int c = getc(stdin); if (c == -1) { break; } int pos = 0; while (c != 23) { if (c == -1) { // in case we don't terminate properly, or are in single-input mode. break; } input_buffer[pos] = c; c = getc(stdin); pos++; } input_buffer[pos] = 0; strip(input_buffer); if (!strcmp(input_buffer, "")) continue; /* get the host name */ ptr1 = strtok(input_buffer, delimiter); if (ptr1 == NULL) continue; /* get the service description or return code */ ptr2 = strtok(NULL, delimiter); if (ptr2 == NULL) continue; /* get the return code or plugin output */ ptr3 = strtok(NULL, delimiter); if (ptr3 == NULL) continue; /* get the plugin output - if NULL, this is a host check result */ ptr4 = strtok(NULL, "\x0"); strncpy(host_name, ptr1, sizeof(host_name) - 1); host_name[sizeof(host_name) - 1] = '\x0'; if (ptr4 == NULL) { strcpy(svc_description, ""); return_code = atoi(ptr2); ptr3 = escape_newlines(ptr3); strncpy(plugin_output, ptr3, sizeof(plugin_output) - 1); } else { strncpy(svc_description, ptr2, sizeof(svc_description) - 1); return_code = atoi(ptr3); ptr4 = escape_newlines(ptr4); strncpy(plugin_output, ptr4, sizeof(plugin_output) - 1); } svc_description[sizeof(svc_description) - 1] = '\x0'; plugin_output[sizeof(plugin_output) - 1] = '\x0'; /* increment count of packets we're sending */ total_packets++; /* clear the packet buffer */ bzero(&send_packet, sizeof(send_packet)); /* fill the packet with semi-random data */ randomize_buffer((char *)&send_packet, sizeof(send_packet)); /* copy the data we want to send into the packet */ send_packet.packet_version = (int16_t)htons(NSCA_PACKET_VERSION_3); send_packet.return_code = (int16_t)htons(return_code); strcpy(&send_packet.host_name[0], host_name); strcpy(&send_packet.svc_description[0], svc_description); strcpy(&send_packet.plugin_output[0], plugin_output); /* use timestamp provided by the server */ send_packet.timestamp = (u_int32_t)htonl(packet_timestamp); /* calculate the crc 32 value of the packet */ send_packet.crc32_value = (u_int32_t)0L; calculated_crc32 = calculate_crc32((char *)&send_packet, sizeof(send_packet)); send_packet.crc32_value = (u_int32_t)htonl(calculated_crc32); /* encrypt the packet */ encrypt_buffer((char *)&send_packet, sizeof(send_packet), password, encryption_method, CI); /* send the packet */ bytes_to_send = sizeof(send_packet); rc = sendall(sd, (char *)&send_packet, &bytes_to_send); /* there was an error sending the packet */ if (rc == -1) { printf("Error: Could not send data to host\n"); close(sd); do_exit(STATE_UNKNOWN); } /* for some reason we didn't send all the bytes we were supposed to */ else if (bytes_to_send < sizeof(send_packet)) { printf("Warning: Sent only %d of %d bytes to host\n", rc, sizeof(send_packet)); close(sd); return STATE_UNKNOWN; } } #ifdef DEBUG printf("Done sending data\n"); #endif /* close the connection */ close(sd); printf("%d data packet(s) sent to host successfully.\n", total_packets); /* exit cleanly */ do_exit(STATE_OK); /* no compiler complaints here... */ return STATE_OK; }
int main(int argc, char **argv){ u_int32_t packet_crc32; u_int32_t calculated_crc32; int16_t result; int rc; packet send_packet; packet receive_packet; int bytes_to_send; int bytes_to_recv; result=process_arguments(argc,argv); if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE){ if(result!=OK) printf("Incorrect command line arguments supplied\n"); printf("\n"); printf("NRPE Plugin for Nagios\n"); printf("Copyright (c) 1999-2008 Ethan Galstad ([email protected])\n"); printf("Version: %s\n",PROGRAM_VERSION); printf("Last Modified: %s\n",MODIFICATION_DATE); printf("License: GPL v2 with exemptions (-l for more info)\n"); #ifdef HAVE_SSL printf("SSL/TLS Available: Anonymous DH Mode, OpenSSL 0.9.6 or higher required\n"); #endif printf("\n"); } if(result!=OK || show_help==TRUE){ printf("Usage: check_nrpe -H <host> [-n] [-u] [-p <port>] [-t <timeout>] [-c <command>] [-a <arglist...>]\n"); printf("\n"); printf("Options:\n"); printf(" -n = Do no use SSL\n"); printf(" -u = Make socket timeouts return an UNKNOWN state instead of CRITICAL\n"); printf(" <host> = The address of the host running the NRPE daemon\n"); printf(" [port] = The port on which the daemon is running (default=%d)\n",DEFAULT_SERVER_PORT); printf(" [timeout] = Number of seconds before connection times out (default=%d)\n",DEFAULT_SOCKET_TIMEOUT); printf(" [command] = The name of the command that the remote daemon should run\n"); printf(" [arglist] = Optional arguments that should be passed to the command. Multiple\n"); printf(" arguments should be separated by a space. If provided, this must be\n"); printf(" the last option supplied on the command line.\n"); printf("\n"); printf("Note:\n"); printf("This plugin requires that you have the NRPE daemon running on the remote host.\n"); printf("You must also have configured the daemon to associate a specific plugin command\n"); printf("with the [command] option you are specifying here. Upon receipt of the\n"); printf("[command] argument, the NRPE daemon will run the appropriate plugin command and\n"); printf("send the plugin output and return code back to *this* plugin. This allows you\n"); printf("to execute plugins on remote hosts and 'fake' the results to make Nagios think\n"); printf("the plugin is being run locally.\n"); printf("\n"); } if(show_license==TRUE) display_license(); if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE) exit(STATE_UNKNOWN); /* generate the CRC 32 table */ generate_crc32_table(); #ifdef HAVE_SSL /* initialize SSL */ if(use_ssl==TRUE){ SSL_library_init(); SSLeay_add_ssl_algorithms(); meth=SSLv23_client_method(); SSL_load_error_strings(); if((ctx=SSL_CTX_new(meth))==NULL){ printf("CHECK_NRPE: Error - could not create SSL context.\n"); exit(STATE_CRITICAL); } /* ADDED 01/19/2004 */ /* use only TLSv1 protocol */ SSL_CTX_set_options(ctx,SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); } #endif /* initialize alarm signal handling */ signal(SIGALRM,alarm_handler); /* set socket timeout */ alarm(socket_timeout); /* try to connect to the host at the given port number */ result=my_tcp_connect(server_name,server_port,&sd); #ifdef HAVE_SSL /* do SSL handshake */ if(result==STATE_OK && use_ssl==TRUE){ if((ssl=SSL_new(ctx))!=NULL){ SSL_CTX_set_cipher_list(ctx,"ADH"); SSL_set_fd(ssl,sd); if((rc=SSL_connect(ssl))!=1){ printf("CHECK_NRPE: Error - Could not complete SSL handshake.\n"); #ifdef DEBUG printf("SSL_connect=%d\n",rc); /* rc=SSL_get_error(ssl,rc); printf("SSL_get_error=%d\n",rc); printf("ERR_get_error=%lu\n",ERR_get_error()); printf("%s\n",ERR_error_string(rc,NULL)); */ ERR_print_errors_fp(stdout); #endif result=STATE_CRITICAL; } } else{ printf("CHECK_NRPE: Error - Could not create SSL connection structure.\n"); result=STATE_CRITICAL; } /* bail if we had errors */ if(result!=STATE_OK){ SSL_CTX_free(ctx); close(sd); exit(result); } } #endif /* we're connected and ready to go */ if(result==STATE_OK){ /* clear the packet buffer */ bzero(&send_packet,sizeof(send_packet)); /* fill the packet with semi-random data */ randomize_buffer((char *)&send_packet,sizeof(send_packet)); /* initialize packet data */ send_packet.packet_version=(int16_t)htons(NRPE_PACKET_VERSION_2); send_packet.packet_type=(int16_t)htons(QUERY_PACKET); strncpy(&send_packet.buffer[0],query,MAX_PACKETBUFFER_LENGTH); send_packet.buffer[MAX_PACKETBUFFER_LENGTH-1]='\x0'; /* calculate the crc 32 value of the packet */ send_packet.crc32_value=(u_int32_t)0L; calculated_crc32=calculate_crc32((char *)&send_packet,sizeof(send_packet)); send_packet.crc32_value=(u_int32_t)htonl(calculated_crc32); /***** ENCRYPT REQUEST *****/ /* send the packet */ bytes_to_send=sizeof(send_packet); if(use_ssl==FALSE) rc=sendall(sd,(char *)&send_packet,&bytes_to_send); #ifdef HAVE_SSL else{ rc=SSL_write(ssl,&send_packet,bytes_to_send); if(rc<0) rc=-1; } #endif if(rc==-1){ printf("CHECK_NRPE: Error sending query to host.\n"); close(sd); return STATE_UNKNOWN; } /* wait for the response packet */ bytes_to_recv=sizeof(receive_packet); if(use_ssl==FALSE) rc=recvall(sd,(char *)&receive_packet,&bytes_to_recv,socket_timeout); #ifdef HAVE_SSL else rc=SSL_read(ssl,&receive_packet,bytes_to_recv); #endif /* reset timeout */ alarm(0); /* close the connection */ #ifdef HAVE_SSL if(use_ssl==TRUE){ SSL_shutdown(ssl); SSL_free(ssl); SSL_CTX_free(ctx); } #endif graceful_close(sd,1000); /* recv() error */ if(rc<0){ printf("CHECK_NRPE: Error receiving data from daemon.\n"); return STATE_UNKNOWN; } /* server disconnected */ else if(rc==0){ printf("CHECK_NRPE: Received 0 bytes from daemon. Check the remote server logs for error messages.\n"); return STATE_UNKNOWN; } /* receive underflow */ else if(bytes_to_recv<sizeof(receive_packet)){ printf("CHECK_NRPE: Receive underflow - only %d bytes received (%d expected).\n",bytes_to_recv,sizeof(receive_packet)); return STATE_UNKNOWN; } /***** DECRYPT RESPONSE *****/ /* check the crc 32 value */ packet_crc32=ntohl(receive_packet.crc32_value); receive_packet.crc32_value=0L; calculated_crc32=calculate_crc32((char *)&receive_packet,sizeof(receive_packet)); if(packet_crc32!=calculated_crc32){ printf("CHECK_NRPE: Response packet had invalid CRC32.\n"); close(sd); return STATE_UNKNOWN; } /* check packet version */ if(ntohs(receive_packet.packet_version)!=NRPE_PACKET_VERSION_2){ printf("CHECK_NRPE: Invalid packet version received from server.\n"); close(sd); return STATE_UNKNOWN; } /* check packet type */ if(ntohs(receive_packet.packet_type)!=RESPONSE_PACKET){ printf("CHECK_NRPE: Invalid packet type received from server.\n"); close(sd); return STATE_UNKNOWN; } /* get the return code from the remote plugin */ result=(int16_t)ntohs(receive_packet.result_code); /* print the output returned by the daemon */ receive_packet.buffer[MAX_PACKETBUFFER_LENGTH-1]='\x0'; if(!strcmp(receive_packet.buffer,"")) printf("CHECK_NRPE: No output returned from daemon.\n"); else printf("%s\n",receive_packet.buffer); } /* reset the alarm */ else alarm(0); return result; }