-/* $OpenBSD: monitor_wrap.c,v 1.47 2006/07/11 20:07:25 stevesk Exp $ */
+/* $OpenBSD: monitor_wrap.c,v 1.62 2008/05/08 12:21:16 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
#include "includes.h"
#include <sys/types.h>
-
-#include <openssl/bn.h>
-#include <openssl/dh.h>
+#include <sys/uio.h>
#include <errno.h>
#include <pwd.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include "openbsd-compat/sys-queue.h"
+#include "xmalloc.h"
#include "ssh.h"
#include "dh.h"
+#include "buffer.h"
+#include "key.h"
+#include "cipher.h"
#include "kex.h"
+#include "hostfile.h"
#include "auth.h"
#include "auth-options.h"
-#include "buffer.h"
-#include "bufaux.h"
#include "packet.h"
#include "mac.h"
#include "log.h"
#include "zlib.h"
#endif
#include "monitor.h"
+#ifdef GSSAPI
+#include "ssh-gss.h"
+#endif
#include "monitor_wrap.h"
-#include "xmalloc.h"
#include "atomicio.h"
#include "monitor_fdpass.h"
#include "misc.h"
#include "servconf.h"
-#include "auth.h"
#include "channels.h"
#include "session.h"
-
-#ifdef GSSAPI
-#include "ssh-gss.h"
-#endif
+#include "servconf.h"
/* Imports */
extern int compat20;
{
Buffer m;
struct passwd *pw;
- u_int pwlen;
+ u_int len;
+ ServerOptions *newopts;
debug3("%s entering", __func__);
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m);
if (buffer_get_char(&m) == 0) {
- buffer_free(&m);
- return (NULL);
+ pw = NULL;
+ goto out;
}
- pw = buffer_get_string(&m, &pwlen);
- if (pwlen != sizeof(struct passwd))
+ pw = buffer_get_string(&m, &len);
+ if (len != sizeof(struct passwd))
fatal("%s: struct passwd size mismatch", __func__);
pw->pw_name = buffer_get_string(&m, NULL);
pw->pw_passwd = buffer_get_string(&m, NULL);
#endif
pw->pw_dir = buffer_get_string(&m, NULL);
pw->pw_shell = buffer_get_string(&m, NULL);
+
+out:
+ /* copy options block as a Match directive may have changed some */
+ newopts = buffer_get_string(&m, &len);
+ if (len != sizeof(*newopts))
+ fatal("%s: option block size mismatch", __func__);
+ if (newopts->banner != NULL)
+ newopts->banner = buffer_get_string(&m, NULL);
+ copy_set_server_options(&options, newopts, 1);
+ xfree(newopts);
+
buffer_free(&m);
return (pw);
/* Mac structure */
mac->name = buffer_get_string(&b, NULL);
- if (mac->name == NULL || mac_init(mac, mac->name) == -1)
- fatal("%s: can not init mac %s", __func__, mac->name);
+ if (mac->name == NULL || mac_setup(mac, mac->name) == -1)
+ fatal("%s: can not setup mac %s", __func__, mac->name);
mac->enabled = buffer_get_int(&b);
mac->key = buffer_get_string(&b, &len);
if (len > mac->key_len)
{
Buffer m;
char *p, *msg;
- int success = 0;
+ int success = 0, tmp1 = -1, tmp2 = -1;
+
+ /* Kludge: ensure there are fds free to receive the pty/tty */
+ if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 ||
+ (tmp2 = dup(pmonitor->m_recvfd)) == -1) {
+ error("%s: cannot allocate fds for pty", __func__);
+ if (tmp1 > 0)
+ close(tmp1);
+ if (tmp2 > 0)
+ close(tmp2);
+ return 0;
+ }
+ close(tmp1);
+ close(tmp2);
buffer_init(&m);
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, &m);
buffer_append(&loginmsg, msg, strlen(msg));
xfree(msg);
- *ptyfd = mm_receive_fd(pmonitor->m_recvfd);
- *ttyfd = mm_receive_fd(pmonitor->m_recvfd);
+ if ((*ptyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1 ||
+ (*ttyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1)
+ fatal("%s: receive fds failed", __func__);
/* Success */
return (1);
buffer_free(&m);
/* closed dup'ed master */
- if (close(s->ptymaster) < 0)
- error("close(s->ptymaster): %s", strerror(errno));
+ if (s->ptymaster != -1 && close(s->ptymaster) < 0)
+ error("close(s->ptymaster/%d): %s",
+ s->ptymaster, strerror(errno));
/* unlink pty from session */
s->ttyfd = -1;
u_int *numprompts, char ***prompts, u_int **echo_on)
{
Buffer m;
- int len;
u_int success;
- char *p, *challenge;
+ char *challenge;
debug3("%s: entering", __func__);