daemon.c 24 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004
  1. /*
  2. * Copyright (C) 2006-2017 Tobias Brunner
  3. * Copyright (C) 2005-2009 Martin Willi
  4. * Copyright (C) 2006 Daniel Roethlisberger
  5. * Copyright (C) 2005 Jan Hutter
  6. * HSR Hochschule fuer Technik Rapperswil
  7. *
  8. * This program is free software; you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License as published by the
  10. * Free Software Foundation; either version 2 of the License, or (at your
  11. * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
  12. *
  13. * This program is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  15. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  16. * for more details.
  17. */
  18. /*
  19. * Copyright (C) 2016 secunet Security Networks AG
  20. * Copyright (C) 2016 Thomas Egerer
  21. *
  22. * Permission is hereby granted, free of charge, to any person obtaining a copy
  23. * of this software and associated documentation files (the "Software"), to deal
  24. * in the Software without restriction, including without limitation the rights
  25. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  26. * copies of the Software, and to permit persons to whom the Software is
  27. * furnished to do so, subject to the following conditions:
  28. *
  29. * The above copyright notice and this permission notice shall be included in
  30. * all copies or substantial portions of the Software.
  31. *
  32. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  33. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  34. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  35. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  36. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  37. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  38. * THE SOFTWARE.
  39. */
  40. #include <stdio.h>
  41. #include <sys/types.h>
  42. #include <unistd.h>
  43. #include <time.h>
  44. #include <errno.h>
  45. #ifdef HAVE_SYSLOG
  46. #include <syslog.h>
  47. #endif
  48. #include "daemon.h"
  49. #include <library.h>
  50. #include <bus/listeners/sys_logger.h>
  51. #include <bus/listeners/file_logger.h>
  52. #include <collections/array.h>
  53. #include <plugins/plugin_feature.h>
  54. #include <kernel/kernel_handler.h>
  55. #include <processing/jobs/start_action_job.h>
  56. #include <threading/mutex.h>
  57. #ifndef LOG_AUTHPRIV /* not defined on OpenSolaris */
  58. #define LOG_AUTHPRIV LOG_AUTH
  59. #endif
  60. typedef struct private_daemon_t private_daemon_t;
  61. /**
  62. * Private additions to daemon_t, contains threads and internal functions.
  63. */
  64. struct private_daemon_t {
  65. /**
  66. * Public members of daemon_t.
  67. */
  68. daemon_t public;
  69. /**
  70. * Handler for kernel events
  71. */
  72. kernel_handler_t *kernel_handler;
  73. /**
  74. * A list of installed loggers (as logger_entry_t*)
  75. */
  76. linked_list_t *loggers;
  77. /**
  78. * Cached log levels for default loggers
  79. */
  80. level_t *levels;
  81. /**
  82. * Whether to log to stdout/err by default
  83. */
  84. bool to_stderr;
  85. /**
  86. * Identifier used for syslog (in the openlog call)
  87. */
  88. char *syslog_identifier;
  89. /**
  90. * Mutex for configured loggers
  91. */
  92. mutex_t *mutex;
  93. /**
  94. * Integrity check failed?
  95. */
  96. bool integrity_failed;
  97. /**
  98. * Number of times we have been initialized
  99. */
  100. refcount_t ref;
  101. };
  102. /**
  103. * Register plugins if built statically
  104. */
  105. #ifdef STATIC_PLUGIN_CONSTRUCTORS
  106. #include "plugin_constructors.c"
  107. #endif
  108. /**
  109. * One and only instance of the daemon.
  110. */
  111. daemon_t *charon;
  112. /**
  113. * hook in library for debugging messages
  114. */
  115. extern void (*dbg) (debug_t group, level_t level, char *fmt, ...);
  116. /**
  117. * we store the previous debug function so we can reset it
  118. */
  119. static void (*dbg_old) (debug_t group, level_t level, char *fmt, ...);
  120. /**
  121. * Logging hook for library logs, spreads debug message over bus
  122. */
  123. static void dbg_bus(debug_t group, level_t level, char *fmt, ...)
  124. {
  125. va_list args;
  126. va_start(args, fmt);
  127. charon->bus->vlog(charon->bus, group, level, fmt, args);
  128. va_end(args);
  129. }
  130. /**
  131. * Data for registered custom loggers
  132. */
  133. typedef struct {
  134. /**
  135. * Name of the custom logger (also used for loglevel configuration)
  136. */
  137. char *name;
  138. /**
  139. * Constructor to be called for custom logger creation
  140. */
  141. custom_logger_constructor_t constructor;
  142. } custom_logger_entry_t;
  143. #define MAX_CUSTOM_LOGGERS 10
  144. /**
  145. * Static array for logger registration using __attribute__((constructor))
  146. */
  147. static custom_logger_entry_t custom_loggers[MAX_CUSTOM_LOGGERS];
  148. static int custom_logger_count;
  149. /**
  150. * Described in header
  151. */
  152. void register_custom_logger(char *name,
  153. custom_logger_constructor_t constructor)
  154. {
  155. if (custom_logger_count < MAX_CUSTOM_LOGGERS - 1)
  156. {
  157. custom_loggers[custom_logger_count].name = name;
  158. custom_loggers[custom_logger_count].constructor = constructor;
  159. custom_logger_count++;
  160. }
  161. else
  162. {
  163. fprintf(stderr, "failed to register custom logger, please increase "
  164. "MAX_CUSTOM_LOGGERS");
  165. }
  166. }
  167. /**
  168. * Types of supported loggers
  169. */
  170. typedef enum {
  171. /**
  172. * Syslog logger instance
  173. */
  174. SYS_LOGGER,
  175. /**
  176. * File logger instance
  177. */
  178. FILE_LOGGER,
  179. /**
  180. * Custom logger instance
  181. */
  182. CUSTOM_LOGGER,
  183. } logger_type_t;
  184. /**
  185. * Some metadata about configured loggers
  186. */
  187. typedef struct {
  188. /**
  189. * Target of the logger (syslog facility or filename)
  190. */
  191. char *target;
  192. /**
  193. * Type of logger
  194. */
  195. logger_type_t type;
  196. /**
  197. * The actual logger
  198. */
  199. union {
  200. sys_logger_t *sys;
  201. file_logger_t *file;
  202. custom_logger_t *custom;
  203. } logger;
  204. } logger_entry_t;
  205. /**
  206. * Destroy a logger entry
  207. */
  208. static void logger_entry_destroy(logger_entry_t *this)
  209. {
  210. switch (this->type)
  211. {
  212. case FILE_LOGGER:
  213. DESTROY_IF(this->logger.file);
  214. break;
  215. case SYS_LOGGER:
  216. DESTROY_IF(this->logger.sys);
  217. break;
  218. case CUSTOM_LOGGER:
  219. DESTROY_IF(this->logger.custom);
  220. break;
  221. }
  222. free(this->target);
  223. free(this);
  224. }
  225. /**
  226. * Unregister and destroy a logger entry
  227. */
  228. static void logger_entry_unregister_destroy(logger_entry_t *this)
  229. {
  230. switch (this->type)
  231. {
  232. case FILE_LOGGER:
  233. charon->bus->remove_logger(charon->bus, &this->logger.file->logger);
  234. break;
  235. case SYS_LOGGER:
  236. charon->bus->remove_logger(charon->bus, &this->logger.sys->logger);
  237. break;
  238. case CUSTOM_LOGGER:
  239. charon->bus->remove_logger(charon->bus,
  240. &this->logger.custom->logger);
  241. break;
  242. }
  243. logger_entry_destroy(this);
  244. }
  245. CALLBACK(logger_entry_match, bool,
  246. logger_entry_t *this, va_list args)
  247. {
  248. logger_type_t type;
  249. char *target;
  250. VA_ARGS_VGET(args, target, type);
  251. return this->type == type && streq(this->target, target);
  252. }
  253. /**
  254. * Handle configured syslog identifier
  255. *
  256. * mutex must be locked when calling this function
  257. */
  258. static void handle_syslog_identifier(private_daemon_t *this)
  259. {
  260. #ifdef HAVE_SYSLOG
  261. char *identifier;
  262. identifier = lib->settings->get_str(lib->settings, "%s.syslog.identifier",
  263. NULL, lib->ns);
  264. if (identifier)
  265. { /* set identifier, which is prepended to each log line */
  266. if (!this->syslog_identifier ||
  267. !streq(identifier, this->syslog_identifier))
  268. {
  269. closelog();
  270. this->syslog_identifier = identifier;
  271. openlog(this->syslog_identifier, 0, 0);
  272. }
  273. }
  274. else if (this->syslog_identifier)
  275. {
  276. closelog();
  277. this->syslog_identifier = NULL;
  278. }
  279. #endif /* HAVE_SYSLOG */
  280. }
  281. /**
  282. * Convert the given string into a syslog facility, returns -1 if the facility
  283. * is not supported
  284. */
  285. static int get_syslog_facility(char *facility)
  286. {
  287. #ifdef HAVE_SYSLOG
  288. if (streq(facility, "daemon"))
  289. {
  290. return LOG_DAEMON;
  291. }
  292. else if (streq(facility, "auth"))
  293. {
  294. return LOG_AUTHPRIV;
  295. }
  296. #endif /* HAVE_SYSLOG */
  297. return -1;
  298. }
  299. /**
  300. * Returns an existing or newly created logger entry (if found, it is removed
  301. * from the given linked list of existing loggers)
  302. */
  303. static logger_entry_t *get_logger_entry(char *target, logger_type_t type,
  304. linked_list_t *existing,
  305. custom_logger_constructor_t constructor)
  306. {
  307. logger_entry_t *entry;
  308. if (!existing->find_first(existing, logger_entry_match, (void**)&entry,
  309. target, type))
  310. {
  311. INIT(entry,
  312. .target = strdup(target),
  313. .type = type,
  314. );
  315. switch (type)
  316. {
  317. case FILE_LOGGER:
  318. entry->logger.file = file_logger_create(target);
  319. break;
  320. case SYS_LOGGER:
  321. #ifdef HAVE_SYSLOG
  322. entry->logger.sys = sys_logger_create(
  323. get_syslog_facility(target));
  324. break;
  325. #else
  326. free(entry);
  327. return NULL;
  328. #endif /* HAVE_SYSLOG */
  329. case CUSTOM_LOGGER:
  330. if (constructor)
  331. {
  332. entry->logger.custom = constructor(target);
  333. }
  334. if (!entry->logger.custom)
  335. {
  336. free(entry);
  337. return NULL;
  338. }
  339. break;
  340. }
  341. }
  342. else
  343. {
  344. existing->remove(existing, entry, NULL);
  345. }
  346. return entry;
  347. }
  348. /**
  349. * Create or reuse a syslog logger
  350. */
  351. static sys_logger_t *add_sys_logger(private_daemon_t *this, char *facility,
  352. linked_list_t *current_loggers)
  353. {
  354. logger_entry_t *entry;
  355. entry = get_logger_entry(facility, SYS_LOGGER, current_loggers, NULL);
  356. if (entry)
  357. {
  358. this->loggers->insert_last(this->loggers, entry);
  359. }
  360. return entry ? entry->logger.sys : NULL;
  361. }
  362. /**
  363. * Create or reuse a file logger
  364. */
  365. static file_logger_t *add_file_logger(private_daemon_t *this, char *filename,
  366. linked_list_t *current_loggers)
  367. {
  368. logger_entry_t *entry;
  369. entry = get_logger_entry(filename, FILE_LOGGER, current_loggers, NULL);
  370. if (entry)
  371. {
  372. this->loggers->insert_last(this->loggers, entry);
  373. }
  374. return entry ? entry->logger.file : NULL;
  375. }
  376. /**
  377. * Create or reuse a custom logger
  378. */
  379. static custom_logger_t *add_custom_logger(private_daemon_t *this,
  380. custom_logger_entry_t *custom,
  381. linked_list_t *current_loggers)
  382. {
  383. logger_entry_t *entry;
  384. entry = get_logger_entry(custom->name, CUSTOM_LOGGER, current_loggers,
  385. custom->constructor);
  386. if (entry)
  387. {
  388. this->loggers->insert_last(this->loggers, entry);
  389. }
  390. return entry ? entry->logger.custom : NULL;
  391. }
  392. /**
  393. * Load the given syslog logger configured in strongswan.conf
  394. */
  395. static void load_sys_logger(private_daemon_t *this, char *facility,
  396. linked_list_t *current_loggers)
  397. {
  398. sys_logger_t *sys_logger;
  399. debug_t group;
  400. level_t def;
  401. if (get_syslog_facility(facility) == -1)
  402. {
  403. return;
  404. }
  405. sys_logger = add_sys_logger(this, facility, current_loggers);
  406. if (!sys_logger)
  407. {
  408. return;
  409. }
  410. sys_logger->set_options(sys_logger,
  411. lib->settings->get_bool(lib->settings, "%s.syslog.%s.ike_name",
  412. FALSE, lib->ns, facility));
  413. def = lib->settings->get_int(lib->settings, "%s.syslog.%s.default", 1,
  414. lib->ns, facility);
  415. for (group = 0; group < DBG_MAX; group++)
  416. {
  417. sys_logger->set_level(sys_logger, group,
  418. lib->settings->get_int(lib->settings, "%s.syslog.%s.%N", def,
  419. lib->ns, facility, debug_lower_names, group));
  420. }
  421. charon->bus->add_logger(charon->bus, &sys_logger->logger);
  422. }
  423. /**
  424. * Load the given file logger configured in strongswan.conf
  425. */
  426. static void load_file_logger(private_daemon_t *this, char *section,
  427. linked_list_t *current_loggers)
  428. {
  429. file_logger_t *file_logger;
  430. debug_t group;
  431. level_t def;
  432. bool add_ms, ike_name, flush_line, append;
  433. char *time_format, *filename;
  434. time_format = lib->settings->get_str(lib->settings,
  435. "%s.filelog.%s.time_format", NULL, lib->ns, section);
  436. add_ms = lib->settings->get_bool(lib->settings,
  437. "%s.filelog.%s.time_add_ms", FALSE, lib->ns, section);
  438. ike_name = lib->settings->get_bool(lib->settings,
  439. "%s.filelog.%s.ike_name", FALSE, lib->ns, section);
  440. flush_line = lib->settings->get_bool(lib->settings,
  441. "%s.filelog.%s.flush_line", FALSE, lib->ns, section);
  442. append = lib->settings->get_bool(lib->settings,
  443. "%s.filelog.%s.append", TRUE, lib->ns, section);
  444. filename = lib->settings->get_str(lib->settings,
  445. "%s.filelog.%s.path", section, lib->ns, section);
  446. file_logger = add_file_logger(this, filename, current_loggers);
  447. if (!file_logger)
  448. {
  449. return;
  450. }
  451. file_logger->set_options(file_logger, time_format, add_ms, ike_name);
  452. file_logger->open(file_logger, flush_line, append);
  453. def = lib->settings->get_int(lib->settings, "%s.filelog.%s.default", 1,
  454. lib->ns, section);
  455. for (group = 0; group < DBG_MAX; group++)
  456. {
  457. file_logger->set_level(file_logger, group,
  458. lib->settings->get_int(lib->settings, "%s.filelog.%s.%N", def,
  459. lib->ns, section, debug_lower_names, group));
  460. }
  461. charon->bus->add_logger(charon->bus, &file_logger->logger);
  462. }
  463. /**
  464. * Load the given custom logger configured in strongswan.conf
  465. */
  466. static void load_custom_logger(private_daemon_t *this,
  467. custom_logger_entry_t *entry,
  468. linked_list_t *current_loggers)
  469. {
  470. custom_logger_t *custom_logger;
  471. debug_t group;
  472. level_t def;
  473. custom_logger = add_custom_logger(this, entry, current_loggers);
  474. if (!custom_logger)
  475. {
  476. return;
  477. }
  478. def = lib->settings->get_int(lib->settings, "%s.customlog.%s.default", 1,
  479. lib->ns, entry->name);
  480. for (group = 0; group < DBG_MAX; group++)
  481. {
  482. custom_logger->set_level(custom_logger, group,
  483. lib->settings->get_int(lib->settings, "%s.customlog.%s.%N", def,
  484. lib->ns, entry->name, debug_lower_names, group));
  485. }
  486. if (custom_logger->reload)
  487. {
  488. custom_logger->reload(custom_logger);
  489. }
  490. charon->bus->add_logger(charon->bus, &custom_logger->logger);
  491. }
  492. METHOD(daemon_t, load_loggers, void,
  493. private_daemon_t *this)
  494. {
  495. enumerator_t *enumerator;
  496. linked_list_t *current_loggers;
  497. char *target;
  498. int i;
  499. this->mutex->lock(this->mutex);
  500. handle_syslog_identifier(this);
  501. current_loggers = this->loggers;
  502. this->loggers = linked_list_create();
  503. enumerator = lib->settings->create_section_enumerator(lib->settings,
  504. "%s.syslog", lib->ns);
  505. while (enumerator->enumerate(enumerator, &target))
  506. {
  507. load_sys_logger(this, target, current_loggers);
  508. }
  509. enumerator->destroy(enumerator);
  510. enumerator = lib->settings->create_section_enumerator(lib->settings,
  511. "%s.filelog", lib->ns);
  512. while (enumerator->enumerate(enumerator, &target))
  513. {
  514. load_file_logger(this, target, current_loggers);
  515. }
  516. enumerator->destroy(enumerator);
  517. for (i = 0; i < custom_logger_count; ++i)
  518. {
  519. load_custom_logger(this, &custom_loggers[i], current_loggers);
  520. }
  521. if (!this->loggers->get_count(this->loggers) && this->levels)
  522. { /* setup legacy style default loggers configured via command-line */
  523. file_logger_t *file_logger;
  524. sys_logger_t *sys_logger;
  525. debug_t group;
  526. sys_logger = add_sys_logger(this, "daemon", current_loggers);
  527. file_logger = add_file_logger(this, "stdout", current_loggers);
  528. file_logger->open(file_logger, FALSE, FALSE);
  529. for (group = 0; group < DBG_MAX; group++)
  530. {
  531. if (sys_logger)
  532. {
  533. sys_logger->set_level(sys_logger, group, this->levels[group]);
  534. }
  535. if (this->to_stderr)
  536. {
  537. file_logger->set_level(file_logger, group, this->levels[group]);
  538. }
  539. }
  540. if (sys_logger)
  541. {
  542. charon->bus->add_logger(charon->bus, &sys_logger->logger);
  543. }
  544. charon->bus->add_logger(charon->bus, &file_logger->logger);
  545. sys_logger = add_sys_logger(this, "auth", current_loggers);
  546. if (sys_logger)
  547. {
  548. sys_logger->set_level(sys_logger, DBG_ANY, LEVEL_AUDIT);
  549. charon->bus->add_logger(charon->bus, &sys_logger->logger);
  550. }
  551. }
  552. /* unregister and destroy any unused remaining loggers */
  553. current_loggers->destroy_function(current_loggers,
  554. (void*)logger_entry_unregister_destroy);
  555. this->mutex->unlock(this->mutex);
  556. }
  557. METHOD(daemon_t, set_default_loggers, void,
  558. private_daemon_t *this, level_t levels[DBG_MAX], bool to_stderr)
  559. {
  560. debug_t group;
  561. this->mutex->lock(this->mutex);
  562. if (!levels)
  563. {
  564. free(this->levels);
  565. this->levels = NULL;
  566. }
  567. else
  568. {
  569. if (!this->levels)
  570. {
  571. this->levels = calloc(sizeof(level_t), DBG_MAX);
  572. }
  573. for (group = 0; group < DBG_MAX; group++)
  574. {
  575. this->levels[group] = levels[group];
  576. }
  577. this->to_stderr = to_stderr;
  578. }
  579. this->mutex->unlock(this->mutex);
  580. }
  581. METHOD(daemon_t, set_level, void,
  582. private_daemon_t *this, debug_t group, level_t level)
  583. {
  584. enumerator_t *enumerator;
  585. logger_entry_t *entry;
  586. /* we set the loglevel on ALL loggers */
  587. this->mutex->lock(this->mutex);
  588. enumerator = this->loggers->create_enumerator(this->loggers);
  589. while (enumerator->enumerate(enumerator, &entry))
  590. {
  591. switch (entry->type)
  592. {
  593. case FILE_LOGGER:
  594. entry->logger.file->set_level(entry->logger.file, group, level);
  595. charon->bus->add_logger(charon->bus,
  596. &entry->logger.file->logger);
  597. break;
  598. case SYS_LOGGER:
  599. entry->logger.sys->set_level(entry->logger.sys, group, level);
  600. charon->bus->add_logger(charon->bus,
  601. &entry->logger.sys->logger);
  602. break;
  603. case CUSTOM_LOGGER:
  604. entry->logger.custom->set_level(entry->logger.custom, group,
  605. level);
  606. charon->bus->add_logger(charon->bus,
  607. &entry->logger.sys->logger);
  608. break;
  609. }
  610. }
  611. enumerator->destroy(enumerator);
  612. this->mutex->unlock(this->mutex);
  613. }
  614. /**
  615. * Clean up all daemon resources
  616. */
  617. static void destroy(private_daemon_t *this)
  618. {
  619. /* terminate all idle threads */
  620. lib->processor->set_threads(lib->processor, 0);
  621. /* make sure nobody waits for a DNS query */
  622. lib->hosts->flush(lib->hosts);
  623. /* close all IKE_SAs */
  624. if (this->public.ike_sa_manager)
  625. {
  626. this->public.ike_sa_manager->flush(this->public.ike_sa_manager);
  627. }
  628. if (this->public.traps)
  629. {
  630. this->public.traps->flush(this->public.traps);
  631. }
  632. if (this->public.shunts)
  633. {
  634. this->public.shunts->flush(this->public.shunts);
  635. }
  636. if (this->public.sender)
  637. {
  638. this->public.sender->flush(this->public.sender);
  639. }
  640. /* cancel all threads and wait for their termination */
  641. lib->processor->cancel(lib->processor);
  642. #ifdef ME
  643. DESTROY_IF(this->public.connect_manager);
  644. DESTROY_IF(this->public.mediation_manager);
  645. #endif /* ME */
  646. /* make sure the cache and scheduler are clear before unloading plugins */
  647. lib->credmgr->flush_cache(lib->credmgr, CERT_ANY);
  648. lib->scheduler->flush(lib->scheduler);
  649. lib->plugins->unload(lib->plugins);
  650. DESTROY_IF(this->public.attributes);
  651. DESTROY_IF(this->kernel_handler);
  652. DESTROY_IF(this->public.traps);
  653. DESTROY_IF(this->public.shunts);
  654. DESTROY_IF(this->public.redirect);
  655. DESTROY_IF(this->public.controller);
  656. DESTROY_IF(this->public.eap);
  657. DESTROY_IF(this->public.xauth);
  658. DESTROY_IF(this->public.backends);
  659. DESTROY_IF(this->public.socket);
  660. DESTROY_IF(this->public.kernel);
  661. /* rehook library logging, shutdown logging */
  662. dbg = dbg_old;
  663. DESTROY_IF(this->public.bus);
  664. this->loggers->destroy_function(this->loggers, (void*)logger_entry_destroy);
  665. this->mutex->destroy(this->mutex);
  666. free(this->levels);
  667. free(this);
  668. }
  669. /**
  670. * Run a set of configured scripts
  671. */
  672. static void run_scripts(private_daemon_t *this, char *verb)
  673. {
  674. struct {
  675. char *name;
  676. char *path;
  677. } *script;
  678. array_t *scripts = NULL;
  679. enumerator_t *enumerator;
  680. char *key, *value, *pos, buf[1024];
  681. FILE *cmd;
  682. /* copy the scripts so we don't hold any locks while executing them */
  683. enumerator = lib->settings->create_key_value_enumerator(lib->settings,
  684. "%s.%s-scripts", lib->ns, verb);
  685. while (enumerator->enumerate(enumerator, &key, &value))
  686. {
  687. INIT(script,
  688. .name = key,
  689. .path = value,
  690. );
  691. array_insert_create(&scripts, ARRAY_TAIL, script);
  692. }
  693. enumerator->destroy(enumerator);
  694. enumerator = array_create_enumerator(scripts);
  695. while (enumerator->enumerate(enumerator, &script))
  696. {
  697. DBG1(DBG_DMN, "executing %s script '%s' (%s)", verb, script->name,
  698. script->path);
  699. cmd = popen(script->path, "r");
  700. if (!cmd)
  701. {
  702. DBG1(DBG_DMN, "executing %s script '%s' (%s) failed: %s",
  703. verb, script->name, script->path, strerror(errno));
  704. }
  705. else
  706. {
  707. while (TRUE)
  708. {
  709. if (!fgets(buf, sizeof(buf), cmd))
  710. {
  711. if (ferror(cmd))
  712. {
  713. DBG1(DBG_DMN, "reading from %s script '%s' (%s) failed",
  714. verb, script->name, script->path);
  715. }
  716. break;
  717. }
  718. else
  719. {
  720. pos = buf + strlen(buf);
  721. if (pos > buf && pos[-1] == '\n')
  722. {
  723. pos[-1] = '\0';
  724. }
  725. DBG1(DBG_DMN, "%s: %s", script->name, buf);
  726. }
  727. }
  728. pclose(cmd);
  729. }
  730. free(script);
  731. }
  732. enumerator->destroy(enumerator);
  733. array_destroy(scripts);
  734. }
  735. METHOD(daemon_t, start, void,
  736. private_daemon_t *this)
  737. {
  738. /* start the engine, go multithreaded */
  739. lib->processor->set_threads(lib->processor,
  740. lib->settings->get_int(lib->settings, "%s.threads",
  741. DEFAULT_THREADS, lib->ns));
  742. run_scripts(this, "start");
  743. }
  744. /**
  745. * Initialize/deinitialize sender and receiver
  746. */
  747. static bool sender_receiver_cb(void *plugin, plugin_feature_t *feature,
  748. bool reg, private_daemon_t *this)
  749. {
  750. if (reg)
  751. {
  752. this->public.receiver = receiver_create();
  753. if (!this->public.receiver)
  754. {
  755. return FALSE;
  756. }
  757. this->public.sender = sender_create();
  758. }
  759. else
  760. {
  761. DESTROY_IF(this->public.receiver);
  762. DESTROY_IF(this->public.sender);
  763. }
  764. return TRUE;
  765. }
  766. /**
  767. * Initialize/deinitialize IKE_SA/CHILD_SA managers
  768. */
  769. static bool sa_managers_cb(void *plugin, plugin_feature_t *feature,
  770. bool reg, private_daemon_t *this)
  771. {
  772. if (reg)
  773. {
  774. this->public.ike_sa_manager = ike_sa_manager_create();
  775. if (!this->public.ike_sa_manager)
  776. {
  777. return FALSE;
  778. }
  779. this->public.child_sa_manager = child_sa_manager_create();
  780. }
  781. else
  782. {
  783. DESTROY_IF(this->public.ike_sa_manager);
  784. DESTROY_IF(this->public.child_sa_manager);
  785. }
  786. return TRUE;
  787. }
  788. METHOD(daemon_t, initialize, bool,
  789. private_daemon_t *this, char *plugins)
  790. {
  791. plugin_feature_t features[] = {
  792. PLUGIN_PROVIDE(CUSTOM, "libcharon"),
  793. PLUGIN_DEPENDS(NONCE_GEN),
  794. PLUGIN_DEPENDS(CUSTOM, "libcharon-sa-managers"),
  795. PLUGIN_DEPENDS(CUSTOM, "libcharon-receiver"),
  796. PLUGIN_DEPENDS(CUSTOM, "kernel-ipsec"),
  797. PLUGIN_DEPENDS(CUSTOM, "kernel-net"),
  798. PLUGIN_CALLBACK((plugin_feature_callback_t)sender_receiver_cb, this),
  799. PLUGIN_PROVIDE(CUSTOM, "libcharon-receiver"),
  800. PLUGIN_DEPENDS(HASHER, HASH_SHA1),
  801. PLUGIN_DEPENDS(RNG, RNG_STRONG),
  802. PLUGIN_DEPENDS(CUSTOM, "socket"),
  803. PLUGIN_CALLBACK((plugin_feature_callback_t)sa_managers_cb, this),
  804. PLUGIN_PROVIDE(CUSTOM, "libcharon-sa-managers"),
  805. PLUGIN_DEPENDS(HASHER, HASH_SHA1),
  806. PLUGIN_DEPENDS(RNG, RNG_WEAK),
  807. };
  808. lib->plugins->add_static_features(lib->plugins, lib->ns, features,
  809. countof(features), TRUE, NULL, NULL);
  810. /* load plugins, further infrastructure may need it */
  811. if (!lib->plugins->load(lib->plugins, plugins))
  812. {
  813. return FALSE;
  814. }
  815. /* Queue start_action job */
  816. lib->processor->queue_job(lib->processor, (job_t*)start_action_job_create());
  817. #ifdef ME
  818. this->public.connect_manager = connect_manager_create();
  819. if (this->public.connect_manager == NULL)
  820. {
  821. return FALSE;
  822. }
  823. this->public.mediation_manager = mediation_manager_create();
  824. #endif /* ME */
  825. return TRUE;
  826. }
  827. /**
  828. * Create the daemon.
  829. */
  830. private_daemon_t *daemon_create()
  831. {
  832. private_daemon_t *this;
  833. INIT(this,
  834. .public = {
  835. .initialize = _initialize,
  836. .start = _start,
  837. .load_loggers = _load_loggers,
  838. .set_default_loggers = _set_default_loggers,
  839. .set_level = _set_level,
  840. .bus = bus_create(),
  841. },
  842. .loggers = linked_list_create(),
  843. .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
  844. .ref = 1,
  845. );
  846. charon = &this->public;
  847. this->public.kernel = kernel_interface_create();
  848. this->public.attributes = attribute_manager_create();
  849. this->public.controller = controller_create();
  850. this->public.eap = eap_manager_create();
  851. this->public.xauth = xauth_manager_create();
  852. this->public.backends = backend_manager_create();
  853. this->public.socket = socket_manager_create();
  854. this->public.traps = trap_manager_create();
  855. this->public.shunts = shunt_manager_create();
  856. this->public.redirect = redirect_manager_create();
  857. this->kernel_handler = kernel_handler_create();
  858. return this;
  859. }
  860. /**
  861. * Described in header.
  862. */
  863. void libcharon_deinit()
  864. {
  865. private_daemon_t *this = (private_daemon_t*)charon;
  866. if (!this || !ref_put(&this->ref))
  867. { /* have more users */
  868. return;
  869. }
  870. run_scripts(this, "stop");
  871. destroy(this);
  872. charon = NULL;
  873. }
  874. /**
  875. * Described in header.
  876. */
  877. bool libcharon_init()
  878. {
  879. private_daemon_t *this;
  880. if (charon)
  881. { /* already initialized, increase refcount */
  882. this = (private_daemon_t*)charon;
  883. ref_get(&this->ref);
  884. return !this->integrity_failed;
  885. }
  886. this = daemon_create();
  887. /* for uncritical pseudo random numbers */
  888. srandom(time(NULL) + getpid());
  889. /* set up hook to log dbg message in library via charons message bus */
  890. dbg_old = dbg;
  891. dbg = dbg_bus;
  892. if (lib->integrity &&
  893. !lib->integrity->check(lib->integrity, "libcharon", libcharon_init))
  894. {
  895. dbg(DBG_DMN, 1, "integrity check of libcharon failed");
  896. this->integrity_failed = TRUE;
  897. }
  898. return !this->integrity_failed;
  899. }