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" |
@@ -179,6 +187,8 @@ int mm_answer_audit_event(int, Buffer *); | |||
179 | int mm_answer_audit_command(int, Buffer *); | 187 | int mm_answer_audit_command(int, Buffer *); |
180 | #endif | 188 | #endif |
181 | 189 | ||
190 | static int monitor_read_log(struct monitor *); | ||
191 | |||
182 | static Authctxt *authctxt; | 192 | static Authctxt *authctxt; |
183 | static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */ | 193 | static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */ |
184 | 194 | ||
@@ -346,6 +356,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) | |||
346 | 356 | ||
347 | debug3("preauth child monitor started"); | 357 | debug3("preauth child monitor started"); |
348 | 358 | ||
359 | close(pmonitor->m_recvfd); | ||
360 | close(pmonitor->m_log_sendfd); | ||
361 | pmonitor->m_log_sendfd = pmonitor->m_recvfd = -1; | ||
362 | |||
349 | authctxt = _authctxt; | 363 | authctxt = _authctxt; |
350 | memset(authctxt, 0, sizeof(*authctxt)); | 364 | memset(authctxt, 0, sizeof(*authctxt)); |
351 | 365 | ||
@@ -405,6 +419,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) | |||
405 | #endif | 419 | #endif |
406 | } | 420 | } |
407 | 421 | ||
422 | /* Drain any buffered messages from the child */ | ||
423 | while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0) | ||
424 | ; | ||
425 | |||
408 | if (!authctxt->valid) | 426 | if (!authctxt->valid) |
409 | fatal("%s: authenticated invalid user", __func__); | 427 | fatal("%s: authenticated invalid user", __func__); |
410 | if (strcmp(auth_method, "unknown") == 0) | 428 | if (strcmp(auth_method, "unknown") == 0) |
@@ -414,6 +432,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) | |||
414 | __func__, authctxt->user); | 432 | __func__, authctxt->user); |
415 | 433 | ||
416 | mm_get_keystate(pmonitor); | 434 | mm_get_keystate(pmonitor); |
435 | |||
436 | close(pmonitor->m_sendfd); | ||
437 | close(pmonitor->m_log_recvfd); | ||
438 | pmonitor->m_sendfd = pmonitor->m_log_recvfd = -1; | ||
417 | } | 439 | } |
418 | 440 | ||
419 | static void | 441 | static void |
@@ -431,6 +453,9 @@ monitor_child_handler(int sig) | |||
431 | void | 453 | void |
432 | monitor_child_postauth(struct monitor *pmonitor) | 454 | monitor_child_postauth(struct monitor *pmonitor) |
433 | { | 455 | { |
456 | close(pmonitor->m_recvfd); | ||
457 | pmonitor->m_recvfd = -1; | ||
458 | |||
434 | monitor_set_child_handler(pmonitor->m_pid); | 459 | monitor_set_child_handler(pmonitor->m_pid); |
435 | signal(SIGHUP, &monitor_child_handler); | 460 | signal(SIGHUP, &monitor_child_handler); |
436 | signal(SIGTERM, &monitor_child_handler); | 461 | signal(SIGTERM, &monitor_child_handler); |
@@ -454,6 +479,9 @@ monitor_child_postauth(struct monitor *pmonitor) | |||
454 | 479 | ||
455 | for (;;) | 480 | for (;;) |
456 | monitor_read(pmonitor, mon_dispatch, NULL); | 481 | monitor_read(pmonitor, mon_dispatch, NULL); |
482 | |||
483 | close(pmonitor->m_sendfd); | ||
484 | pmonitor->m_sendfd = -1; | ||
457 | } | 485 | } |
458 | 486 | ||
459 | void | 487 | void |
@@ -465,6 +493,52 @@ monitor_sync(struct monitor *pmonitor) | |||
465 | } | 493 | } |
466 | } | 494 | } |
467 | 495 | ||
496 | static int | ||
497 | monitor_read_log(struct monitor *pmonitor) | ||
498 | { | ||
499 | Buffer logmsg; | ||
500 | u_int len, level; | ||
501 | char *msg; | ||
502 | |||
503 | buffer_init(&logmsg); | ||
504 | |||
505 | /* Read length */ | ||
506 | buffer_append_space(&logmsg, 4); | ||
507 | if (atomicio(read, pmonitor->m_log_recvfd, | ||
508 | buffer_ptr(&logmsg), buffer_len(&logmsg)) != buffer_len(&logmsg)) { | ||
509 | if (errno == EPIPE) { | ||
510 | debug("%s: child log fd closed", __func__); | ||
511 | close(pmonitor->m_log_recvfd); | ||
512 | pmonitor->m_log_recvfd = -1; | ||
513 | return -1; | ||
514 | } | ||
515 | fatal("%s: log fd read: %s", __func__, strerror(errno)); | ||
516 | } | ||
517 | len = buffer_get_int(&logmsg); | ||
518 | if (len <= 4 || len > 8192) | ||
519 | fatal("%s: invalid log message length %u", __func__, len); | ||
520 | |||
521 | /* Read severity, message */ | ||
522 | buffer_clear(&logmsg); | ||
523 | buffer_append_space(&logmsg, len); | ||
524 | if (atomicio(read, pmonitor->m_log_recvfd, | ||
525 | buffer_ptr(&logmsg), buffer_len(&logmsg)) != buffer_len(&logmsg)) | ||
526 | fatal("%s: log fd read: %s", __func__, strerror(errno)); | ||
527 | |||
528 | /* Log it */ | ||
529 | level = buffer_get_int(&logmsg); | ||
530 | msg = buffer_get_string(&logmsg, NULL); | ||
531 | if (log_level_name(level) == NULL) | ||
532 | fatal("%s: invalid log level %u (corrupted message?)", | ||
533 | __func__, level); | ||
534 | do_log2(level, "%s [preauth]", msg); | ||
535 | |||
536 | buffer_free(&logmsg); | ||
537 | xfree(msg); | ||
538 | |||
539 | return 0; | ||
540 | } | ||
541 | |||
468 | int | 542 | int |
469 | monitor_read(struct monitor *pmonitor, struct mon_table *ent, | 543 | monitor_read(struct monitor *pmonitor, struct mon_table *ent, |
470 | struct mon_table **pent) | 544 | struct mon_table **pent) |
@@ -472,6 +546,30 @@ monitor_read(struct monitor *pmonitor, struct mon_table *ent, | |||
472 | Buffer m; | 546 | Buffer m; |
473 | int ret; | 547 | int ret; |
474 | u_char type; | 548 | u_char type; |
549 | struct pollfd pfd[2]; | ||
550 | |||
551 | for (;;) { | ||
552 | bzero(&pfd, sizeof(pfd)); | ||
553 | pfd[0].fd = pmonitor->m_sendfd; | ||
554 | pfd[0].events = POLLIN; | ||
555 | pfd[1].fd = pmonitor->m_log_recvfd; | ||
556 | pfd[1].events = pfd[1].fd == -1 ? 0 : POLLIN; | ||
557 | if (poll(pfd, pfd[1].fd == -1 ? 1 : 2, -1) == -1) { | ||
558 | if (errno == EINTR || errno == EAGAIN) | ||
559 | continue; | ||
560 | fatal("%s: poll: %s", __func__, strerror(errno)); | ||
561 | } | ||
562 | if (pfd[1].revents) { | ||
563 | /* | ||
564 | * Drain all log messages before processing next | ||
565 | * monitor request. | ||
566 | */ | ||
567 | monitor_read_log(pmonitor); | ||
568 | continue; | ||
569 | } | ||
570 | if (pfd[0].revents) | ||
571 | break; /* Continues below */ | ||
572 | } | ||
475 | 573 | ||
476 | buffer_init(&m); | 574 | buffer_init(&m); |
477 | 575 | ||
@@ -632,6 +730,7 @@ mm_answer_pwnamallow(int sock, Buffer *m) | |||
632 | char *username; | 730 | char *username; |
633 | struct passwd *pwent; | 731 | struct passwd *pwent; |
634 | int allowed = 0; | 732 | int allowed = 0; |
733 | u_int i; | ||
635 | 734 | ||
636 | debug3("%s", __func__); | 735 | debug3("%s", __func__); |
637 | 736 | ||
@@ -671,8 +770,20 @@ mm_answer_pwnamallow(int sock, Buffer *m) | |||
671 | 770 | ||
672 | out: | 771 | out: |
673 | buffer_put_string(m, &options, sizeof(options)); | 772 | buffer_put_string(m, &options, sizeof(options)); |
674 | if (options.banner != NULL) | 773 | |
675 | buffer_put_cstring(m, options.banner); | 774 | #define M_CP_STROPT(x) do { \ |
775 | if (options.x != NULL) \ | ||
776 | buffer_put_cstring(m, options.x); \ | ||
777 | } while (0) | ||
778 | #define M_CP_STRARRAYOPT(x, nx) do { \ | ||
779 | for (i = 0; i < options.nx; i++) \ | ||
780 | buffer_put_cstring(m, options.x[i]); \ | ||
781 | } while (0) | ||
782 | /* See comment in servconf.h */ | ||
783 | COPY_MATCH_STRING_OPTS(); | ||
784 | #undef M_CP_STROPT | ||
785 | #undef M_CP_STRARRAYOPT | ||
786 | |||
676 | debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed); | 787 | debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed); |
677 | mm_request_send(sock, MONITOR_ANS_PWNAM, m); | 788 | mm_request_send(sock, MONITOR_ANS_PWNAM, m); |
678 | 789 | ||
@@ -684,7 +795,6 @@ mm_answer_pwnamallow(int sock, Buffer *m) | |||
684 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); | 795 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); |
685 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); | 796 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); |
686 | } | 797 | } |
687 | |||
688 | #ifdef USE_PAM | 798 | #ifdef USE_PAM |
689 | if (options.use_pam) | 799 | if (options.use_pam) |
690 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); | 800 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); |
@@ -1834,22 +1944,31 @@ mm_init_compression(struct mm_master *mm) | |||
1834 | /* XXX */ | 1944 | /* XXX */ |
1835 | 1945 | ||
1836 | #define FD_CLOSEONEXEC(x) do { \ | 1946 | #define FD_CLOSEONEXEC(x) do { \ |
1837 | if (fcntl(x, F_SETFD, 1) == -1) \ | 1947 | if (fcntl(x, F_SETFD, FD_CLOEXEC) == -1) \ |
1838 | fatal("fcntl(%d, F_SETFD)", x); \ | 1948 | fatal("fcntl(%d, F_SETFD)", x); \ |
1839 | } while (0) | 1949 | } while (0) |
1840 | 1950 | ||
1841 | static void | 1951 | static void |
1842 | monitor_socketpair(int *pair) | 1952 | monitor_openfds(struct monitor *mon, int do_logfds) |
1843 | { | 1953 | { |
1844 | #ifdef HAVE_SOCKETPAIR | 1954 | int pair[2]; |
1955 | |||
1845 | if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) | 1956 | if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) |
1846 | fatal("%s: socketpair", __func__); | 1957 | fatal("%s: socketpair: %s", __func__, strerror(errno)); |
1847 | #else | ||
1848 | fatal("%s: UsePrivilegeSeparation=yes not supported", | ||
1849 | __func__); | ||
1850 | #endif | ||
1851 | FD_CLOSEONEXEC(pair[0]); | 1958 | FD_CLOSEONEXEC(pair[0]); |
1852 | FD_CLOSEONEXEC(pair[1]); | 1959 | FD_CLOSEONEXEC(pair[1]); |
1960 | mon->m_recvfd = pair[0]; | ||
1961 | mon->m_sendfd = pair[1]; | ||
1962 | |||
1963 | if (do_logfds) { | ||
1964 | if (pipe(pair) == -1) | ||
1965 | fatal("%s: pipe: %s", __func__, strerror(errno)); | ||
1966 | FD_CLOSEONEXEC(pair[0]); | ||
1967 | FD_CLOSEONEXEC(pair[1]); | ||
1968 | mon->m_log_recvfd = pair[0]; | ||
1969 | mon->m_log_sendfd = pair[1]; | ||
1970 | } else | ||
1971 | mon->m_log_recvfd = mon->m_log_sendfd = -1; | ||
1853 | } | 1972 | } |
1854 | 1973 | ||
1855 | #define MM_MEMSIZE 65536 | 1974 | #define MM_MEMSIZE 65536 |
@@ -1858,14 +1977,10 @@ struct monitor * | |||
1858 | monitor_init(void) | 1977 | monitor_init(void) |
1859 | { | 1978 | { |
1860 | struct monitor *mon; | 1979 | struct monitor *mon; |
1861 | int pair[2]; | ||
1862 | 1980 | ||
1863 | mon = xcalloc(1, sizeof(*mon)); | 1981 | mon = xcalloc(1, sizeof(*mon)); |
1864 | 1982 | ||
1865 | monitor_socketpair(pair); | 1983 | monitor_openfds(mon, 1); |
1866 | |||
1867 | mon->m_recvfd = pair[0]; | ||
1868 | mon->m_sendfd = pair[1]; | ||
1869 | 1984 | ||
1870 | /* Used to share zlib space across processes */ | 1985 | /* Used to share zlib space across processes */ |
1871 | if (options.compression) { | 1986 | if (options.compression) { |
@@ -1882,12 +1997,7 @@ monitor_init(void) | |||
1882 | void | 1997 | void |
1883 | monitor_reinit(struct monitor *mon) | 1998 | monitor_reinit(struct monitor *mon) |
1884 | { | 1999 | { |
1885 | int pair[2]; | 2000 | monitor_openfds(mon, 0); |
1886 | |||
1887 | monitor_socketpair(pair); | ||
1888 | |||
1889 | mon->m_recvfd = pair[0]; | ||
1890 | mon->m_sendfd = pair[1]; | ||
1891 | } | 2001 | } |
1892 | 2002 | ||
1893 | #ifdef GSSAPI | 2003 | #ifdef GSSAPI |