log.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. /* $OpenBSD: log.c,v 1.52 2020/07/03 06:46:41 djm Exp $ */
  2. /*
  3. * Author: Tatu Ylonen <ylo@cs.hut.fi>
  4. * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  5. * All rights reserved
  6. *
  7. * As far as I am concerned, the code I have written for this software
  8. * can be used freely for any purpose. Any derived versions of this
  9. * software must be clearly marked as such, and if the derived work is
  10. * incompatible with the protocol description in the RFC file, it must be
  11. * called by a name other than "ssh" or "Secure Shell".
  12. */
  13. /*
  14. * Copyright (c) 2000 Markus Friedl. All rights reserved.
  15. *
  16. * Redistribution and use in source and binary forms, with or without
  17. * modification, are permitted provided that the following conditions
  18. * are met:
  19. * 1. Redistributions of source code must retain the above copyright
  20. * notice, this list of conditions and the following disclaimer.
  21. * 2. Redistributions in binary form must reproduce the above copyright
  22. * notice, this list of conditions and the following disclaimer in the
  23. * documentation and/or other materials provided with the distribution.
  24. *
  25. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  26. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  27. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  28. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  29. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  30. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  31. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  32. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  33. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  34. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35. */
  36. #include "includes.h"
  37. #include <sys/types.h>
  38. #include <fcntl.h>
  39. #include <stdarg.h>
  40. #include <stdio.h>
  41. #include <stdlib.h>
  42. #include <string.h>
  43. #include <syslog.h>
  44. #include <unistd.h>
  45. #include <errno.h>
  46. #include "packet.h" /* needed for host and port look ups */
  47. #ifdef HAVE_SYS_TIME_H
  48. # include <sys/time.h> /* to get current time */
  49. #endif
  50. #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS)
  51. # include <vis.h>
  52. #endif
  53. #include "log.h"
  54. static LogLevel log_level = SYSLOG_LEVEL_INFO;
  55. static int log_on_stderr = 1;
  56. static int log_stderr_fd = STDERR_FILENO;
  57. static int log_facility = LOG_AUTH;
  58. static const char *argv0;
  59. static log_handler_fn *log_handler;
  60. static void *log_handler_ctx;
  61. extern char *__progname;
  62. extern struct ssh *active_state;
  63. #define LOG_SYSLOG_VIS (VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL)
  64. #define LOG_STDERR_VIS (VIS_SAFE|VIS_OCTAL)
  65. /* textual representation of log-facilities/levels */
  66. static struct {
  67. const char *name;
  68. SyslogFacility val;
  69. } log_facilities[] = {
  70. { "DAEMON", SYSLOG_FACILITY_DAEMON },
  71. { "USER", SYSLOG_FACILITY_USER },
  72. { "AUTH", SYSLOG_FACILITY_AUTH },
  73. #ifdef LOG_AUTHPRIV
  74. { "AUTHPRIV", SYSLOG_FACILITY_AUTHPRIV },
  75. #endif
  76. { "LOCAL0", SYSLOG_FACILITY_LOCAL0 },
  77. { "LOCAL1", SYSLOG_FACILITY_LOCAL1 },
  78. { "LOCAL2", SYSLOG_FACILITY_LOCAL2 },
  79. { "LOCAL3", SYSLOG_FACILITY_LOCAL3 },
  80. { "LOCAL4", SYSLOG_FACILITY_LOCAL4 },
  81. { "LOCAL5", SYSLOG_FACILITY_LOCAL5 },
  82. { "LOCAL6", SYSLOG_FACILITY_LOCAL6 },
  83. { "LOCAL7", SYSLOG_FACILITY_LOCAL7 },
  84. { NULL, SYSLOG_FACILITY_NOT_SET }
  85. };
  86. static struct {
  87. const char *name;
  88. LogLevel val;
  89. } log_levels[] =
  90. {
  91. { "SILENT", SYSLOG_LEVEL_QUIET }, /* compatibility */
  92. { "QUIET", SYSLOG_LEVEL_QUIET },
  93. { "FATAL", SYSLOG_LEVEL_FATAL },
  94. { "ERROR", SYSLOG_LEVEL_ERROR },
  95. { "INFO", SYSLOG_LEVEL_INFO },
  96. { "VERBOSE", SYSLOG_LEVEL_VERBOSE },
  97. { "DEBUG", SYSLOG_LEVEL_DEBUG1 },
  98. { "DEBUG1", SYSLOG_LEVEL_DEBUG1 },
  99. { "DEBUG2", SYSLOG_LEVEL_DEBUG2 },
  100. { "DEBUG3", SYSLOG_LEVEL_DEBUG3 },
  101. { NULL, SYSLOG_LEVEL_NOT_SET }
  102. };
  103. LogLevel
  104. log_level_get(void)
  105. {
  106. return log_level;
  107. }
  108. SyslogFacility
  109. log_facility_number(char *name)
  110. {
  111. int i;
  112. if (name != NULL)
  113. for (i = 0; log_facilities[i].name; i++)
  114. if (strcasecmp(log_facilities[i].name, name) == 0)
  115. return log_facilities[i].val;
  116. return SYSLOG_FACILITY_NOT_SET;
  117. }
  118. const char *
  119. log_facility_name(SyslogFacility facility)
  120. {
  121. u_int i;
  122. for (i = 0; log_facilities[i].name; i++)
  123. if (log_facilities[i].val == facility)
  124. return log_facilities[i].name;
  125. return NULL;
  126. }
  127. LogLevel
  128. log_level_number(char *name)
  129. {
  130. int i;
  131. if (name != NULL)
  132. for (i = 0; log_levels[i].name; i++)
  133. if (strcasecmp(log_levels[i].name, name) == 0)
  134. return log_levels[i].val;
  135. return SYSLOG_LEVEL_NOT_SET;
  136. }
  137. const char *
  138. log_level_name(LogLevel level)
  139. {
  140. u_int i;
  141. for (i = 0; log_levels[i].name != NULL; i++)
  142. if (log_levels[i].val == level)
  143. return log_levels[i].name;
  144. return NULL;
  145. }
  146. /* Error messages that should be logged. */
  147. void
  148. error(const char *fmt,...)
  149. {
  150. va_list args;
  151. va_start(args, fmt);
  152. do_log(SYSLOG_LEVEL_ERROR, fmt, args);
  153. va_end(args);
  154. }
  155. void
  156. sigdie(const char *fmt,...)
  157. {
  158. #ifdef DO_LOG_SAFE_IN_SIGHAND
  159. va_list args;
  160. va_start(args, fmt);
  161. do_log(SYSLOG_LEVEL_FATAL, fmt, args);
  162. va_end(args);
  163. #endif
  164. _exit(1);
  165. }
  166. void
  167. logdie(const char *fmt,...)
  168. {
  169. va_list args;
  170. va_start(args, fmt);
  171. do_log(SYSLOG_LEVEL_INFO, fmt, args);
  172. va_end(args);
  173. cleanup_exit(255);
  174. }
  175. /* Log this message (information that usually should go to the log). */
  176. void
  177. logit(const char *fmt,...)
  178. {
  179. va_list args;
  180. va_start(args, fmt);
  181. do_log(SYSLOG_LEVEL_INFO, fmt, args);
  182. va_end(args);
  183. }
  184. /* More detailed messages (information that does not need to go to the log). */
  185. void
  186. verbose(const char *fmt,...)
  187. {
  188. va_list args;
  189. va_start(args, fmt);
  190. do_log(SYSLOG_LEVEL_VERBOSE, fmt, args);
  191. va_end(args);
  192. }
  193. /* Debugging messages that should not be logged during normal operation. */
  194. void
  195. debug(const char *fmt,...)
  196. {
  197. va_list args;
  198. va_start(args, fmt);
  199. do_log(SYSLOG_LEVEL_DEBUG1, fmt, args);
  200. va_end(args);
  201. }
  202. void
  203. debug2(const char *fmt,...)
  204. {
  205. va_list args;
  206. va_start(args, fmt);
  207. do_log(SYSLOG_LEVEL_DEBUG2, fmt, args);
  208. va_end(args);
  209. }
  210. void
  211. debug3(const char *fmt,...)
  212. {
  213. va_list args;
  214. va_start(args, fmt);
  215. do_log(SYSLOG_LEVEL_DEBUG3, fmt, args);
  216. va_end(args);
  217. }
  218. /*
  219. * Initialize the log.
  220. */
  221. void
  222. log_init(const char *av0, LogLevel level, SyslogFacility facility,
  223. int on_stderr)
  224. {
  225. log_init_handler(av0, level, facility, on_stderr, 1);
  226. }
  227. void
  228. log_init_handler(const char *av0, LogLevel level, SyslogFacility facility, int on_stderr, int reset_handler) {
  229. #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
  230. struct syslog_data sdata = SYSLOG_DATA_INIT;
  231. #endif
  232. argv0 = av0;
  233. if (log_change_level(level) != 0) {
  234. fprintf(stderr, "Unrecognized internal syslog level code %d\n",
  235. (int) level);
  236. exit(1);
  237. }
  238. if (reset_handler) {
  239. log_handler = NULL;
  240. log_handler_ctx = NULL;
  241. }
  242. log_on_stderr = on_stderr;
  243. if (on_stderr)
  244. return;
  245. switch (facility) {
  246. case SYSLOG_FACILITY_DAEMON:
  247. log_facility = LOG_DAEMON;
  248. break;
  249. case SYSLOG_FACILITY_USER:
  250. log_facility = LOG_USER;
  251. break;
  252. case SYSLOG_FACILITY_AUTH:
  253. log_facility = LOG_AUTH;
  254. break;
  255. #ifdef LOG_AUTHPRIV
  256. case SYSLOG_FACILITY_AUTHPRIV:
  257. log_facility = LOG_AUTHPRIV;
  258. break;
  259. #endif
  260. case SYSLOG_FACILITY_LOCAL0:
  261. log_facility = LOG_LOCAL0;
  262. break;
  263. case SYSLOG_FACILITY_LOCAL1:
  264. log_facility = LOG_LOCAL1;
  265. break;
  266. case SYSLOG_FACILITY_LOCAL2:
  267. log_facility = LOG_LOCAL2;
  268. break;
  269. case SYSLOG_FACILITY_LOCAL3:
  270. log_facility = LOG_LOCAL3;
  271. break;
  272. case SYSLOG_FACILITY_LOCAL4:
  273. log_facility = LOG_LOCAL4;
  274. break;
  275. case SYSLOG_FACILITY_LOCAL5:
  276. log_facility = LOG_LOCAL5;
  277. break;
  278. case SYSLOG_FACILITY_LOCAL6:
  279. log_facility = LOG_LOCAL6;
  280. break;
  281. case SYSLOG_FACILITY_LOCAL7:
  282. log_facility = LOG_LOCAL7;
  283. break;
  284. default:
  285. fprintf(stderr,
  286. "Unrecognized internal syslog facility code %d\n",
  287. (int) facility);
  288. exit(1);
  289. }
  290. /*
  291. * If an external library (eg libwrap) attempts to use syslog
  292. * immediately after reexec, syslog may be pointing to the wrong
  293. * facility, so we force an open/close of syslog here.
  294. */
  295. #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
  296. openlog_r(argv0 ? argv0 : __progname, LOG_PID, log_facility, &sdata);
  297. closelog_r(&sdata);
  298. #else
  299. openlog(argv0 ? argv0 : __progname, LOG_PID, log_facility);
  300. closelog();
  301. #endif
  302. }
  303. int
  304. log_change_level(LogLevel new_log_level)
  305. {
  306. /* no-op if log_init has not been called */
  307. if (argv0 == NULL)
  308. return 0;
  309. switch (new_log_level) {
  310. case SYSLOG_LEVEL_QUIET:
  311. case SYSLOG_LEVEL_FATAL:
  312. case SYSLOG_LEVEL_ERROR:
  313. case SYSLOG_LEVEL_INFO:
  314. case SYSLOG_LEVEL_VERBOSE:
  315. case SYSLOG_LEVEL_DEBUG1:
  316. case SYSLOG_LEVEL_DEBUG2:
  317. case SYSLOG_LEVEL_DEBUG3:
  318. log_level = new_log_level;
  319. return 0;
  320. default:
  321. return -1;
  322. }
  323. }
  324. int
  325. log_is_on_stderr(void)
  326. {
  327. return log_on_stderr && log_stderr_fd == STDERR_FILENO;
  328. }
  329. /* redirect what would usually get written to stderr to specified file */
  330. void
  331. log_redirect_stderr_to(const char *logfile)
  332. {
  333. int fd;
  334. if (logfile == NULL) {
  335. if (log_stderr_fd != STDERR_FILENO) {
  336. close(log_stderr_fd);
  337. log_stderr_fd = STDERR_FILENO;
  338. }
  339. return;
  340. }
  341. if ((fd = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0600)) == -1) {
  342. fprintf(stderr, "Couldn't open logfile %s: %s\n", logfile,
  343. strerror(errno));
  344. exit(1);
  345. }
  346. log_stderr_fd = fd;
  347. }
  348. #define MSGBUFSIZ 1024
  349. void
  350. set_log_handler(log_handler_fn *handler, void *ctx)
  351. {
  352. log_handler = handler;
  353. log_handler_ctx = ctx;
  354. }
  355. void
  356. do_log2(LogLevel level, const char *fmt,...)
  357. {
  358. va_list args;
  359. va_start(args, fmt);
  360. do_log(level, fmt, args);
  361. va_end(args);
  362. }
  363. void
  364. do_log(LogLevel level, const char *fmt, va_list args)
  365. {
  366. #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
  367. struct syslog_data sdata = SYSLOG_DATA_INIT;
  368. #endif
  369. char msgbuf[MSGBUFSIZ];
  370. char fmtbuf[MSGBUFSIZ];
  371. char *txt = NULL;
  372. int pri = LOG_INFO;
  373. int saved_errno = errno;
  374. log_handler_fn *tmp_handler;
  375. if (level > log_level)
  376. return;
  377. switch (level) {
  378. case SYSLOG_LEVEL_FATAL:
  379. if (!log_on_stderr)
  380. txt = "fatal";
  381. pri = LOG_CRIT;
  382. break;
  383. case SYSLOG_LEVEL_ERROR:
  384. if (!log_on_stderr)
  385. txt = "error";
  386. pri = LOG_ERR;
  387. break;
  388. case SYSLOG_LEVEL_INFO:
  389. pri = LOG_INFO;
  390. break;
  391. case SYSLOG_LEVEL_VERBOSE:
  392. pri = LOG_INFO;
  393. break;
  394. case SYSLOG_LEVEL_DEBUG1:
  395. txt = "debug1";
  396. pri = LOG_DEBUG;
  397. break;
  398. case SYSLOG_LEVEL_DEBUG2:
  399. txt = "debug2";
  400. pri = LOG_DEBUG;
  401. break;
  402. case SYSLOG_LEVEL_DEBUG3:
  403. txt = "debug3";
  404. pri = LOG_DEBUG;
  405. break;
  406. default:
  407. txt = "internal error";
  408. pri = LOG_ERR;
  409. break;
  410. }
  411. if (txt != NULL && log_handler == NULL) {
  412. snprintf(fmtbuf, sizeof(fmtbuf), "%s: %s", txt, fmt);
  413. vsnprintf(msgbuf, sizeof(msgbuf), fmtbuf, args);
  414. } else {
  415. vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
  416. }
  417. strnvis(fmtbuf, msgbuf, sizeof(fmtbuf),
  418. log_on_stderr ? LOG_STDERR_VIS : LOG_SYSLOG_VIS);
  419. if (log_handler != NULL) {
  420. /* Avoid recursion */
  421. tmp_handler = log_handler;
  422. log_handler = NULL;
  423. tmp_handler(level, fmtbuf, log_handler_ctx);
  424. log_handler = tmp_handler;
  425. } else if (log_on_stderr) {
  426. snprintf(msgbuf, sizeof msgbuf, "%.*s\r\n",
  427. (int)sizeof msgbuf - 3, fmtbuf);
  428. (void)write(log_stderr_fd, msgbuf, strlen(msgbuf));
  429. } else {
  430. #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
  431. openlog_r(argv0 ? argv0 : __progname, LOG_PID, log_facility, &sdata);
  432. syslog_r(pri, &sdata, "%.500s", fmtbuf);
  433. closelog_r(&sdata);
  434. #else
  435. openlog(argv0 ? argv0 : __progname, LOG_PID, log_facility);
  436. syslog(pri, "%.500s", fmtbuf);
  437. closelog();
  438. #endif
  439. }
  440. errno = saved_errno;
  441. }