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