version 1.10, 2002/05/12 23:53:45 |
version 1.11, 2002/05/15 15:47:49 |
|
|
} |
} |
|
|
Authctxt * |
Authctxt * |
monitor_child_preauth(struct monitor *monitor) |
monitor_child_preauth(struct monitor *pmonitor) |
{ |
{ |
struct mon_table *ent; |
struct mon_table *ent; |
int authenticated = 0; |
int authenticated = 0; |
|
|
|
|
/* The first few requests do not require asynchronous access */ |
/* The first few requests do not require asynchronous access */ |
while (!authenticated) { |
while (!authenticated) { |
authenticated = monitor_read(monitor, mon_dispatch, &ent); |
authenticated = monitor_read(pmonitor, mon_dispatch, &ent); |
if (authenticated) { |
if (authenticated) { |
if (!(ent->flags & MON_AUTHDECIDE)) |
if (!(ent->flags & MON_AUTHDECIDE)) |
fatal("%s: unexpected authentication from %d", |
fatal("%s: unexpected authentication from %d", |
|
|
debug("%s: %s has been authenticated by privileged process", |
debug("%s: %s has been authenticated by privileged process", |
__FUNCTION__, authctxt->user); |
__FUNCTION__, authctxt->user); |
|
|
mm_get_keystate(monitor); |
mm_get_keystate(pmonitor); |
|
|
return (authctxt); |
return (authctxt); |
} |
} |
|
|
void |
void |
monitor_child_postauth(struct monitor *monitor) |
monitor_child_postauth(struct monitor *pmonitor) |
{ |
{ |
if (compat20) { |
if (compat20) { |
mon_dispatch = mon_dispatch_postauth20; |
mon_dispatch = mon_dispatch_postauth20; |
|
|
} |
} |
|
|
for (;;) |
for (;;) |
monitor_read(monitor, mon_dispatch, NULL); |
monitor_read(pmonitor, mon_dispatch, NULL); |
} |
} |
|
|
void |
void |
monitor_sync(struct monitor *monitor) |
monitor_sync(struct monitor *pmonitor) |
{ |
{ |
/* The member allocation is not visible, so sync it */ |
/* The member allocation is not visible, so sync it */ |
mm_share_sync(&monitor->m_zlib, &monitor->m_zback); |
mm_share_sync(&pmonitor->m_zlib, &pmonitor->m_zback); |
} |
} |
|
|
int |
int |
monitor_read(struct monitor *monitor, 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; |
|
|
|
|
buffer_init(&m); |
buffer_init(&m); |
|
|
mm_request_receive(monitor->m_sendfd, &m); |
mm_request_receive(pmonitor->m_sendfd, &m); |
type = buffer_get_char(&m); |
type = buffer_get_char(&m); |
|
|
debug3("%s: checking request %d", __FUNCTION__, type); |
debug3("%s: checking request %d", __FUNCTION__, type); |
|
|
if (!(ent->flags & MON_PERMIT)) |
if (!(ent->flags & MON_PERMIT)) |
fatal("%s: unpermitted request %d", __FUNCTION__, |
fatal("%s: unpermitted request %d", __FUNCTION__, |
type); |
type); |
ret = (*ent->f)(monitor->m_sendfd, &m); |
ret = (*ent->f)(pmonitor->m_sendfd, &m); |
buffer_free(&m); |
buffer_free(&m); |
|
|
/* The child may use this request only once, disable it */ |
/* The child may use this request only once, disable it */ |
|
|
int |
int |
mm_answer_pty(int socket, Buffer *m) |
mm_answer_pty(int socket, Buffer *m) |
{ |
{ |
extern struct monitor *monitor; |
extern struct monitor *pmonitor; |
Session *s; |
Session *s; |
int res, fd0; |
int res, fd0; |
|
|
|
|
goto error; |
goto error; |
s->authctxt = authctxt; |
s->authctxt = authctxt; |
s->pw = authctxt->pw; |
s->pw = authctxt->pw; |
s->pid = monitor->m_pid; |
s->pid = pmonitor->m_pid; |
res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); |
res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); |
if (res == 0) |
if (res == 0) |
goto error; |
goto error; |
|
|
int |
int |
mm_answer_term(int socket, Buffer *req) |
mm_answer_term(int socket, Buffer *req) |
{ |
{ |
extern struct monitor *monitor; |
extern struct monitor *pmonitor; |
int res, status; |
int res, status; |
|
|
debug3("%s: tearing down sessions", __FUNCTION__); |
debug3("%s: tearing down sessions", __FUNCTION__); |
|
|
/* The child is terminating */ |
/* The child is terminating */ |
session_destroy_all(&mm_session_close); |
session_destroy_all(&mm_session_close); |
|
|
while (waitpid(monitor->m_pid, &status, 0) == -1) |
while (waitpid(pmonitor->m_pid, &status, 0) == -1) |
if (errno != EINTR) |
if (errno != EINTR) |
exit(1); |
exit(1); |
|
|
|
|
} |
} |
|
|
void |
void |
monitor_apply_keystate(struct monitor *monitor) |
monitor_apply_keystate(struct monitor *pmonitor) |
{ |
{ |
if (compat20) { |
if (compat20) { |
set_newkeys(MODE_IN); |
set_newkeys(MODE_IN); |
|
|
sizeof(outgoing_stream)); |
sizeof(outgoing_stream)); |
|
|
/* Update with new address */ |
/* Update with new address */ |
mm_init_compression(monitor->m_zlib); |
mm_init_compression(pmonitor->m_zlib); |
|
|
/* Network I/O buffers */ |
/* Network I/O buffers */ |
/* XXX inefficient for large buffers, need: buffer_init_from_string */ |
/* XXX inefficient for large buffers, need: buffer_init_from_string */ |
|
|
/* This function requries careful sanity checking */ |
/* This function requries careful sanity checking */ |
|
|
void |
void |
mm_get_keystate(struct monitor *monitor) |
mm_get_keystate(struct monitor *pmonitor) |
{ |
{ |
Buffer m; |
Buffer m; |
u_char *blob, *p; |
u_char *blob, *p; |
|
|
debug3("%s: Waiting for new keys", __FUNCTION__); |
debug3("%s: Waiting for new keys", __FUNCTION__); |
|
|
buffer_init(&m); |
buffer_init(&m); |
mm_request_receive_expect(monitor->m_sendfd, MONITOR_REQ_KEYEXPORT, &m); |
mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, &m); |
if (!compat20) { |
if (!compat20) { |
child_state.ssh1protoflags = buffer_get_int(&m); |
child_state.ssh1protoflags = buffer_get_int(&m); |
child_state.ssh1cipher = buffer_get_int(&m); |
child_state.ssh1cipher = buffer_get_int(&m); |
|
|
goto skip; |
goto skip; |
} else { |
} else { |
/* Get the Kex for rekeying */ |
/* Get the Kex for rekeying */ |
*monitor->m_pkex = mm_get_kex(&m); |
*pmonitor->m_pkex = mm_get_kex(&m); |
} |
} |
|
|
blob = buffer_get_string(&m, &bloblen); |
blob = buffer_get_string(&m, &bloblen); |