1 /* $NetBSD: syslogd.c,v 1.104 2011/06/20 08:27:15 enami Exp $ */ 2 3 /* 4 * Copyright (c) 1983, 1988, 1993, 1994 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 #ifndef lint 34 __COPYRIGHT("@(#) Copyright (c) 1983, 1988, 1993, 1994\ 35 The Regents of the University of California. All rights reserved."); 36 #endif /* not lint */ 37 38 #ifndef lint 39 #if 0 40 static char sccsid[] = "@(#)syslogd.c 8.3 (Berkeley) 4/4/94"; 41 #else 42 __RCSID("$NetBSD: syslogd.c,v 1.104 2011/06/20 08:27:15 enami Exp $"); 43 #endif 44 #endif /* not lint */ 45 46 /* 47 * syslogd -- log system messages 48 * 49 * This program implements a system log. It takes a series of lines. 50 * Each line may have a priority, signified as "<n>" as 51 * the first characters of the line. If this is 52 * not present, a default priority is used. 53 * 54 * To kill syslogd, send a signal 15 (terminate). A signal 1 (hup) will 55 * cause it to reread its configuration file. 56 * 57 * Defined Constants: 58 * 59 * MAXLINE -- the maximimum line length that can be handled. 60 * DEFUPRI -- the default priority for user messages 61 * DEFSPRI -- the default priority for kernel messages 62 * 63 * Author: Eric Allman 64 * extensive changes by Ralph Campbell 65 * more extensive changes by Eric Allman (again) 66 * Extension to log by program name as well as facility and priority 67 * by Peter da Silva. 68 * -U and -v by Harlan Stenn. 69 * Priority comparison code by Harlan Stenn. 70 * TLS, syslog-protocol, and syslog-sign code by Martin Schuette. 71 */ 72 #define SYSLOG_NAMES 73 #include "syslogd.h" 74 #include "extern.h" 75 76 #ifndef DISABLE_SIGN 77 #include "sign.h" 78 struct sign_global_t GlobalSign = { 79 .rsid = 0, 80 .sig2_delims = STAILQ_HEAD_INITIALIZER(GlobalSign.sig2_delims) 81 }; 82 #endif /* !DISABLE_SIGN */ 83 84 #ifndef DISABLE_TLS 85 #include "tls.h" 86 #endif /* !DISABLE_TLS */ 87 88 #ifdef LIBWRAP 89 int allow_severity = LOG_AUTH|LOG_INFO; 90 int deny_severity = LOG_AUTH|LOG_WARNING; 91 #endif 92 93 const char *ConfFile = _PATH_LOGCONF; 94 char ctty[] = _PATH_CONSOLE; 95 96 /* 97 * Queue of about-to-be-dead processes we should watch out for. 98 */ 99 TAILQ_HEAD(, deadq_entry) deadq_head = TAILQ_HEAD_INITIALIZER(deadq_head); 100 101 typedef struct deadq_entry { 102 pid_t dq_pid; 103 int dq_timeout; 104 TAILQ_ENTRY(deadq_entry) dq_entries; 105 } *dq_t; 106 107 /* 108 * The timeout to apply to processes waiting on the dead queue. Unit 109 * of measure is "mark intervals", i.e. 20 minutes by default. 110 * Processes on the dead queue will be terminated after that time. 111 */ 112 #define DQ_TIMO_INIT 2 113 114 /* 115 * Intervals at which we flush out "message repeated" messages, 116 * in seconds after previous message is logged. After each flush, 117 * we move to the next interval until we reach the largest. 118 */ 119 int repeatinterval[] = { 30, 120, 600 }; /* # of secs before flush */ 120 #define MAXREPEAT ((sizeof(repeatinterval) / sizeof(repeatinterval[0])) - 1) 121 #define REPEATTIME(f) ((f)->f_time + repeatinterval[(f)->f_repeatcount]) 122 #define BACKOFF(f) { if ((size_t)(++(f)->f_repeatcount) > MAXREPEAT) \ 123 (f)->f_repeatcount = MAXREPEAT; \ 124 } 125 126 /* values for f_type */ 127 #define F_UNUSED 0 /* unused entry */ 128 #define F_FILE 1 /* regular file */ 129 #define F_TTY 2 /* terminal */ 130 #define F_CONSOLE 3 /* console terminal */ 131 #define F_FORW 4 /* remote machine */ 132 #define F_USERS 5 /* list of users */ 133 #define F_WALL 6 /* everyone logged on */ 134 #define F_PIPE 7 /* pipe to program */ 135 #define F_TLS 8 136 137 struct TypeInfo { 138 const char *name; 139 char *queue_length_string; 140 const char *default_length_string; 141 char *queue_size_string; 142 const char *default_size_string; 143 int64_t queue_length; 144 int64_t queue_size; 145 int max_msg_length; 146 } TypeInfo[] = { 147 /* numeric values are set in init() 148 * -1 in length/size or max_msg_length means infinite */ 149 {"UNUSED", NULL, "0", NULL, "0", 0, 0, 0}, 150 {"FILE", NULL, "1024", NULL, "1M", 0, 0, 16384}, 151 {"TTY", NULL, "0", NULL, "0", 0, 0, 1024}, 152 {"CONSOLE", NULL, "0", NULL, "0", 0, 0, 1024}, 153 {"FORW", NULL, "0", NULL, "1M", 0, 0, 16384}, 154 {"USERS", NULL, "0", NULL, "0", 0, 0, 1024}, 155 {"WALL", NULL, "0", NULL, "0", 0, 0, 1024}, 156 {"PIPE", NULL, "1024", NULL, "1M", 0, 0, 16384}, 157 #ifndef DISABLE_TLS 158 {"TLS", NULL, "-1", NULL, "16M", 0, 0, 16384} 159 #endif /* !DISABLE_TLS */ 160 }; 161 162 struct filed *Files = NULL; 163 struct filed consfile; 164 165 time_t now; 166 int Debug = D_NONE; /* debug flag */ 167 int daemonized = 0; /* we are not daemonized yet */ 168 char *LocalFQDN = NULL; /* our FQDN */ 169 char *oldLocalFQDN = NULL; /* our previous FQDN */ 170 char LocalHostName[MAXHOSTNAMELEN]; /* our hostname */ 171 struct socketEvent *finet; /* Internet datagram sockets and events */ 172 int *funix; /* Unix domain datagram sockets */ 173 #ifndef DISABLE_TLS 174 struct socketEvent *TLS_Listen_Set; /* TLS/TCP sockets and events */ 175 #endif /* !DISABLE_TLS */ 176 int Initialized = 0; /* set when we have initialized ourselves */ 177 int ShuttingDown; /* set when we die() */ 178 int MarkInterval = 20 * 60; /* interval between marks in seconds */ 179 int MarkSeq = 0; /* mark sequence number */ 180 int SecureMode = 0; /* listen only on unix domain socks */ 181 int UseNameService = 1; /* make domain name queries */ 182 int NumForwards = 0; /* number of forwarding actions in conf file */ 183 char **LogPaths; /* array of pathnames to read messages from */ 184 int NoRepeat = 0; /* disable "repeated"; log always */ 185 int RemoteAddDate = 0; /* always add date to messages from network */ 186 int SyncKernel = 0; /* write kernel messages synchronously */ 187 int UniquePriority = 0; /* only log specified priority */ 188 int LogFacPri = 0; /* put facility and priority in log messages: */ 189 /* 0=no, 1=numeric, 2=names */ 190 bool BSDOutputFormat = true; /* if true emit traditional BSD Syslog lines, 191 * otherwise new syslog-protocol lines 192 * 193 * Open Issue: having a global flag is the 194 * easiest solution. If we get a more detailed 195 * config file this could/should be changed 196 * into a destination-specific flag. 197 * Most output code should be ready to handle 198 * this, it will only break some syslog-sign 199 * configurations (e.g. with SG="0"). 200 */ 201 char appname[] = "syslogd";/* the APPNAME for own messages */ 202 char *include_pid = NULL; /* include PID in own messages */ 203 204 205 /* init and setup */ 206 void usage(void) __attribute__((__noreturn__)); 207 void logpath_add(char ***, int *, int *, const char *); 208 void logpath_fileadd(char ***, int *, int *, const char *); 209 void init(int fd, short event, void *ev); /* SIGHUP kevent dispatch routine */ 210 struct socketEvent* 211 socksetup(int, const char *); 212 int getmsgbufsize(void); 213 char *getLocalFQDN(void); 214 void trim_anydomain(char *); 215 /* pipe & subprocess handling */ 216 int p_open(char *, pid_t *); 217 void deadq_enter(pid_t, const char *); 218 int deadq_remove(pid_t); 219 void log_deadchild(pid_t, int, const char *); 220 void reapchild(int fd, short event, void *ev); /* SIGCHLD kevent dispatch routine */ 221 /* input message parsing & formatting */ 222 const char *cvthname(struct sockaddr_storage *); 223 void printsys(char *); 224 struct buf_msg *printline_syslogprotocol(const char*, char*, int, int); 225 struct buf_msg *printline_bsdsyslog(const char*, char*, int, int); 226 struct buf_msg *printline_kernelprintf(const char*, char*, int, int); 227 size_t check_timestamp(unsigned char *, char **, bool, bool); 228 char *copy_utf8_ascii(char*, size_t); 229 uint_fast32_t get_utf8_value(const char*); 230 unsigned valid_utf8(const char *); 231 static unsigned check_sd(char*); 232 static unsigned check_msgid(char *); 233 /* event handling */ 234 static void dispatch_read_klog(int fd, short event, void *ev); 235 static void dispatch_read_finet(int fd, short event, void *ev); 236 static void dispatch_read_funix(int fd, short event, void *ev); 237 static void domark(int fd, short event, void *ev); /* timer kevent dispatch routine */ 238 /* log messages */ 239 void logmsg_async(int, const char *, const char *, int); 240 void logmsg(struct buf_msg *); 241 int matches_spec(const char *, const char *, 242 char *(*)(const char *, const char *)); 243 void udp_send(struct filed *, char *, size_t); 244 void wallmsg(struct filed *, struct iovec *, size_t); 245 /* buffer & queue functions */ 246 size_t message_queue_purge(struct filed *f, size_t, int); 247 size_t message_allqueues_check(void); 248 static struct buf_queue * 249 find_qentry_to_delete(const struct buf_queue_head *, int, bool); 250 struct buf_queue * 251 message_queue_add(struct filed *, struct buf_msg *); 252 size_t buf_queue_obj_size(struct buf_queue*); 253 /* configuration & parsing */ 254 void cfline(size_t, const char *, struct filed *, const char *, 255 const char *); 256 void read_config_file(FILE*, struct filed**); 257 void store_sign_delim_sg2(char*); 258 int decode(const char *, CODE *); 259 bool copy_config_value(const char *, char **, const char **, 260 const char *, int); 261 bool copy_config_value_word(char **, const char **); 262 263 /* config parsing */ 264 #ifndef DISABLE_TLS 265 void free_cred_SLIST(struct peer_cred_head *); 266 static inline void 267 free_incoming_tls_sockets(void); 268 #endif /* !DISABLE_TLS */ 269 270 /* for make_timestamp() */ 271 #define TIMESTAMPBUFSIZE 35 272 char timestamp[TIMESTAMPBUFSIZE]; 273 274 /* 275 * Global line buffer. Since we only process one event at a time, 276 * a global one will do. But for klog, we use own buffer so that 277 * partial line at the end of buffer can be deferred. 278 */ 279 char *linebuf, *klog_linebuf; 280 size_t linebufsize, klog_linebufoff; 281 282 static const char *bindhostname = NULL; 283 284 #ifndef DISABLE_TLS 285 struct TLS_Incoming TLS_Incoming_Head = \ 286 SLIST_HEAD_INITIALIZER(TLS_Incoming_Head); 287 extern char *SSL_ERRCODE[]; 288 struct tls_global_options_t tls_opt; 289 #endif /* !DISABLE_TLS */ 290 291 int 292 main(int argc, char *argv[]) 293 { 294 int ch, j, fklog; 295 int funixsize = 0, funixmaxsize = 0; 296 struct sockaddr_un sunx; 297 char **pp; 298 struct event *ev; 299 uid_t uid = 0; 300 gid_t gid = 0; 301 char *user = NULL; 302 char *group = NULL; 303 const char *root = "/"; 304 char *endp; 305 struct group *gr; 306 struct passwd *pw; 307 unsigned long l; 308 309 /* should we set LC_TIME="C" to ensure correct timestamps&parsing? */ 310 (void)setlocale(LC_ALL, ""); 311 312 while ((ch = getopt(argc, argv, "b:dnsSf:m:o:p:P:ru:g:t:TUv")) != -1) 313 switch(ch) { 314 case 'b': 315 bindhostname = optarg; 316 break; 317 case 'd': /* debug */ 318 Debug = D_DEFAULT; 319 /* is there a way to read the integer value 320 * for Debug as an optional argument? */ 321 break; 322 case 'f': /* configuration file */ 323 ConfFile = optarg; 324 break; 325 case 'g': 326 group = optarg; 327 if (*group == '\0') 328 usage(); 329 break; 330 case 'm': /* mark interval */ 331 MarkInterval = atoi(optarg) * 60; 332 break; 333 case 'n': /* turn off DNS queries */ 334 UseNameService = 0; 335 break; 336 case 'o': /* message format */ 337 if (!strncmp(optarg, "rfc3164", sizeof("rfc3164")-1)) 338 BSDOutputFormat = true; 339 else if (!strncmp(optarg, "syslog", sizeof("syslog")-1)) 340 BSDOutputFormat = false; 341 else 342 usage(); 343 /* TODO: implement additional output option "osyslog" 344 * for old syslogd behaviour as introduced after 345 * FreeBSD PR#bin/7055. 346 */ 347 break; 348 case 'p': /* path */ 349 logpath_add(&LogPaths, &funixsize, 350 &funixmaxsize, optarg); 351 break; 352 case 'P': /* file of paths */ 353 logpath_fileadd(&LogPaths, &funixsize, 354 &funixmaxsize, optarg); 355 break; 356 case 'r': /* disable "repeated" compression */ 357 NoRepeat++; 358 break; 359 case 's': /* no network listen mode */ 360 SecureMode++; 361 break; 362 case 'S': 363 SyncKernel = 1; 364 break; 365 case 't': 366 root = optarg; 367 if (*root == '\0') 368 usage(); 369 break; 370 case 'T': 371 RemoteAddDate = 1; 372 break; 373 case 'u': 374 user = optarg; 375 if (*user == '\0') 376 usage(); 377 break; 378 case 'U': /* only log specified priority */ 379 UniquePriority = 1; 380 break; 381 case 'v': /* log facility and priority */ 382 if (LogFacPri < 2) 383 LogFacPri++; 384 break; 385 default: 386 usage(); 387 } 388 if ((argc -= optind) != 0) 389 usage(); 390 391 setlinebuf(stdout); 392 tzset(); /* init TZ information for localtime. */ 393 394 if (user != NULL) { 395 if (isdigit((unsigned char)*user)) { 396 errno = 0; 397 endp = NULL; 398 l = strtoul(user, &endp, 0); 399 if (errno || *endp != '\0') 400 goto getuser; 401 uid = (uid_t)l; 402 if (uid != l) {/* TODO: never executed */ 403 errno = 0; 404 logerror("UID out of range"); 405 die(0, 0, NULL); 406 } 407 } else { 408 getuser: 409 if ((pw = getpwnam(user)) != NULL) { 410 uid = pw->pw_uid; 411 } else { 412 errno = 0; 413 logerror("Cannot find user `%s'", user); 414 die(0, 0, NULL); 415 } 416 } 417 } 418 419 if (group != NULL) { 420 if (isdigit((unsigned char)*group)) { 421 errno = 0; 422 endp = NULL; 423 l = strtoul(group, &endp, 0); 424 if (errno || *endp != '\0') 425 goto getgroup; 426 gid = (gid_t)l; 427 if (gid != l) {/* TODO: never executed */ 428 errno = 0; 429 logerror("GID out of range"); 430 die(0, 0, NULL); 431 } 432 } else { 433 getgroup: 434 if ((gr = getgrnam(group)) != NULL) { 435 gid = gr->gr_gid; 436 } else { 437 errno = 0; 438 logerror("Cannot find group `%s'", group); 439 die(0, 0, NULL); 440 } 441 } 442 } 443 444 if (access(root, F_OK | R_OK)) { 445 logerror("Cannot access `%s'", root); 446 die(0, 0, NULL); 447 } 448 449 consfile.f_type = F_CONSOLE; 450 (void)strlcpy(consfile.f_un.f_fname, ctty, 451 sizeof(consfile.f_un.f_fname)); 452 linebufsize = getmsgbufsize(); 453 if (linebufsize < MAXLINE) 454 linebufsize = MAXLINE; 455 linebufsize++; 456 457 if (!(linebuf = malloc(linebufsize))) { 458 logerror("Couldn't allocate buffer"); 459 die(0, 0, NULL); 460 } 461 if (!(klog_linebuf = malloc(linebufsize))) { 462 logerror("Couldn't allocate buffer for klog"); 463 die(0, 0, NULL); 464 } 465 466 467 #ifndef SUN_LEN 468 #define SUN_LEN(unp) (strlen((unp)->sun_path) + 2) 469 #endif 470 if (funixsize == 0) 471 logpath_add(&LogPaths, &funixsize, 472 &funixmaxsize, _PATH_LOG); 473 funix = (int *)malloc(sizeof(int) * funixsize); 474 if (funix == NULL) { 475 logerror("Couldn't allocate funix descriptors"); 476 die(0, 0, NULL); 477 } 478 for (j = 0, pp = LogPaths; *pp; pp++, j++) { 479 DPRINTF(D_NET, "Making unix dgram socket `%s'\n", *pp); 480 unlink(*pp); 481 memset(&sunx, 0, sizeof(sunx)); 482 sunx.sun_family = AF_LOCAL; 483 (void)strncpy(sunx.sun_path, *pp, sizeof(sunx.sun_path)); 484 funix[j] = socket(AF_LOCAL, SOCK_DGRAM, 0); 485 if (funix[j] < 0 || bind(funix[j], 486 (struct sockaddr *)&sunx, SUN_LEN(&sunx)) < 0 || 487 chmod(*pp, 0666) < 0) { 488 logerror("Cannot create `%s'", *pp); 489 die(0, 0, NULL); 490 } 491 DPRINTF(D_NET, "Listening on unix dgram socket `%s'\n", *pp); 492 } 493 494 if ((fklog = open(_PATH_KLOG, O_RDONLY, 0)) < 0) { 495 DPRINTF(D_FILE, "Can't open `%s' (%d)\n", _PATH_KLOG, errno); 496 } else { 497 DPRINTF(D_FILE, "Listening on kernel log `%s' with fd %d\n", 498 _PATH_KLOG, fklog); 499 } 500 501 #if (!defined(DISABLE_TLS) && !defined(DISABLE_SIGN)) 502 /* basic OpenSSL init */ 503 SSL_load_error_strings(); 504 (void) SSL_library_init(); 505 OpenSSL_add_all_digests(); 506 /* OpenSSL PRNG needs /dev/urandom, thus initialize before chroot() */ 507 if (!RAND_status()) 508 logerror("Unable to initialize OpenSSL PRNG"); 509 else { 510 DPRINTF(D_TLS, "Initializing PRNG\n"); 511 } 512 #endif /* (!defined(DISABLE_TLS) && !defined(DISABLE_SIGN)) */ 513 #ifndef DISABLE_SIGN 514 /* initialize rsid -- we will use that later to determine 515 * whether sign_global_init() was already called */ 516 GlobalSign.rsid = 0; 517 #endif /* !DISABLE_SIGN */ 518 #if (IETF_NUM_PRIVALUES != (LOG_NFACILITIES<<3)) 519 logerror("Warning: system defines %d priority values, but " 520 "syslog-protocol/syslog-sign specify %d values", 521 LOG_NFACILITIES, SIGN_NUM_PRIVALS); 522 #endif 523 524 /* 525 * All files are open, we can drop privileges and chroot 526 */ 527 DPRINTF(D_MISC, "Attempt to chroot to `%s'\n", root); 528 if (chroot(root)) { 529 logerror("Failed to chroot to `%s'", root); 530 die(0, 0, NULL); 531 } 532 DPRINTF(D_MISC, "Attempt to set GID/EGID to `%d'\n", gid); 533 if (setgid(gid) || setegid(gid)) { 534 logerror("Failed to set gid to `%d'", gid); 535 die(0, 0, NULL); 536 } 537 DPRINTF(D_MISC, "Attempt to set UID/EUID to `%d'\n", uid); 538 if (setuid(uid) || seteuid(uid)) { 539 logerror("Failed to set uid to `%d'", uid); 540 die(0, 0, NULL); 541 } 542 /* 543 * We cannot detach from the terminal before we are sure we won't 544 * have a fatal error, because error message would not go to the 545 * terminal and would not be logged because syslogd dies. 546 * All die() calls are behind us, we can call daemon() 547 */ 548 if (!Debug) { 549 (void)daemon(0, 0); 550 daemonized = 1; 551 /* tuck my process id away, if i'm not in debug mode */ 552 #ifdef __NetBSD_Version__ 553 pidfile(NULL); 554 #endif /* __NetBSD_Version__ */ 555 } 556 557 #define MAX_PID_LEN 5 558 include_pid = malloc(MAX_PID_LEN+1); 559 snprintf(include_pid, MAX_PID_LEN+1, "%d", getpid()); 560 561 /* 562 * Create the global kernel event descriptor. 563 * 564 * NOTE: We MUST do this after daemon(), bacause the kqueue() 565 * API dictates that kqueue descriptors are not inherited 566 * across forks (lame!). 567 */ 568 (void)event_init(); 569 570 /* 571 * We must read the configuration file for the first time 572 * after the kqueue descriptor is created, because we install 573 * events during this process. 574 */ 575 init(0, 0, NULL); 576 577 /* 578 * Always exit on SIGTERM. Also exit on SIGINT and SIGQUIT 579 * if we're debugging. 580 */ 581 (void)signal(SIGTERM, SIG_IGN); 582 (void)signal(SIGINT, SIG_IGN); 583 (void)signal(SIGQUIT, SIG_IGN); 584 585 ev = allocev(); 586 signal_set(ev, SIGTERM, die, ev); 587 EVENT_ADD(ev); 588 589 if (Debug) { 590 ev = allocev(); 591 signal_set(ev, SIGINT, die, ev); 592 EVENT_ADD(ev); 593 ev = allocev(); 594 signal_set(ev, SIGQUIT, die, ev); 595 EVENT_ADD(ev); 596 } 597 598 ev = allocev(); 599 signal_set(ev, SIGCHLD, reapchild, ev); 600 EVENT_ADD(ev); 601 602 ev = allocev(); 603 schedule_event(&ev, 604 &((struct timeval){TIMERINTVL, 0}), 605 domark, ev); 606 607 (void)signal(SIGPIPE, SIG_IGN); /* We'll catch EPIPE instead. */ 608 609 /* Re-read configuration on SIGHUP. */ 610 (void) signal(SIGHUP, SIG_IGN); 611 ev = allocev(); 612 signal_set(ev, SIGHUP, init, ev); 613 EVENT_ADD(ev); 614 615 #ifndef DISABLE_TLS 616 ev = allocev(); 617 signal_set(ev, SIGUSR1, dispatch_force_tls_reconnect, ev); 618 EVENT_ADD(ev); 619 #endif /* !DISABLE_TLS */ 620 621 if (fklog >= 0) { 622 ev = allocev(); 623 DPRINTF(D_EVENT, 624 "register klog for fd %d with ev@%p\n", fklog, ev); 625 event_set(ev, fklog, EV_READ | EV_PERSIST, 626 dispatch_read_klog, ev); 627 EVENT_ADD(ev); 628 } 629 for (j = 0, pp = LogPaths; *pp; pp++, j++) { 630 ev = allocev(); 631 event_set(ev, funix[j], EV_READ | EV_PERSIST, 632 dispatch_read_funix, ev); 633 EVENT_ADD(ev); 634 } 635 636 DPRINTF(D_MISC, "Off & running....\n"); 637 638 j = event_dispatch(); 639 /* normal termination via die(), reaching this is an error */ 640 DPRINTF(D_MISC, "event_dispatch() returned %d\n", j); 641 die(0, 0, NULL); 642 /*NOTREACHED*/ 643 return 0; 644 } 645 646 void 647 usage(void) 648 { 649 650 (void)fprintf(stderr, 651 "usage: %s [-dnrSsTUv] [-b bind_address] [-f config_file] [-g group]\n" 652 "\t[-m mark_interval] [-P file_list] [-p log_socket\n" 653 "\t[-p log_socket2 ...]] [-t chroot_dir] [-u user]\n", 654 getprogname()); 655 exit(1); 656 } 657 658 /* 659 * Dispatch routine for reading /dev/klog 660 * 661 * Note: slightly different semantic in dispatch_read functions: 662 * - read_klog() might give multiple messages in linebuf and 663 * leaves the task of splitting them to printsys() 664 * - all other read functions receive one message and 665 * then call printline() with one buffer. 666 */ 667 static void 668 dispatch_read_klog(int fd, short event, void *ev) 669 { 670 ssize_t rv; 671 size_t resid = linebufsize - klog_linebufoff; 672 673 DPRINTF((D_CALL|D_EVENT), "Kernel log active (%d, %d, %p)" 674 " with linebuf@%p, length %zu)\n", fd, event, ev, 675 klog_linebuf, linebufsize); 676 677 rv = read(fd, &klog_linebuf[klog_linebufoff], resid - 1); 678 if (rv > 0) { 679 klog_linebuf[klog_linebufoff + rv] = '\0'; 680 printsys(klog_linebuf); 681 } else if (rv < 0 && errno != EINTR) { 682 /* 683 * /dev/klog has croaked. Disable the event 684 * so it won't bother us again. 685 */ 686 logerror("klog failed"); 687 event_del(ev); 688 } 689 } 690 691 /* 692 * Dispatch routine for reading Unix domain sockets. 693 */ 694 static void 695 dispatch_read_funix(int fd, short event, void *ev) 696 { 697 struct sockaddr_un myname, fromunix; 698 ssize_t rv; 699 socklen_t sunlen; 700 701 sunlen = sizeof(myname); 702 if (getsockname(fd, (struct sockaddr *)&myname, &sunlen) != 0) { 703 /* 704 * This should never happen, so ensure that it doesn't 705 * happen again. 706 */ 707 logerror("getsockname() unix failed"); 708 event_del(ev); 709 return; 710 } 711 712 DPRINTF((D_CALL|D_EVENT|D_NET), "Unix socket (%.*s) active (%d, %d %p)" 713 " with linebuf@%p, size %zu)\n", (int)(myname.sun_len 714 - sizeof(myname.sun_len) - sizeof(myname.sun_family)), 715 myname.sun_path, fd, event, ev, linebuf, linebufsize-1); 716 717 sunlen = sizeof(fromunix); 718 rv = recvfrom(fd, linebuf, linebufsize-1, 0, 719 (struct sockaddr *)&fromunix, &sunlen); 720 if (rv > 0) { 721 linebuf[rv] = '\0'; 722 printline(LocalFQDN, linebuf, 0); 723 } else if (rv < 0 && errno != EINTR) { 724 logerror("recvfrom() unix `%.*s'", 725 myname.sun_len, myname.sun_path); 726 } 727 } 728 729 /* 730 * Dispatch routine for reading Internet sockets. 731 */ 732 static void 733 dispatch_read_finet(int fd, short event, void *ev) 734 { 735 #ifdef LIBWRAP 736 struct request_info req; 737 #endif 738 struct sockaddr_storage frominet; 739 ssize_t rv; 740 socklen_t len; 741 int reject = 0; 742 743 DPRINTF((D_CALL|D_EVENT|D_NET), "inet socket active (%d, %d %p) " 744 " with linebuf@%p, size %zu)\n", 745 fd, event, ev, linebuf, linebufsize-1); 746 747 #ifdef LIBWRAP 748 request_init(&req, RQ_DAEMON, appname, RQ_FILE, fd, NULL); 749 fromhost(&req); 750 reject = !hosts_access(&req); 751 if (reject) 752 DPRINTF(D_NET, "access denied\n"); 753 #endif 754 755 len = sizeof(frominet); 756 rv = recvfrom(fd, linebuf, linebufsize-1, 0, 757 (struct sockaddr *)&frominet, &len); 758 if (rv == 0 || (rv < 0 && errno == EINTR)) 759 return; 760 else if (rv < 0) { 761 logerror("recvfrom inet"); 762 return; 763 } 764 765 linebuf[rv] = '\0'; 766 if (!reject) 767 printline(cvthname(&frominet), linebuf, 768 RemoteAddDate ? ADDDATE : 0); 769 } 770 771 /* 772 * given a pointer to an array of char *'s, a pointer to its current 773 * size and current allocated max size, and a new char * to add, add 774 * it, update everything as necessary, possibly allocating a new array 775 */ 776 void 777 logpath_add(char ***lp, int *szp, int *maxszp, const char *new) 778 { 779 char **nlp; 780 int newmaxsz; 781 782 DPRINTF(D_FILE, "Adding `%s' to the %p logpath list\n", new, *lp); 783 if (*szp == *maxszp) { 784 if (*maxszp == 0) { 785 newmaxsz = 4; /* start of with enough for now */ 786 *lp = NULL; 787 } else 788 newmaxsz = *maxszp * 2; 789 nlp = realloc(*lp, sizeof(char *) * (newmaxsz + 1)); 790 if (nlp == NULL) { 791 logerror("Couldn't allocate line buffer"); 792 die(0, 0, NULL); 793 } 794 *lp = nlp; 795 *maxszp = newmaxsz; 796 } 797 if (((*lp)[(*szp)++] = strdup(new)) == NULL) { 798 logerror("Couldn't allocate logpath"); 799 die(0, 0, NULL); 800 } 801 (*lp)[(*szp)] = NULL; /* always keep it NULL terminated */ 802 } 803 804 /* do a file of log sockets */ 805 void 806 logpath_fileadd(char ***lp, int *szp, int *maxszp, const char *file) 807 { 808 FILE *fp; 809 char *line; 810 size_t len; 811 812 fp = fopen(file, "r"); 813 if (fp == NULL) { 814 logerror("Could not open socket file list `%s'", file); 815 die(0, 0, NULL); 816 } 817 818 while ((line = fgetln(fp, &len)) != NULL) { 819 line[len - 1] = 0; 820 logpath_add(lp, szp, maxszp, line); 821 } 822 fclose(fp); 823 } 824 825 /* 826 * checks UTF-8 codepoint 827 * returns either its length in bytes or 0 if *input is invalid 828 */ 829 unsigned 830 valid_utf8(const char *c) { 831 unsigned rc, nb; 832 833 /* first byte gives sequence length */ 834 if ((*c & 0x80) == 0x00) return 1; /* 0bbbbbbb -- ASCII */ 835 else if ((*c & 0xc0) == 0x80) return 0; /* 10bbbbbb -- trailing byte */ 836 else if ((*c & 0xe0) == 0xc0) nb = 2; /* 110bbbbb */ 837 else if ((*c & 0xf0) == 0xe0) nb = 3; /* 1110bbbb */ 838 else if ((*c & 0xf8) == 0xf0) nb = 4; /* 11110bbb */ 839 else return 0; /* UTF-8 allows only up to 4 bytes */ 840 841 /* catch overlong encodings */ 842 if ((*c & 0xfe) == 0xc0) 843 return 0; /* 1100000b ... */ 844 else if (((*c & 0xff) == 0xe0) && ((*(c+1) & 0xe0) == 0x80)) 845 return 0; /* 11100000 100bbbbb ... */ 846 else if (((*c & 0xff) == 0xf0) && ((*(c+1) & 0xf0) == 0x80)) 847 return 0; /* 11110000 1000bbbb ... ... */ 848 849 /* and also filter UTF-16 surrogates (=invalid in UTF-8) */ 850 if (((*c & 0xff) == 0xed) && ((*(c+1) & 0xe0) == 0xa0)) 851 return 0; /* 11101101 101bbbbb ... */ 852 853 rc = nb; 854 /* check trailing bytes */ 855 switch (nb) { 856 default: return 0; 857 case 4: if ((*(c+3) & 0xc0) != 0x80) return 0; /*FALLTHROUGH*/ 858 case 3: if ((*(c+2) & 0xc0) != 0x80) return 0; /*FALLTHROUGH*/ 859 case 2: if ((*(c+1) & 0xc0) != 0x80) return 0; /*FALLTHROUGH*/ 860 } 861 return rc; 862 } 863 #define UTF8CHARMAX 4 864 865 /* 866 * read UTF-8 value 867 * returns a the codepoint number 868 */ 869 uint_fast32_t 870 get_utf8_value(const char *c) { 871 uint_fast32_t sum; 872 unsigned nb, i; 873 874 /* first byte gives sequence length */ 875 if ((*c & 0x80) == 0x00) return *c;/* 0bbbbbbb -- ASCII */ 876 else if ((*c & 0xc0) == 0x80) return 0; /* 10bbbbbb -- trailing byte */ 877 else if ((*c & 0xe0) == 0xc0) { /* 110bbbbb */ 878 nb = 2; 879 sum = (*c & ~0xe0) & 0xff; 880 } else if ((*c & 0xf0) == 0xe0) { /* 1110bbbb */ 881 nb = 3; 882 sum = (*c & ~0xf0) & 0xff; 883 } else if ((*c & 0xf8) == 0xf0) { /* 11110bbb */ 884 nb = 4; 885 sum = (*c & ~0xf8) & 0xff; 886 } else return 0; /* UTF-8 allows only up to 4 bytes */ 887 888 /* check trailing bytes -- 10bbbbbb */ 889 i = 1; 890 while (i < nb) { 891 sum <<= 6; 892 sum |= ((*(c+i) & ~0xc0) & 0xff); 893 i++; 894 } 895 return sum; 896 } 897 898 /* note previous versions transscribe 899 * control characters, e.g. \007 --> "^G" 900 * did anyone rely on that? 901 * 902 * this new version works on only one buffer and 903 * replaces control characters with a space 904 */ 905 #define NEXTFIELD(ptr) if (*(p) == ' ') (p)++; /* SP */ \ 906 else { \ 907 DPRINTF(D_DATA, "format error\n"); \ 908 if (*(p) == '\0') start = (p); \ 909 goto all_syslog_msg; \ 910 } 911 #define FORCE2ASCII(c) ((iscntrl((unsigned char)(c)) && (c) != '\t') \ 912 ? ((c) == '\n' ? ' ' : '?') \ 913 : (c) & 0177) 914 915 /* following syslog-protocol */ 916 #define printusascii(ch) (ch >= 33 && ch <= 126) 917 #define sdname(ch) (ch != '=' && ch != ' ' \ 918 && ch != ']' && ch != '"' \ 919 && printusascii(ch)) 920 921 /* checks whether the first word of string p can be interpreted as 922 * a syslog-protocol MSGID and if so returns its length. 923 * 924 * otherwise returns 0 925 */ 926 static unsigned 927 check_msgid(char *p) 928 { 929 char *q = p; 930 931 /* consider the NILVALUE to be valid */ 932 if (*q == '-' && *(q+1) == ' ') 933 return 1; 934 935 for (;;) { 936 if (*q == ' ') 937 return q - p; 938 else if (*q == '\0' || !printusascii(*q) || q - p >= MSGID_MAX) 939 return 0; 940 else 941 q++; 942 } 943 } 944 945 /* 946 * returns number of chars found in SD at beginning of string p 947 * thus returns 0 if no valid SD is found 948 * 949 * if ascii == true then substitute all non-ASCII chars 950 * otherwise use syslog-protocol rules to allow UTF-8 in values 951 * note: one pass for filtering and scanning, so a found SD 952 * is always filtered, but an invalid one could be partially 953 * filtered up to the format error. 954 */ 955 static unsigned 956 check_sd(char* p) 957 { 958 char *q = p; 959 bool esc = false; 960 961 /* consider the NILVALUE to be valid */ 962 if (*q == '-' && (*(q+1) == ' ' || *(q+1) == '\0')) 963 return 1; 964 965 for(;;) { /* SD-ELEMENT */ 966 if (*q++ != '[') return 0; 967 /* SD-ID */ 968 if (!sdname(*q)) return 0; 969 while (sdname(*q)) { 970 *q = FORCE2ASCII(*q); 971 q++; 972 } 973 for(;;) { /* SD-PARAM */ 974 if (*q == ']') { 975 q++; 976 if (*q == ' ' || *q == '\0') return q - p; 977 else if (*q == '[') break; 978 } else if (*q++ != ' ') return 0; 979 980 /* PARAM-NAME */ 981 if (!sdname(*q)) return 0; 982 while (sdname(*q)) { 983 *q = FORCE2ASCII(*q); 984 q++; 985 } 986 987 if (*q++ != '=') return 0; 988 if (*q++ != '"') return 0; 989 990 for(;;) { /* PARAM-VALUE */ 991 if (esc) { 992 esc = false; 993 if (*q == '\\' || *q == '"' || 994 *q == ']') { 995 q++; 996 continue; 997 } 998 /* no else because invalid 999 * escape sequences are accepted */ 1000 } 1001 else if (*q == '"') break; 1002 else if (*q == '\0' || *q == ']') return 0; 1003 else if (*q == '\\') esc = true; 1004 else { 1005 int i; 1006 i = valid_utf8(q); 1007 if (i == 0) 1008 *q = '?'; 1009 else if (i == 1) 1010 *q = FORCE2ASCII(*q); 1011 else /* multi byte char */ 1012 q += (i-1); 1013 } 1014 q++; 1015 } 1016 q++; 1017 } 1018 } 1019 } 1020 1021 struct buf_msg * 1022 printline_syslogprotocol(const char *hname, char *msg, 1023 int flags, int pri) 1024 { 1025 struct buf_msg *buffer; 1026 char *p, *start; 1027 unsigned sdlen = 0, i = 0; 1028 bool utf8allowed = false; /* for some fields */ 1029 1030 DPRINTF((D_CALL|D_BUFFER|D_DATA), "printline_syslogprotocol(" 1031 "\"%s\", \"%s\", %d, %d)\n", hname, msg, flags, pri); 1032 1033 buffer = buf_msg_new(0); 1034 p = msg; 1035 p += check_timestamp((unsigned char*) p, 1036 &buffer->timestamp, true, !BSDOutputFormat); 1037 DPRINTF(D_DATA, "Got timestamp \"%s\"\n", buffer->timestamp); 1038 1039 if (flags & ADDDATE) { 1040 FREEPTR(buffer->timestamp); 1041 buffer->timestamp = strdup(make_timestamp(NULL, 1042 !BSDOutputFormat)); 1043 } 1044 1045 start = p; 1046 NEXTFIELD(p); 1047 /* extract host */ 1048 for (start = p;; p++) { 1049 if ((*p == ' ' || *p == '\0') 1050 && start == p-1 && *(p-1) == '-') { 1051 /* NILVALUE */ 1052 break; 1053 } else if ((*p == ' ' || *p == '\0') 1054 && (start != p-1 || *(p-1) != '-')) { 1055 buffer->host = strndup(start, p - start); 1056 break; 1057 } else { 1058 *p = FORCE2ASCII(*p); 1059 } 1060 } 1061 /* p @ SP after host */ 1062 DPRINTF(D_DATA, "Got host \"%s\"\n", buffer->host); 1063 1064 /* extract app-name */ 1065 NEXTFIELD(p); 1066 for (start = p;; p++) { 1067 if ((*p == ' ' || *p == '\0') 1068 && start == p-1 && *(p-1) == '-') { 1069 /* NILVALUE */ 1070 break; 1071 } else if ((*p == ' ' || *p == '\0') 1072 && (start != p-1 || *(p-1) != '-')) { 1073 buffer->prog = strndup(start, p - start); 1074 break; 1075 } else { 1076 *p = FORCE2ASCII(*p); 1077 } 1078 } 1079 DPRINTF(D_DATA, "Got prog \"%s\"\n", buffer->prog); 1080 1081 /* extract procid */ 1082 NEXTFIELD(p); 1083 for (start = p;; p++) { 1084 if ((*p == ' ' || *p == '\0') 1085 && start == p-1 && *(p-1) == '-') { 1086 /* NILVALUE */ 1087 break; 1088 } else if ((*p == ' ' || *p == '\0') 1089 && (start != p-1 || *(p-1) != '-')) { 1090 buffer->pid = strndup(start, p - start); 1091 start = p; 1092 break; 1093 } else { 1094 *p = FORCE2ASCII(*p); 1095 } 1096 } 1097 DPRINTF(D_DATA, "Got pid \"%s\"\n", buffer->pid); 1098 1099 /* extract msgid */ 1100 NEXTFIELD(p); 1101 for (start = p;; p++) { 1102 if ((*p == ' ' || *p == '\0') 1103 && start == p-1 && *(p-1) == '-') { 1104 /* NILVALUE */ 1105 start = p+1; 1106 break; 1107 } else if ((*p == ' ' || *p == '\0') 1108 && (start != p-1 || *(p-1) != '-')) { 1109 buffer->msgid = strndup(start, p - start); 1110 start = p+1; 1111 break; 1112 } else { 1113 *p = FORCE2ASCII(*p); 1114 } 1115 } 1116 DPRINTF(D_DATA, "Got msgid \"%s\"\n", buffer->msgid); 1117 1118 /* extract SD */ 1119 NEXTFIELD(p); 1120 start = p; 1121 sdlen = check_sd(p); 1122 DPRINTF(D_DATA, "check_sd(\"%s\") returned %d\n", p, sdlen); 1123 1124 if (sdlen == 1 && *p == '-') { 1125 /* NILVALUE */ 1126 p++; 1127 } else if (sdlen > 1) { 1128 buffer->sd = strndup(p, sdlen); 1129 p += sdlen; 1130 } else { 1131 DPRINTF(D_DATA, "format error\n"); 1132 } 1133 if (*p == '\0') start = p; 1134 else if (*p == ' ') start = ++p; /* SP */ 1135 DPRINTF(D_DATA, "Got SD \"%s\"\n", buffer->sd); 1136 1137 /* and now the message itself 1138 * note: move back to last start to check for BOM 1139 */ 1140 all_syslog_msg: 1141 p = start; 1142 1143 /* check for UTF-8-BOM */ 1144 if (IS_BOM(p)) { 1145 DPRINTF(D_DATA, "UTF-8 BOM\n"); 1146 utf8allowed = true; 1147 p += 3; 1148 } 1149 1150 if (*p != '\0' && !utf8allowed) { 1151 size_t msglen; 1152 1153 msglen = strlen(p); 1154 assert(!buffer->msg); 1155 buffer->msg = copy_utf8_ascii(p, msglen); 1156 buffer->msgorig = buffer->msg; 1157 buffer->msglen = buffer->msgsize = strlen(buffer->msg)+1; 1158 } else if (*p != '\0' && utf8allowed) { 1159 while (*p != '\0') { 1160 i = valid_utf8(p); 1161 if (i == 0) 1162 *p++ = '?'; 1163 else if (i == 1) 1164 *p = FORCE2ASCII(*p); 1165 p += i; 1166 } 1167 assert(p != start); 1168 assert(!buffer->msg); 1169 buffer->msg = strndup(start, p - start); 1170 buffer->msgorig = buffer->msg; 1171 buffer->msglen = buffer->msgsize = 1 + p - start; 1172 } 1173 DPRINTF(D_DATA, "Got msg \"%s\"\n", buffer->msg); 1174 1175 buffer->recvhost = strdup(hname); 1176 buffer->pri = pri; 1177 buffer->flags = flags; 1178 1179 return buffer; 1180 } 1181 1182 /* copies an input into a new ASCII buffer 1183 * ASCII controls are converted to format "^X" 1184 * multi-byte UTF-8 chars are converted to format "<ab><cd>" 1185 */ 1186 #define INIT_BUFSIZE 512 1187 char * 1188 copy_utf8_ascii(char *p, size_t p_len) 1189 { 1190 size_t idst = 0, isrc = 0, dstsize = INIT_BUFSIZE, i; 1191 char *dst, *tmp_dst; 1192 1193 MALLOC(dst, dstsize); 1194 while (isrc < p_len) { 1195 if (dstsize < idst + 10) { 1196 /* check for enough space for \0 and a UTF-8 1197 * conversion; longest possible is <U+123456> */ 1198 tmp_dst = realloc(dst, dstsize + INIT_BUFSIZE); 1199 if (!tmp_dst) 1200 break; 1201 dst = tmp_dst; 1202 dstsize += INIT_BUFSIZE; 1203 } 1204 1205 i = valid_utf8(&p[isrc]); 1206 if (i == 0) { /* invalid encoding */ 1207 dst[idst++] = '?'; 1208 isrc++; 1209 } else if (i == 1) { /* check printable */ 1210 if (iscntrl((unsigned char)p[isrc]) 1211 && p[isrc] != '\t') { 1212 if (p[isrc] == '\n') { 1213 dst[idst++] = ' '; 1214 isrc++; 1215 } else { 1216 dst[idst++] = '^'; 1217 dst[idst++] = p[isrc++] ^ 0100; 1218 } 1219 } else 1220 dst[idst++] = p[isrc++]; 1221 } else { /* convert UTF-8 to ASCII */ 1222 dst[idst++] = '<'; 1223 idst += snprintf(&dst[idst], dstsize - idst, "U+%x", 1224 get_utf8_value(&p[isrc])); 1225 isrc += i; 1226 dst[idst++] = '>'; 1227 } 1228 } 1229 dst[idst] = '\0'; 1230 1231 /* shrink buffer to right size */ 1232 tmp_dst = realloc(dst, idst+1); 1233 if (tmp_dst) 1234 return tmp_dst; 1235 else 1236 return dst; 1237 } 1238 1239 struct buf_msg * 1240 printline_bsdsyslog(const char *hname, char *msg, 1241 int flags, int pri) 1242 { 1243 struct buf_msg *buffer; 1244 char *p, *start; 1245 unsigned msgidlen = 0, sdlen = 0; 1246 1247 DPRINTF((D_CALL|D_BUFFER|D_DATA), "printline_bsdsyslog(" 1248 "\"%s\", \"%s\", %d, %d)\n", hname, msg, flags, pri); 1249 1250 buffer = buf_msg_new(0); 1251 p = msg; 1252 p += check_timestamp((unsigned char*) p, 1253 &buffer->timestamp, false, !BSDOutputFormat); 1254 DPRINTF(D_DATA, "Got timestamp \"%s\"\n", buffer->timestamp); 1255 1256 if (flags & ADDDATE || !buffer->timestamp) { 1257 FREEPTR(buffer->timestamp); 1258 buffer->timestamp = strdup(make_timestamp(NULL, 1259 !BSDOutputFormat)); 1260 } 1261 1262 if (*p == ' ') p++; /* SP */ 1263 else goto all_bsd_msg; 1264 /* in any error case we skip header parsing and 1265 * treat all following data as message content */ 1266 1267 /* extract host */ 1268 for (start = p;; p++) { 1269 if (*p == ' ' || *p == '\0') { 1270 buffer->host = strndup(start, p - start); 1271 break; 1272 } else if (*p == '[' || (*p == ':' 1273 && (*(p+1) == ' ' || *(p+1) == '\0'))) { 1274 /* no host in message */ 1275 buffer->host = LocalFQDN; 1276 buffer->prog = strndup(start, p - start); 1277 break; 1278 } else { 1279 *p = FORCE2ASCII(*p); 1280 } 1281 } 1282 DPRINTF(D_DATA, "Got host \"%s\"\n", buffer->host); 1283 /* p @ SP after host, or @ :/[ after prog */ 1284 1285 /* extract program */ 1286 if (!buffer->prog) { 1287 if (*p == ' ') p++; /* SP */ 1288 else goto all_bsd_msg; 1289 1290 for (start = p;; p++) { 1291 if (*p == ' ' || *p == '\0') { /* error */ 1292 goto all_bsd_msg; 1293 } else if (*p == '[' || (*p == ':' 1294 && (*(p+1) == ' ' || *(p+1) == '\0'))) { 1295 buffer->prog = strndup(start, p - start); 1296 break; 1297 } else { 1298 *p = FORCE2ASCII(*p); 1299 } 1300 } 1301 } 1302 DPRINTF(D_DATA, "Got prog \"%s\"\n", buffer->prog); 1303 start = p; 1304 1305 /* p @ :/[ after prog */ 1306 if (*p == '[') { 1307 p++; 1308 if (*p == ' ') p++; /* SP */ 1309 for (start = p;; p++) { 1310 if (*p == ' ' || *p == '\0') { /* error */ 1311 goto all_bsd_msg; 1312 } else if (*p == ']') { 1313 buffer->pid = strndup(start, p - start); 1314 break; 1315 } else { 1316 *p = FORCE2ASCII(*p); 1317 } 1318 } 1319 } 1320 DPRINTF(D_DATA, "Got pid \"%s\"\n", buffer->pid); 1321 1322 if (*p == ']') p++; 1323 if (*p == ':') p++; 1324 if (*p == ' ') p++; 1325 1326 /* p @ msgid, @ opening [ of SD or @ first byte of message 1327 * accept either case and try to detect MSGID and SD fields 1328 * 1329 * only limitation: we do not accept UTF-8 data in 1330 * BSD Syslog messages -- so all SD values are ASCII-filtered 1331 * 1332 * I have found one scenario with 'unexpected' behaviour: 1333 * if there is only a SD intended, but a) it is short enough 1334 * to be a MSGID and b) the first word of the message can also 1335 * be parsed as an SD. 1336 * example: 1337 * "<35>Jul 6 12:39:08 tag[123]: [exampleSDID@0] - hello" 1338 * --> parsed as 1339 * MSGID = "[exampleSDID@0]" 1340 * SD = "-" 1341 * MSG = "hello" 1342 */ 1343 start = p; 1344 msgidlen = check_msgid(p); 1345 if (msgidlen) /* check for SD in 2nd field */ 1346 sdlen = check_sd(p+msgidlen+1); 1347 1348 if (msgidlen && sdlen) { 1349 /* MSGID in 1st and SD in 2nd field 1350 * now check for NILVALUEs and copy */ 1351 if (msgidlen == 1 && *p == '-') { 1352 p++; /* - */ 1353 p++; /* SP */ 1354 DPRINTF(D_DATA, "Got MSGID \"-\"\n"); 1355 } else { 1356 /* only has ASCII chars after check_msgid() */ 1357 buffer->msgid = strndup(p, msgidlen); 1358 p += msgidlen; 1359 p++; /* SP */ 1360 DPRINTF(D_DATA, "Got MSGID \"%s\"\n", 1361 buffer->msgid); 1362 } 1363 } else { 1364 /* either no msgid or no SD in 2nd field 1365 * --> check 1st field for SD */ 1366 DPRINTF(D_DATA, "No MSGID\n"); 1367 sdlen = check_sd(p); 1368 } 1369 1370 if (sdlen == 0) { 1371 DPRINTF(D_DATA, "No SD\n"); 1372 } else if (sdlen > 1) { 1373 buffer->sd = copy_utf8_ascii(p, sdlen); 1374 DPRINTF(D_DATA, "Got SD \"%s\"\n", buffer->sd); 1375 } else if (sdlen == 1 && *p == '-') { 1376 p++; 1377 DPRINTF(D_DATA, "Got SD \"-\"\n"); 1378 } else { 1379 DPRINTF(D_DATA, "Error\n"); 1380 } 1381 1382 if (*p == ' ') p++; 1383 start = p; 1384 /* and now the message itself 1385 * note: do not reset start, because we might come here 1386 * by goto and want to have the incomplete field as part 1387 * of the msg 1388 */ 1389 all_bsd_msg: 1390 if (*p != '\0') { 1391 size_t msglen = strlen(p); 1392 buffer->msg = copy_utf8_ascii(p, msglen); 1393 buffer->msgorig = buffer->msg; 1394 buffer->msglen = buffer->msgsize = strlen(buffer->msg)+1; 1395 } 1396 DPRINTF(D_DATA, "Got msg \"%s\"\n", buffer->msg); 1397 1398 buffer->recvhost = strdup(hname); 1399 buffer->pri = pri; 1400 buffer->flags = flags | BSDSYSLOG; 1401 1402 return buffer; 1403 } 1404 1405 struct buf_msg * 1406 printline_kernelprintf(const char *hname, char *msg, 1407 int flags, int pri) 1408 { 1409 struct buf_msg *buffer; 1410 char *p; 1411 unsigned sdlen = 0; 1412 1413 DPRINTF((D_CALL|D_BUFFER|D_DATA), "printline_kernelprintf(" 1414 "\"%s\", \"%s\", %d, %d)\n", hname, msg, flags, pri); 1415 1416 buffer = buf_msg_new(0); 1417 buffer->timestamp = strdup(make_timestamp(NULL, !BSDOutputFormat)); 1418 buffer->pri = pri; 1419 buffer->flags = flags; 1420 1421 /* assume there is no MSGID but there might be SD */ 1422 p = msg; 1423 sdlen = check_sd(p); 1424 1425 if (sdlen == 0) { 1426 DPRINTF(D_DATA, "No SD\n"); 1427 } else if (sdlen > 1) { 1428 buffer->sd = copy_utf8_ascii(p, sdlen); 1429 DPRINTF(D_DATA, "Got SD \"%s\"\n", buffer->sd); 1430 } else if (sdlen == 1 && *p == '-') { 1431 p++; 1432 DPRINTF(D_DATA, "Got SD \"-\"\n"); 1433 } else { 1434 DPRINTF(D_DATA, "Error\n"); 1435 } 1436 1437 if (*p == ' ') p++; 1438 if (*p != '\0') { 1439 size_t msglen = strlen(p); 1440 buffer->msg = copy_utf8_ascii(p, msglen); 1441 buffer->msgorig = buffer->msg; 1442 buffer->msglen = buffer->msgsize = strlen(buffer->msg)+1; 1443 } 1444 DPRINTF(D_DATA, "Got msg \"%s\"\n", buffer->msg); 1445 1446 return buffer; 1447 } 1448 1449 /* 1450 * Take a raw input line, read priority and version, call the 1451 * right message parsing function, then call logmsg(). 1452 */ 1453 void 1454 printline(const char *hname, char *msg, int flags) 1455 { 1456 struct buf_msg *buffer; 1457 int pri; 1458 char *p, *q; 1459 long n; 1460 bool bsdsyslog = true; 1461 1462 DPRINTF((D_CALL|D_BUFFER|D_DATA), 1463 "printline(\"%s\", \"%s\", %d)\n", hname, msg, flags); 1464 1465 /* test for special codes */ 1466 pri = DEFUPRI; 1467 p = msg; 1468 if (*p == '<') { 1469 errno = 0; 1470 n = strtol(p + 1, &q, 10); 1471 if (*q == '>' && n >= 0 && n < INT_MAX && errno == 0) { 1472 p = q + 1; 1473 pri = (int)n; 1474 /* check for syslog-protocol version */ 1475 if (*p == '1' && p[1] == ' ') { 1476 p += 2; /* skip version and space */ 1477 bsdsyslog = false; 1478 } else { 1479 bsdsyslog = true; 1480 } 1481 } 1482 } 1483 if (pri & ~(LOG_FACMASK|LOG_PRIMASK)) 1484 pri = DEFUPRI; 1485 1486 /* 1487 * Don't allow users to log kernel messages. 1488 * NOTE: Since LOG_KERN == 0, this will also match 1489 * messages with no facility specified. 1490 */ 1491 if ((pri & LOG_FACMASK) == LOG_KERN) 1492 pri = LOG_MAKEPRI(LOG_USER, LOG_PRI(pri)); 1493 1494 if (bsdsyslog) { 1495 buffer = printline_bsdsyslog(hname, p, flags, pri); 1496 } else { 1497 buffer = printline_syslogprotocol(hname, p, flags, pri); 1498 } 1499 logmsg(buffer); 1500 DELREF(buffer); 1501 } 1502 1503 /* 1504 * Take a raw input line from /dev/klog, split and format similar to syslog(). 1505 */ 1506 void 1507 printsys(char *msg) 1508 { 1509 int n, is_printf, pri, flags; 1510 char *p, *q; 1511 struct buf_msg *buffer; 1512 1513 klog_linebufoff = 0; 1514 for (p = msg; *p != '\0'; ) { 1515 bool bsdsyslog = true; 1516 1517 is_printf = 1; 1518 flags = ISKERNEL | ADDDATE | BSDSYSLOG; 1519 if (SyncKernel) 1520 flags |= SYNC_FILE; 1521 if (is_printf) /* kernel printf's come out on console */ 1522 flags |= IGN_CONS; 1523 pri = DEFSPRI; 1524 1525 if (*p == '<') { 1526 errno = 0; 1527 n = (int)strtol(p + 1, &q, 10); 1528 if (*q == '>' && n >= 0 && n < INT_MAX && errno == 0) { 1529 p = q + 1; 1530 is_printf = 0; 1531 pri = n; 1532 if (*p == '1') { /* syslog-protocol version */ 1533 p += 2; /* skip version and space */ 1534 bsdsyslog = false; 1535 } else { 1536 bsdsyslog = true; 1537 } 1538 } 1539 } 1540 for (q = p; *q != '\0' && *q != '\n'; q++) 1541 /* look for end of line; no further checks. 1542 * trust the kernel to send ASCII only */; 1543 if (*q != '\0') 1544 *q++ = '\0'; 1545 else { 1546 memcpy(linebuf, p, klog_linebufoff = q - p); 1547 break; 1548 } 1549 1550 if (pri &~ (LOG_FACMASK|LOG_PRIMASK)) 1551 pri = DEFSPRI; 1552 1553 /* allow all kinds of input from kernel */ 1554 if (is_printf) 1555 buffer = printline_kernelprintf( 1556 LocalFQDN, p, flags, pri); 1557 else { 1558 if (bsdsyslog) 1559 buffer = printline_bsdsyslog( 1560 LocalFQDN, p, flags, pri); 1561 else 1562 buffer = printline_syslogprotocol( 1563 LocalFQDN, p, flags, pri); 1564 } 1565 1566 /* set fields left open */ 1567 if (!buffer->prog) 1568 buffer->prog = strdup(_PATH_UNIX); 1569 if (!buffer->host) 1570 buffer->host = LocalFQDN; 1571 if (!buffer->recvhost) 1572 buffer->recvhost = LocalFQDN; 1573 1574 logmsg(buffer); 1575 DELREF(buffer); 1576 p = q; 1577 } 1578 } 1579 1580 /* 1581 * Check to see if `name' matches the provided specification, using the 1582 * specified strstr function. 1583 */ 1584 int 1585 matches_spec(const char *name, const char *spec, 1586 char *(*check)(const char *, const char *)) 1587 { 1588 const char *s; 1589 const char *cursor; 1590 char prev, next; 1591 size_t len; 1592 1593 if (name[0] == '\0') 1594 return 0; 1595 1596 if (strchr(name, ',')) /* sanity */ 1597 return 0; 1598 1599 len = strlen(name); 1600 cursor = spec; 1601 while ((s = (*check)(cursor, name)) != NULL) { 1602 prev = s == spec ? ',' : *(s - 1); 1603 cursor = s + len; 1604 next = *cursor; 1605 1606 if (prev == ',' && (next == '\0' || next == ',')) 1607 return 1; 1608 } 1609 1610 return 0; 1611 } 1612 1613 /* 1614 * wrapper with old function signature, 1615 * keeps calling code shorter and hides buffer allocation 1616 */ 1617 void 1618 logmsg_async(int pri, const char *sd, const char *msg, int flags) 1619 { 1620 struct buf_msg *buffer; 1621 size_t msglen; 1622 1623 DPRINTF((D_CALL|D_DATA), "logmsg_async(%d, \"%s\", \"%s\", %d)\n", 1624 pri, sd, msg, flags); 1625 1626 if (msg) { 1627 msglen = strlen(msg); 1628 msglen++; /* adds \0 */ 1629 buffer = buf_msg_new(msglen); 1630 buffer->msglen = strlcpy(buffer->msg, msg, msglen) + 1; 1631 } else { 1632 buffer = buf_msg_new(0); 1633 } 1634 if (sd) buffer->sd = strdup(sd); 1635 buffer->timestamp = strdup(make_timestamp(NULL, !BSDOutputFormat)); 1636 buffer->prog = appname; 1637 buffer->pid = include_pid; 1638 buffer->recvhost = buffer->host = LocalFQDN; 1639 buffer->pri = pri; 1640 buffer->flags = flags; 1641 1642 logmsg(buffer); 1643 DELREF(buffer); 1644 } 1645 1646 /* read timestamp in from_buf, convert into a timestamp in to_buf 1647 * 1648 * returns length of timestamp found in from_buf (= number of bytes consumed) 1649 */ 1650 size_t 1651 check_timestamp(unsigned char *from_buf, char **to_buf, 1652 bool from_iso, bool to_iso) 1653 { 1654 unsigned char *q; 1655 int p; 1656 bool found_ts = false; 1657 1658 DPRINTF((D_CALL|D_DATA), "check_timestamp(%p = \"%s\", from_iso=%d, " 1659 "to_iso=%d)\n", from_buf, from_buf, from_iso, to_iso); 1660 1661 if (!from_buf) return 0; 1662 /* 1663 * Check to see if msg looks non-standard. 1664 * looks at every char because we do not have a msg length yet 1665 */ 1666 /* detailed checking adapted from Albert Mietus' sl_timestamp.c */ 1667 if (from_iso) { 1668 if (from_buf[4] == '-' && from_buf[7] == '-' 1669 && from_buf[10] == 'T' && from_buf[13] == ':' 1670 && from_buf[16] == ':' 1671 && isdigit(from_buf[0]) && isdigit(from_buf[1]) 1672 && isdigit(from_buf[2]) && isdigit(from_buf[3]) /* YYYY */ 1673 && isdigit(from_buf[5]) && isdigit(from_buf[6]) 1674 && isdigit(from_buf[8]) && isdigit(from_buf[9]) /* mm dd */ 1675 && isdigit(from_buf[11]) && isdigit(from_buf[12]) /* HH */ 1676 && isdigit(from_buf[14]) && isdigit(from_buf[15]) /* MM */ 1677 && isdigit(from_buf[17]) && isdigit(from_buf[18]) /* SS */ 1678 ) { 1679 /* time-secfrac */ 1680 if (from_buf[19] == '.') 1681 for (p=20; isdigit(from_buf[p]); p++) /* NOP*/; 1682 else 1683 p = 19; 1684 /* time-offset */ 1685 if (from_buf[p] == 'Z' 1686 || ((from_buf[p] == '+' || from_buf[p] == '-') 1687 && from_buf[p+3] == ':' 1688 && isdigit(from_buf[p+1]) && isdigit(from_buf[p+2]) 1689 && isdigit(from_buf[p+4]) && isdigit(from_buf[p+5]) 1690 )) 1691 found_ts = true; 1692 } 1693 } else { 1694 if (from_buf[3] == ' ' && from_buf[6] == ' ' 1695 && from_buf[9] == ':' && from_buf[12] == ':' 1696 && (from_buf[4] == ' ' || isdigit(from_buf[4])) 1697 && isdigit(from_buf[5]) /* dd */ 1698 && isdigit(from_buf[7]) && isdigit(from_buf[8]) /* HH */ 1699 && isdigit(from_buf[10]) && isdigit(from_buf[11]) /* MM */ 1700 && isdigit(from_buf[13]) && isdigit(from_buf[14]) /* SS */ 1701 && isupper(from_buf[0]) && islower(from_buf[1]) /* month */ 1702 && islower(from_buf[2])) 1703 found_ts = true; 1704 } 1705 if (!found_ts) { 1706 if (from_buf[0] == '-' && from_buf[1] == ' ') { 1707 /* NILVALUE */ 1708 if (to_iso) { 1709 /* with ISO = syslog-protocol output leave 1710 * it as is, because it is better to have 1711 * no timestamp than a wrong one. 1712 */ 1713 *to_buf = strdup("-"); 1714 } else { 1715 /* with BSD Syslog the field is reqired 1716 * so replace it with current time 1717 */ 1718 *to_buf = strdup(make_timestamp(NULL, false)); 1719 } 1720 return 2; 1721 } 1722 return 0; 1723 } 1724 1725 if (!from_iso && !to_iso) { 1726 /* copy BSD timestamp */ 1727 DPRINTF(D_CALL, "check_timestamp(): copy BSD timestamp\n"); 1728 *to_buf = strndup((char *)from_buf, BSD_TIMESTAMPLEN); 1729 return BSD_TIMESTAMPLEN; 1730 } else if (from_iso && to_iso) { 1731 /* copy ISO timestamp */ 1732 DPRINTF(D_CALL, "check_timestamp(): copy ISO timestamp\n"); 1733 if (!(q = (unsigned char *) strchr((char *)from_buf, ' '))) 1734 q = from_buf + strlen((char *)from_buf); 1735 *to_buf = strndup((char *)from_buf, q - from_buf); 1736 return q - from_buf; 1737 } else if (from_iso && !to_iso) { 1738 /* convert ISO->BSD */ 1739 struct tm parsed; 1740 time_t timeval; 1741 char tsbuf[MAX_TIMESTAMPLEN]; 1742 int i = 0; 1743 1744 DPRINTF(D_CALL, "check_timestamp(): convert ISO->BSD\n"); 1745 for(i = 0; i < MAX_TIMESTAMPLEN && from_buf[i] != '\0' 1746 && from_buf[i] != '.' && from_buf[i] != ' '; i++) 1747 tsbuf[i] = from_buf[i]; /* copy date & time */ 1748 for(; i < MAX_TIMESTAMPLEN && from_buf[i] != '\0' 1749 && from_buf[i] != '+' && from_buf[i] != '-' 1750 && from_buf[i] != 'Z' && from_buf[i] != ' '; i++) 1751 ; /* skip fraction digits */ 1752 for(; i < MAX_TIMESTAMPLEN && from_buf[i] != '\0' 1753 && from_buf[i] != ':' && from_buf[i] != ' ' ; i++) 1754 tsbuf[i] = from_buf[i]; /* copy TZ */ 1755 if (from_buf[i] == ':') i++; /* skip colon */ 1756 for(; i < MAX_TIMESTAMPLEN && from_buf[i] != '\0' 1757 && from_buf[i] != ' ' ; i++) 1758 tsbuf[i] = from_buf[i]; /* copy TZ */ 1759 1760 (void)memset(&parsed, 0, sizeof(parsed)); 1761 parsed.tm_isdst = -1; 1762 (void)strptime(tsbuf, "%FT%T%z", &parsed); 1763 timeval = mktime(&parsed); 1764 1765 *to_buf = strndup(make_timestamp(&timeval, false), 1766 BSD_TIMESTAMPLEN); 1767 return i; 1768 } else if (!from_iso && to_iso) { 1769 /* convert BSD->ISO */ 1770 struct tm parsed; 1771 struct tm *current; 1772 time_t timeval; 1773 char *rc; 1774 1775 (void)memset(&parsed, 0, sizeof(parsed)); 1776 parsed.tm_isdst = -1; 1777 DPRINTF(D_CALL, "check_timestamp(): convert BSD->ISO\n"); 1778 rc = strptime((char *)from_buf, "%b %d %T", &parsed); 1779 current = gmtime(&now); 1780 1781 /* use current year and timezone */ 1782 parsed.tm_isdst = current->tm_isdst; 1783 parsed.tm_gmtoff = current->tm_gmtoff; 1784 parsed.tm_year = current->tm_year; 1785 if (current->tm_mon == 0 && parsed.tm_mon == 11) 1786 parsed.tm_year--; 1787 1788 timeval = mktime(&parsed); 1789 rc = make_timestamp(&timeval, true); 1790 *to_buf = strndup(rc, MAX_TIMESTAMPLEN-1); 1791 1792 return BSD_TIMESTAMPLEN; 1793 } else { 1794 DPRINTF(D_MISC, 1795 "Executing unreachable code in check_timestamp()\n"); 1796 return 0; 1797 } 1798 } 1799 1800 /* 1801 * Log a message to the appropriate log files, users, etc. based on 1802 * the priority. 1803 */ 1804 void 1805 logmsg(struct buf_msg *buffer) 1806 { 1807 struct filed *f; 1808 int fac, omask, prilev; 1809 1810 DPRINTF((D_CALL|D_BUFFER), "logmsg: buffer@%p, pri 0%o/%d, flags 0x%x," 1811 " timestamp \"%s\", from \"%s\", sd \"%s\", msg \"%s\"\n", 1812 buffer, buffer->pri, buffer->pri, buffer->flags, 1813 buffer->timestamp, buffer->recvhost, buffer->sd, buffer->msg); 1814 1815 omask = sigblock(sigmask(SIGHUP)|sigmask(SIGALRM)); 1816 1817 /* sanity check */ 1818 assert(buffer->refcount == 1); 1819 assert(buffer->msglen <= buffer->msgsize); 1820 assert(buffer->msgorig <= buffer->msg); 1821 assert((buffer->msg && buffer->msglen == strlen(buffer->msg)+1) 1822 || (!buffer->msg && !buffer->msglen)); 1823 if (!buffer->msg && !buffer->sd && !buffer->msgid) 1824 DPRINTF(D_BUFFER, "Empty message?\n"); 1825 1826 /* extract facility and priority level */ 1827 if (buffer->flags & MARK) 1828 fac = LOG_NFACILITIES; 1829 else 1830 fac = LOG_FAC(buffer->pri); 1831 prilev = LOG_PRI(buffer->pri); 1832 1833 /* log the message to the particular outputs */ 1834 if (!Initialized) { 1835 f = &consfile; 1836 f->f_file = open(ctty, O_WRONLY, 0); 1837 1838 if (f->f_file >= 0) { 1839 DELREF(f->f_prevmsg); 1840 f->f_prevmsg = NEWREF(buffer); 1841 fprintlog(f, NEWREF(buffer), NULL); 1842 DELREF(buffer); 1843 (void)close(f->f_file); 1844 } 1845 (void)sigsetmask(omask); 1846 return; 1847 } 1848 1849 for (f = Files; f; f = f->f_next) { 1850 /* skip messages that are incorrect priority */ 1851 if (!MATCH_PRI(f, fac, prilev) 1852 || f->f_pmask[fac] == INTERNAL_NOPRI) 1853 continue; 1854 1855 /* skip messages with the incorrect host name */ 1856 /* do we compare with host (IMHO correct) or recvhost */ 1857 /* (compatible)? */ 1858 if (f->f_host != NULL && buffer->host != NULL) { 1859 char shost[MAXHOSTNAMELEN + 1], *h; 1860 if (!BSDOutputFormat) { 1861 h = buffer->host; 1862 } else { 1863 (void)strlcpy(shost, buffer->host, 1864 sizeof(shost)); 1865 trim_anydomain(shost); 1866 h = shost; 1867 } 1868 switch (f->f_host[0]) { 1869 case '+': 1870 if (! matches_spec(h, f->f_host + 1, 1871 strcasestr)) 1872 continue; 1873 break; 1874 case '-': 1875 if (matches_spec(h, f->f_host + 1, 1876 strcasestr)) 1877 continue; 1878 break; 1879 } 1880 } 1881 1882 /* skip messages with the incorrect program name */ 1883 if (f->f_program != NULL && buffer->prog != NULL) { 1884 switch (f->f_program[0]) { 1885 case '+': 1886 if (!matches_spec(buffer->prog, 1887 f->f_program + 1, strstr)) 1888 continue; 1889 break; 1890 case '-': 1891 if (matches_spec(buffer->prog, 1892 f->f_program + 1, strstr)) 1893 continue; 1894 break; 1895 default: 1896 if (!matches_spec(buffer->prog, 1897 f->f_program, strstr)) 1898 continue; 1899 break; 1900 } 1901 } 1902 1903 if (f->f_type == F_CONSOLE && (buffer->flags & IGN_CONS)) 1904 continue; 1905 1906 /* don't output marks to recently written files */ 1907 if ((buffer->flags & MARK) 1908 && (now - f->f_time) < MarkInterval / 2) 1909 continue; 1910 1911 /* 1912 * suppress duplicate lines to this file unless NoRepeat 1913 */ 1914 #define MSG_FIELD_EQ(x) ((!buffer->x && !f->f_prevmsg->x) || \ 1915 (buffer->x && f->f_prevmsg->x && !strcmp(buffer->x, f->f_prevmsg->x))) 1916 1917 if ((buffer->flags & MARK) == 0 && 1918 f->f_prevmsg && 1919 buffer->msglen == f->f_prevmsg->msglen && 1920 !NoRepeat && 1921 MSG_FIELD_EQ(host) && 1922 MSG_FIELD_EQ(sd) && 1923 MSG_FIELD_EQ(msg) 1924 ) { 1925 f->f_prevcount++; 1926 DPRINTF(D_DATA, "Msg repeated %d times, %ld sec of %d\n", 1927 f->f_prevcount, (long)(now - f->f_time), 1928 repeatinterval[f->f_repeatcount]); 1929 /* 1930 * If domark would have logged this by now, 1931 * flush it now (so we don't hold isolated messages), 1932 * but back off so we'll flush less often 1933 * in the future. 1934 */ 1935 if (now > REPEATTIME(f)) { 1936 fprintlog(f, NEWREF(buffer), NULL); 1937 DELREF(buffer); 1938 BACKOFF(f); 1939 } 1940 } else { 1941 /* new line, save it */ 1942 if (f->f_prevcount) 1943 fprintlog(f, NULL, NULL); 1944 f->f_repeatcount = 0; 1945 DELREF(f->f_prevmsg); 1946 f->f_prevmsg = NEWREF(buffer); 1947 fprintlog(f, NEWREF(buffer), NULL); 1948 DELREF(buffer); 1949 } 1950 } 1951 (void)sigsetmask(omask); 1952 } 1953 1954 /* 1955 * format one buffer into output format given by flag BSDOutputFormat 1956 * line is allocated and has to be free()d by caller 1957 * size_t pointers are optional, if not NULL then they will return 1958 * different lenghts used for formatting and output 1959 */ 1960 #define OUT(x) ((x)?(x):"-") 1961 bool 1962 format_buffer(struct buf_msg *buffer, char **line, size_t *ptr_linelen, 1963 size_t *ptr_msglen, size_t *ptr_tlsprefixlen, size_t *ptr_prilen) 1964 { 1965 #define FPBUFSIZE 30 1966 static char ascii_empty[] = ""; 1967 char fp_buf[FPBUFSIZE] = "\0"; 1968 char *hostname, *shorthostname = NULL; 1969 char *ascii_sd = ascii_empty; 1970 char *ascii_msg = ascii_empty; 1971 size_t linelen, msglen, tlsprefixlen, prilen, j; 1972 1973 DPRINTF(D_CALL, "format_buffer(%p)\n", buffer); 1974 if (!buffer) return false; 1975 1976 /* All buffer fields are set with strdup(). To avoid problems 1977 * on memory exhaustion we allow them to be empty and replace 1978 * the essential fields with already allocated generic values. 1979 */ 1980 if (!buffer->timestamp) 1981 buffer->timestamp = timestamp; 1982 if (!buffer->host && !buffer->recvhost) 1983 buffer->host = LocalFQDN; 1984 1985 if (LogFacPri) { 1986 const char *f_s = NULL, *p_s = NULL; 1987 int fac = buffer->pri & LOG_FACMASK; 1988 int pri = LOG_PRI(buffer->pri); 1989 char f_n[5], p_n[5]; 1990 1991 if (LogFacPri > 1) { 1992 CODE *c; 1993 1994 for (c = facilitynames; c->c_name != NULL; c++) { 1995 if (c->c_val == fac) { 1996 f_s = c->c_name; 1997 break; 1998 } 1999 } 2000 for (c = prioritynames; c->c_name != NULL; c++) { 2001 if (c->c_val == pri) { 2002 p_s = c->c_name; 2003 break; 2004 } 2005 } 2006 } 2007 if (f_s == NULL) { 2008 snprintf(f_n, sizeof(f_n), "%d", LOG_FAC(fac)); 2009 f_s = f_n; 2010 } 2011 if (p_s == NULL) { 2012 snprintf(p_n, sizeof(p_n), "%d", pri); 2013 p_s = p_n; 2014 } 2015 snprintf(fp_buf, sizeof(fp_buf), "<%s.%s>", f_s, p_s); 2016 } 2017 2018 /* hostname or FQDN */ 2019 hostname = (buffer->host ? buffer->host : buffer->recvhost); 2020 if (BSDOutputFormat 2021 && (shorthostname = strdup(hostname))) { 2022 /* if the previous BSD output format with "host [recvhost]:" 2023 * gets implemented, this is the right place to distinguish 2024 * between buffer->host and buffer->recvhost 2025 */ 2026 trim_anydomain(shorthostname); 2027 hostname = shorthostname; 2028 } 2029 2030 /* new message formatting: 2031 * instead of using iov always assemble one complete TLS-ready line 2032 * with length and priority (depending on BSDOutputFormat either in 2033 * BSD Syslog or syslog-protocol format) 2034 * 2035 * additionally save the length of the prefixes, 2036 * so UDP destinations can skip the length prefix and 2037 * file/pipe/wall destinations can omit length and priority 2038 */ 2039 /* first determine required space */ 2040 if (BSDOutputFormat) { 2041 /* only output ASCII chars */ 2042 if (buffer->sd) 2043 ascii_sd = copy_utf8_ascii(buffer->sd, 2044 strlen(buffer->sd)); 2045 if (buffer->msg) { 2046 if (IS_BOM(buffer->msg)) 2047 ascii_msg = copy_utf8_ascii(buffer->msg, 2048 buffer->msglen - 1); 2049 else /* assume already converted at input */ 2050 ascii_msg = buffer->msg; 2051 } 2052 msglen = snprintf(NULL, 0, "<%d>%s%.15s %s %s%s%s%s: %s%s%s", 2053 buffer->pri, fp_buf, buffer->timestamp, 2054 hostname, OUT(buffer->prog), 2055 buffer->pid ? "[" : "", 2056 buffer->pid ? buffer->pid : "", 2057 buffer->pid ? "]" : "", ascii_sd, 2058 (buffer->sd && buffer->msg ? " ": ""), ascii_msg); 2059 } else 2060 msglen = snprintf(NULL, 0, "<%d>1 %s%s %s %s %s %s %s%s%s", 2061 buffer->pri, fp_buf, buffer->timestamp, 2062 hostname, OUT(buffer->prog), OUT(buffer->pid), 2063 OUT(buffer->msgid), OUT(buffer->sd), 2064 (buffer->msg ? " ": ""), 2065 (buffer->msg ? buffer->msg: "")); 2066 /* add space for length prefix */ 2067 tlsprefixlen = 0; 2068 for (j = msglen; j; j /= 10) 2069 tlsprefixlen++; 2070 /* one more for the space */ 2071 tlsprefixlen++; 2072 2073 prilen = snprintf(NULL, 0, "<%d>", buffer->pri); 2074 if (!BSDOutputFormat) 2075 prilen += 2; /* version char and space */ 2076 MALLOC(*line, msglen + tlsprefixlen + 1); 2077 if (BSDOutputFormat) 2078 linelen = snprintf(*line, 2079 msglen + tlsprefixlen + 1, 2080 "%zu <%d>%s%.15s %s %s%s%s%s: %s%s%s", 2081 msglen, buffer->pri, fp_buf, buffer->timestamp, 2082 hostname, OUT(buffer->prog), 2083 (buffer->pid ? "[" : ""), 2084 (buffer->pid ? buffer->pid : ""), 2085 (buffer->pid ? "]" : ""), ascii_sd, 2086 (buffer->sd && buffer->msg ? " ": ""), ascii_msg); 2087 else 2088 linelen = snprintf(*line, 2089 msglen + tlsprefixlen + 1, 2090 "%zu <%d>1 %s%s %s %s %s %s %s%s%s", 2091 msglen, buffer->pri, fp_buf, buffer->timestamp, 2092 hostname, OUT(buffer->prog), OUT(buffer->pid), 2093 OUT(buffer->msgid), OUT(buffer->sd), 2094 (buffer->msg ? " ": ""), 2095 (buffer->msg ? buffer->msg: "")); 2096 DPRINTF(D_DATA, "formatted %zu octets to: '%.*s' (linelen %zu, " 2097 "msglen %zu, tlsprefixlen %zu, prilen %zu)\n", linelen, 2098 (int)linelen, *line, linelen, msglen, tlsprefixlen, prilen); 2099 2100 FREEPTR(shorthostname); 2101 if (ascii_sd != ascii_empty) 2102 FREEPTR(ascii_sd); 2103 if (ascii_msg != ascii_empty && ascii_msg != buffer->msg) 2104 FREEPTR(ascii_msg); 2105 2106 if (ptr_linelen) *ptr_linelen = linelen; 2107 if (ptr_msglen) *ptr_msglen = msglen; 2108 if (ptr_tlsprefixlen) *ptr_tlsprefixlen = tlsprefixlen; 2109 if (ptr_prilen) *ptr_prilen = prilen; 2110 return true; 2111 } 2112 2113 /* 2114 * if qentry == NULL: new message, if temporarily undeliverable it will be enqueued 2115 * if qentry != NULL: a temporarily undeliverable message will not be enqueued, 2116 * but after delivery be removed from the queue 2117 */ 2118 void 2119 fprintlog(struct filed *f, struct buf_msg *passedbuffer, struct buf_queue *qentry) 2120 { 2121 static char crnl[] = "\r\n"; 2122 struct buf_msg *buffer = passedbuffer; 2123 struct iovec iov[4]; 2124 struct iovec *v = iov; 2125 bool error = false; 2126 int e = 0, len = 0; 2127 size_t msglen, linelen, tlsprefixlen, prilen; 2128 char *p, *line = NULL, *lineptr = NULL; 2129 #ifndef DISABLE_SIGN 2130 bool newhash = false; 2131 #endif 2132 #define REPBUFSIZE 80 2133 char greetings[200]; 2134 #define ADDEV() do { v++; assert((size_t)(v - iov) < A_CNT(iov)); } while(/*CONSTCOND*/0) 2135 2136 DPRINTF(D_CALL, "fprintlog(%p, %p, %p)\n", f, buffer, qentry); 2137 2138 f->f_time = now; 2139 2140 /* increase refcount here and lower again at return. 2141 * this enables the buffer in the else branch to be freed 2142 * --> every branch needs one NEWREF() or buf_msg_new()! */ 2143 if (buffer) { 2144 (void)NEWREF(buffer); 2145 } else { 2146 if (f->f_prevcount > 1) { 2147 /* possible syslog-sign incompatibility: 2148 * assume destinations f1 and f2 share one SG and 2149 * get the same message sequence. 2150 * 2151 * now both f1 and f2 generate "repeated" messages 2152 * "repeated" messages are different due to different 2153 * timestamps 2154 * the SG will get hashes for the two "repeated" messages 2155 * 2156 * now both f1 and f2 are just fine, but a verification 2157 * will report that each 'lost' a message, i.e. the 2158 * other's "repeated" message 2159 * 2160 * conditions for 'safe configurations': 2161 * - use NoRepeat option, 2162 * - use SG 3, or 2163 * - have exactly one destination for every PRI 2164 */ 2165 buffer = buf_msg_new(REPBUFSIZE); 2166 buffer->msglen = snprintf(buffer->msg, REPBUFSIZE, 2167 "last message repeated %d times", f->f_prevcount); 2168 buffer->timestamp = 2169 strdup(make_timestamp(NULL, !BSDOutputFormat)); 2170 buffer->pri = f->f_prevmsg->pri; 2171 buffer->host = LocalFQDN; 2172 buffer->prog = appname; 2173 buffer->pid = include_pid; 2174 2175 } else { 2176 buffer = NEWREF(f->f_prevmsg); 2177 } 2178 } 2179 2180 /* no syslog-sign messages to tty/console/... */ 2181 if ((buffer->flags & SIGN_MSG) 2182 && ((f->f_type == F_UNUSED) 2183 || (f->f_type == F_TTY) 2184 || (f->f_type == F_CONSOLE) 2185 || (f->f_type == F_USERS) 2186 || (f->f_type == F_WALL))) { 2187 DELREF(buffer); 2188 return; 2189 } 2190 2191 /* buffering works only for few types */ 2192 if (qentry 2193 && (f->f_type != F_TLS) 2194 && (f->f_type != F_PIPE) 2195 && (f->f_type != F_FILE)) { 2196 logerror("Warning: unexpected message in buffer"); 2197 DELREF(buffer); 2198 return; 2199 } 2200 2201 if (!format_buffer(buffer, &line, 2202 &linelen, &msglen, &tlsprefixlen, &prilen)) { 2203 DPRINTF(D_CALL, "format_buffer() failed, skip message\n"); 2204 DELREF(buffer); 2205 return; 2206 } 2207 /* assert maximum message length */ 2208 if (TypeInfo[f->f_type].max_msg_length != -1 2209 && (size_t)TypeInfo[f->f_type].max_msg_length 2210 < linelen - tlsprefixlen - prilen) { 2211 linelen = TypeInfo[f->f_type].max_msg_length 2212 + tlsprefixlen + prilen; 2213 DPRINTF(D_DATA, "truncating oversized message to %zu octets\n", 2214 linelen); 2215 } 2216 2217 #ifndef DISABLE_SIGN 2218 /* keep state between appending the hash (before buffer is sent) 2219 * and possibly sending a SB (after buffer is sent): */ 2220 /* get hash */ 2221 if (!(buffer->flags & SIGN_MSG) && !qentry) { 2222 char *hash = NULL; 2223 struct signature_group_t *sg; 2224 2225 if ((sg = sign_get_sg(buffer->pri, f)) != NULL) { 2226 if (sign_msg_hash(line + tlsprefixlen, &hash)) 2227 newhash = sign_append_hash(hash, sg); 2228 else 2229 DPRINTF(D_SIGN, 2230 "Unable to hash line \"%s\"\n", line); 2231 } 2232 } 2233 #endif /* !DISABLE_SIGN */ 2234 2235 /* set start and length of buffer and/or fill iovec */ 2236 switch (f->f_type) { 2237 case F_UNUSED: 2238 /* nothing */ 2239 break; 2240 case F_TLS: 2241 /* nothing, as TLS uses whole buffer to send */ 2242 lineptr = line; 2243 len = linelen; 2244 break; 2245 case F_FORW: 2246 lineptr = line + tlsprefixlen; 2247 len = linelen - tlsprefixlen; 2248 break; 2249 case F_PIPE: 2250 case F_FILE: /* fallthrough */ 2251 if (f->f_flags & FFLAG_FULL) { 2252 v->iov_base = line + tlsprefixlen; 2253 v->iov_len = linelen - tlsprefixlen; 2254 } else { 2255 v->iov_base = line + tlsprefixlen + prilen; 2256 v->iov_len = linelen - tlsprefixlen - prilen; 2257 } 2258 ADDEV(); 2259 v->iov_base = &crnl[1]; 2260 v->iov_len = 1; 2261 ADDEV(); 2262 break; 2263 case F_CONSOLE: 2264 case F_TTY: 2265 /* filter non-ASCII */ 2266 p = line; 2267 while (*p) { 2268 *p = FORCE2ASCII(*p); 2269 p++; 2270 } 2271 v->iov_base = line + tlsprefixlen + prilen; 2272 v->iov_len = linelen - tlsprefixlen - prilen; 2273 ADDEV(); 2274 v->iov_base = crnl; 2275 v->iov_len = 2; 2276 ADDEV(); 2277 break; 2278 case F_WALL: 2279 v->iov_base = greetings; 2280 v->iov_len = snprintf(greetings, sizeof(greetings), 2281 "\r\n\7Message from syslogd@%s at %s ...\r\n", 2282 (buffer->host ? buffer->host : buffer->recvhost), 2283 buffer->timestamp); 2284 ADDEV(); 2285 case F_USERS: /* fallthrough */ 2286 /* filter non-ASCII */ 2287 p = line; 2288 while (*p) { 2289 *p = FORCE2ASCII(*p); 2290 p++; 2291 } 2292 v->iov_base = line + tlsprefixlen + prilen; 2293 v->iov_len = linelen - tlsprefixlen - prilen; 2294 ADDEV(); 2295 v->iov_base = &crnl[1]; 2296 v->iov_len = 1; 2297 ADDEV(); 2298 break; 2299 } 2300 2301 /* send */ 2302 switch (f->f_type) { 2303 case F_UNUSED: 2304 DPRINTF(D_MISC, "Logging to %s\n", TypeInfo[f->f_type].name); 2305 break; 2306 2307 case F_FORW: 2308 DPRINTF(D_MISC, "Logging to %s %s\n", 2309 TypeInfo[f->f_type].name, f->f_un.f_forw.f_hname); 2310 udp_send(f, lineptr, len); 2311 break; 2312 2313 #ifndef DISABLE_TLS 2314 case F_TLS: 2315 DPRINTF(D_MISC, "Logging to %s %s\n", 2316 TypeInfo[f->f_type].name, 2317 f->f_un.f_tls.tls_conn->hostname); 2318 /* make sure every message gets queued once 2319 * it will be removed when sendmsg is sent and free()d */ 2320 if (!qentry) 2321 qentry = message_queue_add(f, NEWREF(buffer)); 2322 (void)tls_send(f, lineptr, len, qentry); 2323 break; 2324 #endif /* !DISABLE_TLS */ 2325 2326 case F_PIPE: 2327 DPRINTF(D_MISC, "Logging to %s %s\n", 2328 TypeInfo[f->f_type].name, f->f_un.f_pipe.f_pname); 2329 if (f->f_un.f_pipe.f_pid == 0) { 2330 /* (re-)open */ 2331 if ((f->f_file = p_open(f->f_un.f_pipe.f_pname, 2332 &f->f_un.f_pipe.f_pid)) < 0) { 2333 f->f_type = F_UNUSED; 2334 message_queue_freeall(f); 2335 logerror("%s", f->f_un.f_pipe.f_pname); 2336 break; 2337 } else if (!qentry) /* prevent recursion */ 2338 SEND_QUEUE(f); 2339 } 2340 if (writev(f->f_file, iov, v - iov) < 0) { 2341 e = errno; 2342 if (f->f_un.f_pipe.f_pid > 0) { 2343 (void) close(f->f_file); 2344 deadq_enter(f->f_un.f_pipe.f_pid, 2345 f->f_un.f_pipe.f_pname); 2346 } 2347 f->f_un.f_pipe.f_pid = 0; 2348 /* 2349 * If the error was EPIPE, then what is likely 2350 * has happened is we have a command that is 2351 * designed to take a single message line and 2352 * then exit, but we tried to feed it another 2353 * one before we reaped the child and thus 2354 * reset our state. 2355 * 2356 * Well, now we've reset our state, so try opening 2357 * the pipe and sending the message again if EPIPE 2358 * was the error. 2359 */ 2360 if (e == EPIPE) { 2361 if ((f->f_file = p_open(f->f_un.f_pipe.f_pname, 2362 &f->f_un.f_pipe.f_pid)) < 0) { 2363 f->f_type = F_UNUSED; 2364 message_queue_freeall(f); 2365 logerror("%s", f->f_un.f_pipe.f_pname); 2366 break; 2367 } 2368 if (writev(f->f_file, iov, v - iov) < 0) { 2369 e = errno; 2370 if (f->f_un.f_pipe.f_pid > 0) { 2371 (void) close(f->f_file); 2372 deadq_enter(f->f_un.f_pipe.f_pid, 2373 f->f_un.f_pipe.f_pname); 2374 } 2375 f->f_un.f_pipe.f_pid = 0; 2376 error = true; /* enqueue on return */ 2377 } else 2378 e = 0; 2379 } 2380 if (e != 0 && !error) { 2381 errno = e; 2382 logerror("%s", f->f_un.f_pipe.f_pname); 2383 } 2384 } 2385 if (e == 0 && qentry) { /* sent buffered msg */ 2386 message_queue_remove(f, qentry); 2387 } 2388 break; 2389 2390 case F_CONSOLE: 2391 if (buffer->flags & IGN_CONS) { 2392 DPRINTF(D_MISC, "Logging to %s (ignored)\n", 2393 TypeInfo[f->f_type].name); 2394 break; 2395 } 2396 /* FALLTHROUGH */ 2397 2398 case F_TTY: 2399 case F_FILE: 2400 DPRINTF(D_MISC, "Logging to %s %s\n", 2401 TypeInfo[f->f_type].name, f->f_un.f_fname); 2402 again: 2403 if (writev(f->f_file, iov, v - iov) < 0) { 2404 e = errno; 2405 if (f->f_type == F_FILE && e == ENOSPC) { 2406 int lasterror = f->f_lasterror; 2407 f->f_lasterror = e; 2408 if (lasterror != e) 2409 logerror("%s", f->f_un.f_fname); 2410 error = true; /* enqueue on return */ 2411 } 2412 (void)close(f->f_file); 2413 /* 2414 * Check for errors on TTY's due to loss of tty 2415 */ 2416 if ((e == EIO || e == EBADF) && f->f_type != F_FILE) { 2417 f->f_file = open(f->f_un.f_fname, 2418 O_WRONLY|O_APPEND, 0); 2419 if (f->f_file < 0) { 2420 f->f_type = F_UNUSED; 2421 logerror("%s", f->f_un.f_fname); 2422 message_queue_freeall(f); 2423 } else 2424 goto again; 2425 } else { 2426 f->f_type = F_UNUSED; 2427 errno = e; 2428 f->f_lasterror = e; 2429 logerror("%s", f->f_un.f_fname); 2430 message_queue_freeall(f); 2431 } 2432 } else { 2433 f->f_lasterror = 0; 2434 if ((buffer->flags & SYNC_FILE) 2435 && (f->f_flags & FFLAG_SYNC)) 2436 (void)fsync(f->f_file); 2437 /* Problem with files: We cannot check beforehand if 2438 * they would be writeable and call send_queue() first. 2439 * So we call send_queue() after a successful write, 2440 * which means the first message will be out of order. 2441 */ 2442 if (!qentry) /* prevent recursion */ 2443 SEND_QUEUE(f); 2444 else if (qentry) /* sent buffered msg */ 2445 message_queue_remove(f, qentry); 2446 } 2447 break; 2448 2449 case F_USERS: 2450 case F_WALL: 2451 DPRINTF(D_MISC, "Logging to %s\n", TypeInfo[f->f_type].name); 2452 wallmsg(f, iov, v - iov); 2453 break; 2454 } 2455 f->f_prevcount = 0; 2456 2457 if (error && !qentry) 2458 message_queue_add(f, NEWREF(buffer)); 2459 #ifndef DISABLE_SIGN 2460 if (newhash) { 2461 struct signature_group_t *sg; 2462 sg = sign_get_sg(buffer->pri, f); 2463 (void)sign_send_signature_block(sg, false); 2464 } 2465 #endif /* !DISABLE_SIGN */ 2466 /* this belongs to the ad-hoc buffer at the first if(buffer) */ 2467 DELREF(buffer); 2468 /* TLS frees on its own */ 2469 if (f->f_type != F_TLS) 2470 FREEPTR(line); 2471 } 2472 2473 /* send one line by UDP */ 2474 void 2475 udp_send(struct filed *f, char *line, size_t len) 2476 { 2477 int lsent, fail, retry, j; 2478 struct addrinfo *r; 2479 2480 DPRINTF((D_NET|D_CALL), "udp_send(f=%p, line=\"%s\", " 2481 "len=%zu) to dest.\n", f, line, len); 2482 2483 if (!finet) 2484 return; 2485 2486 lsent = -1; 2487 fail = 0; 2488 assert(f->f_type == F_FORW); 2489 for (r = f->f_un.f_forw.f_addr; r; r = r->ai_next) { 2490 retry = 0; 2491 for (j = 0; j < finet->fd; j++) { 2492 sendagain: 2493 lsent = sendto(finet[j+1].fd, line, len, 0, 2494 r->ai_addr, r->ai_addrlen); 2495 if (lsent == -1) { 2496 switch (errno) { 2497 case ENOBUFS: 2498 /* wait/retry/drop */ 2499 if (++retry < 5) { 2500 usleep(1000); 2501 goto sendagain; 2502 } 2503 break; 2504 case EHOSTDOWN: 2505 case EHOSTUNREACH: 2506 case ENETDOWN: 2507 /* drop */ 2508 break; 2509 default: 2510 /* busted */ 2511 fail++; 2512 break; 2513 } 2514 } else if ((size_t)lsent == len) 2515 break; 2516 } 2517 if ((size_t)lsent != len && fail) { 2518 f->f_type = F_UNUSED; 2519 logerror("sendto() failed"); 2520 } 2521 } 2522 } 2523 2524 /* 2525 * WALLMSG -- Write a message to the world at large 2526 * 2527 * Write the specified message to either the entire 2528 * world, or a list of approved users. 2529 */ 2530 void 2531 wallmsg(struct filed *f, struct iovec *iov, size_t iovcnt) 2532 { 2533 #ifdef __NetBSD_Version__ 2534 static int reenter; /* avoid calling ourselves */ 2535 int i; 2536 char *p; 2537 struct utmpentry *ep; 2538 2539 if (reenter++) 2540 return; 2541 2542 (void)getutentries(NULL, &ep); 2543 /* NOSTRICT */ 2544 for (; ep; ep = ep->next) { 2545 if (f->f_type == F_WALL) { 2546 if ((p = ttymsg(iov, iovcnt, ep->line, TTYMSGTIME)) 2547 != NULL) { 2548 errno = 0; /* already in msg */ 2549 logerror("%s", p); 2550 } 2551 continue; 2552 } 2553 /* should we send the message to this user? */ 2554 for (i = 0; i < MAXUNAMES; i++) { 2555 if (!f->f_un.f_uname[i][0]) 2556 break; 2557 if (strcmp(f->f_un.f_uname[i], ep->name) == 0) { 2558 if ((p = ttymsg(iov, iovcnt, ep->line, 2559 TTYMSGTIME)) != NULL) { 2560 errno = 0; /* already in msg */ 2561 logerror("%s", p); 2562 } 2563 break; 2564 } 2565 } 2566 } 2567 reenter = 0; 2568 #endif /* __NetBSD_Version__ */ 2569 } 2570 2571 void 2572 /*ARGSUSED*/ 2573 reapchild(int fd, short event, void *ev) 2574 { 2575 int status; 2576 pid_t pid; 2577 struct filed *f; 2578 2579 while ((pid = wait3(&status, WNOHANG, NULL)) > 0) { 2580 if (!Initialized || ShuttingDown) { 2581 /* 2582 * Be silent while we are initializing or 2583 * shutting down. 2584 */ 2585 continue; 2586 } 2587 2588 if (deadq_remove(pid)) 2589 continue; 2590 2591 /* Now, look in the list of active processes. */ 2592 for (f = Files; f != NULL; f = f->f_next) { 2593 if (f->f_type == F_PIPE && 2594 f->f_un.f_pipe.f_pid == pid) { 2595 (void) close(f->f_file); 2596 f->f_un.f_pipe.f_pid = 0; 2597 log_deadchild(pid, status, 2598 f->f_un.f_pipe.f_pname); 2599 break; 2600 } 2601 } 2602 } 2603 } 2604 2605 /* 2606 * Return a printable representation of a host address (FQDN if available) 2607 */ 2608 const char * 2609 cvthname(struct sockaddr_storage *f) 2610 { 2611 int error; 2612 int niflag = NI_DGRAM; 2613 static char host[NI_MAXHOST], ip[NI_MAXHOST]; 2614 2615 error = getnameinfo((struct sockaddr*)f, ((struct sockaddr*)f)->sa_len, 2616 ip, sizeof ip, NULL, 0, NI_NUMERICHOST|niflag); 2617 2618 DPRINTF(D_CALL, "cvthname(%s)\n", ip); 2619 2620 if (error) { 2621 DPRINTF(D_NET, "Malformed from address %s\n", 2622 gai_strerror(error)); 2623 return "???"; 2624 } 2625 2626 if (!UseNameService) 2627 return ip; 2628 2629 error = getnameinfo((struct sockaddr*)f, ((struct sockaddr*)f)->sa_len, 2630 host, sizeof host, NULL, 0, niflag); 2631 if (error) { 2632 DPRINTF(D_NET, "Host name for your address (%s) unknown\n", ip); 2633 return ip; 2634 } 2635 2636 return host; 2637 } 2638 2639 void 2640 trim_anydomain(char *host) 2641 { 2642 bool onlydigits = true; 2643 int i; 2644 2645 if (!BSDOutputFormat) 2646 return; 2647 2648 /* if non-digits found, then assume hostname and cut at first dot (this 2649 * case also covers IPv6 addresses which should not contain dots), 2650 * if only digits then assume IPv4 address and do not cut at all */ 2651 for (i = 0; host[i]; i++) { 2652 if (host[i] == '.' && !onlydigits) 2653 host[i] = '\0'; 2654 else if (!isdigit((unsigned char)host[i]) && host[i] != '.') 2655 onlydigits = false; 2656 } 2657 } 2658 2659 static void 2660 /*ARGSUSED*/ 2661 domark(int fd, short event, void *ev) 2662 { 2663 struct event *ev_pass = (struct event *)ev; 2664 struct filed *f; 2665 dq_t q, nextq; 2666 sigset_t newmask, omask; 2667 2668 schedule_event(&ev_pass, 2669 &((struct timeval){TIMERINTVL, 0}), 2670 domark, ev_pass); 2671 DPRINTF((D_CALL|D_EVENT), "domark()\n"); 2672 2673 BLOCK_SIGNALS(omask, newmask); 2674 now = time((time_t *)NULL); 2675 MarkSeq += TIMERINTVL; 2676 if (MarkSeq >= MarkInterval) { 2677 logmsg_async(LOG_INFO, NULL, "-- MARK --", ADDDATE|MARK); 2678 MarkSeq = 0; 2679 } 2680 2681 for (f = Files; f; f = f->f_next) { 2682 if (f->f_prevcount && now >= REPEATTIME(f)) { 2683 DPRINTF(D_DATA, "Flush %s: repeated %d times, %d sec.\n", 2684 TypeInfo[f->f_type].name, f->f_prevcount, 2685 repeatinterval[f->f_repeatcount]); 2686 fprintlog(f, NULL, NULL); 2687 BACKOFF(f); 2688 } 2689 } 2690 message_allqueues_check(); 2691 RESTORE_SIGNALS(omask); 2692 2693 /* Walk the dead queue, and see if we should signal somebody. */ 2694 for (q = TAILQ_FIRST(&deadq_head); q != NULL; q = nextq) { 2695 nextq = TAILQ_NEXT(q, dq_entries); 2696 switch (q->dq_timeout) { 2697 case 0: 2698 /* Already signalled once, try harder now. */ 2699 if (kill(q->dq_pid, SIGKILL) != 0) 2700 (void) deadq_remove(q->dq_pid); 2701 break; 2702 2703 case 1: 2704 /* 2705 * Timed out on the dead queue, send terminate 2706 * signal. Note that we leave the removal from 2707 * the dead queue to reapchild(), which will 2708 * also log the event (unless the process 2709 * didn't even really exist, in case we simply 2710 * drop it from the dead queue). 2711 */ 2712 if (kill(q->dq_pid, SIGTERM) != 0) { 2713 (void) deadq_remove(q->dq_pid); 2714 break; 2715 } 2716 /* FALLTHROUGH */ 2717 2718 default: 2719 q->dq_timeout--; 2720 } 2721 } 2722 #ifndef DISABLE_SIGN 2723 if (GlobalSign.rsid) { /* check if initialized */ 2724 struct signature_group_t *sg; 2725 STAILQ_FOREACH(sg, &GlobalSign.SigGroups, entries) { 2726 sign_send_certificate_block(sg); 2727 } 2728 } 2729 #endif /* !DISABLE_SIGN */ 2730 } 2731 2732 /* 2733 * Print syslogd errors some place. 2734 */ 2735 void 2736 logerror(const char *fmt, ...) 2737 { 2738 static int logerror_running; 2739 va_list ap; 2740 char tmpbuf[BUFSIZ]; 2741 char buf[BUFSIZ]; 2742 char *outbuf; 2743 2744 /* If there's an error while trying to log an error, give up. */ 2745 if (logerror_running) 2746 return; 2747 logerror_running = 1; 2748 2749 va_start(ap, fmt); 2750 (void)vsnprintf(tmpbuf, sizeof(tmpbuf), fmt, ap); 2751 va_end(ap); 2752 2753 if (errno) { 2754 (void)snprintf(buf, sizeof(buf), "%s: %s", 2755 tmpbuf, strerror(errno)); 2756 outbuf = buf; 2757 } else { 2758 (void)snprintf(buf, sizeof(buf), "%s", tmpbuf); 2759 outbuf = tmpbuf; 2760 } 2761 2762 if (daemonized) 2763 logmsg_async(LOG_SYSLOG|LOG_ERR, NULL, outbuf, ADDDATE); 2764 if (!daemonized && Debug) 2765 DPRINTF(D_MISC, "%s\n", outbuf); 2766 if (!daemonized && !Debug) 2767 printf("%s\n", outbuf); 2768 2769 logerror_running = 0; 2770 } 2771 2772 /* 2773 * Print syslogd info some place. 2774 */ 2775 void 2776 loginfo(const char *fmt, ...) 2777 { 2778 va_list ap; 2779 char buf[BUFSIZ]; 2780 2781 va_start(ap, fmt); 2782 (void)vsnprintf(buf, sizeof(buf), fmt, ap); 2783 va_end(ap); 2784 2785 DPRINTF(D_MISC, "%s\n", buf); 2786 logmsg_async(LOG_SYSLOG|LOG_INFO, NULL, buf, ADDDATE); 2787 } 2788 2789 #ifndef DISABLE_TLS 2790 static inline void 2791 free_incoming_tls_sockets(void) 2792 { 2793 struct TLS_Incoming_Conn *tls_in; 2794 int i; 2795 2796 /* 2797 * close all listening and connected TLS sockets 2798 */ 2799 if (TLS_Listen_Set) 2800 for (i = 0; i < TLS_Listen_Set->fd; i++) { 2801 if (close(TLS_Listen_Set[i+1].fd) == -1) 2802 logerror("close() failed"); 2803 DEL_EVENT(TLS_Listen_Set[i+1].ev); 2804 FREEPTR(TLS_Listen_Set[i+1].ev); 2805 } 2806 FREEPTR(TLS_Listen_Set); 2807 /* close/free incoming TLS connections */ 2808 while (!SLIST_EMPTY(&TLS_Incoming_Head)) { 2809 tls_in = SLIST_FIRST(&TLS_Incoming_Head); 2810 SLIST_REMOVE_HEAD(&TLS_Incoming_Head, entries); 2811 FREEPTR(tls_in->inbuf); 2812 free_tls_conn(tls_in->tls_conn); 2813 free(tls_in); 2814 } 2815 } 2816 #endif /* !DISABLE_TLS */ 2817 2818 void 2819 /*ARGSUSED*/ 2820 die(int fd, short event, void *ev) 2821 { 2822 struct filed *f, *next; 2823 char **p; 2824 sigset_t newmask, omask; 2825 int i; 2826 size_t j; 2827 2828 ShuttingDown = 1; /* Don't log SIGCHLDs. */ 2829 /* prevent recursive signals */ 2830 BLOCK_SIGNALS(omask, newmask); 2831 2832 errno = 0; 2833 if (ev != NULL) 2834 logerror("Exiting on signal %d", fd); 2835 else 2836 logerror("Fatal error, exiting"); 2837 2838 /* 2839 * flush any pending output 2840 */ 2841 for (f = Files; f != NULL; f = f->f_next) { 2842 /* flush any pending output */ 2843 if (f->f_prevcount) 2844 fprintlog(f, NULL, NULL); 2845 SEND_QUEUE(f); 2846 } 2847 2848 #ifndef DISABLE_TLS 2849 free_incoming_tls_sockets(); 2850 #endif /* !DISABLE_TLS */ 2851 #ifndef DISABLE_SIGN 2852 sign_global_free(); 2853 #endif /* !DISABLE_SIGN */ 2854 2855 /* 2856 * Close all open log files. 2857 */ 2858 for (f = Files; f != NULL; f = next) { 2859 message_queue_freeall(f); 2860 2861 switch (f->f_type) { 2862 case F_FILE: 2863 case F_TTY: 2864 case F_CONSOLE: 2865 (void)close(f->f_file); 2866 break; 2867 case F_PIPE: 2868 if (f->f_un.f_pipe.f_pid > 0) { 2869 (void)close(f->f_file); 2870 } 2871 f->f_un.f_pipe.f_pid = 0; 2872 break; 2873 case F_FORW: 2874 if (f->f_un.f_forw.f_addr) 2875 freeaddrinfo(f->f_un.f_forw.f_addr); 2876 break; 2877 #ifndef DISABLE_TLS 2878 case F_TLS: 2879 free_tls_conn(f->f_un.f_tls.tls_conn); 2880 break; 2881 #endif /* !DISABLE_TLS */ 2882 } 2883 next = f->f_next; 2884 DELREF(f->f_prevmsg); 2885 FREEPTR(f->f_program); 2886 FREEPTR(f->f_host); 2887 DEL_EVENT(f->f_sq_event); 2888 free((char *)f); 2889 } 2890 2891 /* 2892 * Close all open UDP sockets 2893 */ 2894 if (finet) { 2895 for (i = 0; i < finet->fd; i++) { 2896 if (close(finet[i+1].fd) < 0) { 2897 logerror("close() failed"); 2898 die(0, 0, NULL); 2899 } 2900 DEL_EVENT(finet[i+1].ev); 2901 FREEPTR(finet[i+1].ev); 2902 } 2903 FREEPTR(finet); 2904 } 2905 2906 /* free config options */ 2907 for (j = 0; j < A_CNT(TypeInfo); j++) { 2908 FREEPTR(TypeInfo[j].queue_length_string); 2909 FREEPTR(TypeInfo[j].queue_size_string); 2910 } 2911 2912 #ifndef DISABLE_TLS 2913 FREEPTR(tls_opt.CAdir); 2914 FREEPTR(tls_opt.CAfile); 2915 FREEPTR(tls_opt.keyfile); 2916 FREEPTR(tls_opt.certfile); 2917 FREEPTR(tls_opt.x509verify); 2918 FREEPTR(tls_opt.bindhost); 2919 FREEPTR(tls_opt.bindport); 2920 FREEPTR(tls_opt.server); 2921 FREEPTR(tls_opt.gen_cert); 2922 free_cred_SLIST(&tls_opt.cert_head); 2923 free_cred_SLIST(&tls_opt.fprint_head); 2924 FREE_SSL_CTX(tls_opt.global_TLS_CTX); 2925 #endif /* !DISABLE_TLS */ 2926 2927 FREEPTR(funix); 2928 for (p = LogPaths; p && *p; p++) 2929 unlink(*p); 2930 exit(0); 2931 } 2932 2933 #ifndef DISABLE_SIGN 2934 /* 2935 * get one "sign_delim_sg2" item, convert and store in ordered queue 2936 */ 2937 void 2938 store_sign_delim_sg2(char *tmp_buf) 2939 { 2940 struct string_queue *sqentry, *sqe1, *sqe2; 2941 2942 if(!(sqentry = malloc(sizeof(*sqentry)))) { 2943 logerror("Unable to allocate memory"); 2944 return; 2945 } 2946 /*LINTED constcond/null effect */ 2947 assert(sizeof(int64_t) == sizeof(uint_fast64_t)); 2948 if (dehumanize_number(tmp_buf, (int64_t*) &(sqentry->key)) == -1 2949 || sqentry->key > (LOG_NFACILITIES<<3)) { 2950 DPRINTF(D_PARSE, "invalid sign_delim_sg2: %s\n", tmp_buf); 2951 free(sqentry); 2952 FREEPTR(tmp_buf); 2953 return; 2954 } 2955 sqentry->data = tmp_buf; 2956 2957 if (STAILQ_EMPTY(&GlobalSign.sig2_delims)) { 2958 STAILQ_INSERT_HEAD(&GlobalSign.sig2_delims, 2959 sqentry, entries); 2960 return; 2961 } 2962 2963 /* keep delimiters sorted */ 2964 sqe1 = sqe2 = STAILQ_FIRST(&GlobalSign.sig2_delims); 2965 if (sqe1->key > sqentry->key) { 2966 STAILQ_INSERT_HEAD(&GlobalSign.sig2_delims, 2967 sqentry, entries); 2968 return; 2969 } 2970 2971 while ((sqe1 = sqe2) 2972 && (sqe2 = STAILQ_NEXT(sqe1, entries))) { 2973 if (sqe2->key > sqentry->key) { 2974 break; 2975 } else if (sqe2->key == sqentry->key) { 2976 DPRINTF(D_PARSE, "duplicate sign_delim_sg2: %s\n", 2977 tmp_buf); 2978 FREEPTR(sqentry); 2979 FREEPTR(tmp_buf); 2980 return; 2981 } 2982 } 2983 STAILQ_INSERT_AFTER(&GlobalSign.sig2_delims, sqe1, sqentry, entries); 2984 } 2985 #endif /* !DISABLE_SIGN */ 2986 2987 /* 2988 * read syslog.conf 2989 */ 2990 void 2991 read_config_file(FILE *cf, struct filed **f_ptr) 2992 { 2993 size_t linenum = 0; 2994 size_t i; 2995 struct filed *f, **nextp; 2996 char cline[LINE_MAX]; 2997 char prog[NAME_MAX + 1]; 2998 char host[MAXHOSTNAMELEN]; 2999 const char *p; 3000 char *q; 3001 bool found_keyword; 3002 #ifndef DISABLE_TLS 3003 struct peer_cred *cred = NULL; 3004 struct peer_cred_head *credhead = NULL; 3005 #endif /* !DISABLE_TLS */ 3006 #ifndef DISABLE_SIGN 3007 char *sign_sg_str = NULL; 3008 #endif /* !DISABLE_SIGN */ 3009 #if (!defined(DISABLE_TLS) || !defined(DISABLE_SIGN)) 3010 char *tmp_buf = NULL; 3011 #endif /* (!defined(DISABLE_TLS) || !defined(DISABLE_SIGN)) */ 3012 /* central list of recognized configuration keywords 3013 * and an address for their values as strings */ 3014 const struct config_keywords { 3015 const char *keyword; 3016 char **variable; 3017 } config_keywords[] = { 3018 #ifndef DISABLE_TLS 3019 /* TLS settings */ 3020 {"tls_ca", &tls_opt.CAfile}, 3021 {"tls_cadir", &tls_opt.CAdir}, 3022 {"tls_cert", &tls_opt.certfile}, 3023 {"tls_key", &tls_opt.keyfile}, 3024 {"tls_verify", &tls_opt.x509verify}, 3025 {"tls_bindport", &tls_opt.bindport}, 3026 {"tls_bindhost", &tls_opt.bindhost}, 3027 {"tls_server", &tls_opt.server}, 3028 {"tls_gen_cert", &tls_opt.gen_cert}, 3029 /* special cases in parsing */ 3030 {"tls_allow_fingerprints",&tmp_buf}, 3031 {"tls_allow_clientcerts", &tmp_buf}, 3032 /* buffer settings */ 3033 {"tls_queue_length", &TypeInfo[F_TLS].queue_length_string}, 3034 {"tls_queue_size", &TypeInfo[F_TLS].queue_size_string}, 3035 #endif /* !DISABLE_TLS */ 3036 {"file_queue_length", &TypeInfo[F_FILE].queue_length_string}, 3037 {"pipe_queue_length", &TypeInfo[F_PIPE].queue_length_string}, 3038 {"file_queue_size", &TypeInfo[F_FILE].queue_size_string}, 3039 {"pipe_queue_size", &TypeInfo[F_PIPE].queue_size_string}, 3040 #ifndef DISABLE_SIGN 3041 /* syslog-sign setting */ 3042 {"sign_sg", &sign_sg_str}, 3043 /* also special case in parsing */ 3044 {"sign_delim_sg2", &tmp_buf}, 3045 #endif /* !DISABLE_SIGN */ 3046 }; 3047 3048 DPRINTF(D_CALL, "read_config_file()\n"); 3049 3050 /* free all previous config options */ 3051 for (i = 0; i < A_CNT(TypeInfo); i++) { 3052 if (TypeInfo[i].queue_length_string 3053 && TypeInfo[i].queue_length_string 3054 != TypeInfo[i].default_length_string) { 3055 FREEPTR(TypeInfo[i].queue_length_string); 3056 TypeInfo[i].queue_length_string = 3057 strdup(TypeInfo[i].default_length_string); 3058 } 3059 if (TypeInfo[i].queue_size_string 3060 && TypeInfo[i].queue_size_string 3061 != TypeInfo[i].default_size_string) { 3062 FREEPTR(TypeInfo[i].queue_size_string); 3063 TypeInfo[i].queue_size_string = 3064 strdup(TypeInfo[i].default_size_string); 3065 } 3066 } 3067 for (i = 0; i < A_CNT(config_keywords); i++) 3068 FREEPTR(*config_keywords[i].variable); 3069 /* 3070 * global settings 3071 */ 3072 while (fgets(cline, sizeof(cline), cf) != NULL) { 3073 linenum++; 3074 for (p = cline; isspace((unsigned char)*p); ++p) 3075 continue; 3076 if ((*p == '\0') || (*p == '#')) 3077 continue; 3078 3079 for (i = 0; i < A_CNT(config_keywords); i++) { 3080 if (copy_config_value(config_keywords[i].keyword, 3081 config_keywords[i].variable, &p, ConfFile, 3082 linenum)) { 3083 DPRINTF((D_PARSE|D_MEM), 3084 "found option %s, saved @%p\n", 3085 config_keywords[i].keyword, 3086 *config_keywords[i].variable); 3087 #ifndef DISABLE_SIGN 3088 if (!strcmp("sign_delim_sg2", 3089 config_keywords[i].keyword)) 3090 do { 3091 store_sign_delim_sg2(tmp_buf); 3092 } while (copy_config_value_word( 3093 &tmp_buf, &p)); 3094 3095 #endif /* !DISABLE_SIGN */ 3096 3097 #ifndef DISABLE_TLS 3098 /* special cases with multiple parameters */ 3099 if (!strcmp("tls_allow_fingerprints", 3100 config_keywords[i].keyword)) 3101 credhead = &tls_opt.fprint_head; 3102 else if (!strcmp("tls_allow_clientcerts", 3103 config_keywords[i].keyword)) 3104 credhead = &tls_opt.cert_head; 3105 3106 if (credhead) do { 3107 if(!(cred = malloc(sizeof(*cred)))) { 3108 logerror("Unable to " 3109 "allocate memory"); 3110 break; 3111 } 3112 cred->data = tmp_buf; 3113 tmp_buf = NULL; 3114 SLIST_INSERT_HEAD(credhead, 3115 cred, entries); 3116 } while /* additional values? */ 3117 (copy_config_value_word(&tmp_buf, &p)); 3118 credhead = NULL; 3119 break; 3120 #endif /* !DISABLE_TLS */ 3121 } 3122 } 3123 } 3124 /* convert strings to integer values */ 3125 for (i = 0; i < A_CNT(TypeInfo); i++) { 3126 if (!TypeInfo[i].queue_length_string 3127 || dehumanize_number(TypeInfo[i].queue_length_string, 3128 &TypeInfo[i].queue_length) == -1) 3129 TypeInfo[i].queue_length = strtol( 3130 TypeInfo[i].default_length_string, NULL, 10); 3131 if (!TypeInfo[i].queue_size_string 3132 || dehumanize_number(TypeInfo[i].queue_size_string, 3133 &TypeInfo[i].queue_size) == -1) 3134 TypeInfo[i].queue_size = strtol( 3135 TypeInfo[i].default_size_string, NULL, 10); 3136 } 3137 3138 #ifndef DISABLE_SIGN 3139 if (sign_sg_str) { 3140 if (sign_sg_str[1] == '\0' 3141 && (sign_sg_str[0] == '0' || sign_sg_str[0] == '1' 3142 || sign_sg_str[0] == '2' || sign_sg_str[0] == '3')) 3143 GlobalSign.sg = sign_sg_str[0] - '0'; 3144 else { 3145 GlobalSign.sg = SIGN_SG; 3146 DPRINTF(D_MISC, "Invalid sign_sg value `%s', " 3147 "use default value `%d'\n", 3148 sign_sg_str, GlobalSign.sg); 3149 } 3150 } else /* disable syslog-sign */ 3151 GlobalSign.sg = -1; 3152 #endif /* !DISABLE_SIGN */ 3153 3154 rewind(cf); 3155 linenum = 0; 3156 /* 3157 * Foreach line in the conf table, open that file. 3158 */ 3159 f = NULL; 3160 nextp = &f; 3161 3162 strcpy(prog, "*"); 3163 strcpy(host, "*"); 3164 while (fgets(cline, sizeof(cline), cf) != NULL) { 3165 linenum++; 3166 found_keyword = false; 3167 /* 3168 * check for end-of-section, comments, strip off trailing 3169 * spaces and newline character. #!prog is treated specially: 3170 * following lines apply only to that program. 3171 */ 3172 for (p = cline; isspace((unsigned char)*p); ++p) 3173 continue; 3174 if (*p == '\0') 3175 continue; 3176 if (*p == '#') { 3177 p++; 3178 if (*p != '!' && *p != '+' && *p != '-') 3179 continue; 3180 } 3181 3182 for (i = 0; i < A_CNT(config_keywords); i++) { 3183 if (!strncasecmp(p, config_keywords[i].keyword, 3184 strlen(config_keywords[i].keyword))) { 3185 DPRINTF(D_PARSE, 3186 "skip cline %zu with keyword %s\n", 3187 linenum, config_keywords[i].keyword); 3188 found_keyword = true; 3189 } 3190 } 3191 if (found_keyword) 3192 continue; 3193 3194 if (*p == '+' || *p == '-') { 3195 host[0] = *p++; 3196 while (isspace((unsigned char)*p)) 3197 p++; 3198 if (*p == '\0' || *p == '*') { 3199 strcpy(host, "*"); 3200 continue; 3201 } 3202 /* the +hostname expression will continue 3203 * to use the LocalHostName, not the FQDN */ 3204 for (i = 1; i < MAXHOSTNAMELEN - 1; i++) { 3205 if (*p == '@') { 3206 (void)strncpy(&host[i], LocalHostName, 3207 sizeof(host) - 1 - i); 3208 host[sizeof(host) - 1] = '\0'; 3209 i = strlen(host) - 1; 3210 p++; 3211 continue; 3212 } 3213 if (!isalnum((unsigned char)*p) && 3214 *p != '.' && *p != '-' && *p != ',') 3215 break; 3216 host[i] = *p++; 3217 } 3218 host[i] = '\0'; 3219 continue; 3220 } 3221 if (*p == '!') { 3222 p++; 3223 while (isspace((unsigned char)*p)) 3224 p++; 3225 if (*p == '\0' || *p == '*') { 3226 strcpy(prog, "*"); 3227 continue; 3228 } 3229 for (i = 0; i < NAME_MAX; i++) { 3230 if (!isprint((unsigned char)p[i])) 3231 break; 3232 prog[i] = p[i]; 3233 } 3234 prog[i] = '\0'; 3235 continue; 3236 } 3237 for (q = strchr(cline, '\0'); isspace((unsigned char)*--q);) 3238 continue; 3239 *++q = '\0'; 3240 if ((f = calloc(1, sizeof(*f))) == NULL) { 3241 logerror("alloc failed"); 3242 die(0, 0, NULL); 3243 } 3244 if (!*f_ptr) *f_ptr = f; /* return first node */ 3245 *nextp = f; 3246 nextp = &f->f_next; 3247 cfline(linenum, cline, f, prog, host); 3248 } 3249 } 3250 3251 /* 3252 * INIT -- Initialize syslogd from configuration table 3253 */ 3254 void 3255 /*ARGSUSED*/ 3256 init(int fd, short event, void *ev) 3257 { 3258 FILE *cf; 3259 int i; 3260 struct filed *f, *newf, **nextp, *f2; 3261 char *p; 3262 sigset_t newmask, omask; 3263 #ifndef DISABLE_TLS 3264 char *tls_status_msg = NULL; 3265 struct peer_cred *cred = NULL; 3266 #endif /* !DISABLE_TLS */ 3267 3268 /* prevent recursive signals */ 3269 BLOCK_SIGNALS(omask, newmask); 3270 3271 DPRINTF((D_EVENT|D_CALL), "init\n"); 3272 3273 /* 3274 * be careful about dependencies and order of actions: 3275 * 1. flush buffer queues 3276 * 2. flush -sign SBs 3277 * 3. flush/delete buffer queue again, in case an SB got there 3278 * 4. close files/connections 3279 */ 3280 3281 /* 3282 * flush any pending output 3283 */ 3284 for (f = Files; f != NULL; f = f->f_next) { 3285 /* flush any pending output */ 3286 if (f->f_prevcount) 3287 fprintlog(f, NULL, NULL); 3288 SEND_QUEUE(f); 3289 } 3290 /* some actions only on SIGHUP and not on first start */ 3291 if (Initialized) { 3292 #ifndef DISABLE_SIGN 3293 sign_global_free(); 3294 #endif /* !DISABLE_SIGN */ 3295 #ifndef DISABLE_TLS 3296 free_incoming_tls_sockets(); 3297 #endif /* !DISABLE_TLS */ 3298 Initialized = 0; 3299 } 3300 /* 3301 * Close all open log files. 3302 */ 3303 for (f = Files; f != NULL; f = f->f_next) { 3304 switch (f->f_type) { 3305 case F_FILE: 3306 case F_TTY: 3307 case F_CONSOLE: 3308 (void)close(f->f_file); 3309 break; 3310 case F_PIPE: 3311 if (f->f_un.f_pipe.f_pid > 0) { 3312 (void)close(f->f_file); 3313 deadq_enter(f->f_un.f_pipe.f_pid, 3314 f->f_un.f_pipe.f_pname); 3315 } 3316 f->f_un.f_pipe.f_pid = 0; 3317 break; 3318 case F_FORW: 3319 if (f->f_un.f_forw.f_addr) 3320 freeaddrinfo(f->f_un.f_forw.f_addr); 3321 break; 3322 #ifndef DISABLE_TLS 3323 case F_TLS: 3324 free_tls_sslptr(f->f_un.f_tls.tls_conn); 3325 break; 3326 #endif /* !DISABLE_TLS */ 3327 } 3328 } 3329 3330 /* 3331 * Close all open UDP sockets 3332 */ 3333 if (finet) { 3334 for (i = 0; i < finet->fd; i++) { 3335 if (close(finet[i+1].fd) < 0) { 3336 logerror("close() failed"); 3337 die(0, 0, NULL); 3338 } 3339 DEL_EVENT(finet[i+1].ev); 3340 FREEPTR(finet[i+1].ev); 3341 } 3342 FREEPTR(finet); 3343 } 3344 3345 /* get FQDN and hostname/domain */ 3346 FREEPTR(oldLocalFQDN); 3347 oldLocalFQDN = LocalFQDN; 3348 LocalFQDN = getLocalFQDN(); 3349 if ((p = strchr(LocalFQDN, '.')) != NULL) 3350 (void)strlcpy(LocalHostName, LocalFQDN, 1+p-LocalFQDN); 3351 else 3352 (void)strlcpy(LocalHostName, LocalFQDN, sizeof(LocalHostName)); 3353 3354 /* 3355 * Reset counter of forwarding actions 3356 */ 3357 3358 NumForwards=0; 3359 3360 /* new destination list to replace Files */ 3361 newf = NULL; 3362 nextp = &newf; 3363 3364 /* open the configuration file */ 3365 if ((cf = fopen(ConfFile, "r")) == NULL) { 3366 DPRINTF(D_FILE, "Cannot open `%s'\n", ConfFile); 3367 *nextp = (struct filed *)calloc(1, sizeof(*f)); 3368 cfline(0, "*.ERR\t/dev/console", *nextp, "*", "*"); 3369 (*nextp)->f_next = (struct filed *)calloc(1, sizeof(*f)); 3370 cfline(0, "*.PANIC\t*", (*nextp)->f_next, "*", "*"); 3371 Initialized = 1; 3372 RESTORE_SIGNALS(omask); 3373 return; 3374 } 3375 3376 #ifndef DISABLE_TLS 3377 /* init with new TLS_CTX 3378 * as far as I see one cannot change the cert/key of an existing CTX 3379 */ 3380 FREE_SSL_CTX(tls_opt.global_TLS_CTX); 3381 3382 free_cred_SLIST(&tls_opt.cert_head); 3383 free_cred_SLIST(&tls_opt.fprint_head); 3384 #endif /* !DISABLE_TLS */ 3385 3386 /* read and close configuration file */ 3387 read_config_file(cf, &newf); 3388 newf = *nextp; 3389 (void)fclose(cf); 3390 DPRINTF(D_MISC, "read_config_file() returned newf=%p\n", newf); 3391 3392 #define MOVE_QUEUE(dst, src) do { \ 3393 struct buf_queue *buf; \ 3394 STAILQ_CONCAT(&dst->f_qhead, &src->f_qhead); \ 3395 STAILQ_FOREACH(buf, &dst->f_qhead, entries) { \ 3396 dst->f_qelements++; \ 3397 dst->f_qsize += buf_queue_obj_size(buf); \ 3398 } \ 3399 src->f_qsize = 0; \ 3400 src->f_qelements = 0; \ 3401 } while (/*CONSTCOND*/0) 3402 3403 /* 3404 * Free old log files. 3405 */ 3406 for (f = Files; f != NULL;) { 3407 struct filed *ftmp; 3408 3409 /* check if a new logfile is equal, if so pass the queue */ 3410 for (f2 = newf; f2 != NULL; f2 = f2->f_next) { 3411 if (f->f_type == f2->f_type 3412 && ((f->f_type == F_PIPE 3413 && !strcmp(f->f_un.f_pipe.f_pname, 3414 f2->f_un.f_pipe.f_pname)) 3415 #ifndef DISABLE_TLS 3416 || (f->f_type == F_TLS 3417 && !strcmp(f->f_un.f_tls.tls_conn->hostname, 3418 f2->f_un.f_tls.tls_conn->hostname) 3419 && !strcmp(f->f_un.f_tls.tls_conn->port, 3420 f2->f_un.f_tls.tls_conn->port)) 3421 #endif /* !DISABLE_TLS */ 3422 || (f->f_type == F_FORW 3423 && !strcmp(f->f_un.f_forw.f_hname, 3424 f2->f_un.f_forw.f_hname)))) { 3425 DPRINTF(D_BUFFER, "move queue from f@%p " 3426 "to f2@%p\n", f, f2); 3427 MOVE_QUEUE(f2, f); 3428 } 3429 } 3430 message_queue_freeall(f); 3431 DELREF(f->f_prevmsg); 3432 #ifndef DISABLE_TLS 3433 if (f->f_type == F_TLS) 3434 free_tls_conn(f->f_un.f_tls.tls_conn); 3435 #endif /* !DISABLE_TLS */ 3436 FREEPTR(f->f_program); 3437 FREEPTR(f->f_host); 3438 DEL_EVENT(f->f_sq_event); 3439 3440 ftmp = f->f_next; 3441 free((char *)f); 3442 f = ftmp; 3443 } 3444 Files = newf; 3445 Initialized = 1; 3446 3447 if (Debug) { 3448 for (f = Files; f; f = f->f_next) { 3449 for (i = 0; i <= LOG_NFACILITIES; i++) 3450 if (f->f_pmask[i] == INTERNAL_NOPRI) 3451 printf("X "); 3452 else 3453 printf("%d ", f->f_pmask[i]); 3454 printf("%s: ", TypeInfo[f->f_type].name); 3455 switch (f->f_type) { 3456 case F_FILE: 3457 case F_TTY: 3458 case F_CONSOLE: 3459 printf("%s", f->f_un.f_fname); 3460 break; 3461 3462 case F_FORW: 3463 printf("%s", f->f_un.f_forw.f_hname); 3464 break; 3465 #ifndef DISABLE_TLS 3466 case F_TLS: 3467 printf("[%s]", f->f_un.f_tls.tls_conn->hostname); 3468 break; 3469 #endif /* !DISABLE_TLS */ 3470 case F_PIPE: 3471 printf("%s", f->f_un.f_pipe.f_pname); 3472 break; 3473 3474 case F_USERS: 3475 for (i = 0; 3476 i < MAXUNAMES && *f->f_un.f_uname[i]; i++) 3477 printf("%s, ", f->f_un.f_uname[i]); 3478 break; 3479 } 3480 if (f->f_program != NULL) 3481 printf(" (%s)", f->f_program); 3482 printf("\n"); 3483 } 3484 } 3485 3486 finet = socksetup(PF_UNSPEC, bindhostname); 3487 if (finet) { 3488 if (SecureMode) { 3489 for (i = 0; i < finet->fd; i++) { 3490 if (shutdown(finet[i+1].fd, SHUT_RD) < 0) { 3491 logerror("shutdown() failed"); 3492 die(0, 0, NULL); 3493 } 3494 } 3495 } else 3496 DPRINTF(D_NET, "Listening on inet and/or inet6 socket\n"); 3497 DPRINTF(D_NET, "Sending on inet and/or inet6 socket\n"); 3498 } 3499 3500 #ifndef DISABLE_TLS 3501 /* TLS setup -- after all local destinations opened */ 3502 DPRINTF(D_PARSE, "Parsed options: tls_ca: %s, tls_cadir: %s, " 3503 "tls_cert: %s, tls_key: %s, tls_verify: %s, " 3504 "bind: %s:%s, max. queue_lengths: %" 3505 PRId64 ", %" PRId64 ", %" PRId64 ", " 3506 "max. queue_sizes: %" 3507 PRId64 ", %" PRId64 ", %" PRId64 "\n", 3508 tls_opt.CAfile, tls_opt.CAdir, 3509 tls_opt.certfile, tls_opt.keyfile, tls_opt.x509verify, 3510 tls_opt.bindhost, tls_opt.bindport, 3511 TypeInfo[F_TLS].queue_length, TypeInfo[F_FILE].queue_length, 3512 TypeInfo[F_PIPE].queue_length, 3513 TypeInfo[F_TLS].queue_size, TypeInfo[F_FILE].queue_size, 3514 TypeInfo[F_PIPE].queue_size); 3515 SLIST_FOREACH(cred, &tls_opt.cert_head, entries) { 3516 DPRINTF(D_PARSE, "Accepting peer certificate " 3517 "from file: \"%s\"\n", cred->data); 3518 } 3519 SLIST_FOREACH(cred, &tls_opt.fprint_head, entries) { 3520 DPRINTF(D_PARSE, "Accepting peer certificate with " 3521 "fingerprint: \"%s\"\n", cred->data); 3522 } 3523 3524 /* Note: The order of initialization is important because syslog-sign 3525 * should use the TLS cert for signing. -- So we check first if TLS 3526 * will be used and initialize it before starting -sign. 3527 * 3528 * This means that if we are a client without TLS destinations TLS 3529 * will not be initialized and syslog-sign will generate a new key. 3530 * -- Even if the user has set a usable tls_cert. 3531 * Is this the expected behaviour? The alternative would be to always 3532 * initialize the TLS structures, even if they will not be needed 3533 * (or only needed to read the DSA key for -sign). 3534 */ 3535 3536 /* Initialize TLS only if used */ 3537 if (tls_opt.server) 3538 tls_status_msg = init_global_TLS_CTX(); 3539 else 3540 for (f = Files; f; f = f->f_next) { 3541 if (f->f_type != F_TLS) 3542 continue; 3543 tls_status_msg = init_global_TLS_CTX(); 3544 break; 3545 } 3546 3547 #endif /* !DISABLE_TLS */ 3548 3549 #ifndef DISABLE_SIGN 3550 /* only initialize -sign if actually used */ 3551 if (GlobalSign.sg == 0 || GlobalSign.sg == 1 || GlobalSign.sg == 2) 3552 (void)sign_global_init(Files); 3553 else if (GlobalSign.sg == 3) 3554 for (f = Files; f; f = f->f_next) 3555 if (f->f_flags & FFLAG_SIGN) { 3556 (void)sign_global_init(Files); 3557 break; 3558 } 3559 #endif /* !DISABLE_SIGN */ 3560 3561 #ifndef DISABLE_TLS 3562 if (tls_status_msg) { 3563 loginfo("%s", tls_status_msg); 3564 free(tls_status_msg); 3565 } 3566 DPRINTF((D_NET|D_TLS), "Preparing sockets for TLS\n"); 3567 TLS_Listen_Set = 3568 socksetup_tls(PF_UNSPEC, tls_opt.bindhost, tls_opt.bindport); 3569 3570 for (f = Files; f; f = f->f_next) { 3571 if (f->f_type != F_TLS) 3572 continue; 3573 if (!tls_connect(f->f_un.f_tls.tls_conn)) { 3574 logerror("Unable to connect to TLS server %s", 3575 f->f_un.f_tls.tls_conn->hostname); 3576 /* Reconnect after x seconds */ 3577 schedule_event(&f->f_un.f_tls.tls_conn->event, 3578 &((struct timeval){TLS_RECONNECT_SEC, 0}), 3579 tls_reconnect, f->f_un.f_tls.tls_conn); 3580 } 3581 } 3582 #endif /* !DISABLE_TLS */ 3583 3584 loginfo("restart"); 3585 /* 3586 * Log a change in hostname, but only on a restart (we detect this 3587 * by checking to see if we're passed a kevent). 3588 */ 3589 if (oldLocalFQDN && strcmp(oldLocalFQDN, LocalFQDN) != 0) 3590 loginfo("host name changed, \"%s\" to \"%s\"", 3591 oldLocalFQDN, LocalFQDN); 3592 3593 RESTORE_SIGNALS(omask); 3594 } 3595 3596 /* 3597 * Crack a configuration file line 3598 */ 3599 void 3600 cfline(size_t linenum, const char *line, struct filed *f, const char *prog, 3601 const char *host) 3602 { 3603 struct addrinfo hints, *res; 3604 int error, i, pri, syncfile; 3605 const char *p, *q; 3606 char *bp; 3607 char buf[MAXLINE]; 3608 3609 DPRINTF((D_CALL|D_PARSE), 3610 "cfline(%zu, \"%s\", f, \"%s\", \"%s\")\n", 3611 linenum, line, prog, host); 3612 3613 errno = 0; /* keep strerror() stuff out of logerror messages */ 3614 3615 /* clear out file entry */ 3616 memset(f, 0, sizeof(*f)); 3617 for (i = 0; i <= LOG_NFACILITIES; i++) 3618 f->f_pmask[i] = INTERNAL_NOPRI; 3619 STAILQ_INIT(&f->f_qhead); 3620 3621 /* 3622 * There should not be any space before the log facility. 3623 * Check this is okay, complain and fix if it is not. 3624 */ 3625 q = line; 3626 if (isblank((unsigned char)*line)) { 3627 errno = 0; 3628 logerror("Warning: `%s' space or tab before the log facility", 3629 line); 3630 /* Fix: strip all spaces/tabs before the log facility */ 3631 while (*q++ && isblank((unsigned char)*q)) 3632 /* skip blanks */; 3633 line = q; 3634 } 3635 3636 /* 3637 * q is now at the first char of the log facility 3638 * There should be at least one tab after the log facility 3639 * Check this is okay, and complain and fix if it is not. 3640 */ 3641 q = line + strlen(line); 3642 while (!isblank((unsigned char)*q) && (q != line)) 3643 q--; 3644 if ((q == line) && strlen(line)) { 3645 /* No tabs or space in a non empty line: complain */ 3646 errno = 0; 3647 logerror( 3648 "Error: `%s' log facility or log target missing", 3649 line); 3650 return; 3651 } 3652 3653 /* save host name, if any */ 3654 if (*host == '*') 3655 f->f_host = NULL; 3656 else { 3657 f->f_host = strdup(host); 3658 trim_anydomain(f->f_host); 3659 } 3660 3661 /* save program name, if any */ 3662 if (*prog == '*') 3663 f->f_program = NULL; 3664 else 3665 f->f_program = strdup(prog); 3666 3667 /* scan through the list of selectors */ 3668 for (p = line; *p && !isblank((unsigned char)*p);) { 3669 int pri_done, pri_cmp, pri_invert; 3670 3671 /* find the end of this facility name list */ 3672 for (q = p; *q && !isblank((unsigned char)*q) && *q++ != '.'; ) 3673 continue; 3674 3675 /* get the priority comparison */ 3676 pri_cmp = 0; 3677 pri_done = 0; 3678 pri_invert = 0; 3679 if (*q == '!') { 3680 pri_invert = 1; 3681 q++; 3682 } 3683 while (! pri_done) { 3684 switch (*q) { 3685 case '<': 3686 pri_cmp = PRI_LT; 3687 q++; 3688 break; 3689 case '=': 3690 pri_cmp = PRI_EQ; 3691 q++; 3692 break; 3693 case '>': 3694 pri_cmp = PRI_GT; 3695 q++; 3696 break; 3697 default: 3698 pri_done = 1; 3699 break; 3700 } 3701 } 3702 3703 /* collect priority name */ 3704 for (bp = buf; *q && !strchr("\t ,;", *q); ) 3705 *bp++ = *q++; 3706 *bp = '\0'; 3707 3708 /* skip cruft */ 3709 while (strchr(",;", *q)) 3710 q++; 3711 3712 /* decode priority name */ 3713 if (*buf == '*') { 3714 pri = LOG_PRIMASK + 1; 3715 pri_cmp = PRI_LT | PRI_EQ | PRI_GT; 3716 } else { 3717 pri = decode(buf, prioritynames); 3718 if (pri < 0) { 3719 errno = 0; 3720 logerror("Unknown priority name `%s'", buf); 3721 return; 3722 } 3723 } 3724 if (pri_cmp == 0) 3725 pri_cmp = UniquePriority ? PRI_EQ 3726 : PRI_EQ | PRI_GT; 3727 if (pri_invert) 3728 pri_cmp ^= PRI_LT | PRI_EQ | PRI_GT; 3729 3730 /* scan facilities */ 3731 while (*p && !strchr("\t .;", *p)) { 3732 for (bp = buf; *p && !strchr("\t ,;.", *p); ) 3733 *bp++ = *p++; 3734 *bp = '\0'; 3735 if (*buf == '*') 3736 for (i = 0; i < LOG_NFACILITIES; i++) { 3737 f->f_pmask[i] = pri; 3738 f->f_pcmp[i] = pri_cmp; 3739 } 3740 else { 3741 i = decode(buf, facilitynames); 3742 if (i < 0) { 3743 errno = 0; 3744 logerror("Unknown facility name `%s'", 3745 buf); 3746 return; 3747 } 3748 f->f_pmask[i >> 3] = pri; 3749 f->f_pcmp[i >> 3] = pri_cmp; 3750 } 3751 while (*p == ',' || *p == ' ') 3752 p++; 3753 } 3754 3755 p = q; 3756 } 3757 3758 /* skip to action part */ 3759 while (isblank((unsigned char)*p)) 3760 p++; 3761 3762 /* 3763 * should this be "#ifndef DISABLE_SIGN" or is it a general option? 3764 * '+' before file destination: write with PRI field for later 3765 * verification 3766 */ 3767 if (*p == '+') { 3768 f->f_flags |= FFLAG_FULL; 3769 p++; 3770 } 3771 if (*p == '-') { 3772 syncfile = 0; 3773 p++; 3774 } else 3775 syncfile = 1; 3776 3777 switch (*p) { 3778 case '@': 3779 #ifndef DISABLE_SIGN 3780 if (GlobalSign.sg == 3) 3781 f->f_flags |= FFLAG_SIGN; 3782 #endif /* !DISABLE_SIGN */ 3783 #ifndef DISABLE_TLS 3784 if (*(p+1) == '[') { 3785 /* TLS destination */ 3786 if (!parse_tls_destination(p, f, linenum)) { 3787 logerror("Unable to parse action %s", p); 3788 break; 3789 } 3790 f->f_type = F_TLS; 3791 break; 3792 } 3793 #endif /* !DISABLE_TLS */ 3794 (void)strlcpy(f->f_un.f_forw.f_hname, ++p, 3795 sizeof(f->f_un.f_forw.f_hname)); 3796 memset(&hints, 0, sizeof(hints)); 3797 hints.ai_family = AF_UNSPEC; 3798 hints.ai_socktype = SOCK_DGRAM; 3799 hints.ai_protocol = 0; 3800 error = getaddrinfo(f->f_un.f_forw.f_hname, "syslog", &hints, 3801 &res); 3802 if (error) { 3803 logerror("%s", gai_strerror(error)); 3804 break; 3805 } 3806 f->f_un.f_forw.f_addr = res; 3807 f->f_type = F_FORW; 3808 NumForwards++; 3809 break; 3810 3811 case '/': 3812 #ifndef DISABLE_SIGN 3813 if (GlobalSign.sg == 3) 3814 f->f_flags |= FFLAG_SIGN; 3815 #endif /* !DISABLE_SIGN */ 3816 (void)strlcpy(f->f_un.f_fname, p, sizeof(f->f_un.f_fname)); 3817 if ((f->f_file = open(p, O_WRONLY|O_APPEND, 0)) < 0) { 3818 f->f_type = F_UNUSED; 3819 logerror("%s", p); 3820 break; 3821 } 3822 if (syncfile) 3823 f->f_flags |= FFLAG_SYNC; 3824 if (isatty(f->f_file)) 3825 f->f_type = F_TTY; 3826 else 3827 f->f_type = F_FILE; 3828 if (strcmp(p, ctty) == 0) 3829 f->f_type = F_CONSOLE; 3830 break; 3831 3832 case '|': 3833 #ifndef DISABLE_SIGN 3834 if (GlobalSign.sg == 3) 3835 f->f_flags |= FFLAG_SIGN; 3836 #endif 3837 f->f_un.f_pipe.f_pid = 0; 3838 (void) strlcpy(f->f_un.f_pipe.f_pname, p + 1, 3839 sizeof(f->f_un.f_pipe.f_pname)); 3840 f->f_type = F_PIPE; 3841 break; 3842 3843 case '*': 3844 f->f_type = F_WALL; 3845 break; 3846 3847 default: 3848 for (i = 0; i < MAXUNAMES && *p; i++) { 3849 for (q = p; *q && *q != ','; ) 3850 q++; 3851 (void)strncpy(f->f_un.f_uname[i], p, UT_NAMESIZE); 3852 if ((q - p) > UT_NAMESIZE) 3853 f->f_un.f_uname[i][UT_NAMESIZE] = '\0'; 3854 else 3855 f->f_un.f_uname[i][q - p] = '\0'; 3856 while (*q == ',' || *q == ' ') 3857 q++; 3858 p = q; 3859 } 3860 f->f_type = F_USERS; 3861 break; 3862 } 3863 } 3864 3865 3866 /* 3867 * Decode a symbolic name to a numeric value 3868 */ 3869 int 3870 decode(const char *name, CODE *codetab) 3871 { 3872 CODE *c; 3873 char *p, buf[40]; 3874 3875 if (isdigit((unsigned char)*name)) 3876 return atoi(name); 3877 3878 for (p = buf; *name && p < &buf[sizeof(buf) - 1]; p++, name++) { 3879 if (isupper((unsigned char)*name)) 3880 *p = tolower((unsigned char)*name); 3881 else 3882 *p = *name; 3883 } 3884 *p = '\0'; 3885 for (c = codetab; c->c_name; c++) 3886 if (!strcmp(buf, c->c_name)) 3887 return c->c_val; 3888 3889 return -1; 3890 } 3891 3892 /* 3893 * Retrieve the size of the kernel message buffer, via sysctl. 3894 */ 3895 int 3896 getmsgbufsize(void) 3897 { 3898 #ifdef __NetBSD_Version__ 3899 int msgbufsize, mib[2]; 3900 size_t size; 3901 3902 mib[0] = CTL_KERN; 3903 mib[1] = KERN_MSGBUFSIZE; 3904 size = sizeof msgbufsize; 3905 if (sysctl(mib, 2, &msgbufsize, &size, NULL, 0) == -1) { 3906 DPRINTF(D_MISC, "Couldn't get kern.msgbufsize\n"); 3907 return 0; 3908 } 3909 return msgbufsize; 3910 #else 3911 return MAXLINE; 3912 #endif /* __NetBSD_Version__ */ 3913 } 3914 3915 /* 3916 * Retrieve the hostname, via sysctl. 3917 */ 3918 char * 3919 getLocalFQDN(void) 3920 { 3921 int mib[2]; 3922 char *hostname; 3923 size_t len; 3924 3925 mib[0] = CTL_KERN; 3926 mib[1] = KERN_HOSTNAME; 3927 sysctl(mib, 2, NULL, &len, NULL, 0); 3928 3929 if (!(hostname = malloc(len))) { 3930 logerror("Unable to allocate memory"); 3931 die(0,0,NULL); 3932 } else if (sysctl(mib, 2, hostname, &len, NULL, 0) == -1) { 3933 DPRINTF(D_MISC, "Couldn't get kern.hostname\n"); 3934 (void)gethostname(hostname, sizeof(len)); 3935 } 3936 return hostname; 3937 } 3938 3939 struct socketEvent * 3940 socksetup(int af, const char *hostname) 3941 { 3942 struct addrinfo hints, *res, *r; 3943 int error, maxs; 3944 int on = 1; 3945 struct socketEvent *s, *socks; 3946 3947 if(SecureMode && !NumForwards) 3948 return NULL; 3949 3950 memset(&hints, 0, sizeof(hints)); 3951 hints.ai_flags = AI_PASSIVE; 3952 hints.ai_family = af; 3953 hints.ai_socktype = SOCK_DGRAM; 3954 error = getaddrinfo(hostname, "syslog", &hints, &res); 3955 if (error) { 3956 logerror("%s", gai_strerror(error)); 3957 errno = 0; 3958 die(0, 0, NULL); 3959 } 3960 3961 /* Count max number of sockets we may open */ 3962 for (maxs = 0, r = res; r; r = r->ai_next, maxs++) 3963 continue; 3964 socks = calloc(maxs+1, sizeof(*socks)); 3965 if (!socks) { 3966 logerror("Couldn't allocate memory for sockets"); 3967 die(0, 0, NULL); 3968 } 3969 3970 socks->fd = 0; /* num of sockets counter at start of array */ 3971 s = socks + 1; 3972 for (r = res; r; r = r->ai_next) { 3973 s->fd = socket(r->ai_family, r->ai_socktype, r->ai_protocol); 3974 if (s->fd < 0) { 3975 logerror("socket() failed"); 3976 continue; 3977 } 3978 if (r->ai_family == AF_INET6 && setsockopt(s->fd, IPPROTO_IPV6, 3979 IPV6_V6ONLY, &on, sizeof(on)) < 0) { 3980 logerror("setsockopt(IPV6_V6ONLY) failed"); 3981 close(s->fd); 3982 continue; 3983 } 3984 3985 if (!SecureMode) { 3986 if (bind(s->fd, r->ai_addr, r->ai_addrlen) < 0) { 3987 logerror("bind() failed"); 3988 close(s->fd); 3989 continue; 3990 } 3991 s->ev = allocev(); 3992 event_set(s->ev, s->fd, EV_READ | EV_PERSIST, 3993 dispatch_read_finet, s->ev); 3994 if (event_add(s->ev, NULL) == -1) { 3995 DPRINTF((D_EVENT|D_NET), 3996 "Failure in event_add()\n"); 3997 } else { 3998 DPRINTF((D_EVENT|D_NET), 3999 "Listen on UDP port " 4000 "(event@%p)\n", s->ev); 4001 } 4002 } 4003 4004 socks->fd++; /* num counter */ 4005 s++; 4006 } 4007 4008 if (res) 4009 freeaddrinfo(res); 4010 if (socks->fd == 0) { 4011 free (socks); 4012 if(Debug) 4013 return NULL; 4014 else 4015 die(0, 0, NULL); 4016 } 4017 return socks; 4018 } 4019 4020 /* 4021 * Fairly similar to popen(3), but returns an open descriptor, as opposed 4022 * to a FILE *. 4023 */ 4024 int 4025 p_open(char *prog, pid_t *rpid) 4026 { 4027 static char sh[] = "sh", mc[] = "-c"; 4028 int pfd[2], nulldesc, i; 4029 pid_t pid; 4030 char *argv[4]; /* sh -c cmd NULL */ 4031 char errmsg[200]; 4032 4033 if (pipe(pfd) == -1) 4034 return -1; 4035 if ((nulldesc = open(_PATH_DEVNULL, O_RDWR)) == -1) { 4036 /* We are royally screwed anyway. */ 4037 return -1; 4038 } 4039 4040 switch ((pid = fork())) { 4041 case -1: 4042 (void) close(nulldesc); 4043 return -1; 4044 4045 case 0: 4046 argv[0] = sh; 4047 argv[1] = mc; 4048 argv[2] = prog; 4049 argv[3] = NULL; 4050 4051 (void) setsid(); /* avoid catching SIGHUPs. */ 4052 4053 /* 4054 * Reset ignored signals to their default behavior. 4055 */ 4056 (void)signal(SIGTERM, SIG_DFL); 4057 (void)signal(SIGINT, SIG_DFL); 4058 (void)signal(SIGQUIT, SIG_DFL); 4059 (void)signal(SIGPIPE, SIG_DFL); 4060 (void)signal(SIGHUP, SIG_DFL); 4061 4062 dup2(pfd[0], STDIN_FILENO); 4063 dup2(nulldesc, STDOUT_FILENO); 4064 dup2(nulldesc, STDERR_FILENO); 4065 for (i = getdtablesize(); i > 2; i--) 4066 (void) close(i); 4067 4068 (void) execvp(_PATH_BSHELL, argv); 4069 _exit(255); 4070 } 4071 4072 (void) close(nulldesc); 4073 (void) close(pfd[0]); 4074 4075 /* 4076 * Avoid blocking on a hung pipe. With O_NONBLOCK, we are 4077 * supposed to get an EWOULDBLOCK on writev(2), which is 4078 * caught by the logic above anyway, which will in turn 4079 * close the pipe, and fork a new logging subprocess if 4080 * necessary. The stale subprocess will be killed some 4081 * time later unless it terminated itself due to closing 4082 * its input pipe. 4083 */ 4084 if (fcntl(pfd[1], F_SETFL, O_NONBLOCK) == -1) { 4085 /* This is bad. */ 4086 (void) snprintf(errmsg, sizeof(errmsg), 4087 "Warning: cannot change pipe to pid %d to " 4088 "non-blocking.", (int) pid); 4089 logerror("%s", errmsg); 4090 } 4091 *rpid = pid; 4092 return pfd[1]; 4093 } 4094 4095 void 4096 deadq_enter(pid_t pid, const char *name) 4097 { 4098 dq_t p; 4099 int status; 4100 4101 /* 4102 * Be paranoid: if we can't signal the process, don't enter it 4103 * into the dead queue (perhaps it's already dead). If possible, 4104 * we try to fetch and log the child's status. 4105 */ 4106 if (kill(pid, 0) != 0) { 4107 if (waitpid(pid, &status, WNOHANG) > 0) 4108 log_deadchild(pid, status, name); 4109 return; 4110 } 4111 4112 p = malloc(sizeof(*p)); 4113 if (p == NULL) { 4114 errno = 0; 4115 logerror("panic: out of memory!"); 4116 exit(1); 4117 } 4118 4119 p->dq_pid = pid; 4120 p->dq_timeout = DQ_TIMO_INIT; 4121 TAILQ_INSERT_TAIL(&deadq_head, p, dq_entries); 4122 } 4123 4124 int 4125 deadq_remove(pid_t pid) 4126 { 4127 dq_t q; 4128 4129 for (q = TAILQ_FIRST(&deadq_head); q != NULL; 4130 q = TAILQ_NEXT(q, dq_entries)) { 4131 if (q->dq_pid == pid) { 4132 TAILQ_REMOVE(&deadq_head, q, dq_entries); 4133 free(q); 4134 return 1; 4135 } 4136 } 4137 return 0; 4138 } 4139 4140 void 4141 log_deadchild(pid_t pid, int status, const char *name) 4142 { 4143 int code; 4144 char buf[256]; 4145 const char *reason; 4146 4147 /* Keep strerror() struff out of logerror messages. */ 4148 errno = 0; 4149 if (WIFSIGNALED(status)) { 4150 reason = "due to signal"; 4151 code = WTERMSIG(status); 4152 } else { 4153 reason = "with status"; 4154 code = WEXITSTATUS(status); 4155 if (code == 0) 4156 return; 4157 } 4158 (void) snprintf(buf, sizeof(buf), 4159 "Logging subprocess %d (%s) exited %s %d.", 4160 pid, name, reason, code); 4161 logerror("%s", buf); 4162 } 4163 4164 struct event * 4165 allocev(void) 4166 { 4167 struct event *ev; 4168 4169 if (!(ev = calloc(1, sizeof(*ev)))) 4170 logerror("Unable to allocate memory"); 4171 return ev; 4172 } 4173 4174 /* *ev is allocated if necessary */ 4175 void 4176 schedule_event(struct event **ev, struct timeval *tv, 4177 void (*cb)(int, short, void *), void *arg) 4178 { 4179 if (!*ev && !(*ev = allocev())) { 4180 return; 4181 } 4182 event_set(*ev, 0, 0, cb, arg); 4183 DPRINTF(D_EVENT, "event_add(%s@%p)\n", "schedule_ev", *ev); \ 4184 if (event_add(*ev, tv) == -1) { 4185 DPRINTF(D_EVENT, "Failure in event_add()\n"); 4186 } 4187 } 4188 4189 #ifndef DISABLE_TLS 4190 /* abbreviation for freeing credential lists */ 4191 void 4192 free_cred_SLIST(struct peer_cred_head *head) 4193 { 4194 struct peer_cred *cred; 4195 4196 while (!SLIST_EMPTY(head)) { 4197 cred = SLIST_FIRST(head); 4198 SLIST_REMOVE_HEAD(head, entries); 4199 FREEPTR(cred->data); 4200 free(cred); 4201 } 4202 } 4203 #endif /* !DISABLE_TLS */ 4204 4205 /* 4206 * send message queue after reconnect 4207 */ 4208 /*ARGSUSED*/ 4209 void 4210 send_queue(int fd, short event, void *arg) 4211 { 4212 struct filed *f = (struct filed *) arg; 4213 struct buf_queue *qentry; 4214 #define SQ_CHUNK_SIZE 250 4215 size_t cnt = 0; 4216 4217 #ifndef DISABLE_TLS 4218 if (f->f_type == F_TLS) { 4219 /* use a flag to prevent recursive calls to send_queue() */ 4220 if (f->f_un.f_tls.tls_conn->send_queue) 4221 return; 4222 else 4223 f->f_un.f_tls.tls_conn->send_queue = true; 4224 } 4225 DPRINTF((D_DATA|D_CALL), "send_queue(f@%p with %zu msgs, " 4226 "cnt@%p = %zu)\n", f, f->f_qelements, &cnt, cnt); 4227 #endif /* !DISABLE_TLS */ 4228 4229 while ((qentry = STAILQ_FIRST(&f->f_qhead))) { 4230 #ifndef DISABLE_TLS 4231 /* send_queue() might be called with an unconnected destination 4232 * from init() or die() or one message might take longer, 4233 * leaving the connection in state ST_WAITING and thus not 4234 * ready for the next message. 4235 * this check is a shortcut to skip these unnecessary calls */ 4236 if (f->f_type == F_TLS 4237 && f->f_un.f_tls.tls_conn->state != ST_TLS_EST) { 4238 DPRINTF(D_TLS, "abort send_queue(cnt@%p = %zu) " 4239 "on TLS connection in state %d\n", 4240 &cnt, cnt, f->f_un.f_tls.tls_conn->state); 4241 return; 4242 } 4243 #endif /* !DISABLE_TLS */ 4244 fprintlog(f, qentry->msg, qentry); 4245 4246 /* Sending a long queue can take some time during which 4247 * SIGHUP and SIGALRM are blocked and no events are handled. 4248 * To avoid that we only send SQ_CHUNK_SIZE messages at once 4249 * and then reschedule ourselves to continue. Thus the control 4250 * will return first from all signal-protected functions so a 4251 * possible SIGHUP/SIGALRM is handled and then back to the 4252 * main loop which can handle possible input. 4253 */ 4254 if (++cnt >= SQ_CHUNK_SIZE) { 4255 if (!f->f_sq_event) { /* alloc on demand */ 4256 f->f_sq_event = allocev(); 4257 event_set(f->f_sq_event, 0, 0, send_queue, f); 4258 } 4259 if (event_add(f->f_sq_event, &((struct timeval){0, 1})) == -1) { 4260 DPRINTF(D_EVENT, "Failure in event_add()\n"); 4261 } 4262 break; 4263 } 4264 } 4265 #ifndef DISABLE_TLS 4266 if (f->f_type == F_TLS) 4267 f->f_un.f_tls.tls_conn->send_queue = false; 4268 #endif 4269 4270 } 4271 4272 /* 4273 * finds the next queue element to delete 4274 * 4275 * has stateful behaviour, before using it call once with reset = true 4276 * after that every call will return one next queue elemen to delete, 4277 * depending on strategy either the oldest or the one with the lowest priority 4278 */ 4279 static struct buf_queue * 4280 find_qentry_to_delete(const struct buf_queue_head *head, int strategy, 4281 bool reset) 4282 { 4283 static int pri; 4284 static struct buf_queue *qentry_static; 4285 4286 struct buf_queue *qentry_tmp; 4287 4288 if (reset || STAILQ_EMPTY(head)) { 4289 pri = LOG_DEBUG; 4290 qentry_static = STAILQ_FIRST(head); 4291 return NULL; 4292 } 4293 4294 /* find elements to delete */ 4295 if (strategy == PURGE_BY_PRIORITY) { 4296 qentry_tmp = qentry_static; 4297 while ((qentry_tmp = STAILQ_NEXT(qentry_tmp, entries)) != NULL) 4298 { 4299 if (LOG_PRI(qentry_tmp->msg->pri) == pri) { 4300 /* save the successor, because qentry_tmp 4301 * is probably deleted by the caller */ 4302 qentry_static = STAILQ_NEXT(qentry_tmp, entries); 4303 return qentry_tmp; 4304 } 4305 } 4306 /* nothing found in while loop --> next pri */ 4307 if (--pri) 4308 return find_qentry_to_delete(head, strategy, false); 4309 else 4310 return NULL; 4311 } else /* strategy == PURGE_OLDEST or other value */ { 4312 qentry_tmp = qentry_static; 4313 qentry_static = STAILQ_NEXT(qentry_tmp, entries); 4314 return qentry_tmp; /* is NULL on empty queue */ 4315 } 4316 } 4317 4318 /* note on TAILQ: newest message added at TAIL, 4319 * oldest to be removed is FIRST 4320 */ 4321 /* 4322 * checks length of a destination's message queue 4323 * if del_entries == 0 then assert queue length is 4324 * less or equal to configured number of queue elements 4325 * otherwise del_entries tells how many entries to delete 4326 * 4327 * returns the number of removed queue elements 4328 * (which not necessarily means free'd messages) 4329 * 4330 * strategy PURGE_OLDEST to delete oldest entry, e.g. after it was resent 4331 * strategy PURGE_BY_PRIORITY to delete messages with lowest priority first, 4332 * this is much slower but might be desirable when unsent messages have 4333 * to be deleted, e.g. in call from domark() 4334 */ 4335 size_t 4336 message_queue_purge(struct filed *f, size_t del_entries, int strategy) 4337 { 4338 size_t removed = 0; 4339 struct buf_queue *qentry = NULL; 4340 4341 DPRINTF((D_CALL|D_BUFFER), "purge_message_queue(%p, %zu, %d) with " 4342 "f_qelements=%zu and f_qsize=%zu\n", 4343 f, del_entries, strategy, 4344 f->f_qelements, f->f_qsize); 4345 4346 /* reset state */ 4347 (void)find_qentry_to_delete(&f->f_qhead, strategy, true); 4348 4349 while (removed < del_entries 4350 || (TypeInfo[f->f_type].queue_length != -1 4351 && (size_t)TypeInfo[f->f_type].queue_length > f->f_qelements) 4352 || (TypeInfo[f->f_type].queue_size != -1 4353 && (size_t)TypeInfo[f->f_type].queue_size > f->f_qsize)) { 4354 qentry = find_qentry_to_delete(&f->f_qhead, strategy, 0); 4355 if (message_queue_remove(f, qentry)) 4356 removed++; 4357 else 4358 break; 4359 } 4360 return removed; 4361 } 4362 4363 /* run message_queue_purge() for all destinations to free memory */ 4364 size_t 4365 message_allqueues_purge(void) 4366 { 4367 size_t sum = 0; 4368 struct filed *f; 4369 4370 for (f = Files; f; f = f->f_next) 4371 sum += message_queue_purge(f, 4372 f->f_qelements/10, PURGE_BY_PRIORITY); 4373 4374 DPRINTF(D_BUFFER, 4375 "message_allqueues_purge(): removed %zu buffer entries\n", sum); 4376 return sum; 4377 } 4378 4379 /* run message_queue_purge() for all destinations to check limits */ 4380 size_t 4381 message_allqueues_check(void) 4382 { 4383 size_t sum = 0; 4384 struct filed *f; 4385 4386 for (f = Files; f; f = f->f_next) 4387 sum += message_queue_purge(f, 0, PURGE_BY_PRIORITY); 4388 DPRINTF(D_BUFFER, 4389 "message_allqueues_check(): removed %zu buffer entries\n", sum); 4390 return sum; 4391 } 4392 4393 struct buf_msg * 4394 buf_msg_new(const size_t len) 4395 { 4396 struct buf_msg *newbuf; 4397 4398 CALLOC(newbuf, sizeof(*newbuf)); 4399 4400 if (len) { /* len = 0 is valid */ 4401 MALLOC(newbuf->msg, len); 4402 newbuf->msgorig = newbuf->msg; 4403 newbuf->msgsize = len; 4404 } 4405 return NEWREF(newbuf); 4406 } 4407 4408 void 4409 buf_msg_free(struct buf_msg *buf) 4410 { 4411 if (!buf) 4412 return; 4413 4414 buf->refcount--; 4415 if (buf->refcount == 0) { 4416 FREEPTR(buf->timestamp); 4417 /* small optimizations: the host/recvhost may point to the 4418 * global HostName/FQDN. of course this must not be free()d 4419 * same goes for appname and include_pid 4420 */ 4421 if (buf->recvhost != buf->host 4422 && buf->recvhost != LocalHostName 4423 && buf->recvhost != LocalFQDN 4424 && buf->recvhost != oldLocalFQDN) 4425 FREEPTR(buf->recvhost); 4426 if (buf->host != LocalHostName 4427 && buf->host != LocalFQDN 4428 && buf->host != oldLocalFQDN) 4429 FREEPTR(buf->host); 4430 if (buf->prog != appname) 4431 FREEPTR(buf->prog); 4432 if (buf->pid != include_pid) 4433 FREEPTR(buf->pid); 4434 FREEPTR(buf->msgid); 4435 FREEPTR(buf->sd); 4436 FREEPTR(buf->msgorig); /* instead of msg */ 4437 FREEPTR(buf); 4438 } 4439 } 4440 4441 size_t 4442 buf_queue_obj_size(struct buf_queue *qentry) 4443 { 4444 size_t sum = 0; 4445 4446 if (!qentry) 4447 return 0; 4448 sum += sizeof(*qentry) 4449 + sizeof(*qentry->msg) 4450 + qentry->msg->msgsize 4451 + SAFEstrlen(qentry->msg->timestamp)+1 4452 + SAFEstrlen(qentry->msg->msgid)+1; 4453 if (qentry->msg->prog 4454 && qentry->msg->prog != include_pid) 4455 sum += strlen(qentry->msg->prog)+1; 4456 if (qentry->msg->pid 4457 && qentry->msg->pid != appname) 4458 sum += strlen(qentry->msg->pid)+1; 4459 if (qentry->msg->recvhost 4460 && qentry->msg->recvhost != LocalHostName 4461 && qentry->msg->recvhost != LocalFQDN 4462 && qentry->msg->recvhost != oldLocalFQDN) 4463 sum += strlen(qentry->msg->recvhost)+1; 4464 if (qentry->msg->host 4465 && qentry->msg->host != LocalHostName 4466 && qentry->msg->host != LocalFQDN 4467 && qentry->msg->host != oldLocalFQDN) 4468 sum += strlen(qentry->msg->host)+1; 4469 4470 return sum; 4471 } 4472 4473 bool 4474 message_queue_remove(struct filed *f, struct buf_queue *qentry) 4475 { 4476 if (!f || !qentry || !qentry->msg) 4477 return false; 4478 4479 assert(!STAILQ_EMPTY(&f->f_qhead)); 4480 STAILQ_REMOVE(&f->f_qhead, qentry, buf_queue, entries); 4481 f->f_qelements--; 4482 f->f_qsize -= buf_queue_obj_size(qentry); 4483 4484 DPRINTF(D_BUFFER, "msg @%p removed from queue @%p, new qlen = %zu\n", 4485 qentry->msg, f, f->f_qelements); 4486 DELREF(qentry->msg); 4487 FREEPTR(qentry); 4488 return true; 4489 } 4490 4491 /* 4492 * returns *qentry on success and NULL on error 4493 */ 4494 struct buf_queue * 4495 message_queue_add(struct filed *f, struct buf_msg *buffer) 4496 { 4497 struct buf_queue *qentry; 4498 4499 /* check on every call or only every n-th time? */ 4500 message_queue_purge(f, 0, PURGE_BY_PRIORITY); 4501 4502 while (!(qentry = malloc(sizeof(*qentry))) 4503 && message_queue_purge(f, 1, PURGE_OLDEST)) 4504 continue; 4505 if (!qentry) { 4506 logerror("Unable to allocate memory"); 4507 DPRINTF(D_BUFFER, "queue empty, no memory, msg dropped\n"); 4508 return NULL; 4509 } else { 4510 qentry->msg = buffer; 4511 f->f_qelements++; 4512 f->f_qsize += buf_queue_obj_size(qentry); 4513 STAILQ_INSERT_TAIL(&f->f_qhead, qentry, entries); 4514 4515 DPRINTF(D_BUFFER, "msg @%p queued @%p, qlen = %zu\n", 4516 buffer, f, f->f_qelements); 4517 return qentry; 4518 } 4519 } 4520 4521 void 4522 message_queue_freeall(struct filed *f) 4523 { 4524 struct buf_queue *qentry; 4525 4526 if (!f) return; 4527 DPRINTF(D_MEM, "message_queue_freeall(f@%p) with f_qhead@%p\n", f, 4528 &f->f_qhead); 4529 4530 while (!STAILQ_EMPTY(&f->f_qhead)) { 4531 qentry = STAILQ_FIRST(&f->f_qhead); 4532 STAILQ_REMOVE(&f->f_qhead, qentry, buf_queue, entries); 4533 DELREF(qentry->msg); 4534 FREEPTR(qentry); 4535 } 4536 4537 f->f_qelements = 0; 4538 f->f_qsize = 0; 4539 } 4540 4541 #ifndef DISABLE_TLS 4542 /* utility function for tls_reconnect() */ 4543 struct filed * 4544 get_f_by_conninfo(struct tls_conn_settings *conn_info) 4545 { 4546 struct filed *f; 4547 4548 for (f = Files; f; f = f->f_next) { 4549 if ((f->f_type == F_TLS) && f->f_un.f_tls.tls_conn == conn_info) 4550 return f; 4551 } 4552 DPRINTF(D_TLS, "get_f_by_conninfo() called on invalid conn_info\n"); 4553 return NULL; 4554 } 4555 4556 /* 4557 * Called on signal. 4558 * Lets the admin reconnect without waiting for the reconnect timer expires. 4559 */ 4560 /*ARGSUSED*/ 4561 void 4562 dispatch_force_tls_reconnect(int fd, short event, void *ev) 4563 { 4564 struct filed *f; 4565 DPRINTF((D_TLS|D_CALL|D_EVENT), "dispatch_force_tls_reconnect()\n"); 4566 for (f = Files; f; f = f->f_next) { 4567 if (f->f_type == F_TLS && 4568 f->f_un.f_tls.tls_conn->state == ST_NONE) 4569 tls_reconnect(fd, event, f->f_un.f_tls.tls_conn); 4570 } 4571 } 4572 #endif /* !DISABLE_TLS */ 4573 4574 /* 4575 * return a timestamp in a static buffer, 4576 * either format the timestamp given by parameter in_now 4577 * or use the current time if in_now is NULL. 4578 */ 4579 char * 4580 make_timestamp(time_t *in_now, bool iso) 4581 { 4582 int frac_digits = 6; 4583 struct timeval tv; 4584 time_t mytime; 4585 struct tm ltime; 4586 int len = 0; 4587 int tzlen = 0; 4588 /* uses global var: time_t now; */ 4589 4590 if (in_now) { 4591 mytime = *in_now; 4592 } else { 4593 gettimeofday(&tv, NULL); 4594 mytime = now = (time_t) tv.tv_sec; 4595 } 4596 4597 if (!iso) { 4598 strlcpy(timestamp, ctime(&mytime) + 4, TIMESTAMPBUFSIZE); 4599 timestamp[BSD_TIMESTAMPLEN] = '\0'; 4600 return timestamp; 4601 } 4602 4603 localtime_r(&mytime, <ime); 4604 len += strftime(timestamp, TIMESTAMPBUFSIZE, "%FT%T", <ime); 4605 snprintf(&(timestamp[len]), frac_digits+2, ".%.*ld", 4606 frac_digits, (long)tv.tv_usec); 4607 len += frac_digits+1; 4608 tzlen = strftime(&(timestamp[len]), TIMESTAMPBUFSIZE-len, "%z", <ime); 4609 len += tzlen; 4610 4611 if (tzlen == 5) { 4612 /* strftime gives "+0200", but we need "+02:00" */ 4613 timestamp[len+1] = timestamp[len]; 4614 timestamp[len] = timestamp[len-1]; 4615 timestamp[len-1] = timestamp[len-2]; 4616 timestamp[len-2] = ':'; 4617 } 4618 return timestamp; 4619 } 4620 4621 /* auxillary code to allocate memory and copy a string */ 4622 bool 4623 copy_string(char **mem, const char *p, const char *q) 4624 { 4625 const size_t len = 1 + q - p; 4626 if (!(*mem = malloc(len))) { 4627 logerror("Unable to allocate memory for config"); 4628 return false; 4629 } 4630 strlcpy(*mem, p, len); 4631 return true; 4632 } 4633 4634 /* keyword has to end with ", everything until next " is copied */ 4635 bool 4636 copy_config_value_quoted(const char *keyword, char **mem, const char **p) 4637 { 4638 const char *q; 4639 if (strncasecmp(*p, keyword, strlen(keyword))) 4640 return false; 4641 q = *p += strlen(keyword); 4642 if (!(q = strchr(*p, '"'))) { 4643 logerror("unterminated \"\n"); 4644 return false; 4645 } 4646 if (!(copy_string(mem, *p, q))) 4647 return false; 4648 *p = ++q; 4649 return true; 4650 } 4651 4652 /* for config file: 4653 * following = required but whitespace allowed, quotes optional 4654 * if numeric, then conversion to integer and no memory allocation 4655 */ 4656 bool 4657 copy_config_value(const char *keyword, char **mem, 4658 const char **p, const char *file, int line) 4659 { 4660 if (strncasecmp(*p, keyword, strlen(keyword))) 4661 return false; 4662 *p += strlen(keyword); 4663 4664 while (isspace((unsigned char)**p)) 4665 *p += 1; 4666 if (**p != '=') { 4667 logerror("expected \"=\" in file %s, line %d", file, line); 4668 return false; 4669 } 4670 *p += 1; 4671 4672 return copy_config_value_word(mem, p); 4673 } 4674 4675 /* copy next parameter from a config line */ 4676 bool 4677 copy_config_value_word(char **mem, const char **p) 4678 { 4679 const char *q; 4680 while (isspace((unsigned char)**p)) 4681 *p += 1; 4682 if (**p == '"') 4683 return copy_config_value_quoted("\"", mem, p); 4684 4685 /* without quotes: find next whitespace or end of line */ 4686 (void)((q = strchr(*p, ' ')) || (q = strchr(*p, '\t')) 4687 || (q = strchr(*p, '\n')) || (q = strchr(*p, '\0'))); 4688 4689 if (q-*p == 0 || !(copy_string(mem, *p, q))) 4690 return false; 4691 4692 *p = ++q; 4693 return true; 4694 } 4695