diff options
Diffstat (limited to 'monitor.c')
-rw-r--r-- | monitor.c | 156 |
1 files changed, 133 insertions, 23 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor.c,v 1.110 2010/09/09 10:45:45 djm Exp $ */ | 1 | /* $OpenBSD: monitor.c,v 1.115 2011/06/23 23:35:42 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> | 3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> |
4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> | 4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> |
@@ -44,6 +44,13 @@ | |||
44 | #include <stdlib.h> | 44 | #include <stdlib.h> |
45 | #include <string.h> | 45 | #include <string.h> |
46 | #include <unistd.h> | 46 | #include <unistd.h> |
47 | #ifdef HAVE_POLL_H | ||
48 | #include <poll.h> | ||
49 | #else | ||
50 | # ifdef HAVE_SYS_POLL_H | ||
51 | # include <sys/poll.h> | ||
52 | # endif | ||
53 | #endif | ||
47 | 54 | ||
48 | #ifdef SKEY | 55 | #ifdef SKEY |
49 | #include <skey.h> | 56 | #include <skey.h> |
@@ -52,6 +59,7 @@ | |||
52 | #include <openssl/dh.h> | 59 | #include <openssl/dh.h> |
53 | 60 | ||
54 | #include "openbsd-compat/sys-queue.h" | 61 | #include "openbsd-compat/sys-queue.h" |
62 | #include "atomicio.h" | ||
55 | #include "xmalloc.h" | 63 | #include "xmalloc.h" |
56 | #include "ssh.h" | 64 | #include "ssh.h" |
57 | #include "key.h" | 65 | #include "key.h" |
@@ -182,6 +190,8 @@ int mm_answer_audit_event(int, Buffer *); | |||
182 | int mm_answer_audit_command(int, Buffer *); | 190 | int mm_answer_audit_command(int, Buffer *); |
183 | #endif | 191 | #endif |
184 | 192 | ||
193 | static int monitor_read_log(struct monitor *); | ||
194 | |||
185 | static Authctxt *authctxt; | 195 | static Authctxt *authctxt; |
186 | static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */ | 196 | static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */ |
187 | 197 | ||
@@ -357,6 +367,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) | |||
357 | 367 | ||
358 | debug3("preauth child monitor started"); | 368 | debug3("preauth child monitor started"); |
359 | 369 | ||
370 | close(pmonitor->m_recvfd); | ||
371 | close(pmonitor->m_log_sendfd); | ||
372 | pmonitor->m_log_sendfd = pmonitor->m_recvfd = -1; | ||
373 | |||
360 | authctxt = _authctxt; | 374 | authctxt = _authctxt; |
361 | memset(authctxt, 0, sizeof(*authctxt)); | 375 | memset(authctxt, 0, sizeof(*authctxt)); |
362 | 376 | ||
@@ -420,6 +434,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) | |||
420 | #endif | 434 | #endif |
421 | } | 435 | } |
422 | 436 | ||
437 | /* Drain any buffered messages from the child */ | ||
438 | while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0) | ||
439 | ; | ||
440 | |||
423 | if (!authctxt->valid) | 441 | if (!authctxt->valid) |
424 | fatal("%s: authenticated invalid user", __func__); | 442 | fatal("%s: authenticated invalid user", __func__); |
425 | if (strcmp(auth_method, "unknown") == 0) | 443 | if (strcmp(auth_method, "unknown") == 0) |
@@ -429,6 +447,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) | |||
429 | __func__, authctxt->user); | 447 | __func__, authctxt->user); |
430 | 448 | ||
431 | mm_get_keystate(pmonitor); | 449 | mm_get_keystate(pmonitor); |
450 | |||
451 | close(pmonitor->m_sendfd); | ||
452 | close(pmonitor->m_log_recvfd); | ||
453 | pmonitor->m_sendfd = pmonitor->m_log_recvfd = -1; | ||
432 | } | 454 | } |
433 | 455 | ||
434 | static void | 456 | static void |
@@ -446,6 +468,9 @@ monitor_child_handler(int sig) | |||
446 | void | 468 | void |
447 | monitor_child_postauth(struct monitor *pmonitor) | 469 | monitor_child_postauth(struct monitor *pmonitor) |
448 | { | 470 | { |
471 | close(pmonitor->m_recvfd); | ||
472 | pmonitor->m_recvfd = -1; | ||
473 | |||
449 | monitor_set_child_handler(pmonitor->m_pid); | 474 | monitor_set_child_handler(pmonitor->m_pid); |
450 | signal(SIGHUP, &monitor_child_handler); | 475 | signal(SIGHUP, &monitor_child_handler); |
451 | signal(SIGTERM, &monitor_child_handler); | 476 | signal(SIGTERM, &monitor_child_handler); |
@@ -473,6 +498,9 @@ monitor_child_postauth(struct monitor *pmonitor) | |||
473 | 498 | ||
474 | for (;;) | 499 | for (;;) |
475 | monitor_read(pmonitor, mon_dispatch, NULL); | 500 | monitor_read(pmonitor, mon_dispatch, NULL); |
501 | |||
502 | close(pmonitor->m_sendfd); | ||
503 | pmonitor->m_sendfd = -1; | ||
476 | } | 504 | } |
477 | 505 | ||
478 | void | 506 | void |
@@ -484,6 +512,52 @@ monitor_sync(struct monitor *pmonitor) | |||
484 | } | 512 | } |
485 | } | 513 | } |
486 | 514 | ||
515 | static int | ||
516 | monitor_read_log(struct monitor *pmonitor) | ||
517 | { | ||
518 | Buffer logmsg; | ||
519 | u_int len, level; | ||
520 | char *msg; | ||
521 | |||
522 | buffer_init(&logmsg); | ||
523 | |||
524 | /* Read length */ | ||
525 | buffer_append_space(&logmsg, 4); | ||
526 | if (atomicio(read, pmonitor->m_log_recvfd, | ||
527 | buffer_ptr(&logmsg), buffer_len(&logmsg)) != buffer_len(&logmsg)) { | ||
528 | if (errno == EPIPE) { | ||
529 | debug("%s: child log fd closed", __func__); | ||
530 | close(pmonitor->m_log_recvfd); | ||
531 | pmonitor->m_log_recvfd = -1; | ||
532 | return -1; | ||
533 | } | ||
534 | fatal("%s: log fd read: %s", __func__, strerror(errno)); | ||
535 | } | ||
536 | len = buffer_get_int(&logmsg); | ||
537 | if (len <= 4 || len > 8192) | ||
538 | fatal("%s: invalid log message length %u", __func__, len); | ||
539 | |||
540 | /* Read severity, message */ | ||
541 | buffer_clear(&logmsg); | ||
542 | buffer_append_space(&logmsg, len); | ||
543 | if (atomicio(read, pmonitor->m_log_recvfd, | ||
544 | buffer_ptr(&logmsg), buffer_len(&logmsg)) != buffer_len(&logmsg)) | ||
545 | fatal("%s: log fd read: %s", __func__, strerror(errno)); | ||
546 | |||
547 | /* Log it */ | ||
548 | level = buffer_get_int(&logmsg); | ||
549 | msg = buffer_get_string(&logmsg, NULL); | ||
550 | if (log_level_name(level) == NULL) | ||
551 | fatal("%s: invalid log level %u (corrupted message?)", | ||
552 | __func__, level); | ||
553 | do_log2(level, "%s [preauth]", msg); | ||
554 | |||
555 | buffer_free(&logmsg); | ||
556 | xfree(msg); | ||
557 | |||
558 | return 0; | ||
559 | } | ||
560 | |||
487 | int | 561 | int |
488 | monitor_read(struct monitor *pmonitor, struct mon_table *ent, | 562 | monitor_read(struct monitor *pmonitor, struct mon_table *ent, |
489 | struct mon_table **pent) | 563 | struct mon_table **pent) |
@@ -491,6 +565,30 @@ monitor_read(struct monitor *pmonitor, struct mon_table *ent, | |||
491 | Buffer m; | 565 | Buffer m; |
492 | int ret; | 566 | int ret; |
493 | u_char type; | 567 | u_char type; |
568 | struct pollfd pfd[2]; | ||
569 | |||
570 | for (;;) { | ||
571 | bzero(&pfd, sizeof(pfd)); | ||
572 | pfd[0].fd = pmonitor->m_sendfd; | ||
573 | pfd[0].events = POLLIN; | ||
574 | pfd[1].fd = pmonitor->m_log_recvfd; | ||
575 | pfd[1].events = pfd[1].fd == -1 ? 0 : POLLIN; | ||
576 | if (poll(pfd, pfd[1].fd == -1 ? 1 : 2, -1) == -1) { | ||
577 | if (errno == EINTR || errno == EAGAIN) | ||
578 | continue; | ||
579 | fatal("%s: poll: %s", __func__, strerror(errno)); | ||
580 | } | ||
581 | if (pfd[1].revents) { | ||
582 | /* | ||
583 | * Drain all log messages before processing next | ||
584 | * monitor request. | ||
585 | */ | ||
586 | monitor_read_log(pmonitor); | ||
587 | continue; | ||
588 | } | ||
589 | if (pfd[0].revents) | ||
590 | break; /* Continues below */ | ||
591 | } | ||
494 | 592 | ||
495 | buffer_init(&m); | 593 | buffer_init(&m); |
496 | 594 | ||
@@ -651,6 +749,7 @@ mm_answer_pwnamallow(int sock, Buffer *m) | |||
651 | char *username; | 749 | char *username; |
652 | struct passwd *pwent; | 750 | struct passwd *pwent; |
653 | int allowed = 0; | 751 | int allowed = 0; |
752 | u_int i; | ||
654 | 753 | ||
655 | debug3("%s", __func__); | 754 | debug3("%s", __func__); |
656 | 755 | ||
@@ -690,8 +789,20 @@ mm_answer_pwnamallow(int sock, Buffer *m) | |||
690 | 789 | ||
691 | out: | 790 | out: |
692 | buffer_put_string(m, &options, sizeof(options)); | 791 | buffer_put_string(m, &options, sizeof(options)); |
693 | if (options.banner != NULL) | 792 | |
694 | buffer_put_cstring(m, options.banner); | 793 | #define M_CP_STROPT(x) do { \ |
794 | if (options.x != NULL) \ | ||
795 | buffer_put_cstring(m, options.x); \ | ||
796 | } while (0) | ||
797 | #define M_CP_STRARRAYOPT(x, nx) do { \ | ||
798 | for (i = 0; i < options.nx; i++) \ | ||
799 | buffer_put_cstring(m, options.x[i]); \ | ||
800 | } while (0) | ||
801 | /* See comment in servconf.h */ | ||
802 | COPY_MATCH_STRING_OPTS(); | ||
803 | #undef M_CP_STROPT | ||
804 | #undef M_CP_STRARRAYOPT | ||
805 | |||
695 | debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed); | 806 | debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed); |
696 | mm_request_send(sock, MONITOR_ANS_PWNAM, m); | 807 | mm_request_send(sock, MONITOR_ANS_PWNAM, m); |
697 | 808 | ||
@@ -704,7 +815,6 @@ mm_answer_pwnamallow(int sock, Buffer *m) | |||
704 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1); | 815 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1); |
705 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); | 816 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); |
706 | } | 817 | } |
707 | |||
708 | #ifdef USE_PAM | 818 | #ifdef USE_PAM |
709 | if (options.use_pam) | 819 | if (options.use_pam) |
710 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); | 820 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); |
@@ -1884,22 +1994,31 @@ mm_init_compression(struct mm_master *mm) | |||
1884 | /* XXX */ | 1994 | /* XXX */ |
1885 | 1995 | ||
1886 | #define FD_CLOSEONEXEC(x) do { \ | 1996 | #define FD_CLOSEONEXEC(x) do { \ |
1887 | if (fcntl(x, F_SETFD, 1) == -1) \ | 1997 | if (fcntl(x, F_SETFD, FD_CLOEXEC) == -1) \ |
1888 | fatal("fcntl(%d, F_SETFD)", x); \ | 1998 | fatal("fcntl(%d, F_SETFD)", x); \ |
1889 | } while (0) | 1999 | } while (0) |
1890 | 2000 | ||
1891 | static void | 2001 | static void |
1892 | monitor_socketpair(int *pair) | 2002 | monitor_openfds(struct monitor *mon, int do_logfds) |
1893 | { | 2003 | { |
1894 | #ifdef HAVE_SOCKETPAIR | 2004 | int pair[2]; |
2005 | |||
1895 | if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) | 2006 | if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) |
1896 | fatal("%s: socketpair", __func__); | 2007 | fatal("%s: socketpair: %s", __func__, strerror(errno)); |
1897 | #else | ||
1898 | fatal("%s: UsePrivilegeSeparation=yes not supported", | ||
1899 | __func__); | ||
1900 | #endif | ||
1901 | FD_CLOSEONEXEC(pair[0]); | 2008 | FD_CLOSEONEXEC(pair[0]); |
1902 | FD_CLOSEONEXEC(pair[1]); | 2009 | FD_CLOSEONEXEC(pair[1]); |
2010 | mon->m_recvfd = pair[0]; | ||
2011 | mon->m_sendfd = pair[1]; | ||
2012 | |||
2013 | if (do_logfds) { | ||
2014 | if (pipe(pair) == -1) | ||
2015 | fatal("%s: pipe: %s", __func__, strerror(errno)); | ||
2016 | FD_CLOSEONEXEC(pair[0]); | ||
2017 | FD_CLOSEONEXEC(pair[1]); | ||
2018 | mon->m_log_recvfd = pair[0]; | ||
2019 | mon->m_log_sendfd = pair[1]; | ||
2020 | } else | ||
2021 | mon->m_log_recvfd = mon->m_log_sendfd = -1; | ||
1903 | } | 2022 | } |
1904 | 2023 | ||
1905 | #define MM_MEMSIZE 65536 | 2024 | #define MM_MEMSIZE 65536 |
@@ -1908,14 +2027,10 @@ struct monitor * | |||
1908 | monitor_init(void) | 2027 | monitor_init(void) |
1909 | { | 2028 | { |
1910 | struct monitor *mon; | 2029 | struct monitor *mon; |
1911 | int pair[2]; | ||
1912 | 2030 | ||
1913 | mon = xcalloc(1, sizeof(*mon)); | 2031 | mon = xcalloc(1, sizeof(*mon)); |
1914 | 2032 | ||
1915 | monitor_socketpair(pair); | 2033 | monitor_openfds(mon, 1); |
1916 | |||
1917 | mon->m_recvfd = pair[0]; | ||
1918 | mon->m_sendfd = pair[1]; | ||
1919 | 2034 | ||
1920 | /* Used to share zlib space across processes */ | 2035 | /* Used to share zlib space across processes */ |
1921 | if (options.compression) { | 2036 | if (options.compression) { |
@@ -1932,12 +2047,7 @@ monitor_init(void) | |||
1932 | void | 2047 | void |
1933 | monitor_reinit(struct monitor *mon) | 2048 | monitor_reinit(struct monitor *mon) |
1934 | { | 2049 | { |
1935 | int pair[2]; | 2050 | monitor_openfds(mon, 0); |
1936 | |||
1937 | monitor_socketpair(pair); | ||
1938 | |||
1939 | mon->m_recvfd = pair[0]; | ||
1940 | mon->m_sendfd = pair[1]; | ||
1941 | } | 2051 | } |
1942 | 2052 | ||
1943 | #ifdef GSSAPI | 2053 | #ifdef GSSAPI |