Home | History | Annotate | Download | only in openssh
      1 /* $OpenBSD: monitor_wrap.c,v 1.89 2016/08/13 17:47:41 markus Exp $ */
      2 /*
      3  * Copyright 2002 Niels Provos <provos (at) citi.umich.edu>
      4  * Copyright 2002 Markus Friedl <markus (at) openbsd.org>
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 #include "includes.h"
     29 
     30 #include <sys/types.h>
     31 #include <sys/uio.h>
     32 
     33 #include <errno.h>
     34 #include <pwd.h>
     35 #include <signal.h>
     36 #include <stdarg.h>
     37 #include <stdio.h>
     38 #include <string.h>
     39 #include <unistd.h>
     40 
     41 #ifdef WITH_OPENSSL
     42 #include <openssl/bn.h>
     43 #include <openssl/dh.h>
     44 #include <openssl/evp.h>
     45 #endif
     46 
     47 #include "openbsd-compat/sys-queue.h"
     48 #include "xmalloc.h"
     49 #include "ssh.h"
     50 #ifdef WITH_OPENSSL
     51 #include "dh.h"
     52 #endif
     53 #include "buffer.h"
     54 #include "key.h"
     55 #include "cipher.h"
     56 #include "kex.h"
     57 #include "hostfile.h"
     58 #include "auth.h"
     59 #include "auth-options.h"
     60 #include "packet.h"
     61 #include "mac.h"
     62 #include "log.h"
     63 #include "auth-pam.h"
     64 #ifdef TARGET_OS_MAC    /* XXX Broken krb5 headers on Mac */
     65 #undef TARGET_OS_MAC
     66 #include "zlib.h"
     67 #define TARGET_OS_MAC 1
     68 #else
     69 #include "zlib.h"
     70 #endif
     71 #include "monitor.h"
     72 #ifdef GSSAPI
     73 #include "ssh-gss.h"
     74 #endif
     75 #include "monitor_wrap.h"
     76 #include "atomicio.h"
     77 #include "monitor_fdpass.h"
     78 #include "misc.h"
     79 #include "uuencode.h"
     80 
     81 #include "channels.h"
     82 #include "session.h"
     83 #include "servconf.h"
     84 
     85 #include "ssherr.h"
     86 
     87 /* Imports */
     88 extern z_stream incoming_stream;
     89 extern z_stream outgoing_stream;
     90 extern struct monitor *pmonitor;
     91 extern Buffer loginmsg;
     92 extern ServerOptions options;
     93 
     94 void
     95 mm_log_handler(LogLevel level, const char *msg, void *ctx)
     96 {
     97 	Buffer log_msg;
     98 	struct monitor *mon = (struct monitor *)ctx;
     99 
    100 	if (mon->m_log_sendfd == -1)
    101 		fatal("%s: no log channel", __func__);
    102 
    103 	buffer_init(&log_msg);
    104 	/*
    105 	 * Placeholder for packet length. Will be filled in with the actual
    106 	 * packet length once the packet has been constucted. This saves
    107 	 * fragile math.
    108 	 */
    109 	buffer_put_int(&log_msg, 0);
    110 
    111 	buffer_put_int(&log_msg, level);
    112 	buffer_put_cstring(&log_msg, msg);
    113 	put_u32(buffer_ptr(&log_msg), buffer_len(&log_msg) - 4);
    114 	if (atomicio(vwrite, mon->m_log_sendfd, buffer_ptr(&log_msg),
    115 	    buffer_len(&log_msg)) != buffer_len(&log_msg))
    116 		fatal("%s: write: %s", __func__, strerror(errno));
    117 	buffer_free(&log_msg);
    118 }
    119 
    120 int
    121 mm_is_monitor(void)
    122 {
    123 	/*
    124 	 * m_pid is only set in the privileged part, and
    125 	 * points to the unprivileged child.
    126 	 */
    127 	return (pmonitor && pmonitor->m_pid > 0);
    128 }
    129 
    130 void
    131 mm_request_send(int sock, enum monitor_reqtype type, Buffer *m)
    132 {
    133 	u_int mlen = buffer_len(m);
    134 	u_char buf[5];
    135 
    136 	debug3("%s entering: type %d", __func__, type);
    137 
    138 	put_u32(buf, mlen + 1);
    139 	buf[4] = (u_char) type;		/* 1st byte of payload is mesg-type */
    140 	if (atomicio(vwrite, sock, buf, sizeof(buf)) != sizeof(buf))
    141 		fatal("%s: write: %s", __func__, strerror(errno));
    142 	if (atomicio(vwrite, sock, buffer_ptr(m), mlen) != mlen)
    143 		fatal("%s: write: %s", __func__, strerror(errno));
    144 }
    145 
    146 void
    147 mm_request_receive(int sock, Buffer *m)
    148 {
    149 	u_char buf[4];
    150 	u_int msg_len;
    151 
    152 	debug3("%s entering", __func__);
    153 
    154 	if (atomicio(read, sock, buf, sizeof(buf)) != sizeof(buf)) {
    155 		if (errno == EPIPE)
    156 			cleanup_exit(255);
    157 		fatal("%s: read: %s", __func__, strerror(errno));
    158 	}
    159 	msg_len = get_u32(buf);
    160 	if (msg_len > 256 * 1024)
    161 		fatal("%s: read: bad msg_len %d", __func__, msg_len);
    162 	buffer_clear(m);
    163 	buffer_append_space(m, msg_len);
    164 	if (atomicio(read, sock, buffer_ptr(m), msg_len) != msg_len)
    165 		fatal("%s: read: %s", __func__, strerror(errno));
    166 }
    167 
    168 void
    169 mm_request_receive_expect(int sock, enum monitor_reqtype type, Buffer *m)
    170 {
    171 	u_char rtype;
    172 
    173 	debug3("%s entering: type %d", __func__, type);
    174 
    175 	mm_request_receive(sock, m);
    176 	rtype = buffer_get_char(m);
    177 	if (rtype != type)
    178 		fatal("%s: read: rtype %d != type %d", __func__,
    179 		    rtype, type);
    180 }
    181 
    182 #ifdef WITH_OPENSSL
    183 DH *
    184 mm_choose_dh(int min, int nbits, int max)
    185 {
    186 	BIGNUM *p, *g;
    187 	int success = 0;
    188 	Buffer m;
    189 
    190 	buffer_init(&m);
    191 	buffer_put_int(&m, min);
    192 	buffer_put_int(&m, nbits);
    193 	buffer_put_int(&m, max);
    194 
    195 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_MODULI, &m);
    196 
    197 	debug3("%s: waiting for MONITOR_ANS_MODULI", __func__);
    198 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_MODULI, &m);
    199 
    200 	success = buffer_get_char(&m);
    201 	if (success == 0)
    202 		fatal("%s: MONITOR_ANS_MODULI failed", __func__);
    203 
    204 	if ((p = BN_new()) == NULL)
    205 		fatal("%s: BN_new failed", __func__);
    206 	if ((g = BN_new()) == NULL)
    207 		fatal("%s: BN_new failed", __func__);
    208 	buffer_get_bignum2(&m, p);
    209 	buffer_get_bignum2(&m, g);
    210 
    211 	debug3("%s: remaining %d", __func__, buffer_len(&m));
    212 	buffer_free(&m);
    213 
    214 	return (dh_new_group(g, p));
    215 }
    216 #endif
    217 
    218 int
    219 mm_key_sign(Key *key, u_char **sigp, u_int *lenp,
    220     const u_char *data, u_int datalen, const char *hostkey_alg)
    221 {
    222 	struct kex *kex = *pmonitor->m_pkex;
    223 	Buffer m;
    224 
    225 	debug3("%s entering", __func__);
    226 
    227 	buffer_init(&m);
    228 	buffer_put_int(&m, kex->host_key_index(key, 0, active_state));
    229 	buffer_put_string(&m, data, datalen);
    230 	buffer_put_cstring(&m, hostkey_alg);
    231 
    232 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, &m);
    233 
    234 	debug3("%s: waiting for MONITOR_ANS_SIGN", __func__);
    235 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SIGN, &m);
    236 	*sigp  = buffer_get_string(&m, lenp);
    237 	buffer_free(&m);
    238 
    239 	return (0);
    240 }
    241 
    242 struct passwd *
    243 mm_getpwnamallow(const char *username)
    244 {
    245 	Buffer m;
    246 	struct passwd *pw;
    247 	u_int len, i;
    248 	ServerOptions *newopts;
    249 
    250 	debug3("%s entering", __func__);
    251 
    252 	buffer_init(&m);
    253 	buffer_put_cstring(&m, username);
    254 
    255 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, &m);
    256 
    257 	debug3("%s: waiting for MONITOR_ANS_PWNAM", __func__);
    258 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m);
    259 
    260 	if (buffer_get_char(&m) == 0) {
    261 		pw = NULL;
    262 		goto out;
    263 	}
    264 	pw = buffer_get_string(&m, &len);
    265 	if (len != sizeof(struct passwd))
    266 		fatal("%s: struct passwd size mismatch", __func__);
    267 	pw->pw_name = buffer_get_string(&m, NULL);
    268 	pw->pw_passwd = buffer_get_string(&m, NULL);
    269 #ifdef HAVE_STRUCT_PASSWD_PW_GECOS
    270 	pw->pw_gecos = buffer_get_string(&m, NULL);
    271 #endif
    272 #ifdef HAVE_STRUCT_PASSWD_PW_CLASS
    273 	pw->pw_class = buffer_get_string(&m, NULL);
    274 #endif
    275 	pw->pw_dir = buffer_get_string(&m, NULL);
    276 	pw->pw_shell = buffer_get_string(&m, NULL);
    277 
    278 out:
    279 	/* copy options block as a Match directive may have changed some */
    280 	newopts = buffer_get_string(&m, &len);
    281 	if (len != sizeof(*newopts))
    282 		fatal("%s: option block size mismatch", __func__);
    283 
    284 #define M_CP_STROPT(x) do { \
    285 		if (newopts->x != NULL) \
    286 			newopts->x = buffer_get_string(&m, NULL); \
    287 	} while (0)
    288 #define M_CP_STRARRAYOPT(x, nx) do { \
    289 		for (i = 0; i < newopts->nx; i++) \
    290 			newopts->x[i] = buffer_get_string(&m, NULL); \
    291 	} while (0)
    292 	/* See comment in servconf.h */
    293 	COPY_MATCH_STRING_OPTS();
    294 #undef M_CP_STROPT
    295 #undef M_CP_STRARRAYOPT
    296 
    297 	copy_set_server_options(&options, newopts, 1);
    298 	free(newopts);
    299 
    300 	buffer_free(&m);
    301 
    302 	return (pw);
    303 }
    304 
    305 char *
    306 mm_auth2_read_banner(void)
    307 {
    308 	Buffer m;
    309 	char *banner;
    310 
    311 	debug3("%s entering", __func__);
    312 
    313 	buffer_init(&m);
    314 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, &m);
    315 	buffer_clear(&m);
    316 
    317 	mm_request_receive_expect(pmonitor->m_recvfd,
    318 	    MONITOR_ANS_AUTH2_READ_BANNER, &m);
    319 	banner = buffer_get_string(&m, NULL);
    320 	buffer_free(&m);
    321 
    322 	/* treat empty banner as missing banner */
    323 	if (strlen(banner) == 0) {
    324 		free(banner);
    325 		banner = NULL;
    326 	}
    327 	return (banner);
    328 }
    329 
    330 /* Inform the privileged process about service and style */
    331 
    332 void
    333 mm_inform_authserv(char *service, char *style)
    334 {
    335 	Buffer m;
    336 
    337 	debug3("%s entering", __func__);
    338 
    339 	buffer_init(&m);
    340 	buffer_put_cstring(&m, service);
    341 	buffer_put_cstring(&m, style ? style : "");
    342 
    343 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m);
    344 
    345 	buffer_free(&m);
    346 }
    347 
    348 /* Do the password authentication */
    349 int
    350 mm_auth_password(Authctxt *authctxt, char *password)
    351 {
    352 	Buffer m;
    353 	int authenticated = 0;
    354 
    355 	debug3("%s entering", __func__);
    356 
    357 	buffer_init(&m);
    358 	buffer_put_cstring(&m, password);
    359 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, &m);
    360 
    361 	debug3("%s: waiting for MONITOR_ANS_AUTHPASSWORD", __func__);
    362 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTHPASSWORD, &m);
    363 
    364 	authenticated = buffer_get_int(&m);
    365 #ifdef USE_PAM
    366 	sshpam_set_maxtries_reached(buffer_get_int(&m));
    367 #endif
    368 
    369 	buffer_free(&m);
    370 
    371 	debug3("%s: user %sauthenticated",
    372 	    __func__, authenticated ? "" : "not ");
    373 	return (authenticated);
    374 }
    375 
    376 int
    377 mm_user_key_allowed(struct passwd *pw, Key *key, int pubkey_auth_attempt)
    378 {
    379 	return (mm_key_allowed(MM_USERKEY, NULL, NULL, key,
    380 	    pubkey_auth_attempt));
    381 }
    382 
    383 int
    384 mm_hostbased_key_allowed(struct passwd *pw, const char *user, const char *host,
    385     Key *key)
    386 {
    387 	return (mm_key_allowed(MM_HOSTKEY, user, host, key, 0));
    388 }
    389 
    390 int
    391 mm_key_allowed(enum mm_keytype type, const char *user, const char *host,
    392     Key *key, int pubkey_auth_attempt)
    393 {
    394 	Buffer m;
    395 	u_char *blob;
    396 	u_int len;
    397 	int allowed = 0, have_forced = 0;
    398 
    399 	debug3("%s entering", __func__);
    400 
    401 	/* Convert the key to a blob and the pass it over */
    402 	if (!key_to_blob(key, &blob, &len))
    403 		return (0);
    404 
    405 	buffer_init(&m);
    406 	buffer_put_int(&m, type);
    407 	buffer_put_cstring(&m, user ? user : "");
    408 	buffer_put_cstring(&m, host ? host : "");
    409 	buffer_put_string(&m, blob, len);
    410 	buffer_put_int(&m, pubkey_auth_attempt);
    411 	free(blob);
    412 
    413 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, &m);
    414 
    415 	debug3("%s: waiting for MONITOR_ANS_KEYALLOWED", __func__);
    416 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYALLOWED, &m);
    417 
    418 	allowed = buffer_get_int(&m);
    419 
    420 	/* fake forced command */
    421 	auth_clear_options();
    422 	have_forced = buffer_get_int(&m);
    423 	forced_command = have_forced ? xstrdup("true") : NULL;
    424 
    425 	buffer_free(&m);
    426 
    427 	return (allowed);
    428 }
    429 
    430 /*
    431  * This key verify needs to send the key type along, because the
    432  * privileged parent makes the decision if the key is allowed
    433  * for authentication.
    434  */
    435 
    436 int
    437 mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
    438 {
    439 	Buffer m;
    440 	u_char *blob;
    441 	u_int len;
    442 	int verified = 0;
    443 
    444 	debug3("%s entering", __func__);
    445 
    446 	/* Convert the key to a blob and the pass it over */
    447 	if (!key_to_blob(key, &blob, &len))
    448 		return (0);
    449 
    450 	buffer_init(&m);
    451 	buffer_put_string(&m, blob, len);
    452 	buffer_put_string(&m, sig, siglen);
    453 	buffer_put_string(&m, data, datalen);
    454 	free(blob);
    455 
    456 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m);
    457 
    458 	debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__);
    459 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m);
    460 
    461 	verified = buffer_get_int(&m);
    462 
    463 	buffer_free(&m);
    464 
    465 	return (verified);
    466 }
    467 
    468 void
    469 mm_send_keystate(struct monitor *monitor)
    470 {
    471 	struct ssh *ssh = active_state;		/* XXX */
    472 	struct sshbuf *m;
    473 	int r;
    474 
    475 	if ((m = sshbuf_new()) == NULL)
    476 		fatal("%s: sshbuf_new failed", __func__);
    477 	if ((r = ssh_packet_get_state(ssh, m)) != 0)
    478 		fatal("%s: get_state failed: %s",
    479 		    __func__, ssh_err(r));
    480 	mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, m);
    481 	debug3("%s: Finished sending state", __func__);
    482 	sshbuf_free(m);
    483 }
    484 
    485 int
    486 mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen)
    487 {
    488 	Buffer m;
    489 	char *p, *msg;
    490 	int success = 0, tmp1 = -1, tmp2 = -1;
    491 
    492 	/* Kludge: ensure there are fds free to receive the pty/tty */
    493 	if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 ||
    494 	    (tmp2 = dup(pmonitor->m_recvfd)) == -1) {
    495 		error("%s: cannot allocate fds for pty", __func__);
    496 		if (tmp1 > 0)
    497 			close(tmp1);
    498 		if (tmp2 > 0)
    499 			close(tmp2);
    500 		return 0;
    501 	}
    502 	close(tmp1);
    503 	close(tmp2);
    504 
    505 	buffer_init(&m);
    506 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, &m);
    507 
    508 	debug3("%s: waiting for MONITOR_ANS_PTY", __func__);
    509 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PTY, &m);
    510 
    511 	success = buffer_get_int(&m);
    512 	if (success == 0) {
    513 		debug3("%s: pty alloc failed", __func__);
    514 		buffer_free(&m);
    515 		return (0);
    516 	}
    517 	p = buffer_get_string(&m, NULL);
    518 	msg = buffer_get_string(&m, NULL);
    519 	buffer_free(&m);
    520 
    521 	strlcpy(namebuf, p, namebuflen); /* Possible truncation */
    522 	free(p);
    523 
    524 	buffer_append(&loginmsg, msg, strlen(msg));
    525 	free(msg);
    526 
    527 	if ((*ptyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1 ||
    528 	    (*ttyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1)
    529 		fatal("%s: receive fds failed", __func__);
    530 
    531 	/* Success */
    532 	return (1);
    533 }
    534 
    535 void
    536 mm_session_pty_cleanup2(Session *s)
    537 {
    538 	Buffer m;
    539 
    540 	if (s->ttyfd == -1)
    541 		return;
    542 	buffer_init(&m);
    543 	buffer_put_cstring(&m, s->tty);
    544 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, &m);
    545 	buffer_free(&m);
    546 
    547 	/* closed dup'ed master */
    548 	if (s->ptymaster != -1 && close(s->ptymaster) < 0)
    549 		error("close(s->ptymaster/%d): %s",
    550 		    s->ptymaster, strerror(errno));
    551 
    552 	/* unlink pty from session */
    553 	s->ttyfd = -1;
    554 }
    555 
    556 #ifdef USE_PAM
    557 void
    558 mm_start_pam(Authctxt *authctxt)
    559 {
    560 	Buffer m;
    561 
    562 	debug3("%s entering", __func__);
    563 	if (!options.use_pam)
    564 		fatal("UsePAM=no, but ended up in %s anyway", __func__);
    565 
    566 	buffer_init(&m);
    567 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_START, &m);
    568 
    569 	buffer_free(&m);
    570 }
    571 
    572 u_int
    573 mm_do_pam_account(void)
    574 {
    575 	Buffer m;
    576 	u_int ret;
    577 	char *msg;
    578 
    579 	debug3("%s entering", __func__);
    580 	if (!options.use_pam)
    581 		fatal("UsePAM=no, but ended up in %s anyway", __func__);
    582 
    583 	buffer_init(&m);
    584 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, &m);
    585 
    586 	mm_request_receive_expect(pmonitor->m_recvfd,
    587 	    MONITOR_ANS_PAM_ACCOUNT, &m);
    588 	ret = buffer_get_int(&m);
    589 	msg = buffer_get_string(&m, NULL);
    590 	buffer_append(&loginmsg, msg, strlen(msg));
    591 	free(msg);
    592 
    593 	buffer_free(&m);
    594 
    595 	debug3("%s returning %d", __func__, ret);
    596 
    597 	return (ret);
    598 }
    599 
    600 void *
    601 mm_sshpam_init_ctx(Authctxt *authctxt)
    602 {
    603 	Buffer m;
    604 	int success;
    605 
    606 	debug3("%s", __func__);
    607 	buffer_init(&m);
    608 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_INIT_CTX, &m);
    609 	debug3("%s: waiting for MONITOR_ANS_PAM_INIT_CTX", __func__);
    610 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_INIT_CTX, &m);
    611 	success = buffer_get_int(&m);
    612 	if (success == 0) {
    613 		debug3("%s: pam_init_ctx failed", __func__);
    614 		buffer_free(&m);
    615 		return (NULL);
    616 	}
    617 	buffer_free(&m);
    618 	return (authctxt);
    619 }
    620 
    621 int
    622 mm_sshpam_query(void *ctx, char **name, char **info,
    623     u_int *num, char ***prompts, u_int **echo_on)
    624 {
    625 	Buffer m;
    626 	u_int i;
    627 	int ret;
    628 
    629 	debug3("%s", __func__);
    630 	buffer_init(&m);
    631 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_QUERY, &m);
    632 	debug3("%s: waiting for MONITOR_ANS_PAM_QUERY", __func__);
    633 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_QUERY, &m);
    634 	ret = buffer_get_int(&m);
    635 	debug3("%s: pam_query returned %d", __func__, ret);
    636 	*name = buffer_get_string(&m, NULL);
    637 	*info = buffer_get_string(&m, NULL);
    638 	sshpam_set_maxtries_reached(buffer_get_int(&m));
    639 	*num = buffer_get_int(&m);
    640 	if (*num > PAM_MAX_NUM_MSG)
    641 		fatal("%s: recieved %u PAM messages, expected <= %u",
    642 		    __func__, *num, PAM_MAX_NUM_MSG);
    643 	*prompts = xcalloc((*num + 1), sizeof(char *));
    644 	*echo_on = xcalloc((*num + 1), sizeof(u_int));
    645 	for (i = 0; i < *num; ++i) {
    646 		(*prompts)[i] = buffer_get_string(&m, NULL);
    647 		(*echo_on)[i] = buffer_get_int(&m);
    648 	}
    649 	buffer_free(&m);
    650 	return (ret);
    651 }
    652 
    653 int
    654 mm_sshpam_respond(void *ctx, u_int num, char **resp)
    655 {
    656 	Buffer m;
    657 	u_int i;
    658 	int ret;
    659 
    660 	debug3("%s", __func__);
    661 	buffer_init(&m);
    662 	buffer_put_int(&m, num);
    663 	for (i = 0; i < num; ++i)
    664 		buffer_put_cstring(&m, resp[i]);
    665 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_RESPOND, &m);
    666 	debug3("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__);
    667 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_RESPOND, &m);
    668 	ret = buffer_get_int(&m);
    669 	debug3("%s: pam_respond returned %d", __func__, ret);
    670 	buffer_free(&m);
    671 	return (ret);
    672 }
    673 
    674 void
    675 mm_sshpam_free_ctx(void *ctxtp)
    676 {
    677 	Buffer m;
    678 
    679 	debug3("%s", __func__);
    680 	buffer_init(&m);
    681 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_FREE_CTX, &m);
    682 	debug3("%s: waiting for MONITOR_ANS_PAM_FREE_CTX", __func__);
    683 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_FREE_CTX, &m);
    684 	buffer_free(&m);
    685 }
    686 #endif /* USE_PAM */
    687 
    688 /* Request process termination */
    689 
    690 void
    691 mm_terminate(void)
    692 {
    693 	Buffer m;
    694 
    695 	buffer_init(&m);
    696 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_TERM, &m);
    697 	buffer_free(&m);
    698 }
    699 
    700 static void
    701 mm_chall_setup(char **name, char **infotxt, u_int *numprompts,
    702     char ***prompts, u_int **echo_on)
    703 {
    704 	*name = xstrdup("");
    705 	*infotxt = xstrdup("");
    706 	*numprompts = 1;
    707 	*prompts = xcalloc(*numprompts, sizeof(char *));
    708 	*echo_on = xcalloc(*numprompts, sizeof(u_int));
    709 	(*echo_on)[0] = 0;
    710 }
    711 
    712 int
    713 mm_bsdauth_query(void *ctx, char **name, char **infotxt,
    714    u_int *numprompts, char ***prompts, u_int **echo_on)
    715 {
    716 	Buffer m;
    717 	u_int success;
    718 	char *challenge;
    719 
    720 	debug3("%s: entering", __func__);
    721 
    722 	buffer_init(&m);
    723 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHQUERY, &m);
    724 
    725 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_BSDAUTHQUERY,
    726 	    &m);
    727 	success = buffer_get_int(&m);
    728 	if (success == 0) {
    729 		debug3("%s: no challenge", __func__);
    730 		buffer_free(&m);
    731 		return (-1);
    732 	}
    733 
    734 	/* Get the challenge, and format the response */
    735 	challenge  = buffer_get_string(&m, NULL);
    736 	buffer_free(&m);
    737 
    738 	mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
    739 	(*prompts)[0] = challenge;
    740 
    741 	debug3("%s: received challenge: %s", __func__, challenge);
    742 
    743 	return (0);
    744 }
    745 
    746 int
    747 mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses)
    748 {
    749 	Buffer m;
    750 	int authok;
    751 
    752 	debug3("%s: entering", __func__);
    753 	if (numresponses != 1)
    754 		return (-1);
    755 
    756 	buffer_init(&m);
    757 	buffer_put_cstring(&m, responses[0]);
    758 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHRESPOND, &m);
    759 
    760 	mm_request_receive_expect(pmonitor->m_recvfd,
    761 	    MONITOR_ANS_BSDAUTHRESPOND, &m);
    762 
    763 	authok = buffer_get_int(&m);
    764 	buffer_free(&m);
    765 
    766 	return ((authok == 0) ? -1 : 0);
    767 }
    768 
    769 #ifdef SKEY
    770 int
    771 mm_skey_query(void *ctx, char **name, char **infotxt,
    772    u_int *numprompts, char ***prompts, u_int **echo_on)
    773 {
    774 	Buffer m;
    775 	u_int success;
    776 	char *challenge;
    777 
    778 	debug3("%s: entering", __func__);
    779 
    780 	buffer_init(&m);
    781 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYQUERY, &m);
    782 
    783 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SKEYQUERY,
    784 	    &m);
    785 	success = buffer_get_int(&m);
    786 	if (success == 0) {
    787 		debug3("%s: no challenge", __func__);
    788 		buffer_free(&m);
    789 		return (-1);
    790 	}
    791 
    792 	/* Get the challenge, and format the response */
    793 	challenge  = buffer_get_string(&m, NULL);
    794 	buffer_free(&m);
    795 
    796 	debug3("%s: received challenge: %s", __func__, challenge);
    797 
    798 	mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
    799 
    800 	xasprintf(*prompts, "%s%s", challenge, SKEY_PROMPT);
    801 	free(challenge);
    802 
    803 	return (0);
    804 }
    805 
    806 int
    807 mm_skey_respond(void *ctx, u_int numresponses, char **responses)
    808 {
    809 	Buffer m;
    810 	int authok;
    811 
    812 	debug3("%s: entering", __func__);
    813 	if (numresponses != 1)
    814 		return (-1);
    815 
    816 	buffer_init(&m);
    817 	buffer_put_cstring(&m, responses[0]);
    818 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYRESPOND, &m);
    819 
    820 	mm_request_receive_expect(pmonitor->m_recvfd,
    821 	    MONITOR_ANS_SKEYRESPOND, &m);
    822 
    823 	authok = buffer_get_int(&m);
    824 	buffer_free(&m);
    825 
    826 	return ((authok == 0) ? -1 : 0);
    827 }
    828 #endif /* SKEY */
    829 
    830 #ifdef SSH_AUDIT_EVENTS
    831 void
    832 mm_audit_event(ssh_audit_event_t event)
    833 {
    834 	Buffer m;
    835 
    836 	debug3("%s entering", __func__);
    837 
    838 	buffer_init(&m);
    839 	buffer_put_int(&m, event);
    840 
    841 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_EVENT, &m);
    842 	buffer_free(&m);
    843 }
    844 
    845 void
    846 mm_audit_run_command(const char *command)
    847 {
    848 	Buffer m;
    849 
    850 	debug3("%s entering command %s", __func__, command);
    851 
    852 	buffer_init(&m);
    853 	buffer_put_cstring(&m, command);
    854 
    855 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m);
    856 	buffer_free(&m);
    857 }
    858 #endif /* SSH_AUDIT_EVENTS */
    859 
    860 #ifdef GSSAPI
    861 OM_uint32
    862 mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid)
    863 {
    864 	Buffer m;
    865 	OM_uint32 major;
    866 
    867 	/* Client doesn't get to see the context */
    868 	*ctx = NULL;
    869 
    870 	buffer_init(&m);
    871 	buffer_put_string(&m, goid->elements, goid->length);
    872 
    873 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, &m);
    874 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, &m);
    875 
    876 	major = buffer_get_int(&m);
    877 
    878 	buffer_free(&m);
    879 	return (major);
    880 }
    881 
    882 OM_uint32
    883 mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in,
    884     gss_buffer_desc *out, OM_uint32 *flags)
    885 {
    886 	Buffer m;
    887 	OM_uint32 major;
    888 	u_int len;
    889 
    890 	buffer_init(&m);
    891 	buffer_put_string(&m, in->value, in->length);
    892 
    893 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, &m);
    894 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, &m);
    895 
    896 	major = buffer_get_int(&m);
    897 	out->value = buffer_get_string(&m, &len);
    898 	out->length = len;
    899 	if (flags)
    900 		*flags = buffer_get_int(&m);
    901 
    902 	buffer_free(&m);
    903 
    904 	return (major);
    905 }
    906 
    907 OM_uint32
    908 mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
    909 {
    910 	Buffer m;
    911 	OM_uint32 major;
    912 
    913 	buffer_init(&m);
    914 	buffer_put_string(&m, gssbuf->value, gssbuf->length);
    915 	buffer_put_string(&m, gssmic->value, gssmic->length);
    916 
    917 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, &m);
    918 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSCHECKMIC,
    919 	    &m);
    920 
    921 	major = buffer_get_int(&m);
    922 	buffer_free(&m);
    923 	return(major);
    924 }
    925 
    926 int
    927 mm_ssh_gssapi_userok(char *user)
    928 {
    929 	Buffer m;
    930 	int authenticated = 0;
    931 
    932 	buffer_init(&m);
    933 
    934 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m);
    935 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK,
    936 				  &m);
    937 
    938 	authenticated = buffer_get_int(&m);
    939 
    940 	buffer_free(&m);
    941 	debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not ");
    942 	return (authenticated);
    943 }
    944 #endif /* GSSAPI */
    945 
    946