version 1.113, 2011/05/23 03:30:07 |
version 1.114, 2011/06/17 21:44:30 |
|
|
#include <errno.h> |
#include <errno.h> |
#include <fcntl.h> |
#include <fcntl.h> |
#include <paths.h> |
#include <paths.h> |
|
#include <poll.h> |
#include <pwd.h> |
#include <pwd.h> |
#include <signal.h> |
#include <signal.h> |
#include <stdlib.h> |
#include <stdlib.h> |
#include <string.h> |
#include <string.h> |
|
|
|
#include "atomicio.h" |
#include "xmalloc.h" |
#include "xmalloc.h" |
#include "ssh.h" |
#include "ssh.h" |
#include "key.h" |
#include "key.h" |
|
|
int mm_answer_gss_checkmic(int, Buffer *); |
int mm_answer_gss_checkmic(int, Buffer *); |
#endif |
#endif |
|
|
|
static int monitor_read_log(struct monitor *); |
|
|
static Authctxt *authctxt; |
static Authctxt *authctxt; |
static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */ |
static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */ |
|
|
|
|
|
|
debug3("preauth child monitor started"); |
debug3("preauth child monitor started"); |
|
|
|
close(pmonitor->m_recvfd); |
|
close(pmonitor->m_log_sendfd); |
|
pmonitor->m_log_sendfd = pmonitor->m_recvfd = -1; |
|
|
authctxt = _authctxt; |
authctxt = _authctxt; |
memset(authctxt, 0, sizeof(*authctxt)); |
memset(authctxt, 0, sizeof(*authctxt)); |
|
|
|
|
#endif |
#endif |
} |
} |
|
|
|
/* Drain any buffered messages from the child */ |
|
while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0) |
|
; |
|
|
if (!authctxt->valid) |
if (!authctxt->valid) |
fatal("%s: authenticated invalid user", __func__); |
fatal("%s: authenticated invalid user", __func__); |
if (strcmp(auth_method, "unknown") == 0) |
if (strcmp(auth_method, "unknown") == 0) |
|
|
__func__, authctxt->user); |
__func__, authctxt->user); |
|
|
mm_get_keystate(pmonitor); |
mm_get_keystate(pmonitor); |
|
|
|
close(pmonitor->m_sendfd); |
|
close(pmonitor->m_log_recvfd); |
|
pmonitor->m_sendfd = pmonitor->m_log_recvfd = -1; |
} |
} |
|
|
static void |
static void |
|
|
void |
void |
monitor_child_postauth(struct monitor *pmonitor) |
monitor_child_postauth(struct monitor *pmonitor) |
{ |
{ |
|
close(pmonitor->m_recvfd); |
|
pmonitor->m_recvfd = -1; |
|
|
monitor_set_child_handler(pmonitor->m_pid); |
monitor_set_child_handler(pmonitor->m_pid); |
signal(SIGHUP, &monitor_child_handler); |
signal(SIGHUP, &monitor_child_handler); |
signal(SIGTERM, &monitor_child_handler); |
signal(SIGTERM, &monitor_child_handler); |
|
|
|
|
for (;;) |
for (;;) |
monitor_read(pmonitor, mon_dispatch, NULL); |
monitor_read(pmonitor, mon_dispatch, NULL); |
|
|
|
close(pmonitor->m_sendfd); |
|
pmonitor->m_sendfd = -1; |
} |
} |
|
|
void |
void |
|
|
} |
} |
} |
} |
|
|
|
static int |
|
monitor_read_log(struct monitor *pmonitor) |
|
{ |
|
Buffer logmsg; |
|
u_int len, level; |
|
char *msg; |
|
|
|
buffer_init(&logmsg); |
|
|
|
/* Read length */ |
|
buffer_append_space(&logmsg, 4); |
|
if (atomicio(read, pmonitor->m_log_recvfd, |
|
buffer_ptr(&logmsg), buffer_len(&logmsg)) != buffer_len(&logmsg)) { |
|
if (errno == EPIPE) { |
|
debug("%s: child log fd closed", __func__); |
|
close(pmonitor->m_log_recvfd); |
|
pmonitor->m_log_recvfd = -1; |
|
return -1; |
|
} |
|
fatal("%s: log fd read: %s", __func__, strerror(errno)); |
|
} |
|
len = buffer_get_int(&logmsg); |
|
if (len <= 4 || len > 8192) |
|
fatal("%s: invalid log message length %u", __func__, len); |
|
|
|
/* Read severity, message */ |
|
buffer_clear(&logmsg); |
|
buffer_append_space(&logmsg, len); |
|
if (atomicio(read, pmonitor->m_log_recvfd, |
|
buffer_ptr(&logmsg), buffer_len(&logmsg)) != buffer_len(&logmsg)) |
|
fatal("%s: log fd read: %s", __func__, strerror(errno)); |
|
|
|
/* Log it */ |
|
level = buffer_get_int(&logmsg); |
|
msg = buffer_get_string(&logmsg, NULL); |
|
if (log_level_name(level) == NULL) |
|
fatal("%s: invalid log level %u (corrupted message?)", |
|
__func__, level); |
|
do_log2(level, "%s [preauth]", msg); |
|
|
|
buffer_free(&logmsg); |
|
xfree(msg); |
|
|
|
return 0; |
|
} |
|
|
int |
int |
monitor_read(struct monitor *pmonitor, struct mon_table *ent, |
monitor_read(struct monitor *pmonitor, struct mon_table *ent, |
struct mon_table **pent) |
struct mon_table **pent) |
|
|
Buffer m; |
Buffer m; |
int ret; |
int ret; |
u_char type; |
u_char type; |
|
struct pollfd pfd[2]; |
|
|
|
for (;;) { |
|
bzero(&pfd, sizeof(pfd)); |
|
pfd[0].fd = pmonitor->m_sendfd; |
|
pfd[0].events = POLLIN; |
|
pfd[1].fd = pmonitor->m_log_recvfd; |
|
pfd[1].events = pfd[1].fd == -1 ? 0 : POLLIN; |
|
if (poll(pfd, pfd[1].fd == -1 ? 1 : 2, -1) == -1) |
|
fatal("%s: poll: %s", __func__, strerror(errno)); |
|
if (pfd[1].revents) { |
|
/* |
|
* Drain all log messages before processing next |
|
* monitor request. |
|
*/ |
|
monitor_read_log(pmonitor); |
|
continue; |
|
} |
|
if (pfd[0].revents) |
|
break; /* Continues below */ |
|
} |
|
|
buffer_init(&m); |
buffer_init(&m); |
|
|
mm_request_receive(pmonitor->m_sendfd, &m); |
mm_request_receive(pmonitor->m_sendfd, &m); |
|
|
} while (0) |
} while (0) |
|
|
static void |
static void |
monitor_socketpair(int *pair) |
monitor_openfds(struct monitor *mon, int do_logfds) |
{ |
{ |
|
int pair[2]; |
|
|
if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) |
if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) |
fatal("%s: socketpair", __func__); |
fatal("%s: socketpair: %s", __func__, strerror(errno)); |
FD_CLOSEONEXEC(pair[0]); |
FD_CLOSEONEXEC(pair[0]); |
FD_CLOSEONEXEC(pair[1]); |
FD_CLOSEONEXEC(pair[1]); |
|
mon->m_recvfd = pair[0]; |
|
mon->m_sendfd = pair[1]; |
|
|
|
if (do_logfds) { |
|
if (pipe(pair) == -1) |
|
fatal("%s: pipe: %s", __func__, strerror(errno)); |
|
FD_CLOSEONEXEC(pair[0]); |
|
FD_CLOSEONEXEC(pair[1]); |
|
mon->m_log_recvfd = pair[0]; |
|
mon->m_log_sendfd = pair[1]; |
|
} else |
|
mon->m_log_recvfd = mon->m_log_sendfd = -1; |
} |
} |
|
|
#define MM_MEMSIZE 65536 |
#define MM_MEMSIZE 65536 |
|
|
monitor_init(void) |
monitor_init(void) |
{ |
{ |
struct monitor *mon; |
struct monitor *mon; |
int pair[2]; |
|
|
|
mon = xcalloc(1, sizeof(*mon)); |
mon = xcalloc(1, sizeof(*mon)); |
|
|
monitor_socketpair(pair); |
monitor_openfds(mon, 1); |
|
|
mon->m_recvfd = pair[0]; |
|
mon->m_sendfd = pair[1]; |
|
|
|
/* Used to share zlib space across processes */ |
/* Used to share zlib space across processes */ |
if (options.compression) { |
if (options.compression) { |
mon->m_zback = mm_create(NULL, MM_MEMSIZE); |
mon->m_zback = mm_create(NULL, MM_MEMSIZE); |
|
|
void |
void |
monitor_reinit(struct monitor *mon) |
monitor_reinit(struct monitor *mon) |
{ |
{ |
int pair[2]; |
monitor_openfds(mon, 0); |
|
|
monitor_socketpair(pair); |
|
|
|
mon->m_recvfd = pair[0]; |
|
mon->m_sendfd = pair[1]; |
|
} |
} |
|
|
#ifdef GSSAPI |
#ifdef GSSAPI |