Esempio n. 1
0
void test_calculate_crc32(CuTest *tc) {
    char *data = "xi'an-chengdu-hangzhou-beijing";

    uint32_t crc32 = calculate_crc32((uint8_t*)data, strlen(data));
    CuAssertIntEquals(tc, -1266222823, crc32);

    crc32 = calculate_crc32((uint8_t*)data, strlen(data));
    CuAssertIntEquals(tc, -1266222823, crc32);
}
Esempio n. 2
0
		void readFrom(const char *buffer, std::size_t length) {
			if (buffer == NULL)
				throw nrpe::nrpe_exception("No buffer.");
			if (length != get_packet_length())
				throw nrpe::nrpe_exception("Invalid packet length: " + strEx::s::xtos(length) + " != " + strEx::s::xtos(get_packet_length()) + " configured payload is: " + strEx::s::xtos(get_payload_length()));
			const nrpe::data::packet *p = reinterpret_cast<const nrpe::data::packet*>(buffer);
			type_ = swap_bytes::ntoh<int16_t>(p->packet_type);
			if ((type_ != nrpe::data::queryPacket)&&(type_ != nrpe::data::responsePacket))
				throw nrpe::nrpe_exception("Invalid packet type: " + strEx::s::xtos(type_));
			version_ = swap_bytes::ntoh<int16_t>(p->packet_version);
			if (version_ != nrpe::data::version2)
				throw nrpe::nrpe_exception("Invalid packet version." + strEx::s::xtos(version_));
			crc32_ = swap_bytes::ntoh<u_int32_t>(p->crc32_value);
			// Verify CRC32
			// @todo Fix this, currently we need a const buffer so we cannot change the CRC to 0.
			char * tb = new char[length+1];
			memcpy(tb, buffer, length);
			nrpe::data::packet *p2 = reinterpret_cast<nrpe::data::packet*>(tb);
			p2->crc32_value = 0;
			calculatedCRC32_ = calculate_crc32(tb, get_packet_length());
			delete [] tb;
			if (crc32_ != calculatedCRC32_) 
				throw nrpe::nrpe_exception("Invalid checksum in NRPE packet: " + strEx::s::xtos(crc32_) + "!=" + strEx::s::xtos(calculatedCRC32_));
			// Verify CRC32 end
			result_ = swap_bytes::ntoh<int16_t>(p->result_code);
			payload_ = fetch_payload(p);
		}
Esempio n. 3
0
int pl_decompress(pl_buffer *input, pl_buffer **output, const char *key, int check_compression) {

    pl_buffer *result;
    unsigned int data_size, real_size, *header,
            header_size, crc32_ptr_compresed, i;
    char   *data;

    if(!input)
        return PL_DECOMP_INVALID;

    if(check_compression && pl_check_compression(input) != PL_CHECK_COMPRESSESED) {
        return PL_DECOMP_CHECK_COMP;
    }

    *output = NULL;

    header = (unsigned int*)((char*)input->buffer + pl_header_magic_text_size);

    // skip version
    ++header;

    // get crc32 of compressed
    crc32_ptr_compresed = *header++;

    // get real size
    real_size = *header++;

    // get compressed size
    data_size = *header;

    header_size = PL_HEADER_ITEMS_SIZE + pl_header_magic_text_size;

    // check buffer crc
    if(crc32_ptr_compresed != calculate_crc32((char*)input->buffer + header_size, data_size)) {
        return PL_DECOMP_WRONG_KEY;
    }

    // decompress
    result = pl_buf_create(real_size + 16); // with dummy
    if(!result) {
        return PL_DECOMP_MEMORY;
    }

    result->length = lzf_decompress((char*)input->buffer + header_size, data_size,
            result->buffer, result->allocated_size);

    if(result->length == 0) {
        pl_buf_destroy(result);
        return PL_DECOMP_DECOMPRESS;
    }

    result->length = real_size;

    *output = result;

    return PL_DECOMP_OK;
}
Esempio n. 4
0
		const char* create_buffer() {
			delete [] tmpBuffer;
			unsigned int packet_length = nrpe::length::get_packet_length(payload_length_);
			tmpBuffer = new char[packet_length+1];
			memset(tmpBuffer, 0, packet_length+1);
			nrpe::data::packet *p = reinterpret_cast<nrpe::data::packet*>(tmpBuffer);
			p->result_code = swap_bytes::hton<int16_t>(result_);
			p->packet_type = swap_bytes::hton<int16_t>(type_);
			p->packet_version = swap_bytes::hton<int16_t>(version_);
			if (payload_.length() >= payload_length_)
				throw nrpe::nrpe_exception("To much data cant create return packet (truncate data)");
			update_payload(p, payload_);
			p->crc32_value = 0;
			crc32_ = p->crc32_value = swap_bytes::hton<u_int32_t>(calculate_crc32(tmpBuffer, packet_length));
			return tmpBuffer;
		}
Esempio n. 5
0
/* tests whether or not a client request is valid */
int validate_request(packet *pkt){
        u_int32_t packet_crc32;
        u_int32_t calculated_crc32;
	char *ptr;
#ifdef ENABLE_COMMAND_ARGUMENTS
	int x;
#endif


	/***** DECRYPT REQUEST ******/


        /* check the crc 32 value */
        packet_crc32=ntohl(pkt->crc32_value);
        pkt->crc32_value=0L;
        calculated_crc32=calculate_crc32((char *)pkt,sizeof(packet));
        if(packet_crc32!=calculated_crc32){
                syslog(LOG_ERR,"Error: Request packet had invalid CRC32.");
                return ERROR;
                }

	/* make sure this is the right type of packet */
	if(ntohs(pkt->packet_type)!=QUERY_PACKET || ntohs(pkt->packet_version)!=NRPE_PACKET_VERSION_2){
		syslog(LOG_ERR,"Error: Request packet type/version was invalid!");
		return ERROR;
	        }

	/* make sure buffer is terminated */
	pkt->buffer[MAX_PACKETBUFFER_LENGTH-1]='\x0';

	/* client must send some kind of request */
	if(!strcmp(pkt->buffer,"")){
		syslog(LOG_ERR,"Error: Request contained no query!");
		return ERROR;
	        }

	/* make sure request doesn't contain nasties */
	if(contains_nasty_metachars(pkt->buffer)==TRUE){
		syslog(LOG_ERR,"Error: Request contained illegal metachars!");
		return ERROR;
	        }

	/* make sure the request doesn't contain arguments */
	if(strchr(pkt->buffer,'!')){
#ifdef ENABLE_COMMAND_ARGUMENTS
		if(allow_arguments==FALSE){
			syslog(LOG_ERR,"Error: Request contained command arguments, but argument option is not enabled!");
			return ERROR;
	                }
#else
		syslog(LOG_ERR,"Error: Request contained command arguments!");
		return ERROR;
#endif
	        }

	/* get command name */
#ifdef ENABLE_COMMAND_ARGUMENTS
	ptr=strtok(pkt->buffer,"!");
#else
	ptr=pkt->buffer;
#endif	
	command_name=strdup(ptr);
	if(command_name==NULL){
		syslog(LOG_ERR,"Error: Memory allocation failed");
		return ERROR;
	        }

#ifdef ENABLE_COMMAND_ARGUMENTS
	/* get command arguments */
	if(allow_arguments==TRUE){

		for(x=0;x<MAX_COMMAND_ARGUMENTS;x++){
			ptr=strtok(NULL,"!");
			if(ptr==NULL)
				break;
			macro_argv[x]=strdup(ptr);
			if(macro_argv[x]==NULL){
				syslog(LOG_ERR,"Error: Memory allocation failed");
				return ERROR;
			        }
			if(!strcmp(macro_argv[x],"")){
				syslog(LOG_ERR,"Error: Request contained an empty command argument");
				return ERROR;
		                }
		        }
	        }
#endif

	return OK;
        }
Esempio n. 6
0
/* handles a client connection */
void handle_connection(int sock){
        u_int32_t calculated_crc32;
	command *temp_command;
	packet receive_packet;
	packet send_packet;
	int bytes_to_send;
	int bytes_to_recv;
	char buffer[MAX_INPUT_BUFFER];
	char raw_command[MAX_INPUT_BUFFER];
	char processed_command[MAX_INPUT_BUFFER];
	int result=STATE_OK;
	int early_timeout=FALSE;
	int rc;
	int x;
#ifdef DEBUG
	FILE *errfp;
#endif
#ifdef HAVE_SSL
	SSL *ssl=NULL;
#endif


	/* log info to syslog facility */
	if(debug==TRUE)
		syslog(LOG_DEBUG,"Handling the connection...");

#ifdef OLDSTUFF
	/* socket should be non-blocking */
	fcntl(sock,F_SETFL,O_NONBLOCK);
#endif

	/* set connection handler */
	signal(SIGALRM,my_connection_sighandler);
	alarm(connection_timeout);

#ifdef HAVE_SSL
	/* do SSL handshake */
	if(result==STATE_OK && use_ssl==TRUE){
		if((ssl=SSL_new(ctx))!=NULL){
			SSL_set_fd(ssl,sock);

			/* keep attempting the request if needed */
                        while(((rc=SSL_accept(ssl))!=1) && (SSL_get_error(ssl,rc)==SSL_ERROR_WANT_READ));

			if(rc!=1){
				syslog(LOG_ERR,"Error: Could not complete SSL handshake. %d\n",SSL_get_error(ssl,rc));
#ifdef DEBUG
				errfp=fopen("/tmp/err.log","w");
				ERR_print_errors_fp(errfp);
				fclose(errfp);
#endif
				return;
			        }
		        }
		else{
			syslog(LOG_ERR,"Error: Could not create SSL connection structure.\n");
#ifdef DEBUG
			errfp=fopen("/tmp/err.log","w");
			ERR_print_errors_fp(errfp);
			fclose(errfp);
#endif
			return;
		        }
	        }
#endif

	bytes_to_recv=sizeof(receive_packet);
	if(use_ssl==FALSE)
		rc=recvall(sock,(char *)&receive_packet,&bytes_to_recv,socket_timeout);
#ifdef HAVE_SSL
	else{
                while(((rc=SSL_read(ssl,&receive_packet,bytes_to_recv))<=0) && (SSL_get_error(ssl,rc)==SSL_ERROR_WANT_READ));
		}
#endif

	/* recv() error or client disconnect */
	if(rc<=0){

		/* log error to syslog facility */
		syslog(LOG_ERR,"Could not read request from client, bailing out...");

#ifdef HAVE_SSL
		if(ssl){
			SSL_shutdown(ssl);
			SSL_free(ssl);
			syslog(LOG_INFO,"INFO: SSL Socket Shutdown.\n");
			}
#endif

		return;
                }

	/* we couldn't read the correct amount of data, so bail out */
	else if(bytes_to_recv!=sizeof(receive_packet)){

		/* log error to syslog facility */
		syslog(LOG_ERR,"Data packet from client was too short, bailing out...");

#ifdef HAVE_SSL
		if(ssl){
			SSL_shutdown(ssl);
			SSL_free(ssl);
			}
#endif

		return;
	        }

#ifdef DEBUG
	fp=fopen("/tmp/packet","w");
	if(fp){
		fwrite(&receive_packet,1,sizeof(receive_packet),fp);
		fclose(fp);
	        }
#endif

	/* make sure the request is valid */
	if(validate_request(&receive_packet)==ERROR){

		/* log an error */
		syslog(LOG_ERR,"Client request was invalid, bailing out...");

		/* free memory */
		free(command_name);
		command_name=NULL;
		for(x=0;x<MAX_COMMAND_ARGUMENTS;x++){
			free(macro_argv[x]);
			macro_argv[x]=NULL;
	                }

#ifdef HAVE_SSL
		if(ssl){
			SSL_shutdown(ssl);
			SSL_free(ssl);
			}
#endif

		return;
	        }

	/* log info to syslog facility */
	if(debug==TRUE)
		syslog(LOG_DEBUG,"Host is asking for command '%s' to be run...",receive_packet.buffer);

	/* disable connection alarm - a new alarm will be setup during my_system */
	alarm(0);

	/* if this is the version check command, just spew it out */
	if(!strcmp(command_name,NRPE_HELLO_COMMAND)){

		snprintf(buffer,sizeof(buffer),"NRPE v%s",PROGRAM_VERSION);
		buffer[sizeof(buffer)-1]='\x0';

		/* log info to syslog facility */
		if(debug==TRUE)
			syslog(LOG_DEBUG,"Response: %s",buffer);

		result=STATE_OK;
	        }

	/* find the command we're supposed to run */
	else{
		temp_command=find_command(command_name);
		if(temp_command==NULL){

			snprintf(buffer,sizeof(buffer),"NRPE: Command '%s' not defined",command_name);
			buffer[sizeof(buffer)-1]='\x0';

			/* log error to syslog facility */
			if(debug==TRUE)
				syslog(LOG_DEBUG,"%s",buffer);

			result=STATE_CRITICAL;
	                }

		else{

			/* process command line */
			if(command_prefix==NULL)
				strncpy(raw_command,temp_command->command_line,sizeof(raw_command)-1);
			else
				snprintf(raw_command,sizeof(raw_command)-1,"%s %s",command_prefix,temp_command->command_line);
			raw_command[sizeof(raw_command)-1]='\x0';
			process_macros(raw_command,processed_command,sizeof(processed_command));

			/* log info to syslog facility */
			if(debug==TRUE)
				syslog(LOG_DEBUG,"Running command: %s",processed_command);

			/* run the command */
			strcpy(buffer,"");
			result=my_system(processed_command,command_timeout,&early_timeout,buffer,sizeof(buffer));

			/* log debug info */
			if(debug==TRUE)
				syslog(LOG_DEBUG,"Command completed with return code %d and output: %s",result,buffer);

			/* see if the command timed out */
			if(early_timeout==TRUE)
				snprintf(buffer,sizeof(buffer)-1,"NRPE: Command timed out after %d seconds\n",command_timeout);
			else if(!strcmp(buffer,""))
				snprintf(buffer,sizeof(buffer)-1,"NRPE: Unable to read output\n");

			buffer[sizeof(buffer)-1]='\x0';

			/* check return code bounds */
			if((result<0) || (result>3)){

				/* log error to syslog facility */
				syslog(LOG_ERR,"Bad return code for [%s]: %d", buffer,result);

				result=STATE_UNKNOWN;
			        }
		        }
	        }

	/* free memory */
	free(command_name);
	command_name=NULL;
	for(x=0;x<MAX_COMMAND_ARGUMENTS;x++){
		free(macro_argv[x]);
		macro_argv[x]=NULL;
	        }

	/* strip newline character from end of output buffer */
	if(buffer[strlen(buffer)-1]=='\n')
		buffer[strlen(buffer)-1]='\x0';

	/* clear the response packet buffer */
	bzero(&send_packet,sizeof(send_packet));

	/* fill the packet with semi-random data */
	randomize_buffer((char *)&send_packet,sizeof(send_packet));

	/* initialize response packet data */
	send_packet.packet_version=(int16_t)htons(NRPE_PACKET_VERSION_2);
	send_packet.packet_type=(int16_t)htons(RESPONSE_PACKET);
	send_packet.result_code=(int16_t)htons(result);
	strncpy(&send_packet.buffer[0],buffer,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 RESPONSE *****/


	/* send the response back to the client */
	bytes_to_send=sizeof(send_packet);
	if(use_ssl==FALSE)
		sendall(sock,(char *)&send_packet,&bytes_to_send);
#ifdef HAVE_SSL
	else
		SSL_write(ssl,&send_packet,bytes_to_send);
#endif

#ifdef HAVE_SSL
	if(ssl){
		SSL_shutdown(ssl);
		SSL_free(ssl);
		}
#endif

	/* log info to syslog facility */
	if(debug==TRUE)
		syslog(LOG_DEBUG,"Return Code: %d, Output: %s",result,buffer);

	return;
        }
Esempio n. 7
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;
}
Esempio n. 8
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> [ -b <bindaddr> ] [-4] [-6] [-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(" <bindaddr> = bind to local address\n");
		printf(" -4         = user ipv4 only\n");
		printf(" -6         = user ipv6 only\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 */
	if((sd=my_connect(server_name, &hostaddr, server_port, address_family, 
			bind_address)) < 0 ) {
		exit (255);
		}
	else {
		result=STATE_OK;
	}

#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;
        }
    int WritePacket( const PacketReadWriteInfo & info, Packet * packet, uint8_t * buffer, int bufferSize )
    {
        assert( packet );
        assert( buffer );
        assert( bufferSize > 0 );
        assert( info.protocolId );
        assert( info.packetFactory );
        assert( info.streamAllocator );

        const int numPacketTypes = info.packetFactory->GetNumPacketTypes();

        WriteStream stream( buffer, bufferSize, *info.streamAllocator );

        stream.SetContext( info.context );

        for ( int i = 0; i < info.prefixBytes; ++i )
        {
            uint8_t zero = 0;
            if ( !stream.SerializeBits( zero, 8 ) )
            {
                debug_printf( "serialize prefix byte failed (write packet)\n" );
                return 0;
            }
        }

        uint32_t crc32 = 0;

        if ( !info.rawFormat )
        {
            if ( !stream.SerializeBits( crc32, 32 ) )
            {
                debug_printf( "serialize crc32 failed (write packet)\n" );
                return 0;
            }
        }

        int packetType = packet->GetType();

        assert( numPacketTypes > 0 );

        if ( numPacketTypes > 1 )
        {
            if ( !stream.SerializeInteger( packetType, 0, numPacketTypes - 1 ) )
                return 0;
        }

        if ( !packet->SerializeInternal( stream ) )
        {
            debug_printf( "serialize packet type %d failed (write packet)\n", packetType );
            return 0;
        }

        if ( !stream.SerializeCheck( "end of packet" ) )
        {
            debug_printf( "serialize check at end of packed failed (write packet)\n" );
            return 0;
        }

        stream.Flush();

        if ( !info.rawFormat )
        {
            uint32_t network_protocolId = host_to_network( info.protocolId );
            crc32 = calculate_crc32( (uint8_t*) &network_protocolId, 4 );
            crc32 = calculate_crc32( buffer + info.prefixBytes, stream.GetBytesProcessed() - info.prefixBytes, crc32 );
            *((uint32_t*)(buffer+info.prefixBytes)) = host_to_network( crc32 );
        }

        if ( stream.GetError() )
        {
            debug_printf( "stream error %d (write packet)\n", stream.GetError() );
            return 0;
        }

        return stream.GetBytesProcessed();
    }
    Packet * ReadPacket( const PacketReadWriteInfo & info, const uint8_t * buffer, int bufferSize, int * errorCode )
    {
        assert( buffer );
        assert( bufferSize > 0 );
        assert( info.protocolId != 0 );
        assert( info.packetFactory );
        assert( info.streamAllocator );

        if ( errorCode )
            *errorCode = YOJIMBO_PROTOCOL_ERROR_NONE;

        ReadStream stream( buffer, bufferSize, *info.streamAllocator );

        stream.SetContext( info.context );

        for ( int i = 0; i < info.prefixBytes; ++i )
        {
            uint32_t dummy = 0;
            if ( !stream.SerializeBits( dummy, 8 ) )
            {
                debug_printf( "serialize prefix byte failed (read packet)\n" );
                return 0;
            }
        }

        uint32_t read_crc32 = 0;
        
        if ( !info.rawFormat )
        {
            if ( !stream.SerializeBits( read_crc32, 32 ) )
            {
                debug_printf( "serialize crc32 failed (read packet)\n" );
                return 0;
            }

            uint32_t network_protocolId = host_to_network( info.protocolId );
            uint32_t crc32 = calculate_crc32( (const uint8_t*) &network_protocolId, 4 );
            uint32_t zero = 0;
            crc32 = calculate_crc32( (const uint8_t*) &zero, 4, crc32 );
            crc32 = calculate_crc32( buffer + info.prefixBytes + 4, bufferSize - 4 - info.prefixBytes, crc32 );

            if ( crc32 != read_crc32 )
            {
                debug_printf( "corrupt packet. expected crc32 %x, got %x (read packet)\n", crc32, read_crc32 );
                if ( errorCode )
                    *errorCode = YOJIMBO_PROTOCOL_ERROR_CRC32_MISMATCH;
                return NULL;
            }
        }

        int packetType = 0;

        const int numPacketTypes = info.packetFactory->GetNumPacketTypes();

        assert( numPacketTypes > 0 );

        if ( numPacketTypes > 1 )
        {
            if ( !stream.SerializeInteger( packetType, 0, numPacketTypes - 1 ) )
            {
                debug_printf( "invalid packet type %d (read packet)\n", packetType );
                if ( errorCode )
                    *errorCode = YOJIMBO_PROTOCOL_ERROR_INVALID_PACKET_TYPE;
                return NULL;
            }
        }

        if ( info.allowedPacketTypes )
        {
            if ( !info.allowedPacketTypes[packetType] )
            {
                debug_printf( "packet type %d not allowed (read packet)\n", packetType );
                if ( errorCode )
                    *errorCode = YOJIMBO_PROTOCOL_ERROR_PACKET_TYPE_NOT_ALLOWED;
                return NULL;
            }
        }

        Packet * packet = info.packetFactory->CreatePacket( packetType );
        if ( !packet )
        {
            debug_printf( "create packet type %d failed (read packet)\n", packetType );
            if ( errorCode )
                *errorCode = YOJIMBO_PROTOCOL_ERROR_CREATE_PACKET_FAILED;
            return NULL;
        }

        if ( !packet->SerializeInternal( stream ) )
        {
            debug_printf( "serialize packet type %d failed (read packet)\n", packetType );
            if ( errorCode )
                *errorCode = YOJIMBO_PROTOCOL_ERROR_SERIALIZE_PACKET_FAILED;
            goto cleanup;
        }

#if YOJIMBO_SERIALIZE_CHECKS
        if ( !stream.SerializeCheck( "end of packet" ) )
        {
            debug_printf( "serialize check failed at end of packet type %d (read packet)\n", packetType );
            if ( errorCode )
                *errorCode = YOJIMBO_PROTOCOL_ERROR_SERIALIZE_CHECK_FAILED;
            goto cleanup;
        }
#endif // #if YOJIMBO_SERIALIZE_CHECKS

        if ( stream.GetError() )
        {
            debug_printf( "stream error %d (read packet)\n", stream.GetError() );
            if ( errorCode )
                *errorCode = stream.GetError();
            goto cleanup;
        }

        return packet;

cleanup:
        info.packetFactory->DestroyPacket( packet );
        return NULL;
    }
Esempio n. 11
0
void test_calculate_crc32_with_empty(CuTest *tc) {
    char *data = "xi'an-chengdu-hangzhou-beijing";
    uint32_t crc32 = calculate_crc32((uint8_t*)data, 0);

    CuAssertIntEquals(tc, 0xFFFFFFFF, crc32);
}
Esempio n. 12
0
int
main(int argc, char *argv[])
{

#if 0
   BinaryInFile ts_file("Stream1-2.ts");

   lm_pid_remux(ts_file.GetDataPointer(), ts_file.GetSize());

   ts_file.Save("output.ts");
#endif

#if 0

   unsigned int i = 0;
   for (auto &st_name: MP2TS::gStreamTypeName) {
      std::cout << "0x" << std::hex << std::setfill('0') << std::setw(2) << i << " : " << st_name << std::endl;
      ++i;
   }

#endif

#if 1
   MP2TS::Demux tsdemux("Stream1-2.ts");

   //MP2TS::Demux tsdemux("football.ts");
   //MP2TS::Demux tsdemux("decode_test_background_20120726_480p-1M.ts");
   //MP2TS::Demux tsdemux("Beauty_3840x2160_120fps_420_8bit_HEVC_TS.ts");

   // Make is quiet
   tsdemux.SetVerbosity(false);

   // Processing Loop
   std::cout << "PES Packets Processing Loop" << std::endl;
   std::cout << "-----------------------------------------------------" << std::endl;
   unsigned int total_ts_packets = 0;
   MP2TS::PES_Packet *packet;
   while (!tsdemux.IsEOF()) {
      tsdemux.Get(packet);
      if (tsdemux.Error() == MP2TS::ErrorCode::NONE) {
         //std::cout << tsdemux.NumberOfTSPackets() << " TS packets have been read" << std::endl;
         total_ts_packets += tsdemux.NumberOfTSPackets();
         //std::cout << "Total TS Packet Read = " << total_ts_packets << std::endl;

         if (packet) {
            std::cout << "Received a " << packet->mSize << " bytes packet." << std::endl;
            std::cout << "Packet State " << packet->mState << std::endl;
            tsdemux.Parse(packet);
            delete packet;
         }
      }
      else {
         std::cout << "Error !!" << std::endl;
         break;
      }
   }

   // Output channel map
   std::cout << "Channel Map" << std::endl;
   std::cout << "-----------------------------------------------------" << std::endl;
   for (auto &channel: tsdemux.GetChannelMap()) {
      std::cout << channel.first << " @ PID "<< channel.second.mPMTPID << std::endl;
      std::cout << "  Channel PMT PDI = " << std::hex << std::setfill('0') << std::setw(4)
                << channel.second.mPMTPID << std::dec << std::endl;

      unsigned int stream_num = 0;
      for (auto &stream: channel.second.mStreams) {
         std::cout << "    " << stream_num << ": Stream Type 0x" << std::hex << std::setfill('0') << std::setw(4) << stream.GetStreamTypeName() << std::dec << std::endl;
         std::cout << "    " << stream_num << ": Stream PID  0x" << std::hex << std::setfill('0') << std::setw(4) << stream.mPID << std::dec << std::endl;
         ++stream_num;
      }
   }

#endif

#if 0
   unsigned char crc_buffer[] = {0x0,0xb0,0x0d,0x00,0x01,0xc1,0x0,0x0,0x0,0x1,0xe0,0x20};
   //unsigned char crc_buffer[] = {0x0,0xb0,0x0d,0x59,0x81,0xeb,0x0,0x0,0x0,0x1,0xe0,0x42};

   // Calculate current CRC
   unsigned long crc = calculate_crc32(crc_buffer, 12);
   std::cout << "PAT CRC = " << std::hex << std::setfill('0') << std::setw(8) << crc << std::endl;
   std::cout << std::dec;
#endif
}
Esempio n. 13
0
/* handle reading from a client connection */
static void handle_connection_read(int sock, void *data) {
	data_packet receive_packet;
	u_int32_t packet_crc32;
	u_int32_t calculated_crc32;
	struct crypt_instance *CI;
	time_t packet_time;
	time_t current_time;
	int16_t return_code;
	unsigned long packet_age = 0L;
	int bytes_to_recv;
	int rc;
	char host_name[MAX_HOSTNAME_LENGTH];
	char svc_description[MAX_DESCRIPTION_LENGTH];
	char plugin_output[MAX_PLUGINOUTPUT_LENGTH];
	int packet_length = sizeof(receive_packet);
	int plugin_length = MAX_PLUGINOUTPUT_LENGTH;

	CI = data;

	/* process all data we get from the client... */

	/* read the packet from the client */
	bytes_to_recv = sizeof(receive_packet);
	rc = recvall(sock, (char *)&receive_packet, &bytes_to_recv, socket_timeout);

	/* recv() error or client disconnect */
	if (rc <= 0) {
		if (bytes_to_recv == OLD_PACKET_LENGTH) {
			packet_length = OLD_PACKET_LENGTH;
			plugin_length = OLD_PLUGINOUTPUT_LENGTH;
		}
		else {
			if (debug == TRUE)
				syslog(LOG_ERR, "End of connection...");
			encrypt_cleanup(decryption_method, CI);
			close(sock);
			if (mode == SINGLE_PROCESS_DAEMON)
				return;
			else
				do_exit(STATE_OK);
		}
	}

	/* we couldn't read the correct amount of data, so bail out */
	if (bytes_to_recv != packet_length) {
		syslog(LOG_ERR, "Data sent from client was too short (%d < %d), aborting...", bytes_to_recv, packet_length);
		encrypt_cleanup(decryption_method, CI);
		close(sock);
		return;
		if (mode == SINGLE_PROCESS_DAEMON)
			return;
		else
			do_exit(STATE_CRITICAL);
	}

	/* if we're single-process, we need to set things up so we handle the next packet after this one... */
	if (mode == SINGLE_PROCESS_DAEMON)
		register_read_handler(sock, handle_connection_read, (void *)CI);

	/* decrypt the packet */
	decrypt_buffer((char *)&receive_packet, packet_length, password, decryption_method, CI);

	/* make sure this is the right type of packet */
	if (ntohs(receive_packet.packet_version) != NSCA_PACKET_VERSION_3) {
		syslog(LOG_ERR, "Received invalid packet type/version from client - possibly due to client using wrong password or crypto algorithm?");
		/*return;*/
		close(sock);
		if (mode == SINGLE_PROCESS_DAEMON)
			return;
		else
			do_exit(STATE_OK);
	}

	/* check the crc 32 value */
	packet_crc32 = ntohl(receive_packet.crc32_value);
	receive_packet.crc32_value = 0L;
	calculated_crc32 = calculate_crc32((char *)&receive_packet, packet_length);

	if (packet_crc32 != calculated_crc32) {
		syslog(LOG_ERR, "Dropping packet with invalid CRC32 - possibly due to client using wrong password or crypto algorithm?");
		/*return;*/
		close(sock);
		if (mode == SINGLE_PROCESS_DAEMON)
			return;
		else
			do_exit(STATE_OK);
	}

	/* host name */
	strncpy(host_name, receive_packet.host_name, sizeof(host_name) - 1);
	host_name[sizeof(host_name) - 1] = '\0';

	/* check the timestamp in the packet */
	packet_age = (unsigned long)(current_time - packet_time);
	if (debug == TRUE)
		syslog(LOG_ERR, "Time difference in packet: %lu seconds for host %s", packet_age, host_name);

	if ((max_packet_age > 0 && (packet_age > max_packet_age) && (packet_age >= 0)) ||
	        ((max_packet_age > 0) && (packet_age < (0 - max_packet_age)) && (packet_age < 0))
	   ) {
			syslog(LOG_ERR, "Dropping packet with stale timestamp for %s - packet was %lu seconds old.", host_name, packet_age);

			close(sock);
			if (mode == SINGLE_PROCESS_DAEMON)
				return;
			else
				do_exit(STATE_OK);
		}

	/**** GET THE SERVICE CHECK INFORMATION ****/

	/* plugin return code */
	return_code = ntohs(receive_packet.return_code);

	/* service description */
	strncpy(svc_description, receive_packet.svc_description, sizeof(svc_description) - 1);
	svc_description[sizeof(svc_description) - 1] = '\0';

	/* plugin output */
	strncpy(plugin_output, receive_packet.plugin_output, plugin_length - 1);
	plugin_output[plugin_length - 1] = '\0';

	/* log info to syslog facility */
	if (debug == TRUE) {
		if (!strcmp(svc_description, ""))
			syslog(LOG_NOTICE, "HOST CHECK -> Host Name: '%s', Return Code: '%d', Output: '%s'", host_name, return_code, plugin_output);
		else
			syslog(LOG_NOTICE, "SERVICE CHECK -> Host Name: '%s', Service Description: '%s', Return Code: '%d', Output: '%s'", host_name, svc_description, return_code, plugin_output);
	}

	/* write the check result to the external command file.
	 * Note: it's OK to hang at this point if the write doesn't succeed, as there's
	 * no way we could handle any other connection properly anyway.  so we don't
	 * use poll() - which fails on a pipe with any data, so it would cause us to
	 * only ever write one command at a time into the pipe.
	 */
	if (check_result_path == NULL) {
		write_check_result(host_name, svc_description, return_code, plugin_output, time(NULL));
	} else {
		write_checkresult_file(host_name, svc_description, return_code, plugin_output, time(NULL));
	}

	return;
}