summaryrefslogtreecommitdiff
path: root/monitor.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2011-09-06 14:56:29 +0100
committerColin Watson <cjwatson@debian.org>2011-09-06 14:56:29 +0100
commit978e62d6f14c60747bddef2cc72d66a9c8b83b54 (patch)
tree89400a44e42d84937deba7864e4964d6c7734da5 /monitor.c
parent87c685b8c6a49814fd782288097b3093f975aa72 (diff)
parent3a7e89697ca363de0f64e0d5704c57219294e41c (diff)
* New upstream release (http://www.openssh.org/txt/release-5.9).
- Introduce sandboxing of the pre-auth privsep child using an optional sshd_config(5) "UsePrivilegeSeparation=sandbox" mode that enables mandatory restrictions on the syscalls the privsep child can perform. - Add new SHA256-based HMAC transport integrity modes from http://www.ietf.org/id/draft-dbider-sha2-mac-for-ssh-02.txt. - The pre-authentication sshd(8) privilege separation slave process now logs via a socket shared with the master process, avoiding the need to maintain /dev/log inside the chroot (closes: #75043, #429243, #599240). - ssh(1) now warns when a server refuses X11 forwarding (closes: #504757). - sshd_config(5)'s AuthorizedKeysFile now accepts multiple paths, separated by whitespace (closes: #76312). The authorized_keys2 fallback is deprecated but documented (closes: #560156). - ssh(1) and sshd(8): set IPv6 traffic class from IPQoS, as well as IPv4 ToS/DSCP (closes: #498297). - ssh-add(1) now accepts keys piped from standard input. E.g. "ssh-add - < /path/to/key" (closes: #229124). - Clean up lost-passphrase text in ssh-keygen(1) (closes: #444691). - Say "required" rather than "recommended" in unprotected-private-key warning (LP: #663455).
Diffstat (limited to 'monitor.c')
-rw-r--r--monitor.c156
1 files changed, 133 insertions, 23 deletions
diff --git a/monitor.c b/monitor.c
index fa7fb0e25..985916b1e 100644
--- a/monitor.c
+++ b/monitor.c
@@ -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 *);
182int mm_answer_audit_command(int, Buffer *); 190int mm_answer_audit_command(int, Buffer *);
183#endif 191#endif
184 192
193static int monitor_read_log(struct monitor *);
194
185static Authctxt *authctxt; 195static Authctxt *authctxt;
186static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */ 196static 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
434static void 456static void
@@ -446,6 +468,9 @@ monitor_child_handler(int sig)
446void 468void
447monitor_child_postauth(struct monitor *pmonitor) 469monitor_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
478void 506void
@@ -484,6 +512,52 @@ monitor_sync(struct monitor *pmonitor)
484 } 512 }
485} 513}
486 514
515static int
516monitor_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
487int 561int
488monitor_read(struct monitor *pmonitor, struct mon_table *ent, 562monitor_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
1891static void 2001static void
1892monitor_socketpair(int *pair) 2002monitor_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 *
1908monitor_init(void) 2027monitor_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)
1932void 2047void
1933monitor_reinit(struct monitor *mon) 2048monitor_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