diff options
Diffstat (limited to 'monitor.c')
-rw-r--r-- | monitor.c | 128 |
1 files changed, 114 insertions, 14 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor.c,v 1.113 2011/05/23 03:30:07 djm Exp $ */ | 1 | /* $OpenBSD: monitor.c,v 1.114 2011/06/17 21:44:30 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,27 @@ 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 | fatal("%s: poll: %s", __func__, strerror(errno)); | ||
559 | if (pfd[1].revents) { | ||
560 | /* | ||
561 | * Drain all log messages before processing next | ||
562 | * monitor request. | ||
563 | */ | ||
564 | monitor_read_log(pmonitor); | ||
565 | continue; | ||
566 | } | ||
567 | if (pfd[0].revents) | ||
568 | break; /* Continues below */ | ||
569 | } | ||
475 | 570 | ||
476 | buffer_init(&m); | 571 | buffer_init(&m); |
477 | 572 | ||
@@ -1851,12 +1946,26 @@ mm_init_compression(struct mm_master *mm) | |||
1851 | } while (0) | 1946 | } while (0) |
1852 | 1947 | ||
1853 | static void | 1948 | static void |
1854 | monitor_socketpair(int *pair) | 1949 | monitor_openfds(struct monitor *mon, int do_logfds) |
1855 | { | 1950 | { |
1951 | int pair[2]; | ||
1952 | |||
1856 | if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) | 1953 | if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) |
1857 | fatal("%s: socketpair", __func__); | 1954 | fatal("%s: socketpair: %s", __func__, strerror(errno)); |
1858 | FD_CLOSEONEXEC(pair[0]); | 1955 | FD_CLOSEONEXEC(pair[0]); |
1859 | FD_CLOSEONEXEC(pair[1]); | 1956 | FD_CLOSEONEXEC(pair[1]); |
1957 | mon->m_recvfd = pair[0]; | ||
1958 | mon->m_sendfd = pair[1]; | ||
1959 | |||
1960 | if (do_logfds) { | ||
1961 | if (pipe(pair) == -1) | ||
1962 | fatal("%s: pipe: %s", __func__, strerror(errno)); | ||
1963 | FD_CLOSEONEXEC(pair[0]); | ||
1964 | FD_CLOSEONEXEC(pair[1]); | ||
1965 | mon->m_log_recvfd = pair[0]; | ||
1966 | mon->m_log_sendfd = pair[1]; | ||
1967 | } else | ||
1968 | mon->m_log_recvfd = mon->m_log_sendfd = -1; | ||
1860 | } | 1969 | } |
1861 | 1970 | ||
1862 | #define MM_MEMSIZE 65536 | 1971 | #define MM_MEMSIZE 65536 |
@@ -1865,14 +1974,10 @@ struct monitor * | |||
1865 | monitor_init(void) | 1974 | monitor_init(void) |
1866 | { | 1975 | { |
1867 | struct monitor *mon; | 1976 | struct monitor *mon; |
1868 | int pair[2]; | ||
1869 | 1977 | ||
1870 | mon = xcalloc(1, sizeof(*mon)); | 1978 | mon = xcalloc(1, sizeof(*mon)); |
1871 | 1979 | ||
1872 | monitor_socketpair(pair); | 1980 | monitor_openfds(mon, 1); |
1873 | |||
1874 | mon->m_recvfd = pair[0]; | ||
1875 | mon->m_sendfd = pair[1]; | ||
1876 | 1981 | ||
1877 | /* Used to share zlib space across processes */ | 1982 | /* Used to share zlib space across processes */ |
1878 | if (options.compression) { | 1983 | if (options.compression) { |
@@ -1889,12 +1994,7 @@ monitor_init(void) | |||
1889 | void | 1994 | void |
1890 | monitor_reinit(struct monitor *mon) | 1995 | monitor_reinit(struct monitor *mon) |
1891 | { | 1996 | { |
1892 | int pair[2]; | 1997 | monitor_openfds(mon, 0); |
1893 | |||
1894 | monitor_socketpair(pair); | ||
1895 | |||
1896 | mon->m_recvfd = pair[0]; | ||
1897 | mon->m_sendfd = pair[1]; | ||
1898 | } | 1998 | } |
1899 | 1999 | ||
1900 | #ifdef GSSAPI | 2000 | #ifdef GSSAPI |