xref: /openbsd-src/usr.bin/ssh/monitor_wrap.c (revision 9f11ffb7133c203312a01e4b986886bc88c7d74b)
1 /* $OpenBSD: monitor_wrap.c,v 1.112 2019/01/21 09:54:11 djm Exp $ */
2 /*
3  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4  * Copyright 2002 Markus Friedl <markus@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 <sys/types.h>
29 #include <sys/uio.h>
30 #include <sys/queue.h>
31 
32 #include <errno.h>
33 #include <pwd.h>
34 #include <signal.h>
35 #include <stdio.h>
36 #include <string.h>
37 #include <unistd.h>
38 
39 #ifdef WITH_OPENSSL
40 #include <openssl/bn.h>
41 #include <openssl/dh.h>
42 #endif
43 
44 #include "xmalloc.h"
45 #include "ssh.h"
46 #ifdef WITH_OPENSSL
47 #include "dh.h"
48 #endif
49 #include "sshbuf.h"
50 #include "sshkey.h"
51 #include "cipher.h"
52 #include "kex.h"
53 #include "hostfile.h"
54 #include "auth.h"
55 #include "auth-options.h"
56 #include "packet.h"
57 #include "mac.h"
58 #include "log.h"
59 #include "monitor.h"
60 #ifdef GSSAPI
61 #include "ssh-gss.h"
62 #endif
63 #include "monitor_wrap.h"
64 #include "atomicio.h"
65 #include "monitor_fdpass.h"
66 #include "misc.h"
67 
68 #include "channels.h"
69 #include "session.h"
70 #include "servconf.h"
71 
72 #include "ssherr.h"
73 
74 /* Imports */
75 extern struct monitor *pmonitor;
76 extern struct sshbuf *loginmsg;
77 extern ServerOptions options;
78 
79 void
80 mm_log_handler(LogLevel level, const char *msg, void *ctx)
81 {
82 	struct sshbuf *log_msg;
83 	struct monitor *mon = (struct monitor *)ctx;
84 	int r;
85 	size_t len;
86 
87 	if (mon->m_log_sendfd == -1)
88 		fatal("%s: no log channel", __func__);
89 
90 	if ((log_msg = sshbuf_new()) == NULL)
91 		fatal("%s: sshbuf_new failed", __func__);
92 
93 	if ((r = sshbuf_put_u32(log_msg, 0)) != 0 || /* length; filled below */
94 	    (r = sshbuf_put_u32(log_msg, level)) != 0 ||
95 	    (r = sshbuf_put_cstring(log_msg, msg)) != 0)
96 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
97 	if ((len = sshbuf_len(log_msg)) < 4 || len > 0xffffffff)
98 		fatal("%s: bad length %zu", __func__, len);
99 	POKE_U32(sshbuf_mutable_ptr(log_msg), len - 4);
100 	if (atomicio(vwrite, mon->m_log_sendfd,
101 	    sshbuf_mutable_ptr(log_msg), len) != len)
102 		fatal("%s: write: %s", __func__, strerror(errno));
103 	sshbuf_free(log_msg);
104 }
105 
106 int
107 mm_is_monitor(void)
108 {
109 	/*
110 	 * m_pid is only set in the privileged part, and
111 	 * points to the unprivileged child.
112 	 */
113 	return (pmonitor && pmonitor->m_pid > 0);
114 }
115 
116 void
117 mm_request_send(int sock, enum monitor_reqtype type, struct sshbuf *m)
118 {
119 	size_t mlen = sshbuf_len(m);
120 	u_char buf[5];
121 
122 	debug3("%s entering: type %d", __func__, type);
123 
124 	if (mlen >= 0xffffffff)
125 		fatal("%s: bad length %zu", __func__, mlen);
126 	POKE_U32(buf, mlen + 1);
127 	buf[4] = (u_char) type;		/* 1st byte of payload is mesg-type */
128 	if (atomicio(vwrite, sock, buf, sizeof(buf)) != sizeof(buf))
129 		fatal("%s: write: %s", __func__, strerror(errno));
130 	if (atomicio(vwrite, sock, sshbuf_mutable_ptr(m), mlen) != mlen)
131 		fatal("%s: write: %s", __func__, strerror(errno));
132 }
133 
134 void
135 mm_request_receive(int sock, struct sshbuf *m)
136 {
137 	u_char buf[4], *p = NULL;
138 	u_int msg_len;
139 	int r;
140 
141 	debug3("%s entering", __func__);
142 
143 	if (atomicio(read, sock, buf, sizeof(buf)) != sizeof(buf)) {
144 		if (errno == EPIPE)
145 			cleanup_exit(255);
146 		fatal("%s: read: %s", __func__, strerror(errno));
147 	}
148 	msg_len = PEEK_U32(buf);
149 	if (msg_len > 256 * 1024)
150 		fatal("%s: read: bad msg_len %d", __func__, msg_len);
151 	sshbuf_reset(m);
152 	if ((r = sshbuf_reserve(m, msg_len, &p)) != 0)
153 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
154 	if (atomicio(read, sock, p, msg_len) != msg_len)
155 		fatal("%s: read: %s", __func__, strerror(errno));
156 }
157 
158 void
159 mm_request_receive_expect(int sock, enum monitor_reqtype type, struct sshbuf *m)
160 {
161 	u_char rtype;
162 	int r;
163 
164 	debug3("%s entering: type %d", __func__, type);
165 
166 	mm_request_receive(sock, m);
167 	if ((r = sshbuf_get_u8(m, &rtype)) != 0)
168 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
169 	if (rtype != type)
170 		fatal("%s: read: rtype %d != type %d", __func__,
171 		    rtype, type);
172 }
173 
174 #ifdef WITH_OPENSSL
175 DH *
176 mm_choose_dh(int min, int nbits, int max)
177 {
178 	BIGNUM *p, *g;
179 	int r;
180 	u_char success = 0;
181 	struct sshbuf *m;
182 
183 	if ((m = sshbuf_new()) == NULL)
184 		fatal("%s: sshbuf_new failed", __func__);
185 	if ((r = sshbuf_put_u32(m, min)) != 0 ||
186 	    (r = sshbuf_put_u32(m, nbits)) != 0 ||
187 	    (r = sshbuf_put_u32(m, max)) != 0)
188 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
189 
190 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_MODULI, m);
191 
192 	debug3("%s: waiting for MONITOR_ANS_MODULI", __func__);
193 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_MODULI, m);
194 
195 	if ((r = sshbuf_get_u8(m, &success)) != 0)
196 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
197 	if (success == 0)
198 		fatal("%s: MONITOR_ANS_MODULI failed", __func__);
199 
200 	if ((r = sshbuf_get_bignum2(m, &p)) != 0 ||
201 	    (r = sshbuf_get_bignum2(m, &g)) != 0)
202 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
203 
204 	debug3("%s: remaining %zu", __func__, sshbuf_len(m));
205 	sshbuf_free(m);
206 
207 	return (dh_new_group(g, p));
208 }
209 #endif
210 
211 int
212 mm_sshkey_sign(struct ssh *ssh, struct sshkey *key, u_char **sigp, size_t *lenp,
213     const u_char *data, size_t datalen, const char *hostkey_alg, u_int compat)
214 {
215 	struct kex *kex = *pmonitor->m_pkex;
216 	struct sshbuf *m;
217 	u_int ndx = kex->host_key_index(key, 0, ssh);
218 	int r;
219 
220 	debug3("%s entering", __func__);
221 
222 	if ((m = sshbuf_new()) == NULL)
223 		fatal("%s: sshbuf_new failed", __func__);
224 	if ((r = sshbuf_put_u32(m, ndx)) != 0 ||
225 	    (r = sshbuf_put_string(m, data, datalen)) != 0 ||
226 	    (r = sshbuf_put_cstring(m, hostkey_alg)) != 0 ||
227 	    (r = sshbuf_put_u32(m, compat)) != 0)
228 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
229 
230 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, m);
231 
232 	debug3("%s: waiting for MONITOR_ANS_SIGN", __func__);
233 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SIGN, m);
234 	if ((r = sshbuf_get_string(m, sigp, lenp)) != 0)
235 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
236 	sshbuf_free(m);
237 
238 	return (0);
239 }
240 
241 struct passwd *
242 mm_getpwnamallow(struct ssh *ssh, const char *username)
243 {
244 	struct sshbuf *m;
245 	struct passwd *pw;
246 	size_t len;
247 	u_int i;
248 	ServerOptions *newopts;
249 	int r;
250 	u_char ok;
251 	const u_char *p;
252 
253 	debug3("%s entering", __func__);
254 
255 	if ((m = sshbuf_new()) == NULL)
256 		fatal("%s: sshbuf_new failed", __func__);
257 	if ((r = sshbuf_put_cstring(m, username)) != 0)
258 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
259 
260 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, m);
261 
262 	debug3("%s: waiting for MONITOR_ANS_PWNAM", __func__);
263 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, m);
264 
265 	if ((r = sshbuf_get_u8(m, &ok)) != 0)
266 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
267 	if (ok == 0) {
268 		pw = NULL;
269 		goto out;
270 	}
271 
272 	/* XXX don't like passing struct passwd like this */
273 	pw = xcalloc(sizeof(*pw), 1);
274 	if ((r = sshbuf_get_string_direct(m, &p, &len)) != 0)
275 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
276 	if (len != sizeof(*pw))
277 		fatal("%s: struct passwd size mismatch", __func__);
278 	memcpy(pw, p, sizeof(*pw));
279 
280 	if ((r = sshbuf_get_cstring(m, &pw->pw_name, NULL)) != 0 ||
281 	    (r = sshbuf_get_cstring(m, &pw->pw_passwd, NULL)) != 0 ||
282 	    (r = sshbuf_get_cstring(m, &pw->pw_gecos, NULL)) != 0 ||
283 	    (r = sshbuf_get_cstring(m, &pw->pw_class, NULL)) != 0 ||
284 	    (r = sshbuf_get_cstring(m, &pw->pw_dir, NULL)) != 0 ||
285 	    (r = sshbuf_get_cstring(m, &pw->pw_shell, NULL)) != 0)
286 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
287 
288 out:
289 	/* copy options block as a Match directive may have changed some */
290 	if ((r = sshbuf_get_string_direct(m, &p, &len)) != 0)
291 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
292 	if (len != sizeof(*newopts))
293 		fatal("%s: option block size mismatch", __func__);
294 	newopts = xcalloc(sizeof(*newopts), 1);
295 	memcpy(newopts, p, sizeof(*newopts));
296 
297 #define M_CP_STROPT(x) do { \
298 		if (newopts->x != NULL) { \
299 			if ((r = sshbuf_get_cstring(m, \
300 			    &newopts->x, NULL)) != 0) \
301 				fatal("%s: buffer error: %s", \
302 				    __func__, ssh_err(r)); \
303 		} \
304 	} while (0)
305 #define M_CP_STRARRAYOPT(x, nx) do { \
306 		newopts->x = newopts->nx == 0 ? \
307 		    NULL : xcalloc(newopts->nx, sizeof(*newopts->x)); \
308 		for (i = 0; i < newopts->nx; i++) { \
309 			if ((r = sshbuf_get_cstring(m, \
310 			    &newopts->x[i], NULL)) != 0) \
311 				fatal("%s: buffer error: %s", \
312 				    __func__, ssh_err(r)); \
313 		} \
314 	} while (0)
315 	/* See comment in servconf.h */
316 	COPY_MATCH_STRING_OPTS();
317 #undef M_CP_STROPT
318 #undef M_CP_STRARRAYOPT
319 
320 	copy_set_server_options(&options, newopts, 1);
321 	log_change_level(options.log_level);
322 	process_permitopen(ssh, &options);
323 	free(newopts);
324 
325 	sshbuf_free(m);
326 
327 	return (pw);
328 }
329 
330 char *
331 mm_auth2_read_banner(void)
332 {
333 	struct sshbuf *m;
334 	char *banner;
335 	int r;
336 
337 	debug3("%s entering", __func__);
338 
339 	if ((m = sshbuf_new()) == NULL)
340 		fatal("%s: sshbuf_new failed", __func__);
341 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, m);
342 	sshbuf_reset(m);
343 
344 	mm_request_receive_expect(pmonitor->m_recvfd,
345 	    MONITOR_ANS_AUTH2_READ_BANNER, m);
346 	if ((r = sshbuf_get_cstring(m, &banner, NULL)) != 0)
347 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
348 	sshbuf_free(m);
349 
350 	/* treat empty banner as missing banner */
351 	if (strlen(banner) == 0) {
352 		free(banner);
353 		banner = NULL;
354 	}
355 	return (banner);
356 }
357 
358 /* Inform the privileged process about service and style */
359 
360 void
361 mm_inform_authserv(char *service, char *style)
362 {
363 	struct sshbuf *m;
364 	int r;
365 
366 	debug3("%s entering", __func__);
367 
368 	if ((m = sshbuf_new()) == NULL)
369 		fatal("%s: sshbuf_new failed", __func__);
370 	if ((r = sshbuf_put_cstring(m, service)) != 0 ||
371 	    (r = sshbuf_put_cstring(m, style ? style : "")) != 0)
372 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
373 
374 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, m);
375 
376 	sshbuf_free(m);
377 }
378 
379 /* Do the password authentication */
380 int
381 mm_auth_password(struct ssh *ssh, char *password)
382 {
383 	struct sshbuf *m;
384 	int r, authenticated = 0;
385 
386 	debug3("%s entering", __func__);
387 
388 	if ((m = sshbuf_new()) == NULL)
389 		fatal("%s: sshbuf_new failed", __func__);
390 	if ((r = sshbuf_put_cstring(m, password)) != 0)
391 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
392 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, m);
393 
394 	debug3("%s: waiting for MONITOR_ANS_AUTHPASSWORD", __func__);
395 	mm_request_receive_expect(pmonitor->m_recvfd,
396 	    MONITOR_ANS_AUTHPASSWORD, m);
397 
398 	if ((r = sshbuf_get_u32(m, &authenticated)) != 0)
399 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
400 
401 	sshbuf_free(m);
402 
403 	debug3("%s: user %sauthenticated",
404 	    __func__, authenticated ? "" : "not ");
405 	return (authenticated);
406 }
407 
408 int
409 mm_user_key_allowed(struct ssh *ssh, struct passwd *pw, struct sshkey *key,
410     int pubkey_auth_attempt, struct sshauthopt **authoptp)
411 {
412 	return (mm_key_allowed(MM_USERKEY, NULL, NULL, key,
413 	    pubkey_auth_attempt, authoptp));
414 }
415 
416 int
417 mm_hostbased_key_allowed(struct ssh *ssh, struct passwd *pw,
418     const char *user, const char *host, struct sshkey *key)
419 {
420 	return (mm_key_allowed(MM_HOSTKEY, user, host, key, 0, NULL));
421 }
422 
423 int
424 mm_key_allowed(enum mm_keytype type, const char *user, const char *host,
425     struct sshkey *key, int pubkey_auth_attempt, struct sshauthopt **authoptp)
426 {
427 	struct sshbuf *m;
428 	int r, allowed = 0;
429 	struct sshauthopt *opts = NULL;
430 
431 	debug3("%s entering", __func__);
432 
433 	if (authoptp != NULL)
434 		*authoptp = NULL;
435 
436 	if ((m = sshbuf_new()) == NULL)
437 		fatal("%s: sshbuf_new failed", __func__);
438 	if ((r = sshbuf_put_u32(m, type)) != 0 ||
439 	    (r = sshbuf_put_cstring(m, user ? user : "")) != 0 ||
440 	    (r = sshbuf_put_cstring(m, host ? host : "")) != 0 ||
441 	    (r = sshkey_puts(key, m)) != 0 ||
442 	    (r = sshbuf_put_u32(m, pubkey_auth_attempt)) != 0)
443 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
444 
445 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, m);
446 
447 	debug3("%s: waiting for MONITOR_ANS_KEYALLOWED", __func__);
448 	mm_request_receive_expect(pmonitor->m_recvfd,
449 	    MONITOR_ANS_KEYALLOWED, m);
450 
451 	if ((r = sshbuf_get_u32(m, &allowed)) != 0)
452 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
453 	if (allowed && type == MM_USERKEY) {
454 		if ((r = sshauthopt_deserialise(m, &opts)) != 0)
455 			fatal("%s: sshauthopt_deserialise: %s",
456 			    __func__, ssh_err(r));
457 	}
458 	sshbuf_free(m);
459 
460 	if (authoptp != NULL) {
461 		*authoptp = opts;
462 		opts = NULL;
463 	}
464 	sshauthopt_free(opts);
465 
466 	return allowed;
467 }
468 
469 /*
470  * This key verify needs to send the key type along, because the
471  * privileged parent makes the decision if the key is allowed
472  * for authentication.
473  */
474 
475 int
476 mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen,
477     const u_char *data, size_t datalen, const char *sigalg, u_int compat)
478 {
479 	struct sshbuf *m;
480 	u_int encoded_ret = 0;
481 	int r;
482 
483 	debug3("%s entering", __func__);
484 
485 
486 	if ((m = sshbuf_new()) == NULL)
487 		fatal("%s: sshbuf_new failed", __func__);
488 	if ((r = sshkey_puts(key, m)) != 0 ||
489 	    (r = sshbuf_put_string(m, sig, siglen)) != 0 ||
490 	    (r = sshbuf_put_string(m, data, datalen)) != 0 ||
491 	    (r = sshbuf_put_cstring(m, sigalg == NULL ? "" : sigalg)) != 0)
492 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
493 
494 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, m);
495 
496 	debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__);
497 	mm_request_receive_expect(pmonitor->m_recvfd,
498 	    MONITOR_ANS_KEYVERIFY, m);
499 
500 	if ((r = sshbuf_get_u32(m, &encoded_ret)) != 0)
501 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
502 
503 	sshbuf_free(m);
504 
505 	if (encoded_ret != 0)
506 		return SSH_ERR_SIGNATURE_INVALID;
507 	return 0;
508 }
509 
510 void
511 mm_send_keystate(struct ssh *ssh, struct monitor *monitor)
512 {
513 	struct sshbuf *m;
514 	int r;
515 
516 	if ((m = sshbuf_new()) == NULL)
517 		fatal("%s: sshbuf_new failed", __func__);
518 	if ((r = ssh_packet_get_state(ssh, m)) != 0)
519 		fatal("%s: get_state failed: %s",
520 		    __func__, ssh_err(r));
521 	mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, m);
522 	debug3("%s: Finished sending state", __func__);
523 	sshbuf_free(m);
524 }
525 
526 int
527 mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen)
528 {
529 	struct sshbuf *m;
530 	char *p, *msg;
531 	int success = 0, tmp1 = -1, tmp2 = -1, r;
532 
533 	/* Kludge: ensure there are fds free to receive the pty/tty */
534 	if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 ||
535 	    (tmp2 = dup(pmonitor->m_recvfd)) == -1) {
536 		error("%s: cannot allocate fds for pty", __func__);
537 		if (tmp1 > 0)
538 			close(tmp1);
539 		if (tmp2 > 0)
540 			close(tmp2);
541 		return 0;
542 	}
543 	close(tmp1);
544 	close(tmp2);
545 
546 	if ((m = sshbuf_new()) == NULL)
547 		fatal("%s: sshbuf_new failed", __func__);
548 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, m);
549 
550 	debug3("%s: waiting for MONITOR_ANS_PTY", __func__);
551 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PTY, m);
552 
553 	if ((r = sshbuf_get_u32(m, &success)) != 0)
554 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
555 	if (success == 0) {
556 		debug3("%s: pty alloc failed", __func__);
557 		sshbuf_free(m);
558 		return (0);
559 	}
560 	if ((r = sshbuf_get_cstring(m, &p, NULL)) != 0 ||
561 	    (r = sshbuf_get_cstring(m, &msg, NULL)) != 0)
562 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
563 	sshbuf_free(m);
564 
565 	strlcpy(namebuf, p, namebuflen); /* Possible truncation */
566 	free(p);
567 
568 	if ((r = sshbuf_put(loginmsg, msg, strlen(msg))) != 0)
569 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
570 	free(msg);
571 
572 	if ((*ptyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1 ||
573 	    (*ttyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1)
574 		fatal("%s: receive fds failed", __func__);
575 
576 	/* Success */
577 	return (1);
578 }
579 
580 void
581 mm_session_pty_cleanup2(Session *s)
582 {
583 	struct sshbuf *m;
584 	int r;
585 
586 	if (s->ttyfd == -1)
587 		return;
588 	if ((m = sshbuf_new()) == NULL)
589 		fatal("%s: sshbuf_new failed", __func__);
590 	if ((r = sshbuf_put_cstring(m, s->tty)) != 0)
591 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
592 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, m);
593 	sshbuf_free(m);
594 
595 	/* closed dup'ed master */
596 	if (s->ptymaster != -1 && close(s->ptymaster) < 0)
597 		error("close(s->ptymaster/%d): %s",
598 		    s->ptymaster, strerror(errno));
599 
600 	/* unlink pty from session */
601 	s->ttyfd = -1;
602 }
603 
604 /* Request process termination */
605 
606 void
607 mm_terminate(void)
608 {
609 	struct sshbuf *m;
610 
611 	if ((m = sshbuf_new()) == NULL)
612 		fatal("%s: sshbuf_new failed", __func__);
613 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_TERM, m);
614 	sshbuf_free(m);
615 }
616 
617 static void
618 mm_chall_setup(char **name, char **infotxt, u_int *numprompts,
619     char ***prompts, u_int **echo_on)
620 {
621 	*name = xstrdup("");
622 	*infotxt = xstrdup("");
623 	*numprompts = 1;
624 	*prompts = xcalloc(*numprompts, sizeof(char *));
625 	*echo_on = xcalloc(*numprompts, sizeof(u_int));
626 	(*echo_on)[0] = 0;
627 }
628 
629 int
630 mm_bsdauth_query(void *ctx, char **name, char **infotxt,
631    u_int *numprompts, char ***prompts, u_int **echo_on)
632 {
633 	struct sshbuf *m;
634 	u_int success;
635 	char *challenge;
636 	int r;
637 
638 	debug3("%s: entering", __func__);
639 
640 	if ((m = sshbuf_new()) == NULL)
641 		fatal("%s: sshbuf_new failed", __func__);
642 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHQUERY, m);
643 
644 	mm_request_receive_expect(pmonitor->m_recvfd,
645 	    MONITOR_ANS_BSDAUTHQUERY, m);
646 	if ((r = sshbuf_get_u32(m, &success)) != 0)
647 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
648 	if (success == 0) {
649 		debug3("%s: no challenge", __func__);
650 		sshbuf_free(m);
651 		return (-1);
652 	}
653 
654 	/* Get the challenge, and format the response */
655 	if ((r = sshbuf_get_cstring(m, &challenge, NULL)) != 0)
656 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
657 	sshbuf_free(m);
658 
659 	mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
660 	(*prompts)[0] = challenge;
661 
662 	debug3("%s: received challenge: %s", __func__, challenge);
663 
664 	return (0);
665 }
666 
667 int
668 mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses)
669 {
670 	struct sshbuf *m;
671 	int r, authok;
672 
673 	debug3("%s: entering", __func__);
674 	if (numresponses != 1)
675 		return (-1);
676 
677 	if ((m = sshbuf_new()) == NULL)
678 		fatal("%s: sshbuf_new failed", __func__);
679 	if ((r = sshbuf_put_cstring(m, responses[0])) != 0)
680 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
681 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHRESPOND, m);
682 
683 	mm_request_receive_expect(pmonitor->m_recvfd,
684 	    MONITOR_ANS_BSDAUTHRESPOND, m);
685 
686 	if ((r = sshbuf_get_u32(m, &authok)) != 0)
687 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
688 	sshbuf_free(m);
689 
690 	return ((authok == 0) ? -1 : 0);
691 }
692 
693 #ifdef GSSAPI
694 OM_uint32
695 mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid)
696 {
697 	struct sshbuf *m;
698 	OM_uint32 major;
699 	int r;
700 
701 	/* Client doesn't get to see the context */
702 	*ctx = NULL;
703 
704 	if ((m = sshbuf_new()) == NULL)
705 		fatal("%s: sshbuf_new failed", __func__);
706 	if ((r = sshbuf_put_string(m, goid->elements, goid->length)) != 0)
707 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
708 
709 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, m);
710 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, m);
711 
712 	if ((r = sshbuf_get_u32(m, &major)) != 0)
713 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
714 
715 	sshbuf_free(m);
716 	return (major);
717 }
718 
719 OM_uint32
720 mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in,
721     gss_buffer_desc *out, OM_uint32 *flagsp)
722 {
723 	struct sshbuf *m;
724 	OM_uint32 major;
725 	u_int flags;
726 	int r;
727 
728 	if ((m = sshbuf_new()) == NULL)
729 		fatal("%s: sshbuf_new failed", __func__);
730 	if ((r = sshbuf_put_string(m, in->value, in->length)) != 0)
731 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
732 
733 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, m);
734 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, m);
735 
736 	if ((r = sshbuf_get_u32(m, &major)) != 0 ||
737 	    (r = ssh_gssapi_get_buffer_desc(m, out)) != 0)
738 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
739 	if (flagsp != NULL) {
740 		if ((r = sshbuf_get_u32(m, &flags)) != 0)
741 			fatal("%s: buffer error: %s", __func__, ssh_err(r));
742 		*flagsp = flags;
743 	}
744 
745 	sshbuf_free(m);
746 
747 	return (major);
748 }
749 
750 OM_uint32
751 mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
752 {
753 	struct sshbuf *m;
754 	OM_uint32 major;
755 	int r;
756 
757 	if ((m = sshbuf_new()) == NULL)
758 		fatal("%s: sshbuf_new failed", __func__);
759 	if ((r = sshbuf_put_string(m, gssbuf->value, gssbuf->length)) != 0 ||
760 	    (r = sshbuf_put_string(m, gssmic->value, gssmic->length)) != 0)
761 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
762 
763 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, m);
764 	mm_request_receive_expect(pmonitor->m_recvfd,
765 	    MONITOR_ANS_GSSCHECKMIC, m);
766 
767 	if ((r = sshbuf_get_u32(m, &major)) != 0)
768 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
769 	sshbuf_free(m);
770 	return(major);
771 }
772 
773 int
774 mm_ssh_gssapi_userok(char *user)
775 {
776 	struct sshbuf *m;
777 	int r, authenticated = 0;
778 
779 	if ((m = sshbuf_new()) == NULL)
780 		fatal("%s: sshbuf_new failed", __func__);
781 
782 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, m);
783 	mm_request_receive_expect(pmonitor->m_recvfd,
784 	    MONITOR_ANS_GSSUSEROK, m);
785 
786 	if ((r = sshbuf_get_u32(m, &authenticated)) != 0)
787 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
788 
789 	sshbuf_free(m);
790 	debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not ");
791 	return (authenticated);
792 }
793 #endif /* GSSAPI */
794