nrpe.c 73 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762
  1. /*******************************************************************************
  2. *
  3. * NRPE.C - Nagios Remote Plugin Executor
  4. *
  5. * Copyright (c) 2009 Nagios Core Development Team and Community Contributors
  6. * Copyright (c) 1999-2008 Ethan Galstad (nagios@nagios.org)
  7. * License: GPL
  8. *
  9. * Command line: nrpe -c <config_file> [--inetd | --daemon]
  10. *
  11. * Description:
  12. *
  13. * This program is designed to run as a background process and
  14. * handle incoming requests (from the host running Nagios) for
  15. * plugin execution. It is useful for running "local" plugins
  16. * such as check_users, check_load, check_disk, etc. without
  17. * having to use rsh or ssh.
  18. *
  19. ******************************************************************************/
  20. /*
  21. * 08-10-2011 IPv4 subnetworks support added.
  22. * Main change in nrpe.c is that is_an_allowed_host() moved to acl.c.
  23. * now allowed_hosts is parsed by parse_allowed_hosts() from acl.c.
  24. */
  25. #include "config.h"
  26. #include "common.h"
  27. #include "nrpe.h"
  28. #include "utils.h"
  29. #include "acl.h"
  30. #ifdef HAVE_SSL
  31. # ifdef USE_SSL_DH
  32. # include "../include/dh.h"
  33. # endif
  34. #endif
  35. #ifndef HAVE_ASPRINTF
  36. extern int asprintf(char **ptr, const char *format, ...);
  37. #endif
  38. #ifdef HAVE_LIBWRAP
  39. int allow_severity = LOG_INFO;
  40. int deny_severity = LOG_WARNING;
  41. # ifndef HAVE_RFC931_TIMEOUT
  42. int rfc931_timeout=15;
  43. # endif
  44. #endif
  45. #ifdef HAVE_SSL
  46. # if (defined(__sun) && defined(SOLARIS_10)) || defined(_AIX) || defined(__hpux)
  47. SSL_METHOD *meth;
  48. # else
  49. const SSL_METHOD *meth;
  50. # endif
  51. SSL_CTX *ctx;
  52. int use_ssl = TRUE;
  53. #else
  54. int use_ssl = FALSE;
  55. #endif
  56. #define DEFAULT_COMMAND_TIMEOUT 60 /* default timeout for execution of plugins */
  57. #define MAXFD 64
  58. #define NASTY_METACHARS "|`&><'\\[]{};\r\n"
  59. #define MAX_LISTEN_SOCKS 16
  60. #define DEFAULT_LISTEN_QUEUE_SIZE 5
  61. #define DEFAULT_SSL_SHUTDOWN_TIMEOUT 15
  62. #define how_many(x,y) (((x)+((y)-1))/(y))
  63. extern int errno;
  64. struct addrinfo *listen_addrs = NULL;
  65. int listen_socks[MAX_LISTEN_SOCKS];
  66. char remote_host[MAX_HOST_ADDRESS_LENGTH];
  67. char *macro_argv[MAX_COMMAND_ARGUMENTS];
  68. char config_file[MAX_INPUT_BUFFER] = "nrpe.cfg";
  69. char server_address[NI_MAXHOST] = "";
  70. char *command_name = NULL;
  71. int log_facility = LOG_DAEMON;
  72. int server_port = DEFAULT_SERVER_PORT;
  73. int num_listen_socks = 0;
  74. int address_family = AF_UNSPEC;
  75. int socket_timeout = DEFAULT_SOCKET_TIMEOUT;
  76. int command_timeout = DEFAULT_COMMAND_TIMEOUT;
  77. int connection_timeout = DEFAULT_CONNECTION_TIMEOUT;
  78. int ssl_shutdown_timeout = DEFAULT_SSL_SHUTDOWN_TIMEOUT;
  79. char *command_prefix = NULL;
  80. int packet_ver = 0;
  81. command *command_list = NULL;
  82. char *nrpe_user = NULL;
  83. char *nrpe_group = NULL;
  84. char *allowed_hosts = NULL;
  85. char *keep_env_vars = NULL;
  86. char *pid_file = NULL;
  87. int wrote_pid_file = FALSE;
  88. int allow_arguments = FALSE;
  89. int allow_bash_cmd_subst = FALSE;
  90. int allow_weak_random_seed = FALSE;
  91. int sigrestart = FALSE;
  92. int sigshutdown = FALSE;
  93. int show_help = FALSE;
  94. int show_license = FALSE;
  95. int show_version = FALSE;
  96. int use_inetd = TRUE;
  97. int debug = FALSE;
  98. int use_src = FALSE; /* Define parameter for SRC option */
  99. int no_forking = FALSE;
  100. int listen_queue_size = DEFAULT_LISTEN_QUEUE_SIZE;
  101. char *nasty_metachars = NULL;
  102. extern char *log_file;
  103. /* SSL/TLS parameters */
  104. typedef enum _SSL_VER {
  105. SSLv2 = 1, SSLv2_plus, SSLv3, SSLv3_plus, TLSv1,
  106. TLSv1_plus, TLSv1_1, TLSv1_1_plus, TLSv1_2, TLSv1_2_plus
  107. } SslVer;
  108. typedef enum _CLNT_CERTS {
  109. ClntCerts_Unknown = 0, Ask_For_Cert = 1, Require_Cert = 2
  110. } ClntCerts;
  111. typedef enum _SSL_LOGGING {
  112. SSL_NoLogging = 0, SSL_LogStartup = 1, SSL_LogIpAddr = 2,
  113. SSL_LogVersion = 4, SSL_LogCipher = 8, SSL_LogIfClientCert = 16,
  114. SSL_LogCertDetails = 32
  115. } SslLogging;
  116. struct _SSL_PARMS {
  117. char *cert_file;
  118. char *cacert_file;
  119. char *privatekey_file;
  120. char cipher_list[MAX_FILENAME_LENGTH];
  121. SslVer ssl_min_ver;
  122. int allowDH;
  123. ClntCerts client_certs;
  124. SslLogging log_opts;
  125. } sslprm = {
  126. NULL, NULL, NULL, "ALL:!MD5:@STRENGTH", TLSv1_plus, TRUE, 0, SSL_NoLogging};
  127. #ifdef HAVE_SSL
  128. static int verify_callback(int ok, X509_STORE_CTX * ctx);
  129. static void my_disconnect_sighandler(int sig);
  130. static void complete_SSL_shutdown(SSL *);
  131. #endif
  132. int main(int argc, char **argv)
  133. {
  134. int result = OK;
  135. int x;
  136. uint32_t y;
  137. char buffer[MAX_INPUT_BUFFER];
  138. init();
  139. /* process command-line args */
  140. result = process_arguments(argc, argv);
  141. if (result != OK || show_help == TRUE || show_license == TRUE || show_version == TRUE)
  142. usage(result);
  143. /* make sure the config file uses an absolute path */
  144. if (config_file[0] != '/') {
  145. /* save the name of the config file */
  146. strncpy(buffer, config_file, sizeof(buffer));
  147. buffer[sizeof(buffer) - 1] = '\x0';
  148. /* get absolute path of current working directory */
  149. strcpy(config_file, "");
  150. getcwd(config_file, sizeof(config_file));
  151. /* append a forward slash */
  152. strncat(config_file, "/", sizeof(config_file) - 2);
  153. config_file[sizeof(config_file) - 1] = '\x0';
  154. /* append the config file to the path */
  155. strncat(config_file, buffer, sizeof(config_file) - strlen(config_file) - 1);
  156. config_file[sizeof(config_file) - 1] = '\x0';
  157. }
  158. /* read the config file */
  159. result = read_config_file(config_file);
  160. /* exit if there are errors... */
  161. if (result == ERROR) {
  162. logit(LOG_ERR, "Config file '%s' contained errors, aborting...", config_file);
  163. return STATE_CRITICAL;
  164. }
  165. open_log_file();
  166. if (!nasty_metachars)
  167. nasty_metachars = strdup(NASTY_METACHARS);
  168. /* initialize macros */
  169. for (x = 0; x < MAX_COMMAND_ARGUMENTS; x++)
  170. macro_argv[x] = NULL;
  171. init_ssl();
  172. /* if we're running under inetd... */
  173. if (use_inetd == TRUE)
  174. run_inetd();
  175. else if (use_src == TRUE || no_forking == TRUE)
  176. run_src();
  177. else
  178. run_daemon();
  179. #ifdef HAVE_SSL
  180. if (use_ssl == TRUE)
  181. SSL_CTX_free(ctx);
  182. #endif
  183. /* We are now running in daemon mode, or the connection handed over by inetd has
  184. been completed, so the parent process exits */
  185. return STATE_OK;
  186. }
  187. int init(void)
  188. {
  189. char *env_string = NULL;
  190. int result = OK;
  191. /* set some environment variables */
  192. asprintf(&env_string, "NRPE_MULTILINESUPPORT=1");
  193. putenv(env_string);
  194. asprintf(&env_string, "NRPE_PROGRAMVERSION=%s", PROGRAM_VERSION);
  195. putenv(env_string);
  196. /* open a connection to the syslog facility */
  197. /* facility name may be overridden later */
  198. get_log_facility(NRPE_LOG_FACILITY);
  199. openlog("nrpe", LOG_PID, log_facility);
  200. /* generate the CRC 32 table */
  201. generate_crc32_table();
  202. return result;
  203. }
  204. void init_ssl(void)
  205. {
  206. #ifdef HAVE_SSL
  207. DH *dh;
  208. char seedfile[FILENAME_MAX];
  209. int i, c, x, vrfy;
  210. unsigned long ssl_opts = SSL_OP_ALL | SSL_OP_SINGLE_DH_USE;
  211. if (use_ssl == FALSE) {
  212. if (debug == TRUE)
  213. logit(LOG_INFO, "INFO: SSL/TLS NOT initialized. Network encryption DISABLED.");
  214. return;
  215. }
  216. #ifndef USE_SSL_DH
  217. ssl_opts = SSL_OP_ALL;
  218. sslprm.allowDH = 0;
  219. #endif
  220. if (sslprm.log_opts & SSL_LogStartup)
  221. log_ssl_startup();
  222. /* initialize SSL */
  223. SSL_load_error_strings();
  224. SSL_library_init();
  225. meth = SSLv23_server_method();
  226. /* use week random seed if necessary */
  227. if (allow_weak_random_seed && (RAND_status() == 0)) {
  228. if (RAND_file_name(seedfile, sizeof(seedfile) - 1))
  229. if (RAND_load_file(seedfile, -1))
  230. RAND_write_file(seedfile);
  231. if (RAND_status() == 0) {
  232. logit(LOG_ERR,
  233. "Warning: SSL/TLS uses a weak random seed which is highly discouraged");
  234. srand(time(NULL));
  235. for (i = 0; i < 500 && RAND_status() == 0; i++) {
  236. for (c = 0; c < sizeof(seedfile); c += sizeof(int)) {
  237. *((int *)(seedfile + c)) = rand();
  238. }
  239. RAND_seed(seedfile, sizeof(seedfile));
  240. }
  241. }
  242. }
  243. # ifndef OPENSSL_NO_SSL2
  244. if (sslprm.ssl_min_ver == SSLv2)
  245. meth = SSLv2_server_method();
  246. # endif
  247. # ifndef OPENSSL_NO_SSL3
  248. if (sslprm.ssl_min_ver == SSLv3)
  249. meth = SSLv3_server_method();
  250. # endif
  251. if (sslprm.ssl_min_ver == TLSv1)
  252. meth = TLSv1_server_method();
  253. # ifdef SSL_TXT_TLSV1_1
  254. if (sslprm.ssl_min_ver == TLSv1_1)
  255. meth = TLSv1_1_server_method();
  256. # ifdef SSL_TXT_TLSV1_2
  257. if (sslprm.ssl_min_ver == TLSv1_2)
  258. meth = TLSv1_2_server_method();
  259. # endif
  260. # endif
  261. ctx = SSL_CTX_new(meth);
  262. if (ctx == NULL) {
  263. logit(LOG_ERR, "Error: could not create SSL context");
  264. SSL_CTX_free(ctx);
  265. exit(STATE_CRITICAL);
  266. }
  267. switch(sslprm.ssl_min_ver) {
  268. case SSLv2:
  269. case SSLv2_plus:
  270. break;
  271. case TLSv1_2:
  272. case TLSv1_2_plus:
  273. ssl_opts |= SSL_OP_NO_TLSv1_1;
  274. case TLSv1_1:
  275. case TLSv1_1_plus:
  276. ssl_opts |= SSL_OP_NO_TLSv1;
  277. case TLSv1:
  278. case TLSv1_plus:
  279. ssl_opts |= SSL_OP_NO_SSLv3;
  280. case SSLv3:
  281. case SSLv3_plus:
  282. ssl_opts |= SSL_OP_NO_SSLv2;
  283. break;
  284. }
  285. SSL_CTX_set_options(ctx, ssl_opts);
  286. if (sslprm.cert_file != NULL) {
  287. char errstr[120] = { "" };
  288. if (!SSL_CTX_use_certificate_file(ctx, sslprm.cert_file, SSL_FILETYPE_PEM)) {
  289. SSL_CTX_free(ctx);
  290. while ((x = ERR_get_error()) != 0) {
  291. ERR_error_string(x, errstr);
  292. logit(LOG_ERR, "Error: could not use certificate file %s : %s",
  293. sslprm.cert_file, errstr);
  294. }
  295. exit(STATE_CRITICAL);
  296. }
  297. if (!SSL_CTX_use_PrivateKey_file(ctx, sslprm.privatekey_file, SSL_FILETYPE_PEM)) {
  298. SSL_CTX_free(ctx);
  299. logit(LOG_ERR, "Error: could not use private key file '%s'",
  300. sslprm.privatekey_file);
  301. exit(STATE_CRITICAL);
  302. }
  303. }
  304. if (sslprm.client_certs != 0) {
  305. vrfy = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
  306. if ((sslprm.client_certs & Require_Cert) != 0)
  307. vrfy |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
  308. SSL_CTX_set_verify(ctx, vrfy, verify_callback);
  309. if (!SSL_CTX_load_verify_locations(ctx, sslprm.cacert_file, NULL)) {
  310. SSL_CTX_free(ctx);
  311. logit(LOG_ERR, "Error: could not use CA certificate '%s'", sslprm.cacert_file);
  312. exit(STATE_CRITICAL);
  313. }
  314. }
  315. if (!sslprm.allowDH) {
  316. if (strlen(sslprm.cipher_list) < sizeof(sslprm.cipher_list) - 6)
  317. strcat(sslprm.cipher_list, ":!ADH");
  318. } else {
  319. /* use anonymous DH ciphers */
  320. if (sslprm.allowDH == 2)
  321. strcpy(sslprm.cipher_list, "ADH");
  322. #ifdef USE_SSL_DH
  323. dh = get_dh2048();
  324. SSL_CTX_set_tmp_dh(ctx, dh);
  325. DH_free(dh);
  326. #endif
  327. }
  328. if (SSL_CTX_set_cipher_list(ctx, sslprm.cipher_list) == 0) {
  329. SSL_CTX_free(ctx);
  330. logit(LOG_ERR, "Error: Could not set SSL/TLS cipher list");
  331. exit(STATE_CRITICAL);
  332. }
  333. if (debug == TRUE)
  334. logit(LOG_INFO, "INFO: SSL/TLS initialized. All network traffic will be encrypted.");
  335. #endif
  336. }
  337. void log_ssl_startup(void)
  338. {
  339. #ifdef HAVE_SSL
  340. char *vers;
  341. logit(LOG_INFO, "SSL Certificate File: %s", sslprm.cert_file ? sslprm.cert_file : "None");
  342. logit(LOG_INFO, "SSL Private Key File: %s",
  343. sslprm.privatekey_file ? sslprm.privatekey_file : "None");
  344. logit(LOG_INFO, "SSL CA Certificate File: %s",
  345. sslprm.cacert_file ? sslprm.cacert_file : "None");
  346. if (sslprm.allowDH < 2)
  347. logit(LOG_INFO, "SSL Cipher List: %s", sslprm.cipher_list);
  348. else
  349. logit(LOG_INFO, "SSL Cipher List: ADH");
  350. logit(LOG_INFO, "SSL Allow ADH: %s",
  351. sslprm.allowDH == 0 ? "No" : (sslprm.allowDH == 1 ? "Allow" : "Require"));
  352. logit(LOG_INFO, "SSL Client Certs: %s",
  353. sslprm.client_certs == 0 ? "Don't Ask" : (sslprm.client_certs ==
  354. 1 ? "Accept" : "Require"));
  355. logit(LOG_INFO, "SSL Log Options: 0x%02x", sslprm.log_opts);
  356. switch (sslprm.ssl_min_ver) {
  357. case SSLv2:
  358. vers = "SSLv2";
  359. break;
  360. case SSLv2_plus:
  361. vers = "SSLv2 And Above";
  362. break;
  363. case SSLv3:
  364. vers = "SSLv3";
  365. break;
  366. case SSLv3_plus:
  367. vers = "SSLv3 And Above";
  368. break;
  369. case TLSv1:
  370. vers = "TLSv1";
  371. break;
  372. case TLSv1_plus:
  373. vers = "TLSv1 And Above";
  374. break;
  375. case TLSv1_1:
  376. vers = "TLSv1_1";
  377. break;
  378. case TLSv1_1_plus:
  379. vers = "TLSv1_1 And Above";
  380. break;
  381. case TLSv1_2:
  382. vers = "TLSv1_2";
  383. break;
  384. case TLSv1_2_plus:
  385. vers = "TLSv1_2 And Above";
  386. break;
  387. default:
  388. vers = "INVALID VALUE!";
  389. break;
  390. }
  391. logit(LOG_INFO, "SSL Version: %s", vers);
  392. #endif
  393. }
  394. void usage(int result)
  395. {
  396. printf("\n");
  397. printf("NRPE - Nagios Remote Plugin Executor\n");
  398. printf("Copyright (c) 1999-2008 Ethan Galstad (nagios@nagios.org)\n");
  399. printf("Version: %s\n", PROGRAM_VERSION);
  400. printf("Last Modified: %s\n", MODIFICATION_DATE);
  401. printf("License: GPL v2 with exemptions (-l for more info)\n");
  402. #ifdef HAVE_SSL
  403. printf("SSL/TLS Available, OpenSSL 0.9.6 or higher required\n");
  404. #endif
  405. #ifdef HAVE_LIBWRAP
  406. printf("TCP Wrappers Available\n");
  407. #endif
  408. printf("\n");
  409. #ifdef ENABLE_COMMAND_ARGUMENTS
  410. printf("***************************************************************\n");
  411. printf("** POSSIBLE SECURITY RISK - COMMAND ARGUMENTS ARE SUPPORTED! **\n");
  412. printf("** Read the NRPE SECURITY file for more information **\n");
  413. printf("***************************************************************\n");
  414. printf("\n");
  415. #endif
  416. #ifndef HAVE_LIBWRAP
  417. printf("***************************************************************\n");
  418. printf("** POSSIBLE SECURITY RISK - TCP WRAPPERS ARE NOT AVAILABLE! **\n");
  419. printf("** Read the NRPE SECURITY file for more information **\n");
  420. printf("***************************************************************\n");
  421. printf("\n");
  422. #endif
  423. if (show_license == TRUE)
  424. display_license();
  425. if (result != OK || show_help == TRUE) {
  426. printf("Usage: nrpe [-n] -c <config_file> [-4|-6] <mode>\n");
  427. printf("\n");
  428. printf("Options:\n");
  429. printf(" -n = Do not use SSL\n");
  430. printf(" -c <config_file> = Name of config file to use\n");
  431. printf(" -4 = use ipv4 only\n");
  432. printf(" -6 = use ipv6 only\n");
  433. printf(" <mode> = One of the following operating modes:\n");
  434. printf(" -i = Run as a service under inetd or xinetd\n");
  435. printf(" -d = Run as a standalone daemon\n");
  436. printf(" -d -s = Run as a subsystem under AIX\n");
  437. printf(" -f = Don't fork() for systemd, launchd, etc.\n");
  438. printf("\n");
  439. printf("Notes:\n");
  440. printf("This program is designed to process requests from the check_nrpe\n");
  441. printf("plugin on the host(s) running Nagios. It can run as a service\n");
  442. printf("under inetd or xinetd (read the docs for info on this), or as a\n");
  443. printf("standalone daemon. Once a request is received from an authorized\n");
  444. printf("host, NRPE will execute the command/plugin (as defined in the\n");
  445. printf("config file) and return the plugin output and return code to the\n");
  446. printf("check_nrpe plugin.\n");
  447. printf("\n");
  448. }
  449. exit(STATE_UNKNOWN);
  450. }
  451. void run_inetd(void)
  452. {
  453. check_privileges(); /* make sure we're not root */
  454. close(2); /* redirect STDERR to /dev/null */
  455. open("/dev/null", O_WRONLY);
  456. handle_connection(0); /* handle the connection */
  457. }
  458. void run_src(void)
  459. {
  460. /* if we're running under SRC we don't fork but does drop-privileges */
  461. set_stdio_sigs();
  462. do {
  463. /* reset flags */
  464. sigrestart = FALSE;
  465. sigshutdown = FALSE;
  466. wait_for_connections(); /* wait for connections */
  467. cleanup();
  468. } while (sigrestart == TRUE && sigshutdown == FALSE);
  469. }
  470. /* daemonize and start listening for requests... */
  471. void run_daemon(void)
  472. {
  473. pid_t pid;
  474. pid = fork();
  475. if (pid != 0) {
  476. if (pid == -1) {
  477. logit(LOG_ERR, "fork() failed with error %d, bailing out...", errno);
  478. exit(STATE_CRITICAL);
  479. }
  480. return;
  481. }
  482. setsid(); /* we're a daemon - set up a new process group */
  483. set_stdio_sigs();
  484. do {
  485. /* reset flags */
  486. sigrestart = FALSE;
  487. sigshutdown = FALSE;
  488. wait_for_connections(); /* wait for connections */
  489. cleanup();
  490. } while (sigrestart == TRUE && sigshutdown == FALSE);
  491. }
  492. void set_stdio_sigs(void)
  493. {
  494. #ifdef HAVE_SIGACTION
  495. struct sigaction sig_action;
  496. #endif
  497. close(0); /* close standard file descriptors */
  498. close(1);
  499. close(2);
  500. open("/dev/null", O_RDONLY); /* redirect standard descriptors to /dev/null */
  501. open("/dev/null", O_WRONLY);
  502. open("/dev/null", O_WRONLY);
  503. chdir("/");
  504. /* handle signals */
  505. #ifdef HAVE_SIGACTION
  506. sig_action.sa_sigaction = NULL;
  507. sig_action.sa_handler = sighandler;
  508. sigfillset(&sig_action.sa_mask);
  509. sig_action.sa_flags = SA_NODEFER | SA_RESTART;
  510. sigaction(SIGQUIT, &sig_action, NULL);
  511. sigaction(SIGTERM, &sig_action, NULL);
  512. sigaction(SIGHUP, &sig_action, NULL);
  513. #else /* HAVE_SIGACTION */
  514. signal(SIGQUIT, sighandler);
  515. signal(SIGTERM, sighandler);
  516. signal(SIGHUP, sighandler);
  517. #endif /* HAVE_SIGACTION */
  518. logit(LOG_NOTICE, "Starting up daemon"); /* log info */
  519. if (write_pid_file() == ERROR) /* write pid file */
  520. exit(STATE_CRITICAL);
  521. clean_environ(keep_env_vars, nrpe_user);
  522. drop_privileges(nrpe_user, nrpe_group, 0); /* drop privileges */
  523. check_privileges(); /* make sure we're not root */
  524. }
  525. void cleanup(void)
  526. {
  527. int result;
  528. free_memory(); /* free all memory we allocated */
  529. if (sigrestart == TRUE && sigshutdown == FALSE) {
  530. result = read_config_file(config_file); /* read the config file */
  531. if (result == ERROR) { /* exit if there are errors... */
  532. logit(LOG_ERR, "Config file '%s' contained errors, bailing out...", config_file);
  533. exit(STATE_CRITICAL);
  534. }
  535. open_log_file();
  536. return;
  537. }
  538. remove_pid_file(); /* remove pid file */
  539. logit(LOG_NOTICE, "Daemon shutdown\n");
  540. close_log_file(); /* close the log file */
  541. }
  542. #ifdef HAVE_SSL
  543. int verify_callback(int preverify_ok, X509_STORE_CTX * ctx)
  544. {
  545. char name[256], issuer[256];
  546. X509 *err_cert;
  547. int err;
  548. SSL *ssl;
  549. if (preverify_ok || ((sslprm.log_opts & SSL_LogCertDetails) == 0))
  550. return preverify_ok;
  551. err_cert = X509_STORE_CTX_get_current_cert(ctx);
  552. err = X509_STORE_CTX_get_error(ctx);
  553. /* Get the pointer to the SSL of the current connection */
  554. ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
  555. X509_NAME_oneline(X509_get_subject_name(err_cert), name, 256);
  556. X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), issuer, 256);
  557. if (!preverify_ok && (sslprm.log_opts & SSL_LogCertDetails)) {
  558. logit(LOG_ERR, "SSL Client has an invalid certificate: %s (issuer=%s) err=%d:%s",
  559. name, issuer, err, X509_verify_cert_error_string(err));
  560. }
  561. return preverify_ok;
  562. }
  563. #endif
  564. /* read in the configuration file */
  565. int read_config_file(char *filename)
  566. {
  567. struct stat st;
  568. FILE *fp;
  569. char config_file[MAX_FILENAME_LENGTH];
  570. char input_buffer[MAX_INPUT_BUFFER];
  571. char *input_line;
  572. char *temp_buffer;
  573. char *varname;
  574. char *varvalue;
  575. int line = 0;
  576. int len = 0;
  577. int x = 0;
  578. fp = fopen(filename, "r"); /* open the config file for reading */
  579. /* exit if we couldn't open the config file */
  580. if (fp == NULL) {
  581. logit(LOG_ERR, "Unable to open config file '%s' for reading\n", filename);
  582. return ERROR;
  583. }
  584. while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
  585. line++;
  586. input_line = input_buffer;
  587. /* skip leading whitespace */
  588. while (isspace(*input_line))
  589. ++input_line;
  590. /* trim trailing whitespace */
  591. len = strlen(input_line);
  592. for (x = len - 1; x >= 0; x--) {
  593. if (isspace(input_line[x]))
  594. input_line[x] = '\x0';
  595. else
  596. break;
  597. }
  598. /* skip comments and blank lines */
  599. if (input_line[0] == '#' || input_line[0] == '\x0' || input_line[0] == '\n')
  600. continue;
  601. /* get the variable name */
  602. varname = strtok(input_line, "=");
  603. if (varname == NULL) {
  604. logit(LOG_ERR, "No variable name specified in config file '%s' - Line %d\n",
  605. filename, line);
  606. return ERROR;
  607. }
  608. /* get the variable value */
  609. varvalue = strtok(NULL, "\n");
  610. if (varvalue == NULL) {
  611. logit(LOG_ERR, "No variable value specified in config file '%s' - Line %d\n",
  612. filename, line);
  613. return ERROR;
  614. } else if (!strcmp(varname, "include_dir")) {
  615. /* allow users to specify directories to recurse into for config files */
  616. strncpy(config_file, varvalue, sizeof(config_file) - 1);
  617. config_file[sizeof(config_file) - 1] = '\x0';
  618. /* strip trailing / if necessary */
  619. if (config_file[strlen(config_file) - 1] == '/')
  620. config_file[strlen(config_file) - 1] = '\x0';
  621. /* process the config directory... */
  622. if (read_config_dir(config_file) == ERROR)
  623. logit(LOG_ERR, "Continuing with errors...");
  624. } else if (!strcmp(varname, "include") || !strcmp(varname, "include_file")) {
  625. /* allow users to specify individual config files to include */
  626. /* process the config file... */
  627. if (read_config_file(varvalue) == ERROR)
  628. logit(LOG_ERR, "Continuing with errors...");
  629. } else if (!strcmp(varname, "server_port")) {
  630. server_port = atoi(varvalue);
  631. if (server_port < 1024) {
  632. logit(LOG_ERR,
  633. "Invalid port number specified in config file '%s' - Line %d\n",
  634. filename, line);
  635. return ERROR;
  636. }
  637. } else if (!strcmp(varname, "command_prefix"))
  638. command_prefix = strdup(varvalue);
  639. else if (!strcmp(varname, "server_address")) {
  640. strncpy(server_address, varvalue, sizeof(server_address) - 1);
  641. server_address[sizeof(server_address) - 1] = '\0';
  642. } else if (!strcmp(varname, "allowed_hosts")) {
  643. allowed_hosts = strdup(varvalue);
  644. parse_allowed_hosts(allowed_hosts);
  645. if (debug == TRUE)
  646. show_acl_lists();
  647. } else if (strstr(input_line, "command[")) {
  648. temp_buffer = strtok(varname, "[");
  649. temp_buffer = strtok(NULL, "]");
  650. if (temp_buffer == NULL) {
  651. logit(LOG_ERR, "Invalid command specified in config file '%s' - Line %d\n",
  652. filename, line);
  653. return ERROR;
  654. }
  655. add_command(temp_buffer, varvalue);
  656. } else if (strstr(input_buffer, "debug")) {
  657. debug = atoi(varvalue);
  658. if (debug > 0)
  659. debug = TRUE;
  660. else
  661. debug = FALSE;
  662. } else if (!strcmp(varname, "nrpe_user"))
  663. nrpe_user = strdup(varvalue);
  664. else if (!strcmp(varname, "nrpe_group"))
  665. nrpe_group = strdup(varvalue);
  666. else if (!strcmp(varname, "dont_blame_nrpe"))
  667. allow_arguments = (atoi(varvalue) == 1) ? TRUE : FALSE;
  668. else if (!strcmp(varname, "allow_bash_command_substitution"))
  669. allow_bash_cmd_subst = (atoi(varvalue) == 1) ? TRUE : FALSE;
  670. else if (!strcmp(varname, "command_timeout")) {
  671. command_timeout = atoi(varvalue);
  672. if (command_timeout < 1) {
  673. logit(LOG_ERR,
  674. "Invalid command_timeout specified in config file '%s' - Line %d\n",
  675. filename, line);
  676. return ERROR;
  677. }
  678. } else if (!strcmp(varname, "connection_timeout")) {
  679. connection_timeout = atoi(varvalue);
  680. if (connection_timeout < 1) {
  681. logit(LOG_ERR,
  682. "Invalid connection_timeout specified in config file '%s' - Line %d\n",
  683. filename, line);
  684. return ERROR;
  685. }
  686. } else if (!strcmp(varname, "ssl_shutdown_timeout")) {
  687. ssl_shutdown_timeout = atoi(varvalue);
  688. if (ssl_shutdown_timeout < 1) {
  689. logit(LOG_ERR,
  690. "Invalid ssl_shutdown_timeout specified in config file '%s' - Line %d\n",
  691. filename, line);
  692. return ERROR;
  693. }
  694. } else if (!strcmp(varname, "allow_weak_random_seed"))
  695. allow_weak_random_seed = (atoi(varvalue) == 1) ? TRUE : FALSE;
  696. else if (!strcmp(varname, "pid_file"))
  697. pid_file = strdup(varvalue);
  698. else if (!strcmp(varname, "listen_queue_size")) {
  699. listen_queue_size = atoi(varvalue);
  700. if (listen_queue_size == 0) {
  701. logit(LOG_ERR,
  702. "Invalid listen queue size specified in config file '%s' - Line %d\n",
  703. filename, line);
  704. return ERROR;
  705. }
  706. } else if (!strcmp(varname, "ssl_version")) {
  707. if (!strcmp(varvalue, "SSLv2"))
  708. sslprm.ssl_min_ver = SSLv2;
  709. else if (!strcmp(varvalue, "SSLv2+"))
  710. sslprm.ssl_min_ver = SSLv2_plus;
  711. else if (!strcmp(varvalue, "SSLv3"))
  712. sslprm.ssl_min_ver = SSLv3;
  713. else if (!strcmp(varvalue, "SSLv3+"))
  714. sslprm.ssl_min_ver = SSLv3_plus;
  715. else if (!strcmp(varvalue, "TLSv1"))
  716. sslprm.ssl_min_ver = TLSv1;
  717. else if (!strcmp(varvalue, "TLSv1+"))
  718. sslprm.ssl_min_ver = TLSv1_plus;
  719. else if (!strcmp(varvalue, "TLSv1.1"))
  720. sslprm.ssl_min_ver = TLSv1_1;
  721. else if (!strcmp(varvalue, "TLSv1.1+"))
  722. sslprm.ssl_min_ver = TLSv1_1_plus;
  723. else if (!strcmp(varvalue, "TLSv1.2"))
  724. sslprm.ssl_min_ver = TLSv1_2;
  725. else if (!strcmp(varvalue, "TLSv1.2+"))
  726. sslprm.ssl_min_ver = TLSv1_2_plus;
  727. else {
  728. logit(LOG_ERR, "Invalid ssl version specified in config file '%s' - Line %d",
  729. filename, line);
  730. return ERROR;
  731. }
  732. } else if (!strcmp(varname, "ssl_use_adh")) {
  733. sslprm.allowDH = atoi(varvalue);
  734. if (sslprm.allowDH < 0 || sslprm.allowDH > 2) {
  735. logit(LOG_ERR,
  736. "Invalid use adh value specified in config file '%s' - Line %d",
  737. filename, line);
  738. return ERROR;
  739. }
  740. } else if (!strcmp(varname, "ssl_logging"))
  741. sslprm.log_opts = strtoul(varvalue, NULL, 0);
  742. else if (!strcmp(varname, "ssl_cipher_list")) {
  743. strncpy(sslprm.cipher_list, varvalue, sizeof(sslprm.cipher_list) - 1);
  744. sslprm.cipher_list[sizeof(sslprm.cipher_list) - 1] = '\0';
  745. } else if (!strcmp(varname, "ssl_cert_file"))
  746. sslprm.cert_file = strdup(varvalue);
  747. else if (!strcmp(varname, "ssl_cacert_file"))
  748. sslprm.cacert_file = strdup(varvalue);
  749. else if (!strcmp(varname, "ssl_privatekey_file"))
  750. sslprm.privatekey_file = strdup(varvalue);
  751. else if (!strcmp(varname, "ssl_client_certs")) {
  752. sslprm.client_certs = atoi(varvalue);
  753. if ((int)sslprm.client_certs < 0 || sslprm.client_certs > Require_Cert) {
  754. logit(LOG_ERR,
  755. "Invalid client certs value specified in config file '%s' - Line %d",
  756. filename, line);
  757. return ERROR;
  758. }
  759. /* if requiring or logging client certs, make sure "Ask" is turned on */
  760. if (sslprm.client_certs & Require_Cert)
  761. sslprm.client_certs |= Ask_For_Cert;
  762. } else if (!strcmp(varname, "log_facility")) {
  763. if ((get_log_facility(varvalue)) == OK) {
  764. /* re-open log using new facility */
  765. closelog();
  766. openlog("nrpe", LOG_PID, log_facility);
  767. } else
  768. logit(LOG_WARNING,
  769. "Invalid log_facility specified in config file '%s' - Line %d\n",
  770. filename, line);
  771. } else if (!strcmp(varname, "keep_env_vars"))
  772. keep_env_vars = strdup(varvalue);
  773. else if (!strcmp(varname, "nasty_metachars"))
  774. nasty_metachars = strdup(varvalue);
  775. else if (!strcmp(varname, "log_file"))
  776. log_file = strdup(varvalue);
  777. else {
  778. logit(LOG_WARNING, "Unknown option specified in config file '%s' - Line %d\n",
  779. filename, line);
  780. continue;
  781. }
  782. }
  783. fclose(fp); /* close the config file */
  784. return OK;
  785. }
  786. /* process all config files in a specific config directory (with directory recursion) */
  787. int read_config_dir(char *dirname)
  788. {
  789. struct dirent *dirfile;
  790. #ifdef HAVE_SCANDIR
  791. struct dirent **dirfiles;
  792. int x, i, n;
  793. #else
  794. DIR *dirp;
  795. int x;
  796. #endif
  797. struct stat buf;
  798. char config_file[MAX_FILENAME_LENGTH];
  799. int result = OK;
  800. #ifdef HAVE_SCANDIR
  801. /* read and sort the directory contents */
  802. n = scandir(dirname, &dirfiles, 0, alphasort);
  803. if (n < 0) {
  804. logit(LOG_ERR, "Could not open config directory '%s' for reading.\n", dirname);
  805. return ERROR;
  806. }
  807. for (i = 0; i < n; i++) {
  808. dirfile = dirfiles[i];
  809. #else
  810. /* open the directory for reading */
  811. dirp = opendir(dirname);
  812. if (dirp == NULL) {
  813. logit(LOG_ERR, "Could not open config directory '%s' for reading.\n", dirname);
  814. return ERROR;
  815. }
  816. while ((dirfile = readdir(dirp)) != NULL) {
  817. #endif
  818. /* process all files in the directory... */
  819. /* create the full path to the config file or subdirectory */
  820. snprintf(config_file, sizeof(config_file) - 1, "%s/%s", dirname, dirfile->d_name);
  821. config_file[sizeof(config_file) - 1] = '\x0';
  822. stat(config_file, &buf);
  823. /* process this if it's a config file... */
  824. x = strlen(dirfile->d_name);
  825. if (x > 4 && !strcmp(dirfile->d_name + (x - 4), ".cfg")) {
  826. /* only process normal files */
  827. if (!S_ISREG(buf.st_mode))
  828. continue;
  829. /* process the config file */
  830. result = read_config_file(config_file);
  831. /* break out if we encountered an error */
  832. if (result == ERROR)
  833. break;
  834. }
  835. /* recurse into subdirectories... */
  836. if (S_ISDIR(buf.st_mode)) {
  837. /* ignore current, parent and hidden directory entries */
  838. if (dirfile->d_name[0] == '.')
  839. continue;
  840. /* process the config directory */
  841. result = read_config_dir(config_file);
  842. /* break out if we encountered an error */
  843. if (result == ERROR)
  844. break;
  845. }
  846. }
  847. #ifdef HAVE_SCANDIR
  848. for (i = 0; i < n; i++)
  849. free(dirfiles[i]);
  850. free(dirfiles);
  851. #else
  852. closedir(dirp);
  853. #endif
  854. return result;
  855. }
  856. /* determines facility to use with syslog */
  857. int get_log_facility(char *varvalue)
  858. {
  859. if (!strcmp(varvalue, "kern"))
  860. log_facility = LOG_KERN;
  861. else if (!strcmp(varvalue, "user"))
  862. log_facility = LOG_USER;
  863. else if (!strcmp(varvalue, "mail"))
  864. log_facility = LOG_MAIL;
  865. else if (!strcmp(varvalue, "daemon"))
  866. log_facility = LOG_DAEMON;
  867. else if (!strcmp(varvalue, "auth"))
  868. log_facility = LOG_AUTH;
  869. else if (!strcmp(varvalue, "syslog"))
  870. log_facility = LOG_SYSLOG;
  871. else if (!strcmp(varvalue, "lrp"))
  872. log_facility = LOG_LPR;
  873. else if (!strcmp(varvalue, "news"))
  874. log_facility = LOG_NEWS;
  875. else if (!strcmp(varvalue, "uucp"))
  876. log_facility = LOG_UUCP;
  877. else if (!strcmp(varvalue, "cron"))
  878. log_facility = LOG_CRON;
  879. else if (!strcmp(varvalue, "authpriv"))
  880. log_facility = LOG_AUTHPRIV;
  881. else if (!strcmp(varvalue, "ftp"))
  882. log_facility = LOG_FTP;
  883. else if (!strcmp(varvalue, "local0"))
  884. log_facility = LOG_LOCAL0;
  885. else if (!strcmp(varvalue, "local1"))
  886. log_facility = LOG_LOCAL1;
  887. else if (!strcmp(varvalue, "local2"))
  888. log_facility = LOG_LOCAL2;
  889. else if (!strcmp(varvalue, "local3"))
  890. log_facility = LOG_LOCAL3;
  891. else if (!strcmp(varvalue, "local4"))
  892. log_facility = LOG_LOCAL4;
  893. else if (!strcmp(varvalue, "local5"))
  894. log_facility = LOG_LOCAL5;
  895. else if (!strcmp(varvalue, "local6"))
  896. log_facility = LOG_LOCAL6;
  897. else if (!strcmp(varvalue, "local7"))
  898. log_facility = LOG_LOCAL7;
  899. else {
  900. log_facility = LOG_DAEMON;
  901. return ERROR;
  902. }
  903. return OK;
  904. }
  905. /* adds a new command definition from the config file to the list in memory */
  906. int add_command(char *command_name, char *command_line)
  907. {
  908. command *new_command;
  909. if (command_name == NULL || command_line == NULL)
  910. return ERROR;
  911. /* allocate memory for the new command */
  912. new_command = (command *) malloc(sizeof(command));
  913. if (new_command == NULL)
  914. return ERROR;
  915. new_command->command_name = strdup(command_name);
  916. if (new_command->command_name == NULL) {
  917. free(new_command);
  918. return ERROR;
  919. }
  920. new_command->command_line = strdup(command_line);
  921. if (new_command->command_line == NULL) {
  922. free(new_command->command_name);
  923. free(new_command);
  924. return ERROR;
  925. }
  926. /* add new command to head of list in memory */
  927. new_command->next = command_list;
  928. command_list = new_command;
  929. if (debug == TRUE)
  930. logit(LOG_DEBUG, "Added command[%s]=%s\n", command_name, command_line);
  931. return OK;
  932. }
  933. /* given a command name, find the structure in memory */
  934. command *find_command(char *command_name)
  935. {
  936. command *temp_command;
  937. for (temp_command = command_list; temp_command != NULL; temp_command = temp_command->next)
  938. if (!strcmp(command_name, temp_command->command_name))
  939. return temp_command;
  940. return NULL;
  941. }
  942. /* Start listen on a particular port */
  943. void create_listener(struct addrinfo *ai)
  944. {
  945. int ret;
  946. char ntop[NI_MAXHOST], strport[NI_MAXSERV];
  947. int listen_sock;
  948. int flag = 1;
  949. if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
  950. return;
  951. if (num_listen_socks >= MAX_LISTEN_SOCKS) {
  952. logit(LOG_ERR, "Too many listen sockets. Enlarge MAX_LISTEN_SOCKS");
  953. exit(1);
  954. }
  955. if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
  956. strport, sizeof(strport), NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
  957. logit(LOG_ERR, "getnameinfo failed: %.100s", gai_strerror(ret));
  958. return;
  959. }
  960. /* Create socket for listening. */
  961. listen_sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
  962. if (listen_sock < 0) {
  963. /* kernel may not support ipv6 */
  964. logit(LOG_ERR, "socket: %.100s", strerror(errno));
  965. return;
  966. }
  967. /* socket should be non-blocking */
  968. fcntl(listen_sock, F_SETFL, O_NONBLOCK);
  969. /* set the reuse address flag so we don't get errors when restarting */
  970. if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)) < 0) {
  971. logit(LOG_ERR, "setsockopt SO_REUSEADDR: %s", strerror(errno));
  972. return;
  973. }
  974. #ifdef IPV6_V6ONLY
  975. /* Only communicate in IPv6 over AF_INET6 sockets. */
  976. if (ai->ai_family == AF_INET6) {
  977. if (setsockopt(listen_sock, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag)) == -1) {
  978. fprintf(stderr, "setsockopt IPV6_V6ONLY: %s", strerror(errno));
  979. }
  980. }
  981. #endif
  982. /* Bind the socket to the desired port. */
  983. if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) {
  984. logit(LOG_ERR, "Bind to port %s on %s failed: %.200s.",
  985. strport, ntop, strerror(errno));
  986. close(listen_sock);
  987. return;
  988. }
  989. listen_socks[num_listen_socks] = listen_sock;
  990. num_listen_socks++;
  991. /* Start listening on the port. */
  992. if (listen(listen_sock, listen_queue_size) < 0) {
  993. logit(LOG_ERR, "listen on [%s]:%s: %.100s", ntop, strport, strerror(errno));
  994. exit(1);
  995. }
  996. logit(LOG_INFO, "Server listening on %s port %s.", ntop, strport);
  997. }
  998. /* Close all listening sockets */
  999. static void close_listen_socks(void)
  1000. {
  1001. int i;
  1002. for (i = 0; i <= num_listen_socks; i++) {
  1003. close(listen_socks[i]);
  1004. num_listen_socks--;
  1005. }
  1006. }
  1007. /* wait for incoming connection requests */
  1008. void wait_for_connections(void)
  1009. {
  1010. #ifdef HAVE_STRUCT_SOCKADDR_STORAGE
  1011. struct sockaddr_storage from;
  1012. #else
  1013. struct sockaddr from;
  1014. #endif
  1015. socklen_t fromlen;
  1016. fd_set *fdset = NULL;
  1017. int maxfd = 0, new_sd = 0, i, rc, retval;
  1018. setup_wait_conn();
  1019. /* listen for connection requests - fork() if we get one */
  1020. while (1) {
  1021. /* bail out if necessary */
  1022. if (sigrestart == TRUE || sigshutdown == TRUE)
  1023. break;
  1024. for (i = 0; i < num_listen_socks; i++) {
  1025. if (listen_socks[i] > maxfd)
  1026. maxfd = listen_socks[i];
  1027. }
  1028. if (fdset != NULL)
  1029. free(fdset);
  1030. fdset = (fd_set *) calloc(how_many(maxfd + 1, NFDBITS), sizeof(fd_mask));
  1031. for (i = 0; i < num_listen_socks; i++)
  1032. FD_SET(listen_socks[i], fdset);
  1033. /* Wait in select until there is a connection. */
  1034. retval = select(maxfd + 1, fdset, NULL, NULL, NULL);
  1035. /* bail out if necessary */
  1036. if (sigrestart == TRUE || sigshutdown == TRUE)
  1037. break;
  1038. /* error */
  1039. if (retval < 0)
  1040. continue;
  1041. for (i = 0; i < num_listen_socks; i++) {
  1042. if (!FD_ISSET(listen_socks[i], fdset))
  1043. continue;
  1044. fromlen = (socklen_t)sizeof(from);
  1045. /* accept a new connection request */
  1046. new_sd = accept(listen_socks[i], (struct sockaddr *)&from, &fromlen);
  1047. /* some kind of error occurred... */
  1048. if (new_sd < 0) {
  1049. /* bail out if necessary */
  1050. if (sigrestart == TRUE || sigshutdown == TRUE)
  1051. break;
  1052. if (errno == EWOULDBLOCK || errno == EINTR) /* retry */
  1053. continue;
  1054. /* socket is nonblocking and we don't have a connection yet */
  1055. if (errno == EAGAIN)
  1056. continue;
  1057. if (errno == ENOBUFS) /* fix for HP-UX 11.0 - just retry */
  1058. continue;
  1059. break; /* else handle the error later */
  1060. }
  1061. rc = wait_conn_fork(new_sd);
  1062. if (rc == TRUE)
  1063. continue; /* Continue if this is the parent returning */
  1064. /* grandchild running here */
  1065. conn_check_peer(new_sd);
  1066. /* handle the client connection */
  1067. handle_connection(new_sd);
  1068. /* log info */
  1069. if (debug == TRUE)
  1070. logit(LOG_DEBUG, "Connection from %s closed.", remote_host);
  1071. /* close socket prior to exiting */
  1072. close(new_sd);
  1073. exit(STATE_OK);
  1074. }
  1075. }
  1076. /* close the sockets we're listening on */
  1077. close_listen_socks();
  1078. freeaddrinfo(listen_addrs);
  1079. listen_addrs = NULL;
  1080. return;
  1081. }
  1082. void setup_wait_conn(void)
  1083. {
  1084. struct addrinfo *ai;
  1085. char addrstr[100];
  1086. void *ptr;
  1087. add_listen_addr(&listen_addrs, address_family,
  1088. (strcmp(server_address, "") == 0) ? NULL : server_address, server_port);
  1089. for (ai = listen_addrs; ai; ai = ai->ai_next) {
  1090. if (debug == TRUE) {
  1091. inet_ntop (ai->ai_family, ai->ai_addr->sa_data, addrstr, 100);
  1092. ptr = &((struct sockaddr_in *) ai->ai_addr)->sin_addr;
  1093. inet_ntop (ai->ai_family, ptr, addrstr, 100);
  1094. logit(LOG_INFO, "SETUP_WAIT_CONN FOR: IPv4 address: %s (%s)\n", addrstr, ai->ai_canonname);
  1095. }
  1096. create_listener(ai);
  1097. }
  1098. if (!num_listen_socks) {
  1099. logit(LOG_ERR, "Cannot bind to any address.");
  1100. exit(1);
  1101. }
  1102. /* log warning about command arguments */
  1103. #ifdef ENABLE_COMMAND_ARGUMENTS
  1104. if (allow_arguments == TRUE)
  1105. logit(LOG_NOTICE,
  1106. "Warning: Daemon is configured to accept command arguments from clients!");
  1107. # ifdef ENABLE_BASH_COMMAND_SUBSTITUTION
  1108. if (TRUE == allow_bash_cmd_subst) {
  1109. if (TRUE == allow_arguments)
  1110. logit(LOG_NOTICE,
  1111. "Warning: Daemon is configured to accept command arguments with bash command substitutions!");
  1112. else
  1113. logit(LOG_NOTICE,
  1114. "Warning: Daemon is configured to accept command arguments with bash command substitutions, but is not configured to accept command arguments from clients. Enable command arguments if you wish to allow command arguments with bash command substitutions.");
  1115. }
  1116. # endif
  1117. #endif
  1118. logit(LOG_INFO, "Listening for connections on port %d", server_port);
  1119. if (allowed_hosts)
  1120. logit(LOG_INFO, "Allowing connections from: %s\n", allowed_hosts);
  1121. }
  1122. int wait_conn_fork(int sock)
  1123. {
  1124. #ifdef HAVE_SIGACTION
  1125. struct sigaction sig_action;
  1126. #endif
  1127. pid_t pid;
  1128. /* child process should handle the connection */
  1129. pid = fork();
  1130. if (pid > 0) {
  1131. close(sock); /* parent doesn't need the new connection */
  1132. waitpid(pid, NULL, 0); /* parent waits for first child to exit */
  1133. return TRUE; /* tell caller this is the parent process */
  1134. }
  1135. if (pid < 0) {
  1136. logit(LOG_ERR, "fork() failed with error %d, bailing out...", errno);
  1137. exit(STATE_CRITICAL);
  1138. }
  1139. /* fork again so we don't create zombies */
  1140. pid = fork();
  1141. if (pid < 0) {
  1142. logit(LOG_ERR, "fork() failed with error %d, bailing out...", errno);
  1143. exit(STATE_CRITICAL);
  1144. }
  1145. if (pid > 0) {
  1146. /* first child returns immediately, grandchild is inherited by
  1147. INIT process -> no zombies... */
  1148. exit(STATE_OK);
  1149. }
  1150. /* hey, there was an error... */
  1151. if (sock < 0) {
  1152. /* log error */
  1153. logit(LOG_ERR, "Network server accept failure (%d: %s)",
  1154. errno, strerror(errno));
  1155. exit(STATE_OK);
  1156. }
  1157. /* all good - handle signals */
  1158. #ifdef HAVE_SIGACTION
  1159. sig_action.sa_sigaction = NULL;
  1160. sig_action.sa_handler = child_sighandler;
  1161. sigfillset(&sig_action.sa_mask);
  1162. sig_action.sa_flags = SA_NODEFER | SA_RESTART;
  1163. sigaction(SIGQUIT, &sig_action, NULL);
  1164. sigaction(SIGTERM, &sig_action, NULL);
  1165. sigaction(SIGHUP, &sig_action, NULL);
  1166. #else /* HAVE_SIGACTION */
  1167. signal(SIGQUIT, child_sighandler);
  1168. signal(SIGTERM, child_sighandler);
  1169. signal(SIGHUP, child_sighandler);
  1170. #endif /* HAVE_SIGACTION */
  1171. close_listen_socks(); /* grandchild does not need to listen */
  1172. return FALSE; /* tell caller this isn't the parent process */
  1173. }
  1174. void conn_check_peer(int sock)
  1175. {
  1176. #ifdef HAVE_LIBWRAP
  1177. struct request_info req;
  1178. #endif
  1179. #ifdef HAVE_STRUCT_SOCKADDR_STORAGE
  1180. struct sockaddr_storage addr;
  1181. #else
  1182. struct sockaddr addr;
  1183. #endif
  1184. struct sockaddr_in *nptr;
  1185. struct sockaddr_in6 *nptr6;
  1186. char ipstr[INET6_ADDRSTRLEN];
  1187. socklen_t addrlen;
  1188. int rc;
  1189. /* find out who just connected... */
  1190. addrlen = sizeof(addr);
  1191. rc = getpeername(sock, (struct sockaddr *)&addr, &addrlen);
  1192. if (rc < 0) {
  1193. /* log error */
  1194. logit(LOG_ERR, "Error: Network server getpeername() failure (%d: %s)",
  1195. errno, strerror(errno));
  1196. /* close socket prior to exiting */
  1197. close(sock);
  1198. return;
  1199. }
  1200. #ifdef HAVE_STRUCT_SOCKADDR_STORAGE
  1201. switch (addr.ss_family) {
  1202. #else
  1203. switch (addr.sa_family) {
  1204. #endif
  1205. case AF_INET:
  1206. nptr = (struct sockaddr_in *)&addr;
  1207. strncpy(remote_host, inet_ntoa(nptr->sin_addr), sizeof(remote_host) - 1);
  1208. remote_host[MAX_HOST_ADDRESS_LENGTH - 1] = '\0';
  1209. break;
  1210. case AF_INET6:
  1211. nptr6 = (struct sockaddr_in6 *)&addr;
  1212. if (inet_ntop(AF_INET6, (const void *)&(nptr6->sin6_addr),
  1213. ipstr, sizeof(ipstr)) == NULL) {
  1214. strncpy(ipstr, "Unknown", sizeof(ipstr));
  1215. }
  1216. strncpy(remote_host, ipstr, sizeof(remote_host) - 1);
  1217. remote_host[MAX_HOST_ADDRESS_LENGTH - 1] = '\0';
  1218. break;
  1219. }
  1220. if (debug == TRUE)
  1221. logit(LOG_INFO, "CONN_CHECK_PEER: is this a blessed machine: %s port %d\n",
  1222. remote_host, nptr->sin_port);
  1223. /* is this is a blessed machine? */
  1224. if (allowed_hosts) {
  1225. #ifdef HAVE_STRUCT_SOCKADDR_STORAGE
  1226. switch (addr.ss_family) {
  1227. #else
  1228. switch (addr.sa_family) {
  1229. #endif
  1230. case AF_INET:
  1231. /* log info */
  1232. if (debug == TRUE || (sslprm.log_opts & SSL_LogIpAddr))
  1233. logit(LOG_DEBUG, "Connection from %s port %d", remote_host, nptr->sin_port);
  1234. if (!is_an_allowed_host(AF_INET, (void *)&(nptr->sin_addr))) {
  1235. /* log error */
  1236. logit(LOG_ERR, "Host %s is not allowed to talk to us!", remote_host);
  1237. /* log info */
  1238. if (debug == TRUE)
  1239. logit(LOG_DEBUG, "Connection from %s closed.", remote_host);
  1240. /* close socket prior to exiting */
  1241. close(sock);
  1242. exit(STATE_OK);
  1243. } else {
  1244. /* log info */
  1245. if (debug == TRUE) {
  1246. logit(LOG_DEBUG, "Host address is in allowed_hosts");
  1247. }
  1248. }
  1249. break;
  1250. case AF_INET6:
  1251. /* log info */
  1252. strcpy(remote_host, ipstr);
  1253. if (debug == TRUE || (sslprm.log_opts & SSL_LogIpAddr)) {
  1254. logit(LOG_DEBUG, "Connection from %s port %d", ipstr, nptr6->sin6_port);
  1255. }
  1256. if (!is_an_allowed_host(AF_INET6, (void *)&(nptr6->sin6_addr))) {
  1257. /* log error */
  1258. logit(LOG_ERR, "Host %s is not allowed to talk to us!", ipstr);
  1259. /* log info */
  1260. if (debug == TRUE)
  1261. logit(LOG_DEBUG, "Connection from %s closed.", ipstr);
  1262. /* close socket prior to exiting */
  1263. close(sock);
  1264. exit(STATE_OK);
  1265. } else {
  1266. /* log info */
  1267. if (debug == TRUE)
  1268. logit(LOG_DEBUG, "Host address is in allowed_hosts");
  1269. }
  1270. break;
  1271. }
  1272. }
  1273. #ifdef HAVE_LIBWRAP
  1274. /* Check whether or not connections are allowed from this host */
  1275. request_init(&req, RQ_DAEMON, "nrpe", RQ_FILE, sock, 0);
  1276. fromhost(&req);
  1277. if (!hosts_access(&req)) {
  1278. logit(LOG_DEBUG, "Connection refused by TCP wrapper");
  1279. refuse(&req); /* refuse the connection */
  1280. /* should not be reached */
  1281. logit(LOG_ERR, "libwrap refuse() returns!");
  1282. close(sock);
  1283. exit(STATE_CRITICAL);
  1284. }
  1285. #endif
  1286. }
  1287. /* handles a client connection */
  1288. void handle_connection(int sock)
  1289. {
  1290. u_int32_t calculated_crc32;
  1291. command *temp_command;
  1292. v2_packet receive_packet, send_packet;
  1293. v3_packet *v3_receive_packet = NULL, *v3_send_packet = NULL;
  1294. int bytes_to_send;
  1295. char buffer[MAX_INPUT_BUFFER], *send_buff = NULL, *send_pkt;
  1296. char raw_command[MAX_INPUT_BUFFER];
  1297. char processed_command[MAX_INPUT_BUFFER];
  1298. int result = STATE_OK;
  1299. int early_timeout = FALSE;
  1300. int rc;
  1301. int x;
  1302. int32_t pkt_size;
  1303. #ifdef DEBUG
  1304. FILE *errfp;
  1305. #endif
  1306. #ifdef HAVE_SSL
  1307. SSL *ssl = NULL;
  1308. #endif
  1309. /* do SSL handshake */
  1310. #ifdef HAVE_SSL
  1311. if (use_ssl == TRUE) {
  1312. if ((ssl = SSL_new(ctx)) == NULL) {
  1313. logit(LOG_ERR, "Error: Could not create SSL connection structure.");
  1314. # ifdef DEBUG
  1315. errfp = fopen("/tmp/err.log", "a");
  1316. ERR_print_errors_fp(errfp);
  1317. fclose(errfp);
  1318. # endif
  1319. return;
  1320. }
  1321. if (handle_conn_ssl(sock, ssl) != OK)
  1322. return;
  1323. }
  1324. #endif
  1325. #ifdef HAVE_SSL
  1326. rc = read_packet(sock, ssl, &receive_packet, &v3_receive_packet);
  1327. #else
  1328. rc = read_packet(sock, NULL, &receive_packet, &v3_receive_packet);
  1329. #endif
  1330. /* disable connection alarm - a new alarm will be setup during my_system */
  1331. alarm(0);
  1332. /* recv() error or client disconnect */
  1333. if (rc <= 0) {
  1334. /* log error */
  1335. logit(LOG_ERR, "Could not read request from client %s, bailing out...", remote_host);
  1336. if (v3_receive_packet)
  1337. free(v3_receive_packet);
  1338. #ifdef HAVE_SSL
  1339. if (ssl) {
  1340. complete_SSL_shutdown(ssl);
  1341. SSL_free(ssl);
  1342. logit(LOG_INFO, "INFO: SSL Socket Shutdown.\n");
  1343. }
  1344. #endif
  1345. return;
  1346. }
  1347. /* make sure the request is valid */
  1348. if (validate_request(&receive_packet, v3_receive_packet) == ERROR) {
  1349. /* log an error */
  1350. logit(LOG_ERR, "Client request from %s was invalid, bailing out...", remote_host);
  1351. /* free memory */
  1352. free(command_name);
  1353. command_name = NULL;
  1354. for (x = 0; x < MAX_COMMAND_ARGUMENTS; x++) {
  1355. free(macro_argv[x]);
  1356. macro_argv[x] = NULL;
  1357. }
  1358. if (v3_receive_packet)
  1359. free(v3_receive_packet);
  1360. #ifdef HAVE_SSL
  1361. if (ssl) {
  1362. complete_SSL_shutdown(ssl);
  1363. SSL_free(ssl);
  1364. }
  1365. #endif
  1366. return;
  1367. }
  1368. /* log info */
  1369. if (debug == TRUE)
  1370. logit(LOG_DEBUG, "Host %s is asking for command '%s' to be run...",
  1371. remote_host, command_name);
  1372. /* if this is the version check command, just spew it out */
  1373. if (!strcmp(command_name, NRPE_HELLO_COMMAND)) {
  1374. snprintf(buffer, sizeof(buffer), "NRPE v%s", PROGRAM_VERSION);
  1375. buffer[sizeof(buffer) - 1] = '\x0';
  1376. if (debug == TRUE) /* log info */
  1377. logit(LOG_DEBUG, "Response to %s: %s", remote_host, buffer);
  1378. if (v3_receive_packet)
  1379. send_buff = strdup(buffer);
  1380. else {
  1381. send_buff = calloc(1, sizeof(buffer));
  1382. strcpy(send_buff, buffer);
  1383. }
  1384. result = STATE_OK;
  1385. } else {
  1386. /* find the command we're supposed to run */
  1387. temp_command = find_command(command_name);
  1388. if (temp_command == NULL) {
  1389. snprintf(buffer, sizeof(buffer), "NRPE: Command '%s' not defined", command_name);
  1390. buffer[sizeof(buffer) - 1] = '\x0';
  1391. if (debug == TRUE) /* log error */
  1392. logit(LOG_DEBUG, "%s", buffer);
  1393. if (v3_receive_packet)
  1394. send_buff = strdup(buffer);
  1395. else {
  1396. send_buff = calloc(1, sizeof(buffer));
  1397. strcpy(send_buff, buffer);
  1398. }
  1399. result = STATE_CRITICAL;
  1400. } else {
  1401. /* process command line */
  1402. if (command_prefix == NULL)
  1403. strncpy(raw_command, temp_command->command_line, sizeof(raw_command) - 1);
  1404. else
  1405. snprintf(raw_command, sizeof(raw_command) - 1, "%s %s", command_prefix,
  1406. temp_command->command_line);
  1407. raw_command[sizeof(raw_command) - 1] = '\x0';
  1408. process_macros(raw_command, processed_command, sizeof(processed_command));
  1409. if (debug == TRUE) /* log info */
  1410. logit(LOG_DEBUG, "Running command: %s", processed_command);
  1411. /* run the command */
  1412. strcpy(buffer, "");
  1413. result = my_system(processed_command, command_timeout, &early_timeout, &send_buff);
  1414. if (debug == TRUE) /* log debug info */
  1415. logit(LOG_DEBUG, "Command completed with return code %d and output: %s",
  1416. result, send_buff);
  1417. /* see if the command timed out */
  1418. if (early_timeout == TRUE) {
  1419. sprintf(send_buff, "NRPE: Command timed out after %d seconds\n",
  1420. command_timeout);
  1421. result = STATE_UNKNOWN;
  1422. } else if (!strcmp(send_buff, "")) {
  1423. sprintf(send_buff, "NRPE: Unable to read output\n");
  1424. result = STATE_UNKNOWN;
  1425. }
  1426. /* check return code bounds */
  1427. if ((result < 0) || (result > 3)) {
  1428. /* log error */
  1429. logit(LOG_ERR, "Bad return code for [%s]: %d", send_buff, result);
  1430. result = STATE_UNKNOWN;
  1431. }
  1432. }
  1433. }
  1434. /* free memory */
  1435. free(command_name);
  1436. command_name = NULL;
  1437. for (x = 0; x < MAX_COMMAND_ARGUMENTS; x++) {
  1438. free(macro_argv[x]);
  1439. macro_argv[x] = NULL;
  1440. }
  1441. if (v3_receive_packet)
  1442. free(v3_receive_packet);
  1443. pkt_size = strlen(send_buff);
  1444. /* strip newline character from end of output buffer */
  1445. if (send_buff[strlen(send_buff) - 1] == '\n')
  1446. send_buff[strlen(send_buff) - 1] = '\x0';
  1447. if (packet_ver == NRPE_PACKET_VERSION_2) {
  1448. pkt_size = sizeof(v2_packet);
  1449. send_pkt = (char *)&send_packet;
  1450. /* clear the response packet buffer */
  1451. memset(&send_packet, 0, sizeof(send_packet));
  1452. /* fill the packet with semi-random data */
  1453. randomize_buffer((char *)&send_packet, sizeof(send_packet));
  1454. /* initialize response packet data */
  1455. send_packet.packet_version = htons(packet_ver);
  1456. send_packet.packet_type = htons(RESPONSE_PACKET);
  1457. send_packet.result_code = htons(result);
  1458. strncpy(&send_packet.buffer[0], send_buff, MAX_PACKETBUFFER_LENGTH);
  1459. send_packet.buffer[MAX_PACKETBUFFER_LENGTH - 1] = '\x0';
  1460. /* calculate the crc 32 value of the packet */
  1461. send_packet.crc32_value = 0;
  1462. calculated_crc32 = calculate_crc32((char *)&send_packet, sizeof(send_packet));
  1463. send_packet.crc32_value = htonl(calculated_crc32);
  1464. } else {
  1465. pkt_size = (sizeof(v3_packet) - 1) + strlen(send_buff);
  1466. v3_send_packet = calloc(1, pkt_size);
  1467. send_pkt = (char *)v3_send_packet;
  1468. /* initialize response packet data */
  1469. v3_send_packet->packet_version = htons(packet_ver);
  1470. v3_send_packet->packet_type = htons(RESPONSE_PACKET);
  1471. v3_send_packet->result_code = htons(result);
  1472. v3_send_packet->alignment = 0;
  1473. v3_send_packet->buffer_length = htonl(strlen(send_buff));
  1474. strcpy(&v3_send_packet->buffer[0], send_buff);
  1475. /* calculate the crc 32 value of the packet */
  1476. v3_send_packet->crc32_value = 0;
  1477. calculated_crc32 = calculate_crc32((char *)v3_send_packet, pkt_size);
  1478. v3_send_packet->crc32_value = htonl(calculated_crc32);
  1479. }
  1480. /* send the response back to the client */
  1481. bytes_to_send = pkt_size;
  1482. if (use_ssl == FALSE)
  1483. sendall(sock, send_pkt, &bytes_to_send);
  1484. #ifdef HAVE_SSL
  1485. else
  1486. SSL_write(ssl, send_pkt, bytes_to_send);
  1487. #endif
  1488. #ifdef HAVE_SSL
  1489. if (ssl) {
  1490. complete_SSL_shutdown(ssl);
  1491. SSL_free(ssl);
  1492. }
  1493. #endif
  1494. if (v3_send_packet)
  1495. free(v3_send_packet);
  1496. /* log info */
  1497. if (debug == TRUE)
  1498. logit(LOG_DEBUG, "Return Code: %d, Output: %s", result, send_buff);
  1499. free(send_buff);
  1500. return;
  1501. }
  1502. void init_handle_conn(void)
  1503. {
  1504. #ifdef HAVE_SIGACTION
  1505. struct sigaction sig_action;
  1506. #endif
  1507. /* log info */
  1508. if (debug == TRUE)
  1509. logit(LOG_DEBUG, "Handling the connection...");
  1510. /* set connection handler */
  1511. #ifdef HAVE_SIGACTION
  1512. sig_action.sa_sigaction = NULL;
  1513. sig_action.sa_handler = my_connection_sighandler;
  1514. sigfillset(&sig_action.sa_mask);
  1515. sig_action.sa_flags = SA_NODEFER | SA_RESTART;
  1516. sigaction(SIGALRM, &sig_action, NULL);
  1517. #else
  1518. signal(SIGALRM, my_connection_sighandler);
  1519. #endif /* HAVE_SIGACTION */
  1520. alarm(connection_timeout);
  1521. }
  1522. int handle_conn_ssl(int sock, void *ssl_ptr)
  1523. {
  1524. #ifdef HAVE_SSL
  1525. # if (defined(__sun) && defined(SOLARIS_10)) || defined(_AIX) || defined(__hpux)
  1526. SSL_CIPHER *c;
  1527. #else
  1528. const SSL_CIPHER *c;
  1529. #endif
  1530. char buffer[MAX_INPUT_BUFFER];
  1531. SSL *ssl = (SSL*)ssl_ptr;
  1532. X509 *peer;
  1533. int rc, x;
  1534. SSL_set_fd(ssl, sock);
  1535. /* keep attempting the request if needed */
  1536. while (((rc = SSL_accept(ssl)) != 1)
  1537. && (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ)) ;
  1538. if (rc != 1) {
  1539. /* oops, got an unrecoverable error -- get out */
  1540. if (sslprm.log_opts & (SSL_LogCertDetails | SSL_LogIfClientCert)) {
  1541. int nerrs = 0;
  1542. rc = 0;
  1543. while ((x = ERR_get_error_line_data(NULL, NULL, NULL, NULL)) != 0) {
  1544. logit(LOG_ERR, "Error: Could not complete SSL handshake with %s: %s",
  1545. remote_host, ERR_reason_error_string(x));
  1546. ++nerrs;
  1547. }
  1548. if (nerrs == 0)
  1549. logit(LOG_ERR, "Error: Could not complete SSL handshake with %s: %d",
  1550. remote_host, SSL_get_error(ssl, rc));
  1551. } else
  1552. logit(LOG_ERR, "Error: Could not complete SSL handshake with %s: %d",
  1553. remote_host, SSL_get_error(ssl, rc));
  1554. # ifdef DEBUG
  1555. errfp = fopen("/tmp/err.log", "a");
  1556. ERR_print_errors_fp(errfp);
  1557. fclose(errfp);
  1558. # endif
  1559. return ERROR;
  1560. }
  1561. /* successful handshake */
  1562. if (sslprm.log_opts & SSL_LogVersion)
  1563. logit(LOG_NOTICE, "Remote %s - SSL Version: %s",
  1564. remote_host, SSL_get_version(ssl));
  1565. if (sslprm.log_opts & SSL_LogCipher) {
  1566. c = SSL_get_current_cipher(ssl);
  1567. logit(LOG_NOTICE, "Remote %s - %s, Cipher is %s", remote_host,
  1568. SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c));
  1569. }
  1570. if ((sslprm.log_opts & SSL_LogIfClientCert)
  1571. || (sslprm.log_opts & SSL_LogCertDetails))
  1572. {
  1573. peer = SSL_get_peer_certificate(ssl);
  1574. if (peer) {
  1575. if (sslprm.log_opts & SSL_LogIfClientCert)
  1576. logit(LOG_NOTICE, "SSL Client %s has %svalid certificate",
  1577. remote_host, peer->valid ? "a " : "an in");
  1578. if (sslprm.log_opts & SSL_LogCertDetails) {
  1579. logit(LOG_NOTICE, "SSL Client %s Cert Name: %s",
  1580. remote_host, peer->name);
  1581. X509_NAME_oneline(X509_get_issuer_name(peer), buffer, sizeof(buffer));
  1582. logit(LOG_NOTICE, "SSL Client %s Cert Issuer: %s",
  1583. remote_host, buffer);
  1584. }
  1585. } else if (sslprm.client_certs == 0)
  1586. logit(LOG_NOTICE, "SSL Not asking for client certification");
  1587. else
  1588. logit(LOG_NOTICE, "SSL Client %s did not present a certificate",
  1589. remote_host);
  1590. }
  1591. #endif
  1592. return OK;
  1593. }
  1594. int read_packet(int sock, void *ssl_ptr, v2_packet * v2_pkt, v3_packet ** v3_pkt)
  1595. {
  1596. int32_t common_size, tot_bytes, bytes_to_recv, buffer_size;
  1597. int rc;
  1598. char *buff_ptr;
  1599. /* Read only the part that's common between versions 2 & 3 */
  1600. common_size = tot_bytes = bytes_to_recv = (char *)&v2_pkt->buffer - (char *)v2_pkt;
  1601. if (use_ssl == FALSE) {
  1602. rc = recvall(sock, (char *)v2_pkt, &tot_bytes, socket_timeout);
  1603. if (rc <= 0 || rc != bytes_to_recv)
  1604. return -1;
  1605. packet_ver = ntohs(v2_pkt->packet_version);
  1606. if (packet_ver != NRPE_PACKET_VERSION_2 && packet_ver != NRPE_PACKET_VERSION_3) {
  1607. logit(LOG_ERR, "Error: Request packet version was invalid!");
  1608. return -1;
  1609. }
  1610. if (packet_ver == NRPE_PACKET_VERSION_2) {
  1611. buffer_size = sizeof(v2_packet) - common_size;
  1612. buff_ptr = (char *)v2_pkt + common_size;
  1613. } else {
  1614. int32_t pkt_size = sizeof(v3_packet) - 1;
  1615. /* Read the alignment filler */
  1616. bytes_to_recv = sizeof(int16_t);
  1617. rc = recvall(sock, (char *)&buffer_size, &bytes_to_recv, socket_timeout);
  1618. if (rc <= 0 || bytes_to_recv != sizeof(int16_t))
  1619. return -1;
  1620. tot_bytes += rc;
  1621. /* Read the buffer size */
  1622. bytes_to_recv = sizeof(buffer_size);
  1623. rc = recvall(sock, (char *)&buffer_size, &bytes_to_recv, socket_timeout);
  1624. if (rc <= 0 || bytes_to_recv != sizeof(buffer_size))
  1625. return -1;
  1626. tot_bytes += rc;
  1627. buffer_size = ntohl(buffer_size);
  1628. pkt_size += buffer_size;
  1629. if ((*v3_pkt = calloc(1, pkt_size)) == NULL) {
  1630. logit(LOG_ERR, "Error: Could not allocate memory for packet");
  1631. return -1;
  1632. }
  1633. memcpy(*v3_pkt, v2_pkt, common_size);
  1634. (*v3_pkt)->buffer_length = htonl(buffer_size);
  1635. buff_ptr = (*v3_pkt)->buffer;
  1636. }
  1637. bytes_to_recv = buffer_size;
  1638. rc = recvall(sock, buff_ptr, &bytes_to_recv, socket_timeout);
  1639. if (rc <= 0 || rc != buffer_size) {
  1640. if (packet_ver == NRPE_PACKET_VERSION_3) {
  1641. free(*v3_pkt);
  1642. *v3_pkt = NULL;
  1643. }
  1644. return -1;
  1645. } else
  1646. tot_bytes += rc;
  1647. }
  1648. #ifdef HAVE_SSL
  1649. else {
  1650. SSL *ssl = (SSL *) ssl_ptr;
  1651. while (((rc = SSL_read(ssl, v2_pkt, bytes_to_recv)) <= 0)
  1652. && (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ)) {
  1653. }
  1654. if (rc <= 0 || rc != bytes_to_recv)
  1655. return -1;
  1656. packet_ver = ntohs(v2_pkt->packet_version);
  1657. if (packet_ver != NRPE_PACKET_VERSION_2 && packet_ver != NRPE_PACKET_VERSION_3) {
  1658. logit(LOG_ERR, "Error: Request packet version was invalid!");
  1659. return -1;
  1660. }
  1661. if (packet_ver == NRPE_PACKET_VERSION_2) {
  1662. buffer_size = sizeof(v2_packet) - common_size;
  1663. buff_ptr = (char *)v2_pkt + common_size;
  1664. } else {
  1665. int32_t pkt_size = sizeof(v3_packet) - 1;
  1666. /* Read the alignment filler */
  1667. bytes_to_recv = sizeof(int16_t);
  1668. while (((rc = SSL_read(ssl, &buffer_size, bytes_to_recv)) <= 0)
  1669. && (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ)) {
  1670. }
  1671. if (rc <= 0 || bytes_to_recv != sizeof(int16_t))
  1672. return -1;
  1673. tot_bytes += rc;
  1674. /* Read the buffer size */
  1675. bytes_to_recv = sizeof(buffer_size);
  1676. while (((rc = SSL_read(ssl, &buffer_size, bytes_to_recv)) <= 0)
  1677. && (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ)) {
  1678. }
  1679. if (rc <= 0 || bytes_to_recv != sizeof(buffer_size))
  1680. return -1;
  1681. tot_bytes += rc;
  1682. buffer_size = ntohl(buffer_size);
  1683. pkt_size += buffer_size;
  1684. if ((*v3_pkt = calloc(1, pkt_size)) == NULL) {
  1685. logit(LOG_ERR, "Error: Could not allocate memory for packet");
  1686. return -1;
  1687. }
  1688. memcpy(*v3_pkt, v2_pkt, common_size);
  1689. (*v3_pkt)->buffer_length = htonl(buffer_size);
  1690. buff_ptr = (*v3_pkt)->buffer;
  1691. }
  1692. bytes_to_recv = buffer_size;
  1693. while (((rc = SSL_read(ssl, buff_ptr, bytes_to_recv)) <= 0)
  1694. && (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ)) {
  1695. }
  1696. if (rc <= 0 || rc != buffer_size) {
  1697. if (packet_ver == NRPE_PACKET_VERSION_3) {
  1698. free(*v3_pkt);
  1699. *v3_pkt = NULL;
  1700. }
  1701. return -1;
  1702. } else
  1703. tot_bytes += rc;
  1704. }
  1705. #endif
  1706. return tot_bytes;
  1707. }
  1708. /* free all allocated memory */
  1709. void free_memory(void)
  1710. {
  1711. command *this_command;
  1712. command *next_command;
  1713. /* free memory for the command list */
  1714. this_command = command_list;
  1715. while (this_command != NULL) {
  1716. next_command = this_command->next;
  1717. if (this_command->command_name)
  1718. free(this_command->command_name);
  1719. if (this_command->command_line)
  1720. free(this_command->command_line);
  1721. free(this_command);
  1722. this_command = next_command;
  1723. }
  1724. command_list = NULL;
  1725. return;
  1726. }
  1727. /* executes a system command via popen(), but protects against timeouts */
  1728. int my_system(char *command, int timeout, int *early_timeout, char **output)
  1729. {
  1730. FILE *fp;
  1731. pid_t pid;
  1732. time_t start_time, end_time;
  1733. int status;
  1734. int result;
  1735. char buffer[MAX_INPUT_BUFFER];
  1736. int fd[2];
  1737. int bytes_read = 0, tot_bytes = 0;
  1738. int output_size;
  1739. #ifdef HAVE_SIGACTION
  1740. struct sigaction sig_action;
  1741. #endif
  1742. *early_timeout = FALSE; /* initialize return variables */
  1743. if (command == NULL) /* if no command was passed, return with no error */
  1744. return STATE_OK;
  1745. pipe(fd); /* create a pipe */
  1746. /* make the pipe non-blocking */
  1747. fcntl(fd[0], F_SETFL, O_NONBLOCK);
  1748. fcntl(fd[1], F_SETFL, O_NONBLOCK);
  1749. time(&start_time); /* get the command start time */
  1750. pid = fork(); /* fork */
  1751. /* return an error if we couldn't fork */
  1752. if (pid == -1) {
  1753. snprintf(buffer, sizeof(buffer) - 1, "NRPE: Call to fork() failed\n");
  1754. buffer[sizeof(buffer) - 1] = '\x0';
  1755. if (packet_ver == NRPE_PACKET_VERSION_2) {
  1756. int output_size = sizeof(v2_packet);
  1757. *output = calloc(1, output_size);
  1758. strncpy(*output, buffer, output_size - 1);
  1759. *output[output_size - 1] = '\0';
  1760. } else
  1761. *output = strdup(buffer);
  1762. /* close both ends of the pipe */
  1763. close(fd[0]);
  1764. close(fd[1]);
  1765. return STATE_UNKNOWN;
  1766. }
  1767. /* execute the command in the child process */
  1768. if (pid == 0) {
  1769. SETEUID(0); /* get root back so the next call works correctly */
  1770. drop_privileges(nrpe_user, nrpe_group, 1); /* drop privileges */
  1771. close(fd[0]); /* close pipe for reading */
  1772. setpgid(0, 0); /* become process group leader */
  1773. /* trap commands that timeout */
  1774. #ifdef HAVE_SIGACTION
  1775. sig_action.sa_sigaction = NULL;
  1776. sig_action.sa_handler = my_system_sighandler;
  1777. sigfillset(&sig_action.sa_mask);
  1778. sig_action.sa_flags = SA_NODEFER | SA_RESTART;
  1779. sigaction(SIGALRM, &sig_action, NULL);
  1780. #else
  1781. signal(SIGALRM, my_system_sighandler);
  1782. #endif /* HAVE_SIGACTION */
  1783. alarm(timeout);
  1784. fp = popen(command, "r"); /* run the command */
  1785. /* report an error if we couldn't run the command */
  1786. if (fp == NULL) {
  1787. strncpy(buffer, "NRPE: Call to popen() failed\n", sizeof(buffer) - 1);
  1788. buffer[sizeof(buffer) - 1] = '\x0';
  1789. /* write the error back to the parent process */
  1790. write(fd[1], buffer, strlen(buffer) + 1);
  1791. result = STATE_CRITICAL;
  1792. } else {
  1793. /* read all lines of output - supports Nagios 3.x multiline output */
  1794. while ((bytes_read = fread(buffer, 1, sizeof(buffer) - 1, fp)) > 0) {
  1795. /* write the output back to the parent process */
  1796. write(fd[1], buffer, bytes_read);
  1797. }
  1798. write(fd[1], "\0", 1);
  1799. status = pclose(fp); /* close the command and get termination status */
  1800. /* report an error if we couldn't close the command */
  1801. if (status == -1)
  1802. result = STATE_CRITICAL;
  1803. else if (!WIFEXITED(status))
  1804. /* report an error if child died due to signal (Klas Lindfors) */
  1805. result = STATE_CRITICAL;
  1806. else
  1807. result = WEXITSTATUS(status);
  1808. }
  1809. close(fd[1]); /* close pipe for writing */
  1810. alarm(0); /* reset the alarm */
  1811. exit(result); /* return plugin exit code to parent process */
  1812. } else {
  1813. /* parent waits for child to finish executing command */
  1814. close(fd[1]); /* close pipe for writing */
  1815. waitpid(pid, &status, 0); /* wait for child to exit */
  1816. time(&end_time); /* get the end time for running the command */
  1817. result = WEXITSTATUS(status); /* get the exit code returned from the program */
  1818. /* because of my idiotic idea of having UNKNOWN states be equivalent to -1, I must hack things a bit... */
  1819. if (result == 255)
  1820. result = STATE_UNKNOWN;
  1821. /* check bounds on the return value */
  1822. if (result < 0 || result > 3)
  1823. result = STATE_UNKNOWN;
  1824. if (packet_ver == NRPE_PACKET_VERSION_2) {
  1825. output_size = sizeof(v2_packet);
  1826. *output = calloc(1, output_size);
  1827. } else {
  1828. output_size = 1024 * 64; /* Maximum buffer is 64K */
  1829. *output = calloc(1, output_size);
  1830. }
  1831. /* try and read the results from the command output (retry if we encountered a signal) */
  1832. for (;;) {
  1833. bytes_read = read(fd[0], buffer, sizeof(buffer) - 1);
  1834. if (bytes_read == 0)
  1835. break;
  1836. if (bytes_read == -1) {
  1837. if (errno == EINTR)
  1838. continue;
  1839. else
  1840. break;
  1841. }
  1842. if (tot_bytes < output_size) /* If buffer is full, discard the rest */
  1843. strncat(*output, buffer, output_size - tot_bytes - 1);
  1844. tot_bytes += bytes_read;
  1845. }
  1846. (*output)[output_size - 1] = '\0';
  1847. /* if there was a critical return code and no output AND the
  1848. * command time exceeded the timeout thresholds, assume a timeout */
  1849. if (result == STATE_CRITICAL && bytes_read == -1 && (end_time - start_time) >= timeout) {
  1850. *early_timeout = TRUE;
  1851. /* send termination signal to child process group */
  1852. kill((pid_t) (-pid), SIGTERM);
  1853. kill((pid_t) (-pid), SIGKILL);
  1854. }
  1855. close(fd[0]); /* close the pipe for reading */
  1856. }
  1857. #ifdef DEBUG
  1858. printf("my_system() end\n");
  1859. #endif
  1860. return result;
  1861. }
  1862. /* handle timeouts when executing commands via my_system() */
  1863. void my_system_sighandler(int sig)
  1864. {
  1865. exit(STATE_CRITICAL); /* force the child process to exit... */
  1866. }
  1867. /* handle errors where connection takes too long */
  1868. void my_connection_sighandler(int sig)
  1869. {
  1870. logit(LOG_ERR, "Connection has taken too long to establish. Exiting...");
  1871. exit(STATE_CRITICAL);
  1872. }
  1873. /* drops privileges */
  1874. int drop_privileges(char *user, char *group, int full_drop)
  1875. {
  1876. uid_t uid = (uid_t)-1;
  1877. gid_t gid = (gid_t)-1;
  1878. struct group *grp;
  1879. struct passwd *pw;
  1880. /* set effective group ID */
  1881. if (group != NULL) {
  1882. /* see if this is a group name */
  1883. if (strspn(group, "0123456789") < strlen(group)) {
  1884. grp = (struct group *)getgrnam(group);
  1885. if (grp != NULL)
  1886. gid = (gid_t) (grp->gr_gid);
  1887. else
  1888. logit(LOG_ERR, "Warning: Could not get group entry for '%s'", group);
  1889. endgrent();
  1890. } else
  1891. /* else we were passed the GID */
  1892. gid = (gid_t) atoi(group);
  1893. /* set effective group ID if other than current EGID */
  1894. if (gid != getegid()) {
  1895. if (setgid(gid) == -1)
  1896. logit(LOG_ERR, "Warning: Could not set effective GID=%d", (int)gid);
  1897. }
  1898. }
  1899. /* set effective user ID */
  1900. if (user != NULL) {
  1901. /* see if this is a user name */
  1902. if (strspn(user, "0123456789") < strlen(user)) {
  1903. pw = (struct passwd *)getpwnam(user);
  1904. if (pw != NULL)
  1905. uid = (uid_t) (pw->pw_uid);
  1906. else
  1907. logit(LOG_ERR, "Warning: Could not get passwd entry for '%s'", user);
  1908. endpwent();
  1909. } else
  1910. /* else we were passed the UID */
  1911. uid = (uid_t) atoi(user);
  1912. if (uid != geteuid()) {
  1913. /* set effective user ID if other than current EUID */
  1914. #ifdef HAVE_INITGROUPS
  1915. /* initialize supplementary groups */
  1916. if (initgroups(user, gid) == -1) {
  1917. if (errno == EPERM)
  1918. logit(LOG_ERR,
  1919. "Warning: Unable to change supplementary groups using initgroups()");
  1920. else {
  1921. logit(LOG_ERR,
  1922. "Warning: Possibly root user failed dropping privileges with initgroups()");
  1923. return ERROR;
  1924. }
  1925. }
  1926. #endif
  1927. if (full_drop) {
  1928. if (setuid(uid) == -1)
  1929. logit(LOG_ERR, "Warning: Could not set UID=%d", (int)uid);
  1930. } else if (SETEUID(uid) == -1)
  1931. logit(LOG_ERR, "Warning: Could not set effective UID=%d", (int)uid);
  1932. }
  1933. }
  1934. return OK;
  1935. }
  1936. /* write an optional pid file */
  1937. int write_pid_file(void)
  1938. {
  1939. int fd;
  1940. int result = 0;
  1941. pid_t pid = 0;
  1942. char pbuf[16];
  1943. /* no pid file was specified */
  1944. if (pid_file == NULL)
  1945. return OK;
  1946. /* read existing pid file */
  1947. if ((fd = open(pid_file, O_RDONLY)) >= 0) {
  1948. result = read(fd, pbuf, (sizeof pbuf) - 1);
  1949. close(fd);
  1950. if (result > 0) {
  1951. pbuf[result] = '\x0';
  1952. pid = (pid_t) atoi(pbuf);
  1953. /* if previous process is no longer running running, remove the old pid file */
  1954. if (pid && (pid == getpid() || kill(pid, 0) < 0))
  1955. unlink(pid_file);
  1956. else {
  1957. /* previous process is still running */
  1958. logit(LOG_ERR,
  1959. "There's already an NRPE server running (PID %lu). Bailing out...",
  1960. (unsigned long)pid);
  1961. return ERROR;
  1962. }
  1963. }
  1964. }
  1965. /* write new pid file */
  1966. if ((fd = open(pid_file, O_WRONLY | O_CREAT, 0644)) >= 0) {
  1967. sprintf(pbuf, "%d\n", (int)getpid());
  1968. write(fd, pbuf, strlen(pbuf));
  1969. close(fd);
  1970. wrote_pid_file = TRUE;
  1971. } else {
  1972. logit(LOG_ERR, "Cannot write to pidfile '%s' - check your privileges.", pid_file);
  1973. return ERROR;
  1974. }
  1975. return OK;
  1976. }
  1977. /* remove pid file */
  1978. int remove_pid_file(void)
  1979. {
  1980. if (pid_file == NULL)
  1981. return OK; /* no pid file was specified */
  1982. if (wrote_pid_file == FALSE)
  1983. return OK; /* pid file was not written */
  1984. SETEUID(0); /* get root back so we can delete the pid file */
  1985. if (unlink(pid_file) == -1) {
  1986. logit(LOG_ERR, "Cannot remove pidfile '%s' - check your privileges.", pid_file);
  1987. return ERROR;
  1988. }
  1989. return OK;
  1990. }
  1991. #ifdef HAVE_SSL
  1992. void my_disconnect_sighandler(int sig)
  1993. {
  1994. logit(LOG_ERR, "SSL_shutdown() has taken too long to complete. Exiting now..");
  1995. exit(STATE_CRITICAL);
  1996. }
  1997. void complete_SSL_shutdown(SSL * ssl)
  1998. {
  1999. /* Thanks to Jari Takkala (jtakkala@gmail.com) for the following information.
  2000. We need to call SSL_shutdown() at least twice, otherwise we'll
  2001. be left with data in the socket receive buffer, and the
  2002. subsequent process termination will cause TCP RST's to be sent
  2003. to the client.
  2004. See http://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/32219/diff
  2005. for more information.
  2006. */
  2007. int x;
  2008. /* set disconnection handler */
  2009. signal(SIGALRM, my_disconnect_sighandler);
  2010. alarm(ssl_shutdown_timeout);
  2011. for (x = 0; x < 4; x++) {
  2012. if (SSL_shutdown(ssl))
  2013. break;
  2014. }
  2015. alarm(0);
  2016. }
  2017. #endif /*HAVE_SSL */
  2018. /* bail if daemon is running as root */
  2019. int check_privileges(void)
  2020. {
  2021. uid_t uid = geteuid();
  2022. gid_t gid = getegid();
  2023. if (uid == 0 || gid == 0) {
  2024. logit(LOG_ERR, "Error: NRPE daemon cannot be run as user/group root!");
  2025. exit(STATE_CRITICAL);
  2026. }
  2027. return OK;
  2028. }
  2029. /* handle signals (parent process) */
  2030. void sighandler(int sig)
  2031. {
  2032. static char *sigs[] = {
  2033. "EXIT", "HUP", "INT", "QUIT", "ILL", "TRAP", "ABRT", "BUS", "FPE",
  2034. "KILL", "USR1", "SEGV", "USR2", "PIPE", "ALRM", "TERM", "STKFLT",
  2035. "CHLD", "CONT", "STOP", "TSTP", "TTIN", "TTOU", "URG", "XCPU",
  2036. "XFSZ", "VTALRM", "PROF", "WINCH", "IO", "PWR", "UNUSED", "ZERR",
  2037. "DEBUG", (char *)NULL
  2038. };
  2039. int i;
  2040. if (sig < 0)
  2041. sig = -sig;
  2042. for (i = 0; sigs[i] != (char *)NULL; i++) ;
  2043. sig %= i;
  2044. /* we received a SIGHUP, so restart... */
  2045. if (sig == SIGHUP) {
  2046. sigrestart = TRUE;
  2047. logit(LOG_NOTICE, "Caught SIGHUP - restarting...\n");
  2048. }
  2049. /* else begin shutting down... */
  2050. if (sig == SIGTERM) {
  2051. /* if shutdown is already true, we're in a signal trap loop! */
  2052. if (sigshutdown == TRUE)
  2053. exit(STATE_CRITICAL);
  2054. sigshutdown = TRUE;
  2055. logit(LOG_NOTICE, "Caught SIG%s - shutting down...\n", sigs[sig]);
  2056. }
  2057. return;
  2058. }
  2059. /* handle signals (child processes) */
  2060. void child_sighandler(int sig)
  2061. {
  2062. exit(0); /* terminate */
  2063. }
  2064. /* tests whether or not a client request is valid */
  2065. int validate_request(v2_packet * v2pkt, v3_packet * v3pkt)
  2066. {
  2067. u_int32_t packet_crc32;
  2068. u_int32_t calculated_crc32;
  2069. char *buff, *ptr;
  2070. int rc;
  2071. #ifdef ENABLE_COMMAND_ARGUMENTS
  2072. int x;
  2073. #endif
  2074. /* check the crc 32 value */
  2075. if (packet_ver == NRPE_PACKET_VERSION_3) {
  2076. int32_t pkt_size = (sizeof(v3_packet) - 1) + ntohl(v3pkt->buffer_length);
  2077. packet_crc32 = ntohl(v3pkt->crc32_value);
  2078. v3pkt->crc32_value = 0L;
  2079. v3pkt->alignment = 0;
  2080. calculated_crc32 = calculate_crc32((char *)v3pkt, pkt_size);
  2081. } else {
  2082. packet_crc32 = ntohl(v2pkt->crc32_value);
  2083. v2pkt->crc32_value = 0L;
  2084. calculated_crc32 = calculate_crc32((char *)v2pkt, sizeof(v2_packet));
  2085. }
  2086. if (packet_crc32 != calculated_crc32) {
  2087. logit(LOG_ERR, "Error: Request packet had invalid CRC32.");
  2088. return ERROR;
  2089. }
  2090. /* make sure this is the right type of packet */
  2091. if (ntohs(v2pkt->packet_type) != QUERY_PACKET) {
  2092. logit(LOG_ERR, "Error: Request packet type was invalid!");
  2093. return ERROR;
  2094. }
  2095. /* make sure buffer is terminated */
  2096. if (packet_ver == NRPE_PACKET_VERSION_3) {
  2097. int32_t l = ntohs(v3pkt->buffer_length);
  2098. v3pkt->buffer[l - 1] = '\x0';
  2099. buff = v3pkt->buffer;
  2100. } else {
  2101. v2pkt->buffer[MAX_PACKETBUFFER_LENGTH - 1] = '\x0';
  2102. buff = v2pkt->buffer;
  2103. }
  2104. /* client must send some kind of request */
  2105. if (buff[0] == '\0') {
  2106. logit(LOG_ERR, "Error: Request contained no query!");
  2107. return ERROR;
  2108. }
  2109. /* make sure request doesn't contain nasties */
  2110. if (packet_ver == NRPE_PACKET_VERSION_3)
  2111. rc = contains_nasty_metachars(v3pkt->buffer);
  2112. else
  2113. rc = contains_nasty_metachars(v2pkt->buffer);
  2114. if (rc == TRUE) {
  2115. logit(LOG_ERR, "Error: Request contained illegal metachars!");
  2116. return ERROR;
  2117. }
  2118. /* make sure the request doesn't contain arguments */
  2119. if (strchr(v2pkt->buffer, '!')) {
  2120. #ifdef ENABLE_COMMAND_ARGUMENTS
  2121. if (allow_arguments == FALSE) {
  2122. logit(LOG_ERR,
  2123. "Error: Request contained command arguments, but argument option is not enabled!");
  2124. return ERROR;
  2125. }
  2126. #else
  2127. logit(LOG_ERR, "Error: Request contained command arguments!");
  2128. return ERROR;
  2129. #endif
  2130. }
  2131. /* get command name */
  2132. #ifdef ENABLE_COMMAND_ARGUMENTS
  2133. ptr = strtok(buff, "!");
  2134. #else
  2135. ptr = buff;
  2136. #endif
  2137. command_name = strdup(ptr);
  2138. if (command_name == NULL) {
  2139. logit(LOG_ERR, "Error: Memory allocation failed");
  2140. return ERROR;
  2141. }
  2142. #ifdef ENABLE_COMMAND_ARGUMENTS
  2143. /* get command arguments */
  2144. if (allow_arguments == TRUE) {
  2145. for (x = 0; x < MAX_COMMAND_ARGUMENTS; x++) {
  2146. ptr = strtok(NULL, "!");
  2147. if (ptr == NULL)
  2148. break;
  2149. macro_argv[x] = strdup(ptr);
  2150. if (macro_argv[x] == NULL) {
  2151. logit(LOG_ERR, "Error: Memory allocation failed");
  2152. return ERROR;
  2153. }
  2154. if (!strcmp(macro_argv[x], "")) {
  2155. logit(LOG_ERR, "Error: Request contained an empty command argument");
  2156. return ERROR;
  2157. }
  2158. if (strstr(macro_argv[x], "$(")) {
  2159. # ifndef ENABLE_BASH_COMMAND_SUBSTITUTION
  2160. logit(LOG_ERR, "Error: Request contained a bash command substitution!");
  2161. return ERROR;
  2162. # else
  2163. if (FALSE == allow_bash_cmd_subst) {
  2164. logit(LOG_ERR,
  2165. "Error: Request contained a bash command substitution, but they are disallowed!");
  2166. return ERROR;
  2167. }
  2168. # endif
  2169. }
  2170. }
  2171. }
  2172. #endif
  2173. return OK;
  2174. }
  2175. /* tests whether a buffer contains illegal metachars */
  2176. int contains_nasty_metachars(char *str)
  2177. {
  2178. int result;
  2179. if (str == NULL)
  2180. return FALSE;
  2181. result = strcspn(str, nasty_metachars);
  2182. if (result != strlen(str))
  2183. return TRUE;
  2184. return FALSE;
  2185. }
  2186. /* replace macros in buffer */
  2187. int process_macros(char *input_buffer, char *output_buffer, int buffer_length)
  2188. {
  2189. char *temp_buffer;
  2190. int in_macro;
  2191. int arg_index = 0;
  2192. char *selected_macro = NULL;
  2193. strcpy(output_buffer, "");
  2194. in_macro = FALSE;
  2195. for (temp_buffer = my_strsep(&input_buffer, "$"); temp_buffer != NULL;
  2196. temp_buffer = my_strsep(&input_buffer, "$")) {
  2197. selected_macro = NULL;
  2198. if (in_macro == FALSE) {
  2199. if (strlen(output_buffer) + strlen(temp_buffer) < buffer_length - 1) {
  2200. strncat(output_buffer, temp_buffer, buffer_length - strlen(output_buffer) - 1);
  2201. output_buffer[buffer_length - 1] = '\x0';
  2202. }
  2203. in_macro = TRUE;
  2204. } else {
  2205. if (strlen(output_buffer) + strlen(temp_buffer) < buffer_length - 1) {
  2206. /* argument macro */
  2207. if (strstr(temp_buffer, "ARG") == temp_buffer) {
  2208. arg_index = atoi(temp_buffer + 3);
  2209. if (arg_index >= 1 && arg_index <= MAX_COMMAND_ARGUMENTS)
  2210. selected_macro = macro_argv[arg_index - 1];
  2211. } else if (!strcmp(temp_buffer, "")) {
  2212. /* an escaped $ is done by specifying two $$ next to each other */
  2213. strncat(output_buffer, "$", buffer_length - strlen(output_buffer) - 1);
  2214. } else {
  2215. /* a non-macro, just some user-defined string between two $s */
  2216. strncat(output_buffer, "$", buffer_length - strlen(output_buffer) - 1);
  2217. output_buffer[buffer_length - 1] = '\x0';
  2218. strncat(output_buffer, temp_buffer,
  2219. buffer_length - strlen(output_buffer) - 1);
  2220. output_buffer[buffer_length - 1] = '\x0';
  2221. strncat(output_buffer, "$", buffer_length - strlen(output_buffer) - 1);
  2222. }
  2223. /* insert macro */
  2224. if (selected_macro != NULL)
  2225. strncat(output_buffer, (selected_macro == NULL) ? "" : selected_macro,
  2226. buffer_length - strlen(output_buffer) - 1);
  2227. output_buffer[buffer_length - 1] = '\x0';
  2228. }
  2229. in_macro = FALSE;
  2230. }
  2231. }
  2232. return OK;
  2233. }
  2234. /* process command line arguments */
  2235. int process_arguments(int argc, char **argv)
  2236. {
  2237. char optchars[MAX_INPUT_BUFFER];
  2238. int c = 1;
  2239. int have_mode = FALSE;
  2240. #ifdef HAVE_GETOPT_LONG
  2241. int option_index = 0;
  2242. static struct option long_options[] = {
  2243. {"config", required_argument, 0, 'c'},
  2244. {"inetd", no_argument, 0, 'i'},
  2245. /* To compatibility between short and long options but not used on AIX */
  2246. {"src", no_argument, 0, 's'},
  2247. {"no-forking", no_argument, 0, 'f'},
  2248. {"4", no_argument, 0, '4'},
  2249. {"6", no_argument, 0, '4'},
  2250. {"daemon", no_argument, 0, 'd'},
  2251. {"no-ssl", no_argument, 0, 'n'},
  2252. {"help", no_argument, 0, 'h'},
  2253. {"license", no_argument, 0, 'l'},
  2254. {0, 0, 0, 0}
  2255. };
  2256. #endif
  2257. /* no options were supplied */
  2258. if (argc < 2)
  2259. return ERROR;
  2260. snprintf(optchars, MAX_INPUT_BUFFER, "c:hVldi46nsf");
  2261. while (1) {
  2262. #ifdef HAVE_GETOPT_LONG
  2263. c = getopt_long(argc, argv, optchars, long_options, &option_index);
  2264. #else
  2265. c = getopt(argc, argv, optchars);
  2266. #endif
  2267. if (c == -1 || c == EOF)
  2268. break;
  2269. /* process all arguments */
  2270. switch (c) {
  2271. case '?':
  2272. case 'h':
  2273. show_help = TRUE;
  2274. break;
  2275. case 'V':
  2276. show_version = TRUE;
  2277. break;
  2278. case 'l':
  2279. show_license = TRUE;
  2280. break;
  2281. case 'c':
  2282. strncpy(config_file, optarg, sizeof(config_file));
  2283. config_file[sizeof(config_file) - 1] = '\x0';
  2284. break;
  2285. case 'd':
  2286. use_inetd = FALSE;
  2287. have_mode = TRUE;
  2288. break;
  2289. case 'i':
  2290. use_inetd = TRUE;
  2291. have_mode = TRUE;
  2292. break;
  2293. case '4':
  2294. address_family = AF_INET;
  2295. break;
  2296. case '6':
  2297. address_family = AF_INET6;
  2298. break;
  2299. case 'n':
  2300. use_ssl = FALSE;
  2301. break;
  2302. case 's': /* Argument s to indicate SRC option */
  2303. use_src = TRUE;
  2304. have_mode = TRUE;
  2305. break;
  2306. case 'f':
  2307. use_inetd = FALSE;
  2308. no_forking = TRUE;
  2309. have_mode = TRUE;
  2310. break;
  2311. default:
  2312. return ERROR;
  2313. }
  2314. }
  2315. /* bail if we didn't get required args */
  2316. if (have_mode == FALSE)
  2317. return ERROR;
  2318. return OK;
  2319. }