diff options
author | Colin Watson <cjwatson@debian.org> | 2011-09-06 09:45:52 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2011-09-06 09:45:52 +0100 |
commit | f38224d546cdde55f45c13d3d8225d273a3f920e (patch) | |
tree | a91a26b88ac90dc72d0ea3767feabb341eaa50a8 /monitor.c | |
parent | 338146a3fc257e216fe5c10fe40e6896b40d7739 (diff) | |
parent | e90790abaf031e037f444a6658e136e48577ea49 (diff) |
merge 5.9p1
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" |
@@ -181,6 +189,8 @@ int mm_answer_audit_event(int, Buffer *); | |||
181 | int mm_answer_audit_command(int, Buffer *); | 189 | int mm_answer_audit_command(int, Buffer *); |
182 | #endif | 190 | #endif |
183 | 191 | ||
192 | static int monitor_read_log(struct monitor *); | ||
193 | |||
184 | static Authctxt *authctxt; | 194 | static Authctxt *authctxt; |
185 | static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */ | 195 | static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */ |
186 | 196 | ||
@@ -355,6 +365,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) | |||
355 | 365 | ||
356 | debug3("preauth child monitor started"); | 366 | debug3("preauth child monitor started"); |
357 | 367 | ||
368 | close(pmonitor->m_recvfd); | ||
369 | close(pmonitor->m_log_sendfd); | ||
370 | pmonitor->m_log_sendfd = pmonitor->m_recvfd = -1; | ||
371 | |||
358 | authctxt = _authctxt; | 372 | authctxt = _authctxt; |
359 | memset(authctxt, 0, sizeof(*authctxt)); | 373 | memset(authctxt, 0, sizeof(*authctxt)); |
360 | 374 | ||
@@ -418,6 +432,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) | |||
418 | #endif | 432 | #endif |
419 | } | 433 | } |
420 | 434 | ||
435 | /* Drain any buffered messages from the child */ | ||
436 | while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0) | ||
437 | ; | ||
438 | |||
421 | if (!authctxt->valid) | 439 | if (!authctxt->valid) |
422 | fatal("%s: authenticated invalid user", __func__); | 440 | fatal("%s: authenticated invalid user", __func__); |
423 | if (strcmp(auth_method, "unknown") == 0) | 441 | if (strcmp(auth_method, "unknown") == 0) |
@@ -427,6 +445,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) | |||
427 | __func__, authctxt->user); | 445 | __func__, authctxt->user); |
428 | 446 | ||
429 | mm_get_keystate(pmonitor); | 447 | mm_get_keystate(pmonitor); |
448 | |||
449 | close(pmonitor->m_sendfd); | ||
450 | close(pmonitor->m_log_recvfd); | ||
451 | pmonitor->m_sendfd = pmonitor->m_log_recvfd = -1; | ||
430 | } | 452 | } |
431 | 453 | ||
432 | static void | 454 | static void |
@@ -444,6 +466,9 @@ monitor_child_handler(int sig) | |||
444 | void | 466 | void |
445 | monitor_child_postauth(struct monitor *pmonitor) | 467 | monitor_child_postauth(struct monitor *pmonitor) |
446 | { | 468 | { |
469 | close(pmonitor->m_recvfd); | ||
470 | pmonitor->m_recvfd = -1; | ||
471 | |||
447 | monitor_set_child_handler(pmonitor->m_pid); | 472 | monitor_set_child_handler(pmonitor->m_pid); |
448 | signal(SIGHUP, &monitor_child_handler); | 473 | signal(SIGHUP, &monitor_child_handler); |
449 | signal(SIGTERM, &monitor_child_handler); | 474 | signal(SIGTERM, &monitor_child_handler); |
@@ -471,6 +496,9 @@ monitor_child_postauth(struct monitor *pmonitor) | |||
471 | 496 | ||
472 | for (;;) | 497 | for (;;) |
473 | monitor_read(pmonitor, mon_dispatch, NULL); | 498 | monitor_read(pmonitor, mon_dispatch, NULL); |
499 | |||
500 | close(pmonitor->m_sendfd); | ||
501 | pmonitor->m_sendfd = -1; | ||
474 | } | 502 | } |
475 | 503 | ||
476 | void | 504 | void |
@@ -482,6 +510,52 @@ monitor_sync(struct monitor *pmonitor) | |||
482 | } | 510 | } |
483 | } | 511 | } |
484 | 512 | ||
513 | static int | ||
514 | monitor_read_log(struct monitor *pmonitor) | ||
515 | { | ||
516 | Buffer logmsg; | ||
517 | u_int len, level; | ||
518 | char *msg; | ||
519 | |||
520 | buffer_init(&logmsg); | ||
521 | |||
522 | /* Read length */ | ||
523 | buffer_append_space(&logmsg, 4); | ||
524 | if (atomicio(read, pmonitor->m_log_recvfd, | ||
525 | buffer_ptr(&logmsg), buffer_len(&logmsg)) != buffer_len(&logmsg)) { | ||
526 | if (errno == EPIPE) { | ||
527 | debug("%s: child log fd closed", __func__); | ||
528 | close(pmonitor->m_log_recvfd); | ||
529 | pmonitor->m_log_recvfd = -1; | ||
530 | return -1; | ||
531 | } | ||
532 | fatal("%s: log fd read: %s", __func__, strerror(errno)); | ||
533 | } | ||
534 | len = buffer_get_int(&logmsg); | ||
535 | if (len <= 4 || len > 8192) | ||
536 | fatal("%s: invalid log message length %u", __func__, len); | ||
537 | |||
538 | /* Read severity, message */ | ||
539 | buffer_clear(&logmsg); | ||
540 | buffer_append_space(&logmsg, len); | ||
541 | if (atomicio(read, pmonitor->m_log_recvfd, | ||
542 | buffer_ptr(&logmsg), buffer_len(&logmsg)) != buffer_len(&logmsg)) | ||
543 | fatal("%s: log fd read: %s", __func__, strerror(errno)); | ||
544 | |||
545 | /* Log it */ | ||
546 | level = buffer_get_int(&logmsg); | ||
547 | msg = buffer_get_string(&logmsg, NULL); | ||
548 | if (log_level_name(level) == NULL) | ||
549 | fatal("%s: invalid log level %u (corrupted message?)", | ||
550 | __func__, level); | ||
551 | do_log2(level, "%s [preauth]", msg); | ||
552 | |||
553 | buffer_free(&logmsg); | ||
554 | xfree(msg); | ||
555 | |||
556 | return 0; | ||
557 | } | ||
558 | |||
485 | int | 559 | int |
486 | monitor_read(struct monitor *pmonitor, struct mon_table *ent, | 560 | monitor_read(struct monitor *pmonitor, struct mon_table *ent, |
487 | struct mon_table **pent) | 561 | struct mon_table **pent) |
@@ -489,6 +563,30 @@ monitor_read(struct monitor *pmonitor, struct mon_table *ent, | |||
489 | Buffer m; | 563 | Buffer m; |
490 | int ret; | 564 | int ret; |
491 | u_char type; | 565 | u_char type; |
566 | struct pollfd pfd[2]; | ||
567 | |||
568 | for (;;) { | ||
569 | bzero(&pfd, sizeof(pfd)); | ||
570 | pfd[0].fd = pmonitor->m_sendfd; | ||
571 | pfd[0].events = POLLIN; | ||
572 | pfd[1].fd = pmonitor->m_log_recvfd; | ||
573 | pfd[1].events = pfd[1].fd == -1 ? 0 : POLLIN; | ||
574 | if (poll(pfd, pfd[1].fd == -1 ? 1 : 2, -1) == -1) { | ||
575 | if (errno == EINTR || errno == EAGAIN) | ||
576 | continue; | ||
577 | fatal("%s: poll: %s", __func__, strerror(errno)); | ||
578 | } | ||
579 | if (pfd[1].revents) { | ||
580 | /* | ||
581 | * Drain all log messages before processing next | ||
582 | * monitor request. | ||
583 | */ | ||
584 | monitor_read_log(pmonitor); | ||
585 | continue; | ||
586 | } | ||
587 | if (pfd[0].revents) | ||
588 | break; /* Continues below */ | ||
589 | } | ||
492 | 590 | ||
493 | buffer_init(&m); | 591 | buffer_init(&m); |
494 | 592 | ||
@@ -649,6 +747,7 @@ mm_answer_pwnamallow(int sock, Buffer *m) | |||
649 | char *username; | 747 | char *username; |
650 | struct passwd *pwent; | 748 | struct passwd *pwent; |
651 | int allowed = 0; | 749 | int allowed = 0; |
750 | u_int i; | ||
652 | 751 | ||
653 | debug3("%s", __func__); | 752 | debug3("%s", __func__); |
654 | 753 | ||
@@ -688,8 +787,20 @@ mm_answer_pwnamallow(int sock, Buffer *m) | |||
688 | 787 | ||
689 | out: | 788 | out: |
690 | buffer_put_string(m, &options, sizeof(options)); | 789 | buffer_put_string(m, &options, sizeof(options)); |
691 | if (options.banner != NULL) | 790 | |
692 | buffer_put_cstring(m, options.banner); | 791 | #define M_CP_STROPT(x) do { \ |
792 | if (options.x != NULL) \ | ||
793 | buffer_put_cstring(m, options.x); \ | ||
794 | } while (0) | ||
795 | #define M_CP_STRARRAYOPT(x, nx) do { \ | ||
796 | for (i = 0; i < options.nx; i++) \ | ||
797 | buffer_put_cstring(m, options.x[i]); \ | ||
798 | } while (0) | ||
799 | /* See comment in servconf.h */ | ||
800 | COPY_MATCH_STRING_OPTS(); | ||
801 | #undef M_CP_STROPT | ||
802 | #undef M_CP_STRARRAYOPT | ||
803 | |||
693 | debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed); | 804 | debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed); |
694 | mm_request_send(sock, MONITOR_ANS_PWNAM, m); | 805 | mm_request_send(sock, MONITOR_ANS_PWNAM, m); |
695 | 806 | ||
@@ -701,7 +812,6 @@ mm_answer_pwnamallow(int sock, Buffer *m) | |||
701 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); | 812 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); |
702 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); | 813 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); |
703 | } | 814 | } |
704 | |||
705 | #ifdef USE_PAM | 815 | #ifdef USE_PAM |
706 | if (options.use_pam) | 816 | if (options.use_pam) |
707 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); | 817 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); |
@@ -1858,22 +1968,31 @@ mm_init_compression(struct mm_master *mm) | |||
1858 | /* XXX */ | 1968 | /* XXX */ |
1859 | 1969 | ||
1860 | #define FD_CLOSEONEXEC(x) do { \ | 1970 | #define FD_CLOSEONEXEC(x) do { \ |
1861 | if (fcntl(x, F_SETFD, 1) == -1) \ | 1971 | if (fcntl(x, F_SETFD, FD_CLOEXEC) == -1) \ |
1862 | fatal("fcntl(%d, F_SETFD)", x); \ | 1972 | fatal("fcntl(%d, F_SETFD)", x); \ |
1863 | } while (0) | 1973 | } while (0) |
1864 | 1974 | ||
1865 | static void | 1975 | static void |
1866 | monitor_socketpair(int *pair) | 1976 | monitor_openfds(struct monitor *mon, int do_logfds) |
1867 | { | 1977 | { |
1868 | #ifdef HAVE_SOCKETPAIR | 1978 | int pair[2]; |
1979 | |||
1869 | if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) | 1980 | if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) |
1870 | fatal("%s: socketpair", __func__); | 1981 | fatal("%s: socketpair: %s", __func__, strerror(errno)); |
1871 | #else | ||
1872 | fatal("%s: UsePrivilegeSeparation=yes not supported", | ||
1873 | __func__); | ||
1874 | #endif | ||
1875 | FD_CLOSEONEXEC(pair[0]); | 1982 | FD_CLOSEONEXEC(pair[0]); |
1876 | FD_CLOSEONEXEC(pair[1]); | 1983 | FD_CLOSEONEXEC(pair[1]); |
1984 | mon->m_recvfd = pair[0]; | ||
1985 | mon->m_sendfd = pair[1]; | ||
1986 | |||
1987 | if (do_logfds) { | ||
1988 | if (pipe(pair) == -1) | ||
1989 | fatal("%s: pipe: %s", __func__, strerror(errno)); | ||
1990 | FD_CLOSEONEXEC(pair[0]); | ||
1991 | FD_CLOSEONEXEC(pair[1]); | ||
1992 | mon->m_log_recvfd = pair[0]; | ||
1993 | mon->m_log_sendfd = pair[1]; | ||
1994 | } else | ||
1995 | mon->m_log_recvfd = mon->m_log_sendfd = -1; | ||
1877 | } | 1996 | } |
1878 | 1997 | ||
1879 | #define MM_MEMSIZE 65536 | 1998 | #define MM_MEMSIZE 65536 |
@@ -1882,14 +2001,10 @@ struct monitor * | |||
1882 | monitor_init(void) | 2001 | monitor_init(void) |
1883 | { | 2002 | { |
1884 | struct monitor *mon; | 2003 | struct monitor *mon; |
1885 | int pair[2]; | ||
1886 | 2004 | ||
1887 | mon = xcalloc(1, sizeof(*mon)); | 2005 | mon = xcalloc(1, sizeof(*mon)); |
1888 | 2006 | ||
1889 | monitor_socketpair(pair); | 2007 | monitor_openfds(mon, 1); |
1890 | |||
1891 | mon->m_recvfd = pair[0]; | ||
1892 | mon->m_sendfd = pair[1]; | ||
1893 | 2008 | ||
1894 | /* Used to share zlib space across processes */ | 2009 | /* Used to share zlib space across processes */ |
1895 | if (options.compression) { | 2010 | if (options.compression) { |
@@ -1906,12 +2021,7 @@ monitor_init(void) | |||
1906 | void | 2021 | void |
1907 | monitor_reinit(struct monitor *mon) | 2022 | monitor_reinit(struct monitor *mon) |
1908 | { | 2023 | { |
1909 | int pair[2]; | 2024 | monitor_openfds(mon, 0); |
1910 | |||
1911 | monitor_socketpair(pair); | ||
1912 | |||
1913 | mon->m_recvfd = pair[0]; | ||
1914 | mon->m_sendfd = pair[1]; | ||
1915 | } | 2025 | } |
1916 | 2026 | ||
1917 | #ifdef GSSAPI | 2027 | #ifdef GSSAPI |