Example #1
0
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;
}
Example #3
0
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;
}
Example #4
0
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;
}
Example #5
0
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;
}
Example #6
0
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;
}
Example #7
0
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;
        }