monitor.c revision 99046
1/*
2 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
3 * Copyright 2002 Markus Friedl <markus@openbsd.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "includes.h"
28RCSID("$OpenBSD: monitor.c,v 1.16 2002/06/21 05:50:51 djm Exp $");
29RCSID("$FreeBSD: head/crypto/openssh/monitor.c 99046 2002-06-29 10:44:37Z des $");
30
31#include <openssl/dh.h>
32
33#ifdef SKEY
34#ifdef OPIE
35#include <opie.h>
36#define skey                    opie
37#define skeychallenge(k, u, c)  opiechallenge((k), (u), (c))
38#define skey_haskey(u)          opie_haskey((u))
39#define skey_passcheck(u, r)    opie_passverify((u), (r))
40#else
41#include <skey.h>
42#endif
43#endif
44
45#include "ssh.h"
46#include "auth.h"
47#include "kex.h"
48#include "dh.h"
49#include "zlib.h"
50#include "packet.h"
51#include "auth-options.h"
52#include "sshpty.h"
53#include "channels.h"
54#include "session.h"
55#include "sshlogin.h"
56#include "canohost.h"
57#include "log.h"
58#include "servconf.h"
59#include "monitor.h"
60#include "monitor_mm.h"
61#include "monitor_wrap.h"
62#include "monitor_fdpass.h"
63#include "xmalloc.h"
64#include "misc.h"
65#include "buffer.h"
66#include "bufaux.h"
67#include "compat.h"
68#include "ssh2.h"
69#include "mpaux.h"
70
71/* Imports */
72extern ServerOptions options;
73extern u_int utmp_len;
74extern Newkeys *current_keys[];
75extern z_stream incoming_stream;
76extern z_stream outgoing_stream;
77extern u_char session_id[];
78extern Buffer input, output;
79extern Buffer auth_debug;
80extern int auth_debug_init;
81
82/* State exported from the child */
83
84struct {
85	z_stream incoming;
86	z_stream outgoing;
87	u_char *keyin;
88	u_int keyinlen;
89	u_char *keyout;
90	u_int keyoutlen;
91	u_char *ivin;
92	u_int ivinlen;
93	u_char *ivout;
94	u_int ivoutlen;
95	u_char *ssh1key;
96	u_int ssh1keylen;
97	int ssh1cipher;
98	int ssh1protoflags;
99	u_char *input;
100	u_int ilen;
101	u_char *output;
102	u_int olen;
103} child_state;
104
105/* Functions on the montior that answer unprivileged requests */
106
107int mm_answer_moduli(int, Buffer *);
108int mm_answer_sign(int, Buffer *);
109int mm_answer_pwnamallow(int, Buffer *);
110int mm_answer_auth2_read_banner(int, Buffer *);
111int mm_answer_authserv(int, Buffer *);
112int mm_answer_authpassword(int, Buffer *);
113int mm_answer_bsdauthquery(int, Buffer *);
114int mm_answer_bsdauthrespond(int, Buffer *);
115int mm_answer_skeyquery(int, Buffer *);
116int mm_answer_skeyrespond(int, Buffer *);
117int mm_answer_keyallowed(int, Buffer *);
118int mm_answer_keyverify(int, Buffer *);
119int mm_answer_pty(int, Buffer *);
120int mm_answer_pty_cleanup(int, Buffer *);
121int mm_answer_term(int, Buffer *);
122int mm_answer_rsa_keyallowed(int, Buffer *);
123int mm_answer_rsa_challenge(int, Buffer *);
124int mm_answer_rsa_response(int, Buffer *);
125int mm_answer_sesskey(int, Buffer *);
126int mm_answer_sessid(int, Buffer *);
127
128#ifdef USE_PAM
129int mm_answer_pam_start(int, Buffer *);
130#endif
131
132static Authctxt *authctxt;
133static BIGNUM *ssh1_challenge = NULL;	/* used for ssh1 rsa auth */
134
135/* local state for key verify */
136static u_char *key_blob = NULL;
137static u_int key_bloblen = 0;
138static int key_blobtype = MM_NOKEY;
139static u_char *hostbased_cuser = NULL;
140static u_char *hostbased_chost = NULL;
141static char *auth_method = "unknown";
142static int session_id2_len = 0;
143static u_char *session_id2 = NULL;
144
145struct mon_table {
146	enum monitor_reqtype type;
147	int flags;
148	int (*f)(int, Buffer *);
149};
150
151#define MON_ISAUTH	0x0004	/* Required for Authentication */
152#define MON_AUTHDECIDE	0x0008	/* Decides Authentication */
153#define MON_ONCE	0x0010	/* Disable after calling */
154
155#define MON_AUTH	(MON_ISAUTH|MON_AUTHDECIDE)
156
157#define MON_PERMIT	0x1000	/* Request is permitted */
158
159struct mon_table mon_dispatch_proto20[] = {
160    {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli},
161    {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
162    {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
163    {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
164    {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
165    {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
166#ifdef USE_PAM
167    {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},
168#endif
169#ifdef BSD_AUTH
170    {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
171    {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond},
172#endif
173#ifdef SKEY
174    {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery},
175    {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond},
176#endif
177    {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed},
178    {MONITOR_REQ_KEYVERIFY, MON_AUTH, mm_answer_keyverify},
179    {0, 0, NULL}
180};
181
182struct mon_table mon_dispatch_postauth20[] = {
183    {MONITOR_REQ_MODULI, 0, mm_answer_moduli},
184    {MONITOR_REQ_SIGN, 0, mm_answer_sign},
185    {MONITOR_REQ_PTY, 0, mm_answer_pty},
186    {MONITOR_REQ_PTYCLEANUP, 0, mm_answer_pty_cleanup},
187    {MONITOR_REQ_TERM, 0, mm_answer_term},
188    {0, 0, NULL}
189};
190
191struct mon_table mon_dispatch_proto15[] = {
192    {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
193    {MONITOR_REQ_SESSKEY, MON_ONCE, mm_answer_sesskey},
194    {MONITOR_REQ_SESSID, MON_ONCE, mm_answer_sessid},
195    {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
196    {MONITOR_REQ_RSAKEYALLOWED, MON_ISAUTH, mm_answer_rsa_keyallowed},
197    {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed},
198    {MONITOR_REQ_RSACHALLENGE, MON_ONCE, mm_answer_rsa_challenge},
199    {MONITOR_REQ_RSARESPONSE, MON_ONCE|MON_AUTHDECIDE, mm_answer_rsa_response},
200#ifdef USE_PAM
201    {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},
202#endif
203#ifdef BSD_AUTH
204    {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
205    {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond},
206#endif
207#ifdef SKEY
208    {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery},
209    {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond},
210#endif
211#ifdef USE_PAM
212    {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},
213#endif
214    {0, 0, NULL}
215};
216
217struct mon_table mon_dispatch_postauth15[] = {
218    {MONITOR_REQ_PTY, MON_ONCE, mm_answer_pty},
219    {MONITOR_REQ_PTYCLEANUP, MON_ONCE, mm_answer_pty_cleanup},
220    {MONITOR_REQ_TERM, 0, mm_answer_term},
221    {0, 0, NULL}
222};
223
224struct mon_table *mon_dispatch;
225
226/* Specifies if a certain message is allowed at the moment */
227
228static void
229monitor_permit(struct mon_table *ent, enum monitor_reqtype type, int permit)
230{
231	while (ent->f != NULL) {
232		if (ent->type == type) {
233			ent->flags &= ~MON_PERMIT;
234			ent->flags |= permit ? MON_PERMIT : 0;
235			return;
236		}
237		ent++;
238	}
239}
240
241static void
242monitor_permit_authentications(int permit)
243{
244	struct mon_table *ent = mon_dispatch;
245
246	while (ent->f != NULL) {
247		if (ent->flags & MON_AUTH) {
248			ent->flags &= ~MON_PERMIT;
249			ent->flags |= permit ? MON_PERMIT : 0;
250		}
251		ent++;
252	}
253}
254
255Authctxt *
256monitor_child_preauth(struct monitor *pmonitor)
257{
258	struct mon_table *ent;
259	int authenticated = 0;
260
261	debug3("preauth child monitor started");
262
263	if (compat20) {
264		mon_dispatch = mon_dispatch_proto20;
265
266		/* Permit requests for moduli and signatures */
267		monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
268		monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
269	} else {
270		mon_dispatch = mon_dispatch_proto15;
271
272		monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1);
273	}
274
275	authctxt = authctxt_new();
276
277	/* The first few requests do not require asynchronous access */
278	while (!authenticated) {
279		authenticated = monitor_read(pmonitor, mon_dispatch, &ent);
280		if (authenticated) {
281			if (!(ent->flags & MON_AUTHDECIDE))
282				fatal("%s: unexpected authentication from %d",
283				    __func__, ent->type);
284			if (authctxt->pw->pw_uid == 0 &&
285			    !auth_root_allowed(auth_method))
286				authenticated = 0;
287#ifdef USE_PAM
288			if (!do_pam_account(authctxt->pw->pw_name, NULL))
289				authenticated = 0;
290#endif
291		}
292
293		if (ent->flags & MON_AUTHDECIDE) {
294			auth_log(authctxt, authenticated, auth_method,
295			    compat20 ? " ssh2" : "");
296			if (!authenticated)
297				authctxt->failures++;
298		}
299	}
300
301	if (!authctxt->valid)
302		fatal("%s: authenticated invalid user", __func__);
303
304	debug("%s: %s has been authenticated by privileged process",
305	    __func__, authctxt->user);
306
307	mm_get_keystate(pmonitor);
308
309	return (authctxt);
310}
311
312void
313monitor_child_postauth(struct monitor *pmonitor)
314{
315	if (compat20) {
316		mon_dispatch = mon_dispatch_postauth20;
317
318		/* Permit requests for moduli and signatures */
319		monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
320		monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
321		monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
322
323	} else {
324		mon_dispatch = mon_dispatch_postauth15;
325		monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
326	}
327	if (!no_pty_flag) {
328		monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1);
329		monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1);
330	}
331
332	for (;;)
333		monitor_read(pmonitor, mon_dispatch, NULL);
334}
335
336void
337monitor_sync(struct monitor *pmonitor)
338{
339	if (options.compression) {
340		/* The member allocation is not visible, so sync it */
341		mm_share_sync(&pmonitor->m_zlib, &pmonitor->m_zback);
342	}
343}
344
345int
346monitor_read(struct monitor *pmonitor, struct mon_table *ent,
347    struct mon_table **pent)
348{
349	Buffer m;
350	int ret;
351	u_char type;
352
353	buffer_init(&m);
354
355	mm_request_receive(pmonitor->m_sendfd, &m);
356	type = buffer_get_char(&m);
357
358	debug3("%s: checking request %d", __func__, type);
359
360	while (ent->f != NULL) {
361		if (ent->type == type)
362			break;
363		ent++;
364	}
365
366	if (ent->f != NULL) {
367		if (!(ent->flags & MON_PERMIT))
368			fatal("%s: unpermitted request %d", __func__,
369			    type);
370		ret = (*ent->f)(pmonitor->m_sendfd, &m);
371		buffer_free(&m);
372
373		/* The child may use this request only once, disable it */
374		if (ent->flags & MON_ONCE) {
375			debug2("%s: %d used once, disabling now", __func__,
376			    type);
377			ent->flags &= ~MON_PERMIT;
378		}
379
380		if (pent != NULL)
381			*pent = ent;
382
383		return ret;
384	}
385
386	fatal("%s: unsupported request: %d", __func__, type);
387
388	/* NOTREACHED */
389	return (-1);
390}
391
392/* allowed key state */
393static int
394monitor_allowed_key(u_char *blob, u_int bloblen)
395{
396	/* make sure key is allowed */
397	if (key_blob == NULL || key_bloblen != bloblen ||
398	    memcmp(key_blob, blob, key_bloblen))
399		return (0);
400	return (1);
401}
402
403static void
404monitor_reset_key_state(void)
405{
406	/* reset state */
407	if (key_blob != NULL)
408		xfree(key_blob);
409	if (hostbased_cuser != NULL)
410		xfree(hostbased_cuser);
411	if (hostbased_chost != NULL)
412		xfree(hostbased_chost);
413	key_blob = NULL;
414	key_bloblen = 0;
415	key_blobtype = MM_NOKEY;
416	hostbased_cuser = NULL;
417	hostbased_chost = NULL;
418}
419
420int
421mm_answer_moduli(int socket, Buffer *m)
422{
423	DH *dh;
424	int min, want, max;
425
426	min = buffer_get_int(m);
427	want = buffer_get_int(m);
428	max = buffer_get_int(m);
429
430	debug3("%s: got parameters: %d %d %d",
431	    __func__, min, want, max);
432	/* We need to check here, too, in case the child got corrupted */
433	if (max < min || want < min || max < want)
434		fatal("%s: bad parameters: %d %d %d",
435		    __func__, min, want, max);
436
437	buffer_clear(m);
438
439	dh = choose_dh(min, want, max);
440	if (dh == NULL) {
441		buffer_put_char(m, 0);
442		return (0);
443	} else {
444		/* Send first bignum */
445		buffer_put_char(m, 1);
446		buffer_put_bignum2(m, dh->p);
447		buffer_put_bignum2(m, dh->g);
448
449		DH_free(dh);
450	}
451	mm_request_send(socket, MONITOR_ANS_MODULI, m);
452	return (0);
453}
454
455int
456mm_answer_sign(int socket, Buffer *m)
457{
458	Key *key;
459	u_char *p;
460	u_char *signature;
461	u_int siglen, datlen;
462	int keyid;
463
464	debug3("%s", __func__);
465
466	keyid = buffer_get_int(m);
467	p = buffer_get_string(m, &datlen);
468
469	if (datlen != 20)
470		fatal("%s: data length incorrect: %d", __func__, datlen);
471
472	/* save session id, it will be passed on the first call */
473	if (session_id2_len == 0) {
474		session_id2_len = datlen;
475		session_id2 = xmalloc(session_id2_len);
476		memcpy(session_id2, p, session_id2_len);
477	}
478
479	if ((key = get_hostkey_by_index(keyid)) == NULL)
480		fatal("%s: no hostkey from index %d", __func__, keyid);
481	if (key_sign(key, &signature, &siglen, p, datlen) < 0)
482		fatal("%s: key_sign failed", __func__);
483
484	debug3("%s: signature %p(%d)", __func__, signature, siglen);
485
486	buffer_clear(m);
487	buffer_put_string(m, signature, siglen);
488
489	xfree(p);
490	xfree(signature);
491
492	mm_request_send(socket, MONITOR_ANS_SIGN, m);
493
494	/* Turn on permissions for getpwnam */
495	monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
496
497	return (0);
498}
499
500/* Retrieves the password entry and also checks if the user is permitted */
501
502int
503mm_answer_pwnamallow(int socket, Buffer *m)
504{
505	char *login;
506	struct passwd *pwent;
507	int allowed = 0;
508
509	debug3("%s", __func__);
510
511	if (authctxt->attempt++ != 0)
512		fatal("%s: multiple attempts for getpwnam", __func__);
513
514	login = buffer_get_string(m, NULL);
515
516	pwent = getpwnamallow(login);
517
518	authctxt->user = xstrdup(login);
519	setproctitle("%s [priv]", pwent ? login : "unknown");
520	xfree(login);
521
522	buffer_clear(m);
523
524	if (pwent == NULL) {
525		buffer_put_char(m, 0);
526		goto out;
527	}
528
529	allowed = 1;
530	authctxt->pw = pwent;
531	authctxt->valid = 1;
532
533	buffer_put_char(m, 1);
534	buffer_put_string(m, pwent, sizeof(struct passwd));
535	buffer_put_cstring(m, pwent->pw_name);
536	buffer_put_cstring(m, "*");
537	buffer_put_cstring(m, pwent->pw_gecos);
538#ifdef HAVE_PW_CLASS_IN_PASSWD
539	buffer_put_cstring(m, pwent->pw_class);
540#endif
541	buffer_put_cstring(m, pwent->pw_dir);
542	buffer_put_cstring(m, pwent->pw_shell);
543
544 out:
545	debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed);
546	mm_request_send(socket, MONITOR_ANS_PWNAM, m);
547
548	/* For SSHv1 allow authentication now */
549	if (!compat20)
550		monitor_permit_authentications(1);
551	else {
552		/* Allow service/style information on the auth context */
553		monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
554		monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
555	}
556
557#ifdef USE_PAM
558	monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1);
559#endif
560
561	return (0);
562}
563
564int mm_answer_auth2_read_banner(int socket, Buffer *m)
565{
566	char *banner;
567
568	buffer_clear(m);
569	banner = auth2_read_banner();
570	buffer_put_cstring(m, banner != NULL ? banner : "");
571	mm_request_send(socket, MONITOR_ANS_AUTH2_READ_BANNER, m);
572
573	if (banner != NULL)
574		free(banner);
575
576	return (0);
577}
578
579int
580mm_answer_authserv(int socket, Buffer *m)
581{
582	monitor_permit_authentications(1);
583
584	authctxt->service = buffer_get_string(m, NULL);
585	authctxt->style = buffer_get_string(m, NULL);
586	debug3("%s: service=%s, style=%s",
587	    __func__, authctxt->service, authctxt->style);
588
589	if (strlen(authctxt->style) == 0) {
590		xfree(authctxt->style);
591		authctxt->style = NULL;
592	}
593
594	return (0);
595}
596
597int
598mm_answer_authpassword(int socket, Buffer *m)
599{
600	static int call_count;
601	char *passwd;
602	int authenticated, plen;
603
604	passwd = buffer_get_string(m, &plen);
605	/* Only authenticate if the context is valid */
606	authenticated = options.password_authentication &&
607	    authctxt->valid && auth_password(authctxt, passwd);
608	memset(passwd, 0, strlen(passwd));
609	xfree(passwd);
610
611	buffer_clear(m);
612	buffer_put_int(m, authenticated);
613
614	debug3("%s: sending result %d", __func__, authenticated);
615	mm_request_send(socket, MONITOR_ANS_AUTHPASSWORD, m);
616
617	call_count++;
618	if (plen == 0 && call_count == 1)
619		auth_method = "none";
620	else
621		auth_method = "password";
622
623	/* Causes monitor loop to terminate if authenticated */
624	return (authenticated);
625}
626
627#ifdef BSD_AUTH
628int
629mm_answer_bsdauthquery(int socket, Buffer *m)
630{
631	char *name, *infotxt;
632	u_int numprompts;
633	u_int *echo_on;
634	char **prompts;
635	int res;
636
637	res = bsdauth_query(authctxt, &name, &infotxt, &numprompts,
638	    &prompts, &echo_on);
639
640	buffer_clear(m);
641	buffer_put_int(m, res);
642	if (res != -1)
643		buffer_put_cstring(m, prompts[0]);
644
645	debug3("%s: sending challenge res: %d", __func__, res);
646	mm_request_send(socket, MONITOR_ANS_BSDAUTHQUERY, m);
647
648	if (res != -1) {
649		xfree(name);
650		xfree(infotxt);
651		xfree(prompts);
652		xfree(echo_on);
653	}
654
655	return (0);
656}
657
658int
659mm_answer_bsdauthrespond(int socket, Buffer *m)
660{
661	char *response;
662	int authok;
663
664	if (authctxt->as == 0)
665		fatal("%s: no bsd auth session", __func__);
666
667	response = buffer_get_string(m, NULL);
668	authok = options.challenge_response_authentication &&
669	    auth_userresponse(authctxt->as, response, 0);
670	authctxt->as = NULL;
671	debug3("%s: <%s> = <%d>", __func__, response, authok);
672	xfree(response);
673
674	buffer_clear(m);
675	buffer_put_int(m, authok);
676
677	debug3("%s: sending authenticated: %d", __func__, authok);
678	mm_request_send(socket, MONITOR_ANS_BSDAUTHRESPOND, m);
679
680	auth_method = "bsdauth";
681
682	return (authok != 0);
683}
684#endif
685
686#ifdef SKEY
687int
688mm_answer_skeyquery(int socket, Buffer *m)
689{
690	struct skey skey;
691	char challenge[1024];
692	int res;
693
694	res = skeychallenge(&skey, authctxt->user, challenge);
695
696	buffer_clear(m);
697	buffer_put_int(m, res);
698	if (res != -1)
699		buffer_put_cstring(m, challenge);
700
701	debug3("%s: sending challenge res: %d", __func__, res);
702	mm_request_send(socket, MONITOR_ANS_SKEYQUERY, m);
703
704	return (0);
705}
706
707int
708mm_answer_skeyrespond(int socket, Buffer *m)
709{
710	char *response;
711	int authok;
712
713	response = buffer_get_string(m, NULL);
714
715	authok = (options.challenge_response_authentication &&
716	    authctxt->valid &&
717	    skey_haskey(authctxt->pw->pw_name) == 0 &&
718	    skey_passcheck(authctxt->pw->pw_name, response) != -1);
719
720	xfree(response);
721
722	buffer_clear(m);
723	buffer_put_int(m, authok);
724
725	debug3("%s: sending authenticated: %d", __func__, authok);
726	mm_request_send(socket, MONITOR_ANS_SKEYRESPOND, m);
727
728	auth_method = "skey";
729
730	return (authok != 0);
731}
732#endif
733
734#ifdef USE_PAM
735int
736mm_answer_pam_start(int socket, Buffer *m)
737{
738	char *user;
739
740	user = buffer_get_string(m, NULL);
741
742	start_pam(user);
743
744	xfree(user);
745
746	return (0);
747}
748#endif
749
750static void
751mm_append_debug(Buffer *m)
752{
753	if (auth_debug_init && buffer_len(&auth_debug)) {
754		debug3("%s: Appending debug messages for child", __func__);
755		buffer_append(m, buffer_ptr(&auth_debug),
756		    buffer_len(&auth_debug));
757		buffer_clear(&auth_debug);
758	}
759}
760
761int
762mm_answer_keyallowed(int socket, Buffer *m)
763{
764	Key *key;
765	u_char *cuser, *chost, *blob;
766	u_int bloblen;
767	enum mm_keytype type = 0;
768	int allowed = 0;
769
770	debug3("%s entering", __func__);
771
772	type = buffer_get_int(m);
773	cuser = buffer_get_string(m, NULL);
774	chost = buffer_get_string(m, NULL);
775	blob = buffer_get_string(m, &bloblen);
776
777	key = key_from_blob(blob, bloblen);
778
779	if ((compat20 && type == MM_RSAHOSTKEY) ||
780	    (!compat20 && type != MM_RSAHOSTKEY))
781		fatal("%s: key type and protocol mismatch", __func__);
782
783	debug3("%s: key_from_blob: %p", __func__, key);
784
785	if (key != NULL && authctxt->pw != NULL) {
786		switch(type) {
787		case MM_USERKEY:
788			allowed = options.pubkey_authentication &&
789			    user_key_allowed(authctxt->pw, key);
790			break;
791		case MM_HOSTKEY:
792			allowed = options.hostbased_authentication &&
793			    hostbased_key_allowed(authctxt->pw,
794			    cuser, chost, key);
795			break;
796		case MM_RSAHOSTKEY:
797			key->type = KEY_RSA1; /* XXX */
798			allowed = options.rhosts_rsa_authentication &&
799			    auth_rhosts_rsa_key_allowed(authctxt->pw,
800			    cuser, chost, key);
801			break;
802		default:
803			fatal("%s: unknown key type %d", __func__, type);
804			break;
805		}
806		key_free(key);
807	}
808
809	/* clear temporarily storage (used by verify) */
810	monitor_reset_key_state();
811
812	if (allowed) {
813		/* Save temporarily for comparison in verify */
814		key_blob = blob;
815		key_bloblen = bloblen;
816		key_blobtype = type;
817		hostbased_cuser = cuser;
818		hostbased_chost = chost;
819	}
820
821	debug3("%s: key %p is %s",
822	    __func__, key, allowed ? "allowed" : "disallowed");
823
824	buffer_clear(m);
825	buffer_put_int(m, allowed);
826
827	mm_append_debug(m);
828
829	mm_request_send(socket, MONITOR_ANS_KEYALLOWED, m);
830
831	if (type == MM_RSAHOSTKEY)
832		monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed);
833
834	return (0);
835}
836
837static int
838monitor_valid_userblob(u_char *data, u_int datalen)
839{
840	Buffer b;
841	u_char *p;
842	u_int len;
843	int fail = 0;
844
845	buffer_init(&b);
846	buffer_append(&b, data, datalen);
847
848	if (datafellows & SSH_OLD_SESSIONID) {
849		p = buffer_ptr(&b);
850		len = buffer_len(&b);
851		if ((session_id2 == NULL) ||
852		    (len < session_id2_len) ||
853		    (memcmp(p, session_id2, session_id2_len) != 0))
854			fail++;
855		buffer_consume(&b, session_id2_len);
856	} else {
857		p = buffer_get_string(&b, &len);
858		if ((session_id2 == NULL) ||
859		    (len != session_id2_len) ||
860		    (memcmp(p, session_id2, session_id2_len) != 0))
861			fail++;
862		xfree(p);
863	}
864	if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST)
865		fail++;
866	p = buffer_get_string(&b, NULL);
867	if (strcmp(authctxt->user, p) != 0) {
868		log("wrong user name passed to monitor: expected %s != %.100s",
869		    authctxt->user, p);
870		fail++;
871	}
872	xfree(p);
873	buffer_skip_string(&b);
874	if (datafellows & SSH_BUG_PKAUTH) {
875		if (!buffer_get_char(&b))
876			fail++;
877	} else {
878		p = buffer_get_string(&b, NULL);
879		if (strcmp("publickey", p) != 0)
880			fail++;
881		xfree(p);
882		if (!buffer_get_char(&b))
883			fail++;
884		buffer_skip_string(&b);
885	}
886	buffer_skip_string(&b);
887	if (buffer_len(&b) != 0)
888		fail++;
889	buffer_free(&b);
890	return (fail == 0);
891}
892
893static int
894monitor_valid_hostbasedblob(u_char *data, u_int datalen, u_char *cuser,
895    u_char *chost)
896{
897	Buffer b;
898	u_char *p;
899	u_int len;
900	int fail = 0;
901
902	buffer_init(&b);
903	buffer_append(&b, data, datalen);
904
905	p = buffer_get_string(&b, &len);
906	if ((session_id2 == NULL) ||
907	    (len != session_id2_len) ||
908	    (memcmp(p, session_id2, session_id2_len) != 0))
909		fail++;
910	xfree(p);
911
912	if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST)
913		fail++;
914	p = buffer_get_string(&b, NULL);
915	if (strcmp(authctxt->user, p) != 0) {
916		log("wrong user name passed to monitor: expected %s != %.100s",
917		    authctxt->user, p);
918		fail++;
919	}
920	xfree(p);
921	buffer_skip_string(&b);	/* service */
922	p = buffer_get_string(&b, NULL);
923	if (strcmp(p, "hostbased") != 0)
924		fail++;
925	xfree(p);
926	buffer_skip_string(&b);	/* pkalg */
927	buffer_skip_string(&b);	/* pkblob */
928
929	/* verify client host, strip trailing dot if necessary */
930	p = buffer_get_string(&b, NULL);
931	if (((len = strlen(p)) > 0) && p[len - 1] == '.')
932		p[len - 1] = '\0';
933	if (strcmp(p, chost) != 0)
934		fail++;
935	xfree(p);
936
937	/* verify client user */
938	p = buffer_get_string(&b, NULL);
939	if (strcmp(p, cuser) != 0)
940		fail++;
941	xfree(p);
942
943	if (buffer_len(&b) != 0)
944		fail++;
945	buffer_free(&b);
946	return (fail == 0);
947}
948
949int
950mm_answer_keyverify(int socket, Buffer *m)
951{
952	Key *key;
953	u_char *signature, *data, *blob;
954	u_int signaturelen, datalen, bloblen;
955	int verified = 0;
956	int valid_data = 0;
957
958	blob = buffer_get_string(m, &bloblen);
959	signature = buffer_get_string(m, &signaturelen);
960	data = buffer_get_string(m, &datalen);
961
962	if (hostbased_cuser == NULL || hostbased_chost == NULL ||
963	  !monitor_allowed_key(blob, bloblen))
964		fatal("%s: bad key, not previously allowed", __func__);
965
966	key = key_from_blob(blob, bloblen);
967	if (key == NULL)
968		fatal("%s: bad public key blob", __func__);
969
970	switch (key_blobtype) {
971	case MM_USERKEY:
972		valid_data = monitor_valid_userblob(data, datalen);
973		break;
974	case MM_HOSTKEY:
975		valid_data = monitor_valid_hostbasedblob(data, datalen,
976		    hostbased_cuser, hostbased_chost);
977		break;
978	default:
979		valid_data = 0;
980		break;
981	}
982	if (!valid_data)
983		fatal("%s: bad signature data blob", __func__);
984
985	verified = key_verify(key, signature, signaturelen, data, datalen);
986	debug3("%s: key %p signature %s",
987	    __func__, key, verified ? "verified" : "unverified");
988
989	key_free(key);
990	xfree(blob);
991	xfree(signature);
992	xfree(data);
993
994	monitor_reset_key_state();
995
996	buffer_clear(m);
997	buffer_put_int(m, verified);
998	mm_request_send(socket, MONITOR_ANS_KEYVERIFY, m);
999
1000	auth_method = key_blobtype == MM_USERKEY ? "publickey" : "hostbased";
1001
1002	return (verified);
1003}
1004
1005static void
1006mm_record_login(Session *s, struct passwd *pw)
1007{
1008	socklen_t fromlen;
1009	struct sockaddr_storage from;
1010
1011	/*
1012	 * Get IP address of client. If the connection is not a socket, let
1013	 * the address be 0.0.0.0.
1014	 */
1015	memset(&from, 0, sizeof(from));
1016	if (packet_connection_is_on_socket()) {
1017		fromlen = sizeof(from);
1018		if (getpeername(packet_get_connection_in(),
1019			(struct sockaddr *) & from, &fromlen) < 0) {
1020			debug("getpeername: %.100s", strerror(errno));
1021			fatal_cleanup();
1022		}
1023	}
1024	/* Record that there was a login on that tty from the remote host. */
1025	record_login(s->pid, s->tty, pw->pw_name, pw->pw_uid,
1026	    get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping),
1027	    (struct sockaddr *)&from);
1028}
1029
1030static void
1031mm_session_close(Session *s)
1032{
1033	debug3("%s: session %d pid %d", __func__, s->self, s->pid);
1034	if (s->ttyfd != -1) {
1035		debug3("%s: tty %s ptyfd %d",  __func__, s->tty, s->ptyfd);
1036		fatal_remove_cleanup(session_pty_cleanup2, (void *)s);
1037		session_pty_cleanup2(s);
1038	}
1039	s->used = 0;
1040}
1041
1042int
1043mm_answer_pty(int socket, Buffer *m)
1044{
1045	extern struct monitor *pmonitor;
1046	Session *s;
1047	int res, fd0;
1048
1049	debug3("%s entering", __func__);
1050
1051	buffer_clear(m);
1052	s = session_new();
1053	if (s == NULL)
1054		goto error;
1055	s->authctxt = authctxt;
1056	s->pw = authctxt->pw;
1057	s->pid = pmonitor->m_pid;
1058	res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty));
1059	if (res == 0)
1060		goto error;
1061	fatal_add_cleanup(session_pty_cleanup2, (void *)s);
1062	pty_setowner(authctxt->pw, s->tty);
1063
1064	buffer_put_int(m, 1);
1065	buffer_put_cstring(m, s->tty);
1066	mm_request_send(socket, MONITOR_ANS_PTY, m);
1067
1068	mm_send_fd(socket, s->ptyfd);
1069	mm_send_fd(socket, s->ttyfd);
1070
1071	/* We need to trick ttyslot */
1072	if (dup2(s->ttyfd, 0) == -1)
1073		fatal("%s: dup2", __func__);
1074
1075	mm_record_login(s, authctxt->pw);
1076
1077	/* Now we can close the file descriptor again */
1078	close(0);
1079
1080	/* make sure nothing uses fd 0 */
1081	if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0)
1082		fatal("%s: open(/dev/null): %s", __func__, strerror(errno));
1083	if (fd0 != 0)
1084		error("%s: fd0 %d != 0", __func__, fd0);
1085
1086	/* slave is not needed */
1087	close(s->ttyfd);
1088	s->ttyfd = s->ptyfd;
1089	/* no need to dup() because nobody closes ptyfd */
1090	s->ptymaster = s->ptyfd;
1091
1092	debug3("%s: tty %s ptyfd %d",  __func__, s->tty, s->ttyfd);
1093
1094	return (0);
1095
1096 error:
1097	if (s != NULL)
1098		mm_session_close(s);
1099	buffer_put_int(m, 0);
1100	mm_request_send(socket, MONITOR_ANS_PTY, m);
1101	return (0);
1102}
1103
1104int
1105mm_answer_pty_cleanup(int socket, Buffer *m)
1106{
1107	Session *s;
1108	char *tty;
1109
1110	debug3("%s entering", __func__);
1111
1112	tty = buffer_get_string(m, NULL);
1113	if ((s = session_by_tty(tty)) != NULL)
1114		mm_session_close(s);
1115	buffer_clear(m);
1116	xfree(tty);
1117	return (0);
1118}
1119
1120int
1121mm_answer_sesskey(int socket, Buffer *m)
1122{
1123	BIGNUM *p;
1124	int rsafail;
1125
1126	/* Turn off permissions */
1127	monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1);
1128
1129	if ((p = BN_new()) == NULL)
1130		fatal("%s: BN_new", __func__);
1131
1132	buffer_get_bignum2(m, p);
1133
1134	rsafail = ssh1_session_key(p);
1135
1136	buffer_clear(m);
1137	buffer_put_int(m, rsafail);
1138	buffer_put_bignum2(m, p);
1139
1140	BN_clear_free(p);
1141
1142	mm_request_send(socket, MONITOR_ANS_SESSKEY, m);
1143
1144	/* Turn on permissions for sessid passing */
1145	monitor_permit(mon_dispatch, MONITOR_REQ_SESSID, 1);
1146
1147	return (0);
1148}
1149
1150int
1151mm_answer_sessid(int socket, Buffer *m)
1152{
1153	int i;
1154
1155	debug3("%s entering", __func__);
1156
1157	if (buffer_len(m) != 16)
1158		fatal("%s: bad ssh1 session id", __func__);
1159	for (i = 0; i < 16; i++)
1160		session_id[i] = buffer_get_char(m);
1161
1162	/* Turn on permissions for getpwnam */
1163	monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
1164
1165	return (0);
1166}
1167
1168int
1169mm_answer_rsa_keyallowed(int socket, Buffer *m)
1170{
1171	BIGNUM *client_n;
1172	Key *key = NULL;
1173	u_char *blob = NULL;
1174	u_int blen = 0;
1175	int allowed = 0;
1176
1177	debug3("%s entering", __func__);
1178
1179	if (options.rsa_authentication && authctxt->valid) {
1180		if ((client_n = BN_new()) == NULL)
1181			fatal("%s: BN_new", __func__);
1182		buffer_get_bignum2(m, client_n);
1183		allowed = auth_rsa_key_allowed(authctxt->pw, client_n, &key);
1184		BN_clear_free(client_n);
1185	}
1186	buffer_clear(m);
1187	buffer_put_int(m, allowed);
1188
1189	/* clear temporarily storage (used by generate challenge) */
1190	monitor_reset_key_state();
1191
1192	if (allowed && key != NULL) {
1193		key->type = KEY_RSA;	/* cheat for key_to_blob */
1194		if (key_to_blob(key, &blob, &blen) == 0)
1195			fatal("%s: key_to_blob failed", __func__);
1196		buffer_put_string(m, blob, blen);
1197
1198		/* Save temporarily for comparison in verify */
1199		key_blob = blob;
1200		key_bloblen = blen;
1201		key_blobtype = MM_RSAUSERKEY;
1202		key_free(key);
1203	}
1204
1205	mm_append_debug(m);
1206
1207	mm_request_send(socket, MONITOR_ANS_RSAKEYALLOWED, m);
1208
1209	monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed);
1210	monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 0);
1211	return (0);
1212}
1213
1214int
1215mm_answer_rsa_challenge(int socket, Buffer *m)
1216{
1217	Key *key = NULL;
1218	u_char *blob;
1219	u_int blen;
1220
1221	debug3("%s entering", __func__);
1222
1223	if (!authctxt->valid)
1224		fatal("%s: authctxt not valid", __func__);
1225	blob = buffer_get_string(m, &blen);
1226	if (!monitor_allowed_key(blob, blen))
1227		fatal("%s: bad key, not previously allowed", __func__);
1228	if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY)
1229		fatal("%s: key type mismatch", __func__);
1230	if ((key = key_from_blob(blob, blen)) == NULL)
1231		fatal("%s: received bad key", __func__);
1232
1233	if (ssh1_challenge)
1234		BN_clear_free(ssh1_challenge);
1235	ssh1_challenge = auth_rsa_generate_challenge(key);
1236
1237	buffer_clear(m);
1238	buffer_put_bignum2(m, ssh1_challenge);
1239
1240	debug3("%s sending reply", __func__);
1241	mm_request_send(socket, MONITOR_ANS_RSACHALLENGE, m);
1242
1243	monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 1);
1244	return (0);
1245}
1246
1247int
1248mm_answer_rsa_response(int socket, Buffer *m)
1249{
1250	Key *key = NULL;
1251	u_char *blob, *response;
1252	u_int blen, len;
1253	int success;
1254
1255	debug3("%s entering", __func__);
1256
1257	if (!authctxt->valid)
1258		fatal("%s: authctxt not valid", __func__);
1259	if (ssh1_challenge == NULL)
1260		fatal("%s: no ssh1_challenge", __func__);
1261
1262	blob = buffer_get_string(m, &blen);
1263	if (!monitor_allowed_key(blob, blen))
1264		fatal("%s: bad key, not previously allowed", __func__);
1265	if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY)
1266		fatal("%s: key type mismatch: %d", __func__, key_blobtype);
1267	if ((key = key_from_blob(blob, blen)) == NULL)
1268		fatal("%s: received bad key", __func__);
1269	response = buffer_get_string(m, &len);
1270	if (len != 16)
1271		fatal("%s: received bad response to challenge", __func__);
1272	success = auth_rsa_verify_response(key, ssh1_challenge, response);
1273
1274	key_free(key);
1275	xfree(response);
1276
1277	auth_method = key_blobtype == MM_RSAUSERKEY ? "rsa" : "rhosts-rsa";
1278
1279	/* reset state */
1280	BN_clear_free(ssh1_challenge);
1281	ssh1_challenge = NULL;
1282	monitor_reset_key_state();
1283
1284	buffer_clear(m);
1285	buffer_put_int(m, success);
1286	mm_request_send(socket, MONITOR_ANS_RSARESPONSE, m);
1287
1288	return (success);
1289}
1290
1291int
1292mm_answer_term(int socket, Buffer *req)
1293{
1294	extern struct monitor *pmonitor;
1295	int res, status;
1296
1297	debug3("%s: tearing down sessions", __func__);
1298
1299	/* The child is terminating */
1300	session_destroy_all(&mm_session_close);
1301
1302	while (waitpid(pmonitor->m_pid, &status, 0) == -1)
1303		if (errno != EINTR)
1304			exit(1);
1305
1306	res = WIFEXITED(status) ? WEXITSTATUS(status) : 1;
1307
1308	/* Terminate process */
1309	exit (res);
1310}
1311
1312void
1313monitor_apply_keystate(struct monitor *pmonitor)
1314{
1315	if (compat20) {
1316		set_newkeys(MODE_IN);
1317		set_newkeys(MODE_OUT);
1318	} else {
1319		packet_set_protocol_flags(child_state.ssh1protoflags);
1320		packet_set_encryption_key(child_state.ssh1key,
1321		    child_state.ssh1keylen, child_state.ssh1cipher);
1322		xfree(child_state.ssh1key);
1323	}
1324
1325	/* for rc4 and other stateful ciphers */
1326	packet_set_keycontext(MODE_OUT, child_state.keyout);
1327	xfree(child_state.keyout);
1328	packet_set_keycontext(MODE_IN, child_state.keyin);
1329	xfree(child_state.keyin);
1330
1331	if (!compat20) {
1332		packet_set_iv(MODE_OUT, child_state.ivout);
1333		xfree(child_state.ivout);
1334		packet_set_iv(MODE_IN, child_state.ivin);
1335		xfree(child_state.ivin);
1336	}
1337
1338	memcpy(&incoming_stream, &child_state.incoming,
1339	    sizeof(incoming_stream));
1340	memcpy(&outgoing_stream, &child_state.outgoing,
1341	    sizeof(outgoing_stream));
1342
1343	/* Update with new address */
1344	if (options.compression)
1345		mm_init_compression(pmonitor->m_zlib);
1346
1347	/* Network I/O buffers */
1348	/* XXX inefficient for large buffers, need: buffer_init_from_string */
1349	buffer_clear(&input);
1350	buffer_append(&input, child_state.input, child_state.ilen);
1351	memset(child_state.input, 0, child_state.ilen);
1352	xfree(child_state.input);
1353
1354	buffer_clear(&output);
1355	buffer_append(&output, child_state.output, child_state.olen);
1356	memset(child_state.output, 0, child_state.olen);
1357	xfree(child_state.output);
1358}
1359
1360static Kex *
1361mm_get_kex(Buffer *m)
1362{
1363	Kex *kex;
1364	void *blob;
1365	u_int bloblen;
1366
1367	kex = xmalloc(sizeof(*kex));
1368	memset(kex, 0, sizeof(*kex));
1369	kex->session_id = buffer_get_string(m, &kex->session_id_len);
1370	if ((session_id2 == NULL) ||
1371	    (kex->session_id_len != session_id2_len) ||
1372	    (memcmp(kex->session_id, session_id2, session_id2_len) != 0))
1373		fatal("mm_get_get: internal error: bad session id");
1374	kex->we_need = buffer_get_int(m);
1375	kex->server = 1;
1376	kex->hostkey_type = buffer_get_int(m);
1377	kex->kex_type = buffer_get_int(m);
1378	blob = buffer_get_string(m, &bloblen);
1379	buffer_init(&kex->my);
1380	buffer_append(&kex->my, blob, bloblen);
1381	xfree(blob);
1382	blob = buffer_get_string(m, &bloblen);
1383	buffer_init(&kex->peer);
1384	buffer_append(&kex->peer, blob, bloblen);
1385	xfree(blob);
1386	kex->done = 1;
1387	kex->flags = buffer_get_int(m);
1388	kex->client_version_string = buffer_get_string(m, NULL);
1389	kex->server_version_string = buffer_get_string(m, NULL);
1390	kex->load_host_key=&get_hostkey_by_type;
1391	kex->host_key_index=&get_hostkey_index;
1392
1393	return (kex);
1394}
1395
1396/* This function requries careful sanity checking */
1397
1398void
1399mm_get_keystate(struct monitor *pmonitor)
1400{
1401	Buffer m;
1402	u_char *blob, *p;
1403	u_int bloblen, plen;
1404
1405	debug3("%s: Waiting for new keys", __func__);
1406
1407	buffer_init(&m);
1408	mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, &m);
1409	if (!compat20) {
1410		child_state.ssh1protoflags = buffer_get_int(&m);
1411		child_state.ssh1cipher = buffer_get_int(&m);
1412		child_state.ssh1key = buffer_get_string(&m,
1413		    &child_state.ssh1keylen);
1414		child_state.ivout = buffer_get_string(&m,
1415		    &child_state.ivoutlen);
1416		child_state.ivin = buffer_get_string(&m, &child_state.ivinlen);
1417		goto skip;
1418	} else {
1419		/* Get the Kex for rekeying */
1420		*pmonitor->m_pkex = mm_get_kex(&m);
1421	}
1422
1423	blob = buffer_get_string(&m, &bloblen);
1424	current_keys[MODE_OUT] = mm_newkeys_from_blob(blob, bloblen);
1425	xfree(blob);
1426
1427	debug3("%s: Waiting for second key", __func__);
1428	blob = buffer_get_string(&m, &bloblen);
1429	current_keys[MODE_IN] = mm_newkeys_from_blob(blob, bloblen);
1430	xfree(blob);
1431
1432	/* Now get sequence numbers for the packets */
1433	packet_set_seqnr(MODE_OUT, buffer_get_int(&m));
1434	packet_set_seqnr(MODE_IN, buffer_get_int(&m));
1435
1436 skip:
1437	/* Get the key context */
1438	child_state.keyout = buffer_get_string(&m, &child_state.keyoutlen);
1439	child_state.keyin  = buffer_get_string(&m, &child_state.keyinlen);
1440
1441	debug3("%s: Getting compression state", __func__);
1442	/* Get compression state */
1443	p = buffer_get_string(&m, &plen);
1444	if (plen != sizeof(child_state.outgoing))
1445		fatal("%s: bad request size", __func__);
1446	memcpy(&child_state.outgoing, p, sizeof(child_state.outgoing));
1447	xfree(p);
1448
1449	p = buffer_get_string(&m, &plen);
1450	if (plen != sizeof(child_state.incoming))
1451		fatal("%s: bad request size", __func__);
1452	memcpy(&child_state.incoming, p, sizeof(child_state.incoming));
1453	xfree(p);
1454
1455	/* Network I/O buffers */
1456	debug3("%s: Getting Network I/O buffers", __func__);
1457	child_state.input = buffer_get_string(&m, &child_state.ilen);
1458	child_state.output = buffer_get_string(&m, &child_state.olen);
1459
1460	buffer_free(&m);
1461}
1462
1463
1464/* Allocation functions for zlib */
1465void *
1466mm_zalloc(struct mm_master *mm, u_int ncount, u_int size)
1467{
1468	void *address;
1469
1470	address = mm_malloc(mm, size * ncount);
1471
1472	return (address);
1473}
1474
1475void
1476mm_zfree(struct mm_master *mm, void *address)
1477{
1478	mm_free(mm, address);
1479}
1480
1481void
1482mm_init_compression(struct mm_master *mm)
1483{
1484	outgoing_stream.zalloc = (alloc_func)mm_zalloc;
1485	outgoing_stream.zfree = (free_func)mm_zfree;
1486	outgoing_stream.opaque = mm;
1487
1488	incoming_stream.zalloc = (alloc_func)mm_zalloc;
1489	incoming_stream.zfree = (free_func)mm_zfree;
1490	incoming_stream.opaque = mm;
1491}
1492
1493/* XXX */
1494
1495#define FD_CLOSEONEXEC(x) do { \
1496	if (fcntl(x, F_SETFD, 1) == -1) \
1497		fatal("fcntl(%d, F_SETFD)", x); \
1498} while (0)
1499
1500static void
1501monitor_socketpair(int *pair)
1502{
1503#ifdef HAVE_SOCKETPAIR
1504	if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
1505		fatal("%s: socketpair", __func__);
1506#else
1507	fatal("%s: UsePrivilegeSeparation=yes not supported",
1508	    __func__);
1509#endif
1510	FD_CLOSEONEXEC(pair[0]);
1511	FD_CLOSEONEXEC(pair[1]);
1512}
1513
1514#define MM_MEMSIZE	65536
1515
1516struct monitor *
1517monitor_init(void)
1518{
1519	struct monitor *mon;
1520	int pair[2];
1521
1522	mon = xmalloc(sizeof(*mon));
1523
1524	monitor_socketpair(pair);
1525
1526	mon->m_recvfd = pair[0];
1527	mon->m_sendfd = pair[1];
1528
1529	/* Used to share zlib space across processes */
1530	if (options.compression) {
1531		mon->m_zback = mm_create(NULL, MM_MEMSIZE);
1532		mon->m_zlib = mm_create(mon->m_zback, 20 * MM_MEMSIZE);
1533
1534		/* Compression needs to share state across borders */
1535		mm_init_compression(mon->m_zlib);
1536	}
1537
1538	return mon;
1539}
1540
1541void
1542monitor_reinit(struct monitor *mon)
1543{
1544	int pair[2];
1545
1546	monitor_socketpair(pair);
1547
1548	mon->m_recvfd = pair[0];
1549	mon->m_sendfd = pair[1];
1550}
1551