int main(int argc, char **argv){ int result=OK; int x; char buffer[MAX_INPUT_BUFFER]; char *env_string=NULL; #ifdef HAVE_SSL DH *dh; char seedfile[FILENAME_MAX]; int i,c; #endif /* set some environment variables */ asprintf(&env_string,"NRPE_MULTILINESUPPORT=1"); putenv(env_string); asprintf(&env_string,"NRPE_PROGRAMVERSION=%s",PROGRAM_VERSION); putenv(env_string); /* process command-line args */ result=process_arguments(argc,argv); if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE){ printf("\n"); printf("NRPE - Nagios Remote Plugin Executor\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 #ifdef HAVE_LIBWRAP printf("TCP Wrappers Available\n"); #endif printf("\n"); #ifdef ENABLE_COMMAND_ARGUMENTS printf("***************************************************************\n"); printf("** POSSIBLE SECURITY RISK - COMMAND ARGUMENTS ARE SUPPORTED! **\n"); printf("** Read the NRPE SECURITY file for more information **\n"); printf("***************************************************************\n"); printf("\n"); #endif #ifndef HAVE_LIBWRAP printf("***************************************************************\n"); printf("** POSSIBLE SECURITY RISK - TCP WRAPPERS ARE NOT AVAILABLE! **\n"); printf("** Read the NRPE SECURITY file for more information **\n"); printf("***************************************************************\n"); printf("\n"); #endif } if(show_license==TRUE) display_license(); else if(result!=OK || show_help==TRUE){ printf("Usage: nrpe [-n] -c <config_file> <mode>\n"); printf("\n"); printf("Options:\n"); printf(" -n = Do not use SSL\n"); printf(" <config_file> = Name of config file to use\n"); printf(" <mode> = One of the following two operating modes:\n"); printf(" -i = Run as a service under inetd or xinetd\n"); printf(" -d = Run as a standalone daemon\n"); printf("\n"); printf("Notes:\n"); printf("This program is designed to process requests from the check_nrpe\n"); printf("plugin on the host(s) running Nagios. It can run as a service\n"); printf("under inetd or xinetd (read the docs for info on this), or as a\n"); printf("standalone daemon. Once a request is received from an authorized\n"); printf("host, NRPE will execute the command/plugin (as defined in the\n"); printf("config file) and return the plugin output and return code to the\n"); printf("check_nrpe plugin.\n"); printf("\n"); } if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE) exit(STATE_UNKNOWN); /* open a connection to the syslog facility */ /* facility name may be overridden later */ get_log_facility(NRPE_LOG_FACILITY); openlog("nrpe",LOG_PID,log_facility); /* make sure the config file uses an absolute path */ if(config_file[0]!='/'){ /* save the name of the config file */ strncpy(buffer,config_file,sizeof(buffer)); buffer[sizeof(buffer)-1]='\x0'; /* get absolute path of current working directory */ strcpy(config_file,""); getcwd(config_file,sizeof(config_file)); /* append a forward slash */ strncat(config_file,"/",sizeof(config_file)-2); config_file[sizeof(config_file)-1]='\x0'; /* append the config file to the path */ strncat(config_file,buffer,sizeof(config_file)-strlen(config_file)-1); config_file[sizeof(config_file)-1]='\x0'; } /* read the config file */ result=read_config_file(config_file); /* exit if there are errors... */ if(result==ERROR){ syslog(LOG_ERR,"Config file '%s' contained errors, aborting...",config_file); return STATE_CRITICAL; } /* generate the CRC 32 table */ generate_crc32_table(); /* initialize macros */ for(x=0;x<MAX_COMMAND_ARGUMENTS;x++) macro_argv[x]=NULL; #ifdef HAVE_SSL /* initialize SSL */ if(use_ssl==TRUE){ SSL_library_init(); SSLeay_add_ssl_algorithms(); meth=SSLv23_server_method(); SSL_load_error_strings(); /* use week random seed if necessary */ if(allow_weak_random_seed && (RAND_status()==0)){ if(RAND_file_name(seedfile,sizeof(seedfile)-1)) if(RAND_load_file(seedfile,-1)) RAND_write_file(seedfile); if(RAND_status()==0){ syslog(LOG_ERR,"Warning: SSL/TLS uses a weak random seed which is highly discouraged"); srand(time(NULL)); for(i=0;i<500 && RAND_status()==0;i++){ for(c=0;c<sizeof(seedfile);c+=sizeof(int)){ *((int *)(seedfile+c))=rand(); } RAND_seed(seedfile,sizeof(seedfile)); } } } if((ctx=SSL_CTX_new(meth))==NULL){ syslog(LOG_ERR,"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); /* use anonymous DH ciphers */ SSL_CTX_set_cipher_list(ctx,"ADH"); dh=get_dh512(); SSL_CTX_set_tmp_dh(ctx,dh); DH_free(dh); if(debug==TRUE) syslog(LOG_INFO,"INFO: SSL/TLS initialized. All network traffic will be encrypted."); } else{ if(debug==TRUE) syslog(LOG_INFO,"INFO: SSL/TLS NOT initialized. Network encryption DISABLED."); } #endif /* if we're running under inetd... */ if(use_inetd==TRUE){ /* make sure we're not root */ check_privileges(); /* redirect STDERR to /dev/null */ close(2); open("/dev/null",O_WRONLY); /* handle the connection */ handle_connection(0); } /* else daemonize and start listening for requests... */ else if(fork()==0){ /* we're a daemon - set up a new process group */ setsid(); /* close standard file descriptors */ close(0); close(1); close(2); /* redirect standard descriptors to /dev/null */ open("/dev/null",O_RDONLY); open("/dev/null",O_WRONLY); open("/dev/null",O_WRONLY); chdir("/"); /*umask(0);*/ /* handle signals */ signal(SIGQUIT,sighandler); signal(SIGTERM,sighandler); signal(SIGHUP,sighandler); /* log info to syslog facility */ syslog(LOG_NOTICE,"Starting up daemon"); /* write pid file */ if(write_pid_file()==ERROR) return STATE_CRITICAL; /* drop privileges */ drop_privileges(nrpe_user,nrpe_group); /* make sure we're not root */ check_privileges(); do{ /* reset flags */ sigrestart=FALSE; sigshutdown=FALSE; /* wait for connections */ wait_for_connections(); /* free all memory we allocated */ free_memory(); if(sigrestart==TRUE){ /* read the config file */ result=read_config_file(config_file); /* exit if there are errors... */ if(result==ERROR){ syslog(LOG_ERR,"Config file '%s' contained errors, bailing out...",config_file); return STATE_CRITICAL; } } }while(sigrestart==TRUE && sigshutdown==FALSE); /* remove pid file */ remove_pid_file(); syslog(LOG_NOTICE,"Daemon shutdown\n"); } #ifdef HAVE_SSL if(use_ssl==TRUE) SSL_CTX_free(ctx); #endif /* We are now running in daemon mode, or the connection handed over by inetd has been completed, so the parent process exits */ return STATE_OK; }
int main(int argc, char **argv){ int result=OK; int x; char buffer[MAX_INPUT_BUFFER]; #ifdef HAVE_SSL DH *dh; #endif result=process_arguments(argc,argv); if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE){ printf("\n"); printf("NRPE - Nagios Remote Plugin Executor\n"); printf("Copyright (c) 1999-2003 Ethan Galstad ([email protected])\n"); printf("Version: %s\n",PROGRAM_VERSION); printf("Last Modified: %s\n",MODIFICATION_DATE); printf("License: GPL 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"); #ifdef ENABLE_COMMAND_ARGUMENTS printf("***************************************************************\n"); printf("** POSSIBLE SECURITY RISK - COMMAND ARGUMENTS ARE SUPPORTED! **\n"); printf("** Read the NRPE SECURITY file for more information **\n"); printf("***************************************************************\n"); printf("\n"); #endif } if(show_license==TRUE) display_license(); else if(result!=OK || show_help==TRUE){ printf("Usage: nrpe -c <config_file> <mode>\n"); printf("\n"); printf("Options:\n"); printf(" <config_file> = Name of config file to use\n"); printf(" <mode> = One of the following two operating modes:\n"); printf(" -i = Run as a service under inetd or xinetd\n"); printf(" -d = Run as a standalone daemon\n"); printf("\n"); printf("Notes:\n"); printf("This program is designed to process requests from the check_nrpe\n"); printf("plugin on the host(s) running Nagios. It can run as a service\n"); printf("under inetd or xinetd (read the docs for info on this), or as a\n"); printf("standalone daemon. Once a request is received from an authorized\n"); printf("host, NRPE will execute the command/plugin (as defined in the\n"); printf("config file) and return the plugin output and return code to the\n"); printf("check_nrpe plugin.\n"); printf("\n"); } if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE) exit(STATE_UNKNOWN); /* open a connection to the syslog facility */ openlog("nrpe",LOG_PID,LOG_DAEMON); /* read the config file */ result=read_config_file(config_file); /* exit if there are errors... */ if(result==ERROR){ syslog(LOG_ERR,"Config file '%s' contained errors, bailing out...",config_file); return STATE_CRITICAL; } /* initialize macros */ for(x=0;x<MAX_COMMAND_ARGUMENTS;x++) macro_argv[x]=NULL; /* 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_server_method(); SSL_load_error_strings(); if((ctx=SSL_CTX_new(meth))==NULL){ syslog(LOG_ERR,"Error: could not create SSL context.\n"); exit(STATE_CRITICAL); } /*SSL_CTX_set_cipher_list(ctx,"ALL");*/ SSL_CTX_set_cipher_list(ctx,"ADH"); dh=get_dh512(); SSL_CTX_set_tmp_dh(ctx,dh); DH_free(dh); if(debug==TRUE) syslog(LOG_INFO,"INFO: SSL/TLS initialized. All network traffic will be encrypted."); } else{ if(debug==TRUE) syslog(LOG_INFO,"INFO: SSL/TLS NOT initialized. Network encryption DISABLED."); } #endif /* wait for connections */ wait_for_connections(); #ifdef HAVE_SSL if(use_ssl==TRUE) SSL_CTX_free(ctx); #endif /* We are now running in daemon mode, or the connection handed over by inetd has been completed, so the parent process exits */ 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> [ -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 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) { char buffer[MAX_INPUT_BUFFER]; int result; uid_t uid = -1; gid_t gid = -1; /* 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 - Nagios Service Check Acceptor for Icinga\n"); printf("Copyright (c) 2010-2012 Icinga Development Team and Community Contributors (http://www.icinga.org)\n"); printf("Copyright (c) 2009-2012 Nagios Core Development Team and Community Contributors\n"); printf("Copyright (c) 2000-2009 Ethan Galstad\n"); printf("Version: %s\n", PROGRAM_VERSION); 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"); #ifdef HAVE_LIBWRAP printf("TCP Wrappers Available\n"); #endif printf("\n"); } if (result != OK || show_help == TRUE) { printf("Usage: %s -c <config_file> [mode]\n", argv[0]); printf("\n"); printf("Options:\n"); printf(" <config_file> = Name of config file to use\n"); printf(" [mode] = Determines how NSCA should run. Valid modes:\n"); printf(" --inetd = Run as a service under inetd or xinetd\n"); printf(" --daemon = Run as a standalone multi-process daemon\n"); printf(" --single = Run as a standalone single-process daemon (default)\n"); printf("\n"); printf("Notes:\n"); printf("This program is designed to accept passive check results from\n"); printf("remote hosts that use the send_nsca utility. Can run as a service\n"); printf("under inetd or xinetd (read the docs for info on this), or as a\n"); printf("standalone daemon.\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); /* open a connection to the syslog facility */ /* facility may be overridden later */ get_log_facility(NSCA_LOG_FACILITY); openlog("nsca", LOG_PID | LOG_NDELAY, log_facility); /* make sure the config file uses an absolute path */ if (config_file[0] != '/') { /* save the name of the config file */ strncpy(buffer, config_file, sizeof(buffer)); buffer[sizeof(buffer) - 1] = '\0'; /* get absolute path of current working directory */ strcpy(config_file, ""); getcwd(config_file, sizeof(config_file)); /* append a forward slash */ strncat(config_file, "/", sizeof(config_file) - 2); config_file[sizeof(config_file) - 1] = '\0'; /* append the config file to the path */ strncat(config_file, buffer, sizeof(config_file) - strlen(config_file) - 1); config_file[sizeof(config_file) - 1] = '\0'; } /* read the config file */ result = read_config_file(config_file); /* exit if there are errors... */ if (result == ERROR) do_exit(STATE_CRITICAL); /* generate the CRC 32 table */ generate_crc32_table(); /* how should we handle client connections? */ switch (mode) { case INETD: /* chroot if configured */ do_chroot(); /* if we're running under inetd, handle one connection and get out */ handle_connection(0, NULL); break; case MULTI_PROCESS_DAEMON: /* older style, mult-process daemon */ /* execution cascades below... */ install_child_handler(); /* | | | */ case SINGLE_PROCESS_DAEMON: /* | | V */ /* daemonize and start listening for requests... */ if (fork() == 0) { /* we're a daemon - set up a new process group */ setsid(); /* handle signals */ signal(SIGQUIT, sighandler); signal(SIGTERM, sighandler); signal(SIGHUP, sighandler); signal(SIGPIPE, SIG_IGN); /* close standard file descriptors */ close(0); close(1); close(2); /* redirect standard descriptors to /dev/null */ open("/dev/null", O_RDONLY); open("/dev/null", O_WRONLY); open("/dev/null", O_WRONLY); /* get group information before chrooting */ get_user_info(nsca_user, &uid); get_group_info(nsca_group, &gid); /* write pid file */ if (write_pid_file(uid, gid) == ERROR) return STATE_CRITICAL; /* chroot if configured */ do_chroot(); /* drop privileges */ if (drop_privileges(nsca_user, uid, gid) == ERROR) do_exit(STATE_CRITICAL); do { /* reset flags */ sigrestart = FALSE; sigshutdown = FALSE; /* wait for connections */ wait_for_connections(); if (sigrestart == TRUE) { /* free memory */ free_memory(); /* re-read the config file */ result = read_config_file(config_file); /* exit if there are errors... */ if (result == ERROR) { syslog(LOG_ERR, "Config file '%s' contained errors, bailing out...", config_file); break; } } } while (sigrestart == TRUE && sigshutdown == FALSE); /* remove pid file */ remove_pid_file(); syslog(LOG_NOTICE, "Daemon shutdown\n"); } break; default: break; } /* we are now running in daemon mode, or the connection handed over by inetd has been completed, so the parent process exits */ do_exit(STATE_OK); /* keep the compilers happy... */ return STATE_OK; }