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