xref: /freebsd/crypto/openssh/monitor_wrap.c (revision aa49c9264c97095f0d273288be7cb0b4b06658ab)
1545d5ecaSDag-Erling Smørgrav /*
2545d5ecaSDag-Erling Smørgrav  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
3545d5ecaSDag-Erling Smørgrav  * Copyright 2002 Markus Friedl <markus@openbsd.org>
4545d5ecaSDag-Erling Smørgrav  * All rights reserved.
5545d5ecaSDag-Erling Smørgrav  *
6545d5ecaSDag-Erling Smørgrav  * Redistribution and use in source and binary forms, with or without
7545d5ecaSDag-Erling Smørgrav  * modification, are permitted provided that the following conditions
8545d5ecaSDag-Erling Smørgrav  * are met:
9545d5ecaSDag-Erling Smørgrav  * 1. Redistributions of source code must retain the above copyright
10545d5ecaSDag-Erling Smørgrav  *    notice, this list of conditions and the following disclaimer.
11545d5ecaSDag-Erling Smørgrav  * 2. Redistributions in binary form must reproduce the above copyright
12545d5ecaSDag-Erling Smørgrav  *    notice, this list of conditions and the following disclaimer in the
13545d5ecaSDag-Erling Smørgrav  *    documentation and/or other materials provided with the distribution.
14545d5ecaSDag-Erling Smørgrav  *
15545d5ecaSDag-Erling Smørgrav  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16545d5ecaSDag-Erling Smørgrav  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17545d5ecaSDag-Erling Smørgrav  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18545d5ecaSDag-Erling Smørgrav  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19545d5ecaSDag-Erling Smørgrav  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20545d5ecaSDag-Erling Smørgrav  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21545d5ecaSDag-Erling Smørgrav  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22545d5ecaSDag-Erling Smørgrav  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23545d5ecaSDag-Erling Smørgrav  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24545d5ecaSDag-Erling Smørgrav  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25545d5ecaSDag-Erling Smørgrav  */
26545d5ecaSDag-Erling Smørgrav 
27545d5ecaSDag-Erling Smørgrav #include "includes.h"
2821e764dfSDag-Erling Smørgrav RCSID("$OpenBSD: monitor_wrap.c,v 1.39 2004/07/17 05:31:41 dtucker Exp $");
29382d19eeSDag-Erling Smørgrav RCSID("$FreeBSD$");
30545d5ecaSDag-Erling Smørgrav 
31545d5ecaSDag-Erling Smørgrav #include <openssl/bn.h>
32545d5ecaSDag-Erling Smørgrav #include <openssl/dh.h>
33545d5ecaSDag-Erling Smørgrav 
34545d5ecaSDag-Erling Smørgrav #include "ssh.h"
35545d5ecaSDag-Erling Smørgrav #include "dh.h"
36545d5ecaSDag-Erling Smørgrav #include "kex.h"
37545d5ecaSDag-Erling Smørgrav #include "auth.h"
38e73e9afaSDag-Erling Smørgrav #include "auth-options.h"
39545d5ecaSDag-Erling Smørgrav #include "buffer.h"
40545d5ecaSDag-Erling Smørgrav #include "bufaux.h"
41545d5ecaSDag-Erling Smørgrav #include "packet.h"
42545d5ecaSDag-Erling Smørgrav #include "mac.h"
43545d5ecaSDag-Erling Smørgrav #include "log.h"
445962c0e9SDag-Erling Smørgrav #ifdef TARGET_OS_MAC    /* XXX Broken krb5 headers on Mac */
455962c0e9SDag-Erling Smørgrav #undef TARGET_OS_MAC
46545d5ecaSDag-Erling Smørgrav #include "zlib.h"
475962c0e9SDag-Erling Smørgrav #define TARGET_OS_MAC 1
485962c0e9SDag-Erling Smørgrav #else
495962c0e9SDag-Erling Smørgrav #include "zlib.h"
505962c0e9SDag-Erling Smørgrav #endif
51545d5ecaSDag-Erling Smørgrav #include "monitor.h"
52545d5ecaSDag-Erling Smørgrav #include "monitor_wrap.h"
53545d5ecaSDag-Erling Smørgrav #include "xmalloc.h"
54545d5ecaSDag-Erling Smørgrav #include "atomicio.h"
55545d5ecaSDag-Erling Smørgrav #include "monitor_fdpass.h"
56545d5ecaSDag-Erling Smørgrav #include "getput.h"
57cf2b5f3bSDag-Erling Smørgrav #include "servconf.h"
58545d5ecaSDag-Erling Smørgrav 
59545d5ecaSDag-Erling Smørgrav #include "auth.h"
60545d5ecaSDag-Erling Smørgrav #include "channels.h"
61545d5ecaSDag-Erling Smørgrav #include "session.h"
62545d5ecaSDag-Erling Smørgrav 
63cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI
64cf2b5f3bSDag-Erling Smørgrav #include "ssh-gss.h"
65cf2b5f3bSDag-Erling Smørgrav #endif
66cf2b5f3bSDag-Erling Smørgrav 
67545d5ecaSDag-Erling Smørgrav /* Imports */
68545d5ecaSDag-Erling Smørgrav extern int compat20;
69545d5ecaSDag-Erling Smørgrav extern Newkeys *newkeys[];
70545d5ecaSDag-Erling Smørgrav extern z_stream incoming_stream;
71545d5ecaSDag-Erling Smørgrav extern z_stream outgoing_stream;
72545d5ecaSDag-Erling Smørgrav extern struct monitor *pmonitor;
73545d5ecaSDag-Erling Smørgrav extern Buffer input, output;
7421e764dfSDag-Erling Smørgrav extern Buffer loginmsg;
75cf2b5f3bSDag-Erling Smørgrav extern ServerOptions options;
76aa49c926SDag-Erling Smørgrav extern Buffer loginmsg;
77545d5ecaSDag-Erling Smørgrav 
781ec0d754SDag-Erling Smørgrav int
791ec0d754SDag-Erling Smørgrav mm_is_monitor(void)
801ec0d754SDag-Erling Smørgrav {
811ec0d754SDag-Erling Smørgrav 	/*
821ec0d754SDag-Erling Smørgrav 	 * m_pid is only set in the privileged part, and
831ec0d754SDag-Erling Smørgrav 	 * points to the unprivileged child.
841ec0d754SDag-Erling Smørgrav 	 */
851ec0d754SDag-Erling Smørgrav 	return (pmonitor && pmonitor->m_pid > 0);
861ec0d754SDag-Erling Smørgrav }
871ec0d754SDag-Erling Smørgrav 
88545d5ecaSDag-Erling Smørgrav void
8921e764dfSDag-Erling Smørgrav mm_request_send(int sock, enum monitor_reqtype type, Buffer *m)
90545d5ecaSDag-Erling Smørgrav {
91545d5ecaSDag-Erling Smørgrav 	u_int mlen = buffer_len(m);
92f388f5efSDag-Erling Smørgrav 	u_char buf[5];
93545d5ecaSDag-Erling Smørgrav 
94545d5ecaSDag-Erling Smørgrav 	debug3("%s entering: type %d", __func__, type);
95545d5ecaSDag-Erling Smørgrav 
96545d5ecaSDag-Erling Smørgrav 	PUT_32BIT(buf, mlen + 1);
97545d5ecaSDag-Erling Smørgrav 	buf[4] = (u_char) type;		/* 1st byte of payload is mesg-type */
9821e764dfSDag-Erling Smørgrav 	if (atomicio(vwrite, sock, buf, sizeof(buf)) != sizeof(buf))
99545d5ecaSDag-Erling Smørgrav 		fatal("%s: write", __func__);
10021e764dfSDag-Erling Smørgrav 	if (atomicio(vwrite, sock, buffer_ptr(m), mlen) != mlen)
101545d5ecaSDag-Erling Smørgrav 		fatal("%s: write", __func__);
102545d5ecaSDag-Erling Smørgrav }
103545d5ecaSDag-Erling Smørgrav 
104545d5ecaSDag-Erling Smørgrav void
10521e764dfSDag-Erling Smørgrav mm_request_receive(int sock, Buffer *m)
106545d5ecaSDag-Erling Smørgrav {
107545d5ecaSDag-Erling Smørgrav 	u_char buf[4];
108545d5ecaSDag-Erling Smørgrav 	u_int msg_len;
109f388f5efSDag-Erling Smørgrav 	ssize_t res;
110545d5ecaSDag-Erling Smørgrav 
111545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
112545d5ecaSDag-Erling Smørgrav 
11321e764dfSDag-Erling Smørgrav 	res = atomicio(read, sock, buf, sizeof(buf));
114545d5ecaSDag-Erling Smørgrav 	if (res != sizeof(buf)) {
115545d5ecaSDag-Erling Smørgrav 		if (res == 0)
1161ec0d754SDag-Erling Smørgrav 			cleanup_exit(255);
117545d5ecaSDag-Erling Smørgrav 		fatal("%s: read: %ld", __func__, (long)res);
118545d5ecaSDag-Erling Smørgrav 	}
119545d5ecaSDag-Erling Smørgrav 	msg_len = GET_32BIT(buf);
120545d5ecaSDag-Erling Smørgrav 	if (msg_len > 256 * 1024)
121545d5ecaSDag-Erling Smørgrav 		fatal("%s: read: bad msg_len %d", __func__, msg_len);
122545d5ecaSDag-Erling Smørgrav 	buffer_clear(m);
123545d5ecaSDag-Erling Smørgrav 	buffer_append_space(m, msg_len);
12421e764dfSDag-Erling Smørgrav 	res = atomicio(read, sock, buffer_ptr(m), msg_len);
125545d5ecaSDag-Erling Smørgrav 	if (res != msg_len)
126545d5ecaSDag-Erling Smørgrav 		fatal("%s: read: %ld != msg_len", __func__, (long)res);
127545d5ecaSDag-Erling Smørgrav }
128545d5ecaSDag-Erling Smørgrav 
129545d5ecaSDag-Erling Smørgrav void
13021e764dfSDag-Erling Smørgrav mm_request_receive_expect(int sock, enum monitor_reqtype type, Buffer *m)
131545d5ecaSDag-Erling Smørgrav {
132545d5ecaSDag-Erling Smørgrav 	u_char rtype;
133545d5ecaSDag-Erling Smørgrav 
134545d5ecaSDag-Erling Smørgrav 	debug3("%s entering: type %d", __func__, type);
135545d5ecaSDag-Erling Smørgrav 
13621e764dfSDag-Erling Smørgrav 	mm_request_receive(sock, m);
137545d5ecaSDag-Erling Smørgrav 	rtype = buffer_get_char(m);
138545d5ecaSDag-Erling Smørgrav 	if (rtype != type)
139545d5ecaSDag-Erling Smørgrav 		fatal("%s: read: rtype %d != type %d", __func__,
140545d5ecaSDag-Erling Smørgrav 		    rtype, type);
141545d5ecaSDag-Erling Smørgrav }
142545d5ecaSDag-Erling Smørgrav 
143545d5ecaSDag-Erling Smørgrav DH *
144545d5ecaSDag-Erling Smørgrav mm_choose_dh(int min, int nbits, int max)
145545d5ecaSDag-Erling Smørgrav {
146545d5ecaSDag-Erling Smørgrav 	BIGNUM *p, *g;
147545d5ecaSDag-Erling Smørgrav 	int success = 0;
148545d5ecaSDag-Erling Smørgrav 	Buffer m;
149545d5ecaSDag-Erling Smørgrav 
150545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
151545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&m, min);
152545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&m, nbits);
153545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&m, max);
154545d5ecaSDag-Erling Smørgrav 
155545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_MODULI, &m);
156545d5ecaSDag-Erling Smørgrav 
157545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_MODULI", __func__);
158545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_MODULI, &m);
159545d5ecaSDag-Erling Smørgrav 
160545d5ecaSDag-Erling Smørgrav 	success = buffer_get_char(&m);
161545d5ecaSDag-Erling Smørgrav 	if (success == 0)
162545d5ecaSDag-Erling Smørgrav 		fatal("%s: MONITOR_ANS_MODULI failed", __func__);
163545d5ecaSDag-Erling Smørgrav 
164545d5ecaSDag-Erling Smørgrav 	if ((p = BN_new()) == NULL)
165545d5ecaSDag-Erling Smørgrav 		fatal("%s: BN_new failed", __func__);
166545d5ecaSDag-Erling Smørgrav 	if ((g = BN_new()) == NULL)
167545d5ecaSDag-Erling Smørgrav 		fatal("%s: BN_new failed", __func__);
168545d5ecaSDag-Erling Smørgrav 	buffer_get_bignum2(&m, p);
169545d5ecaSDag-Erling Smørgrav 	buffer_get_bignum2(&m, g);
170545d5ecaSDag-Erling Smørgrav 
171545d5ecaSDag-Erling Smørgrav 	debug3("%s: remaining %d", __func__, buffer_len(&m));
172545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
173545d5ecaSDag-Erling Smørgrav 
174545d5ecaSDag-Erling Smørgrav 	return (dh_new_group(g, p));
175545d5ecaSDag-Erling Smørgrav }
176545d5ecaSDag-Erling Smørgrav 
177545d5ecaSDag-Erling Smørgrav int
178545d5ecaSDag-Erling Smørgrav mm_key_sign(Key *key, u_char **sigp, u_int *lenp, u_char *data, u_int datalen)
179545d5ecaSDag-Erling Smørgrav {
180545d5ecaSDag-Erling Smørgrav 	Kex *kex = *pmonitor->m_pkex;
181545d5ecaSDag-Erling Smørgrav 	Buffer m;
182545d5ecaSDag-Erling Smørgrav 
183545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
184545d5ecaSDag-Erling Smørgrav 
185545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
186545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&m, kex->host_key_index(key));
187545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, data, datalen);
188545d5ecaSDag-Erling Smørgrav 
189545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, &m);
190545d5ecaSDag-Erling Smørgrav 
191545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_SIGN", __func__);
192545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SIGN, &m);
193545d5ecaSDag-Erling Smørgrav 	*sigp  = buffer_get_string(&m, lenp);
194545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
195545d5ecaSDag-Erling Smørgrav 
196545d5ecaSDag-Erling Smørgrav 	return (0);
197545d5ecaSDag-Erling Smørgrav }
198545d5ecaSDag-Erling Smørgrav 
199545d5ecaSDag-Erling Smørgrav struct passwd *
20021e764dfSDag-Erling Smørgrav mm_getpwnamallow(const char *username)
201545d5ecaSDag-Erling Smørgrav {
202545d5ecaSDag-Erling Smørgrav 	Buffer m;
203545d5ecaSDag-Erling Smørgrav 	struct passwd *pw;
204545d5ecaSDag-Erling Smørgrav 	u_int pwlen;
205545d5ecaSDag-Erling Smørgrav 
206545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
207545d5ecaSDag-Erling Smørgrav 
208545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
20921e764dfSDag-Erling Smørgrav 	buffer_put_cstring(&m, username);
210545d5ecaSDag-Erling Smørgrav 
211545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, &m);
212545d5ecaSDag-Erling Smørgrav 
213545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PWNAM", __func__);
214545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m);
215545d5ecaSDag-Erling Smørgrav 
216545d5ecaSDag-Erling Smørgrav 	if (buffer_get_char(&m) == 0) {
217545d5ecaSDag-Erling Smørgrav 		buffer_free(&m);
218545d5ecaSDag-Erling Smørgrav 		return (NULL);
219545d5ecaSDag-Erling Smørgrav 	}
220545d5ecaSDag-Erling Smørgrav 	pw = buffer_get_string(&m, &pwlen);
221545d5ecaSDag-Erling Smørgrav 	if (pwlen != sizeof(struct passwd))
222545d5ecaSDag-Erling Smørgrav 		fatal("%s: struct passwd size mismatch", __func__);
223545d5ecaSDag-Erling Smørgrav 	pw->pw_name = buffer_get_string(&m, NULL);
224545d5ecaSDag-Erling Smørgrav 	pw->pw_passwd = buffer_get_string(&m, NULL);
225545d5ecaSDag-Erling Smørgrav 	pw->pw_gecos = buffer_get_string(&m, NULL);
22683d2307dSDag-Erling Smørgrav #ifdef HAVE_PW_CLASS_IN_PASSWD
227545d5ecaSDag-Erling Smørgrav 	pw->pw_class = buffer_get_string(&m, NULL);
22883d2307dSDag-Erling Smørgrav #endif
229545d5ecaSDag-Erling Smørgrav 	pw->pw_dir = buffer_get_string(&m, NULL);
230545d5ecaSDag-Erling Smørgrav 	pw->pw_shell = buffer_get_string(&m, NULL);
231545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
232545d5ecaSDag-Erling Smørgrav 
233545d5ecaSDag-Erling Smørgrav 	return (pw);
234545d5ecaSDag-Erling Smørgrav }
235545d5ecaSDag-Erling Smørgrav 
2361ec0d754SDag-Erling Smørgrav char *
2371ec0d754SDag-Erling Smørgrav mm_auth2_read_banner(void)
238545d5ecaSDag-Erling Smørgrav {
239545d5ecaSDag-Erling Smørgrav 	Buffer m;
240545d5ecaSDag-Erling Smørgrav 	char *banner;
241545d5ecaSDag-Erling Smørgrav 
242545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
243545d5ecaSDag-Erling Smørgrav 
244545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
245545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, &m);
246545d5ecaSDag-Erling Smørgrav 	buffer_clear(&m);
247545d5ecaSDag-Erling Smørgrav 
2481ec0d754SDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
2491ec0d754SDag-Erling Smørgrav 	    MONITOR_ANS_AUTH2_READ_BANNER, &m);
250545d5ecaSDag-Erling Smørgrav 	banner = buffer_get_string(&m, NULL);
251545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
252545d5ecaSDag-Erling Smørgrav 
2531ec0d754SDag-Erling Smørgrav 	/* treat empty banner as missing banner */
2541ec0d754SDag-Erling Smørgrav 	if (strlen(banner) == 0) {
2551ec0d754SDag-Erling Smørgrav 		xfree(banner);
2561ec0d754SDag-Erling Smørgrav 		banner = NULL;
2571ec0d754SDag-Erling Smørgrav 	}
258545d5ecaSDag-Erling Smørgrav 	return (banner);
259545d5ecaSDag-Erling Smørgrav }
260545d5ecaSDag-Erling Smørgrav 
261545d5ecaSDag-Erling Smørgrav /* Inform the privileged process about service and style */
262545d5ecaSDag-Erling Smørgrav 
263545d5ecaSDag-Erling Smørgrav void
264545d5ecaSDag-Erling Smørgrav mm_inform_authserv(char *service, char *style)
265545d5ecaSDag-Erling Smørgrav {
266545d5ecaSDag-Erling Smørgrav 	Buffer m;
267545d5ecaSDag-Erling Smørgrav 
268545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
269545d5ecaSDag-Erling Smørgrav 
270545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
271545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, service);
272545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, style ? style : "");
273545d5ecaSDag-Erling Smørgrav 
274545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m);
275545d5ecaSDag-Erling Smørgrav 
276545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
277545d5ecaSDag-Erling Smørgrav }
278545d5ecaSDag-Erling Smørgrav 
279545d5ecaSDag-Erling Smørgrav /* Do the password authentication */
280545d5ecaSDag-Erling Smørgrav int
281545d5ecaSDag-Erling Smørgrav mm_auth_password(Authctxt *authctxt, char *password)
282545d5ecaSDag-Erling Smørgrav {
283545d5ecaSDag-Erling Smørgrav 	Buffer m;
284545d5ecaSDag-Erling Smørgrav 	int authenticated = 0;
285545d5ecaSDag-Erling Smørgrav 
286545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
287545d5ecaSDag-Erling Smørgrav 
288545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
289545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, password);
290545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, &m);
291545d5ecaSDag-Erling Smørgrav 
292545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_AUTHPASSWORD", __func__);
293545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTHPASSWORD, &m);
294545d5ecaSDag-Erling Smørgrav 
295545d5ecaSDag-Erling Smørgrav 	authenticated = buffer_get_int(&m);
296545d5ecaSDag-Erling Smørgrav 
297545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
298545d5ecaSDag-Erling Smørgrav 
299545d5ecaSDag-Erling Smørgrav 	debug3("%s: user %sauthenticated",
300545d5ecaSDag-Erling Smørgrav 	    __func__, authenticated ? "" : "not ");
301545d5ecaSDag-Erling Smørgrav 	return (authenticated);
302545d5ecaSDag-Erling Smørgrav }
303545d5ecaSDag-Erling Smørgrav 
304545d5ecaSDag-Erling Smørgrav int
305545d5ecaSDag-Erling Smørgrav mm_user_key_allowed(struct passwd *pw, Key *key)
306545d5ecaSDag-Erling Smørgrav {
307545d5ecaSDag-Erling Smørgrav 	return (mm_key_allowed(MM_USERKEY, NULL, NULL, key));
308545d5ecaSDag-Erling Smørgrav }
309545d5ecaSDag-Erling Smørgrav 
310545d5ecaSDag-Erling Smørgrav int
311545d5ecaSDag-Erling Smørgrav mm_hostbased_key_allowed(struct passwd *pw, char *user, char *host,
312545d5ecaSDag-Erling Smørgrav     Key *key)
313545d5ecaSDag-Erling Smørgrav {
314545d5ecaSDag-Erling Smørgrav 	return (mm_key_allowed(MM_HOSTKEY, user, host, key));
315545d5ecaSDag-Erling Smørgrav }
316545d5ecaSDag-Erling Smørgrav 
317545d5ecaSDag-Erling Smørgrav int
318545d5ecaSDag-Erling Smørgrav mm_auth_rhosts_rsa_key_allowed(struct passwd *pw, char *user,
319545d5ecaSDag-Erling Smørgrav     char *host, Key *key)
320545d5ecaSDag-Erling Smørgrav {
321545d5ecaSDag-Erling Smørgrav 	int ret;
322545d5ecaSDag-Erling Smørgrav 
323545d5ecaSDag-Erling Smørgrav 	key->type = KEY_RSA; /* XXX hack for key_to_blob */
324545d5ecaSDag-Erling Smørgrav 	ret = mm_key_allowed(MM_RSAHOSTKEY, user, host, key);
325545d5ecaSDag-Erling Smørgrav 	key->type = KEY_RSA1;
326545d5ecaSDag-Erling Smørgrav 	return (ret);
327545d5ecaSDag-Erling Smørgrav }
328545d5ecaSDag-Erling Smørgrav 
329545d5ecaSDag-Erling Smørgrav static void
330545d5ecaSDag-Erling Smørgrav mm_send_debug(Buffer *m)
331545d5ecaSDag-Erling Smørgrav {
332545d5ecaSDag-Erling Smørgrav 	char *msg;
333545d5ecaSDag-Erling Smørgrav 
334545d5ecaSDag-Erling Smørgrav 	while (buffer_len(m)) {
335545d5ecaSDag-Erling Smørgrav 		msg = buffer_get_string(m, NULL);
336545d5ecaSDag-Erling Smørgrav 		debug3("%s: Sending debug: %s", __func__, msg);
337545d5ecaSDag-Erling Smørgrav 		packet_send_debug("%s", msg);
338545d5ecaSDag-Erling Smørgrav 		xfree(msg);
339545d5ecaSDag-Erling Smørgrav 	}
340545d5ecaSDag-Erling Smørgrav }
341545d5ecaSDag-Erling Smørgrav 
342545d5ecaSDag-Erling Smørgrav int
343545d5ecaSDag-Erling Smørgrav mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key)
344545d5ecaSDag-Erling Smørgrav {
345545d5ecaSDag-Erling Smørgrav 	Buffer m;
346545d5ecaSDag-Erling Smørgrav 	u_char *blob;
347545d5ecaSDag-Erling Smørgrav 	u_int len;
348e73e9afaSDag-Erling Smørgrav 	int allowed = 0, have_forced = 0;
349545d5ecaSDag-Erling Smørgrav 
350545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
351545d5ecaSDag-Erling Smørgrav 
352545d5ecaSDag-Erling Smørgrav 	/* Convert the key to a blob and the pass it over */
353545d5ecaSDag-Erling Smørgrav 	if (!key_to_blob(key, &blob, &len))
354545d5ecaSDag-Erling Smørgrav 		return (0);
355545d5ecaSDag-Erling Smørgrav 
356545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
357545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&m, type);
358545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, user ? user : "");
359545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, host ? host : "");
360545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, blob, len);
361545d5ecaSDag-Erling Smørgrav 	xfree(blob);
362545d5ecaSDag-Erling Smørgrav 
363545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, &m);
364545d5ecaSDag-Erling Smørgrav 
365545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_KEYALLOWED", __func__);
366545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYALLOWED, &m);
367545d5ecaSDag-Erling Smørgrav 
368545d5ecaSDag-Erling Smørgrav 	allowed = buffer_get_int(&m);
369545d5ecaSDag-Erling Smørgrav 
370e73e9afaSDag-Erling Smørgrav 	/* fake forced command */
371e73e9afaSDag-Erling Smørgrav 	auth_clear_options();
372e73e9afaSDag-Erling Smørgrav 	have_forced = buffer_get_int(&m);
373e73e9afaSDag-Erling Smørgrav 	forced_command = have_forced ? xstrdup("true") : NULL;
374e73e9afaSDag-Erling Smørgrav 
375545d5ecaSDag-Erling Smørgrav 	/* Send potential debug messages */
376545d5ecaSDag-Erling Smørgrav 	mm_send_debug(&m);
377545d5ecaSDag-Erling Smørgrav 
378545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
379545d5ecaSDag-Erling Smørgrav 
380545d5ecaSDag-Erling Smørgrav 	return (allowed);
381545d5ecaSDag-Erling Smørgrav }
382545d5ecaSDag-Erling Smørgrav 
383545d5ecaSDag-Erling Smørgrav /*
384545d5ecaSDag-Erling Smørgrav  * This key verify needs to send the key type along, because the
385545d5ecaSDag-Erling Smørgrav  * privileged parent makes the decision if the key is allowed
386545d5ecaSDag-Erling Smørgrav  * for authentication.
387545d5ecaSDag-Erling Smørgrav  */
388545d5ecaSDag-Erling Smørgrav 
389545d5ecaSDag-Erling Smørgrav int
390545d5ecaSDag-Erling Smørgrav mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
391545d5ecaSDag-Erling Smørgrav {
392545d5ecaSDag-Erling Smørgrav 	Buffer m;
393545d5ecaSDag-Erling Smørgrav 	u_char *blob;
394545d5ecaSDag-Erling Smørgrav 	u_int len;
395545d5ecaSDag-Erling Smørgrav 	int verified = 0;
396545d5ecaSDag-Erling Smørgrav 
397545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
398545d5ecaSDag-Erling Smørgrav 
399545d5ecaSDag-Erling Smørgrav 	/* Convert the key to a blob and the pass it over */
400545d5ecaSDag-Erling Smørgrav 	if (!key_to_blob(key, &blob, &len))
401545d5ecaSDag-Erling Smørgrav 		return (0);
402545d5ecaSDag-Erling Smørgrav 
403545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
404545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, blob, len);
405545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, sig, siglen);
406545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, data, datalen);
407545d5ecaSDag-Erling Smørgrav 	xfree(blob);
408545d5ecaSDag-Erling Smørgrav 
409545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m);
410545d5ecaSDag-Erling Smørgrav 
411545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__);
412545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m);
413545d5ecaSDag-Erling Smørgrav 
414545d5ecaSDag-Erling Smørgrav 	verified = buffer_get_int(&m);
415545d5ecaSDag-Erling Smørgrav 
416545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
417545d5ecaSDag-Erling Smørgrav 
418545d5ecaSDag-Erling Smørgrav 	return (verified);
419545d5ecaSDag-Erling Smørgrav }
420545d5ecaSDag-Erling Smørgrav 
421545d5ecaSDag-Erling Smørgrav /* Export key state after authentication */
422545d5ecaSDag-Erling Smørgrav Newkeys *
423545d5ecaSDag-Erling Smørgrav mm_newkeys_from_blob(u_char *blob, int blen)
424545d5ecaSDag-Erling Smørgrav {
425545d5ecaSDag-Erling Smørgrav 	Buffer b;
426545d5ecaSDag-Erling Smørgrav 	u_int len;
427545d5ecaSDag-Erling Smørgrav 	Newkeys *newkey = NULL;
428545d5ecaSDag-Erling Smørgrav 	Enc *enc;
429545d5ecaSDag-Erling Smørgrav 	Mac *mac;
430545d5ecaSDag-Erling Smørgrav 	Comp *comp;
431545d5ecaSDag-Erling Smørgrav 
432545d5ecaSDag-Erling Smørgrav 	debug3("%s: %p(%d)", __func__, blob, blen);
433545d5ecaSDag-Erling Smørgrav #ifdef DEBUG_PK
434545d5ecaSDag-Erling Smørgrav 	dump_base64(stderr, blob, blen);
435545d5ecaSDag-Erling Smørgrav #endif
436545d5ecaSDag-Erling Smørgrav 	buffer_init(&b);
437545d5ecaSDag-Erling Smørgrav 	buffer_append(&b, blob, blen);
438545d5ecaSDag-Erling Smørgrav 
439545d5ecaSDag-Erling Smørgrav 	newkey = xmalloc(sizeof(*newkey));
440545d5ecaSDag-Erling Smørgrav 	enc = &newkey->enc;
441545d5ecaSDag-Erling Smørgrav 	mac = &newkey->mac;
442545d5ecaSDag-Erling Smørgrav 	comp = &newkey->comp;
443545d5ecaSDag-Erling Smørgrav 
444545d5ecaSDag-Erling Smørgrav 	/* Enc structure */
445545d5ecaSDag-Erling Smørgrav 	enc->name = buffer_get_string(&b, NULL);
446545d5ecaSDag-Erling Smørgrav 	buffer_get(&b, &enc->cipher, sizeof(enc->cipher));
447545d5ecaSDag-Erling Smørgrav 	enc->enabled = buffer_get_int(&b);
448545d5ecaSDag-Erling Smørgrav 	enc->block_size = buffer_get_int(&b);
449545d5ecaSDag-Erling Smørgrav 	enc->key = buffer_get_string(&b, &enc->key_len);
450545d5ecaSDag-Erling Smørgrav 	enc->iv = buffer_get_string(&b, &len);
451545d5ecaSDag-Erling Smørgrav 	if (len != enc->block_size)
452f388f5efSDag-Erling Smørgrav 		fatal("%s: bad ivlen: expected %u != %u", __func__,
453545d5ecaSDag-Erling Smørgrav 		    enc->block_size, len);
454545d5ecaSDag-Erling Smørgrav 
455545d5ecaSDag-Erling Smørgrav 	if (enc->name == NULL || cipher_by_name(enc->name) != enc->cipher)
456545d5ecaSDag-Erling Smørgrav 		fatal("%s: bad cipher name %s or pointer %p", __func__,
457545d5ecaSDag-Erling Smørgrav 		    enc->name, enc->cipher);
458545d5ecaSDag-Erling Smørgrav 
459545d5ecaSDag-Erling Smørgrav 	/* Mac structure */
460545d5ecaSDag-Erling Smørgrav 	mac->name = buffer_get_string(&b, NULL);
461545d5ecaSDag-Erling Smørgrav 	if (mac->name == NULL || mac_init(mac, mac->name) == -1)
462545d5ecaSDag-Erling Smørgrav 		fatal("%s: can not init mac %s", __func__, mac->name);
463545d5ecaSDag-Erling Smørgrav 	mac->enabled = buffer_get_int(&b);
464545d5ecaSDag-Erling Smørgrav 	mac->key = buffer_get_string(&b, &len);
465545d5ecaSDag-Erling Smørgrav 	if (len > mac->key_len)
466f388f5efSDag-Erling Smørgrav 		fatal("%s: bad mac key length: %u > %d", __func__, len,
467545d5ecaSDag-Erling Smørgrav 		    mac->key_len);
468545d5ecaSDag-Erling Smørgrav 	mac->key_len = len;
469545d5ecaSDag-Erling Smørgrav 
470545d5ecaSDag-Erling Smørgrav 	/* Comp structure */
471545d5ecaSDag-Erling Smørgrav 	comp->type = buffer_get_int(&b);
472545d5ecaSDag-Erling Smørgrav 	comp->enabled = buffer_get_int(&b);
473545d5ecaSDag-Erling Smørgrav 	comp->name = buffer_get_string(&b, NULL);
474545d5ecaSDag-Erling Smørgrav 
475545d5ecaSDag-Erling Smørgrav 	len = buffer_len(&b);
476545d5ecaSDag-Erling Smørgrav 	if (len != 0)
477f388f5efSDag-Erling Smørgrav 		error("newkeys_from_blob: remaining bytes in blob %u", len);
478545d5ecaSDag-Erling Smørgrav 	buffer_free(&b);
479545d5ecaSDag-Erling Smørgrav 	return (newkey);
480545d5ecaSDag-Erling Smørgrav }
481545d5ecaSDag-Erling Smørgrav 
482545d5ecaSDag-Erling Smørgrav int
483545d5ecaSDag-Erling Smørgrav mm_newkeys_to_blob(int mode, u_char **blobp, u_int *lenp)
484545d5ecaSDag-Erling Smørgrav {
485545d5ecaSDag-Erling Smørgrav 	Buffer b;
486545d5ecaSDag-Erling Smørgrav 	int len;
487545d5ecaSDag-Erling Smørgrav 	Enc *enc;
488545d5ecaSDag-Erling Smørgrav 	Mac *mac;
489545d5ecaSDag-Erling Smørgrav 	Comp *comp;
490545d5ecaSDag-Erling Smørgrav 	Newkeys *newkey = newkeys[mode];
491545d5ecaSDag-Erling Smørgrav 
492545d5ecaSDag-Erling Smørgrav 	debug3("%s: converting %p", __func__, newkey);
493545d5ecaSDag-Erling Smørgrav 
494545d5ecaSDag-Erling Smørgrav 	if (newkey == NULL) {
495545d5ecaSDag-Erling Smørgrav 		error("%s: newkey == NULL", __func__);
496545d5ecaSDag-Erling Smørgrav 		return 0;
497545d5ecaSDag-Erling Smørgrav 	}
498545d5ecaSDag-Erling Smørgrav 	enc = &newkey->enc;
499545d5ecaSDag-Erling Smørgrav 	mac = &newkey->mac;
500545d5ecaSDag-Erling Smørgrav 	comp = &newkey->comp;
501545d5ecaSDag-Erling Smørgrav 
502545d5ecaSDag-Erling Smørgrav 	buffer_init(&b);
503545d5ecaSDag-Erling Smørgrav 	/* Enc structure */
504545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&b, enc->name);
505545d5ecaSDag-Erling Smørgrav 	/* The cipher struct is constant and shared, you export pointer */
506545d5ecaSDag-Erling Smørgrav 	buffer_append(&b, &enc->cipher, sizeof(enc->cipher));
507545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&b, enc->enabled);
508545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&b, enc->block_size);
509545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&b, enc->key, enc->key_len);
510545d5ecaSDag-Erling Smørgrav 	packet_get_keyiv(mode, enc->iv, enc->block_size);
511545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&b, enc->iv, enc->block_size);
512545d5ecaSDag-Erling Smørgrav 
513545d5ecaSDag-Erling Smørgrav 	/* Mac structure */
514545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&b, mac->name);
515545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&b, mac->enabled);
516545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&b, mac->key, mac->key_len);
517545d5ecaSDag-Erling Smørgrav 
518545d5ecaSDag-Erling Smørgrav 	/* Comp structure */
519545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&b, comp->type);
520545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&b, comp->enabled);
521545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&b, comp->name);
522545d5ecaSDag-Erling Smørgrav 
523545d5ecaSDag-Erling Smørgrav 	len = buffer_len(&b);
524545d5ecaSDag-Erling Smørgrav 	if (lenp != NULL)
525545d5ecaSDag-Erling Smørgrav 		*lenp = len;
526f388f5efSDag-Erling Smørgrav 	if (blobp != NULL) {
527f388f5efSDag-Erling Smørgrav 		*blobp = xmalloc(len);
528f388f5efSDag-Erling Smørgrav 		memcpy(*blobp, buffer_ptr(&b), len);
529f388f5efSDag-Erling Smørgrav 	}
530f388f5efSDag-Erling Smørgrav 	memset(buffer_ptr(&b), 0, len);
531f388f5efSDag-Erling Smørgrav 	buffer_free(&b);
532545d5ecaSDag-Erling Smørgrav 	return len;
533545d5ecaSDag-Erling Smørgrav }
534545d5ecaSDag-Erling Smørgrav 
535545d5ecaSDag-Erling Smørgrav static void
536545d5ecaSDag-Erling Smørgrav mm_send_kex(Buffer *m, Kex *kex)
537545d5ecaSDag-Erling Smørgrav {
538545d5ecaSDag-Erling Smørgrav 	buffer_put_string(m, kex->session_id, kex->session_id_len);
539545d5ecaSDag-Erling Smørgrav 	buffer_put_int(m, kex->we_need);
540545d5ecaSDag-Erling Smørgrav 	buffer_put_int(m, kex->hostkey_type);
541545d5ecaSDag-Erling Smørgrav 	buffer_put_int(m, kex->kex_type);
542545d5ecaSDag-Erling Smørgrav 	buffer_put_string(m, buffer_ptr(&kex->my), buffer_len(&kex->my));
543545d5ecaSDag-Erling Smørgrav 	buffer_put_string(m, buffer_ptr(&kex->peer), buffer_len(&kex->peer));
544545d5ecaSDag-Erling Smørgrav 	buffer_put_int(m, kex->flags);
545545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(m, kex->client_version_string);
546545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(m, kex->server_version_string);
547545d5ecaSDag-Erling Smørgrav }
548545d5ecaSDag-Erling Smørgrav 
549545d5ecaSDag-Erling Smørgrav void
55021e764dfSDag-Erling Smørgrav mm_send_keystate(struct monitor *monitor)
551545d5ecaSDag-Erling Smørgrav {
552545d5ecaSDag-Erling Smørgrav 	Buffer m;
553545d5ecaSDag-Erling Smørgrav 	u_char *blob, *p;
554545d5ecaSDag-Erling Smørgrav 	u_int bloblen, plen;
555cf2b5f3bSDag-Erling Smørgrav 	u_int32_t seqnr, packets;
556cf2b5f3bSDag-Erling Smørgrav 	u_int64_t blocks;
557545d5ecaSDag-Erling Smørgrav 
558545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
559545d5ecaSDag-Erling Smørgrav 
560545d5ecaSDag-Erling Smørgrav 	if (!compat20) {
561545d5ecaSDag-Erling Smørgrav 		u_char iv[24];
562545d5ecaSDag-Erling Smørgrav 		u_char *key;
563545d5ecaSDag-Erling Smørgrav 		u_int ivlen, keylen;
564545d5ecaSDag-Erling Smørgrav 
565545d5ecaSDag-Erling Smørgrav 		buffer_put_int(&m, packet_get_protocol_flags());
566545d5ecaSDag-Erling Smørgrav 
567545d5ecaSDag-Erling Smørgrav 		buffer_put_int(&m, packet_get_ssh1_cipher());
568545d5ecaSDag-Erling Smørgrav 
569545d5ecaSDag-Erling Smørgrav 		debug3("%s: Sending ssh1 KEY+IV", __func__);
570545d5ecaSDag-Erling Smørgrav 		keylen = packet_get_encryption_key(NULL);
571545d5ecaSDag-Erling Smørgrav 		key = xmalloc(keylen+1);	/* add 1 if keylen == 0 */
572545d5ecaSDag-Erling Smørgrav 		keylen = packet_get_encryption_key(key);
573545d5ecaSDag-Erling Smørgrav 		buffer_put_string(&m, key, keylen);
574545d5ecaSDag-Erling Smørgrav 		memset(key, 0, keylen);
575545d5ecaSDag-Erling Smørgrav 		xfree(key);
576545d5ecaSDag-Erling Smørgrav 
577545d5ecaSDag-Erling Smørgrav 		ivlen = packet_get_keyiv_len(MODE_OUT);
578545d5ecaSDag-Erling Smørgrav 		packet_get_keyiv(MODE_OUT, iv, ivlen);
579545d5ecaSDag-Erling Smørgrav 		buffer_put_string(&m, iv, ivlen);
580545d5ecaSDag-Erling Smørgrav 		ivlen = packet_get_keyiv_len(MODE_OUT);
581545d5ecaSDag-Erling Smørgrav 		packet_get_keyiv(MODE_IN, iv, ivlen);
582545d5ecaSDag-Erling Smørgrav 		buffer_put_string(&m, iv, ivlen);
583545d5ecaSDag-Erling Smørgrav 		goto skip;
584545d5ecaSDag-Erling Smørgrav 	} else {
585545d5ecaSDag-Erling Smørgrav 		/* Kex for rekeying */
58621e764dfSDag-Erling Smørgrav 		mm_send_kex(&m, *monitor->m_pkex);
587545d5ecaSDag-Erling Smørgrav 	}
588545d5ecaSDag-Erling Smørgrav 
589545d5ecaSDag-Erling Smørgrav 	debug3("%s: Sending new keys: %p %p",
590545d5ecaSDag-Erling Smørgrav 	    __func__, newkeys[MODE_OUT], newkeys[MODE_IN]);
591545d5ecaSDag-Erling Smørgrav 
592545d5ecaSDag-Erling Smørgrav 	/* Keys from Kex */
593545d5ecaSDag-Erling Smørgrav 	if (!mm_newkeys_to_blob(MODE_OUT, &blob, &bloblen))
594545d5ecaSDag-Erling Smørgrav 		fatal("%s: conversion of newkeys failed", __func__);
595545d5ecaSDag-Erling Smørgrav 
596545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, blob, bloblen);
597545d5ecaSDag-Erling Smørgrav 	xfree(blob);
598545d5ecaSDag-Erling Smørgrav 
599545d5ecaSDag-Erling Smørgrav 	if (!mm_newkeys_to_blob(MODE_IN, &blob, &bloblen))
600545d5ecaSDag-Erling Smørgrav 		fatal("%s: conversion of newkeys failed", __func__);
601545d5ecaSDag-Erling Smørgrav 
602545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, blob, bloblen);
603545d5ecaSDag-Erling Smørgrav 	xfree(blob);
604545d5ecaSDag-Erling Smørgrav 
605cf2b5f3bSDag-Erling Smørgrav 	packet_get_state(MODE_OUT, &seqnr, &blocks, &packets);
606cf2b5f3bSDag-Erling Smørgrav 	buffer_put_int(&m, seqnr);
607cf2b5f3bSDag-Erling Smørgrav 	buffer_put_int64(&m, blocks);
608cf2b5f3bSDag-Erling Smørgrav 	buffer_put_int(&m, packets);
609cf2b5f3bSDag-Erling Smørgrav 	packet_get_state(MODE_IN, &seqnr, &blocks, &packets);
610cf2b5f3bSDag-Erling Smørgrav 	buffer_put_int(&m, seqnr);
611cf2b5f3bSDag-Erling Smørgrav 	buffer_put_int64(&m, blocks);
612cf2b5f3bSDag-Erling Smørgrav 	buffer_put_int(&m, packets);
613545d5ecaSDag-Erling Smørgrav 
614545d5ecaSDag-Erling Smørgrav 	debug3("%s: New keys have been sent", __func__);
615545d5ecaSDag-Erling Smørgrav  skip:
616545d5ecaSDag-Erling Smørgrav 	/* More key context */
617545d5ecaSDag-Erling Smørgrav 	plen = packet_get_keycontext(MODE_OUT, NULL);
618545d5ecaSDag-Erling Smørgrav 	p = xmalloc(plen+1);
619545d5ecaSDag-Erling Smørgrav 	packet_get_keycontext(MODE_OUT, p);
620545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, p, plen);
621545d5ecaSDag-Erling Smørgrav 	xfree(p);
622545d5ecaSDag-Erling Smørgrav 
623545d5ecaSDag-Erling Smørgrav 	plen = packet_get_keycontext(MODE_IN, NULL);
624545d5ecaSDag-Erling Smørgrav 	p = xmalloc(plen+1);
625545d5ecaSDag-Erling Smørgrav 	packet_get_keycontext(MODE_IN, p);
626545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, p, plen);
627545d5ecaSDag-Erling Smørgrav 	xfree(p);
628545d5ecaSDag-Erling Smørgrav 
629545d5ecaSDag-Erling Smørgrav 	/* Compression state */
630545d5ecaSDag-Erling Smørgrav 	debug3("%s: Sending compression state", __func__);
631545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, &outgoing_stream, sizeof(outgoing_stream));
632545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, &incoming_stream, sizeof(incoming_stream));
633545d5ecaSDag-Erling Smørgrav 
634545d5ecaSDag-Erling Smørgrav 	/* Network I/O buffers */
635545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, buffer_ptr(&input), buffer_len(&input));
636545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, buffer_ptr(&output), buffer_len(&output));
637545d5ecaSDag-Erling Smørgrav 
63821e764dfSDag-Erling Smørgrav 	mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, &m);
639545d5ecaSDag-Erling Smørgrav 	debug3("%s: Finished sending state", __func__);
640545d5ecaSDag-Erling Smørgrav 
641545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
642545d5ecaSDag-Erling Smørgrav }
643545d5ecaSDag-Erling Smørgrav 
644545d5ecaSDag-Erling Smørgrav int
645545d5ecaSDag-Erling Smørgrav mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
646545d5ecaSDag-Erling Smørgrav {
647545d5ecaSDag-Erling Smørgrav 	Buffer m;
64821e764dfSDag-Erling Smørgrav 	char *p, *msg;
649545d5ecaSDag-Erling Smørgrav 	int success = 0;
650545d5ecaSDag-Erling Smørgrav 
651545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
652545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, &m);
653545d5ecaSDag-Erling Smørgrav 
654545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PTY", __func__);
655545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PTY, &m);
656545d5ecaSDag-Erling Smørgrav 
657545d5ecaSDag-Erling Smørgrav 	success = buffer_get_int(&m);
658545d5ecaSDag-Erling Smørgrav 	if (success == 0) {
659545d5ecaSDag-Erling Smørgrav 		debug3("%s: pty alloc failed", __func__);
660545d5ecaSDag-Erling Smørgrav 		buffer_free(&m);
661545d5ecaSDag-Erling Smørgrav 		return (0);
662545d5ecaSDag-Erling Smørgrav 	}
663545d5ecaSDag-Erling Smørgrav 	p = buffer_get_string(&m, NULL);
66421e764dfSDag-Erling Smørgrav 	msg = buffer_get_string(&m, NULL);
665545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
666545d5ecaSDag-Erling Smørgrav 
667545d5ecaSDag-Erling Smørgrav 	strlcpy(namebuf, p, namebuflen); /* Possible truncation */
668545d5ecaSDag-Erling Smørgrav 	xfree(p);
669545d5ecaSDag-Erling Smørgrav 
67021e764dfSDag-Erling Smørgrav 	buffer_append(&loginmsg, msg, strlen(msg));
67121e764dfSDag-Erling Smørgrav 	xfree(msg);
67221e764dfSDag-Erling Smørgrav 
673545d5ecaSDag-Erling Smørgrav 	*ptyfd = mm_receive_fd(pmonitor->m_recvfd);
674545d5ecaSDag-Erling Smørgrav 	*ttyfd = mm_receive_fd(pmonitor->m_recvfd);
675545d5ecaSDag-Erling Smørgrav 
676545d5ecaSDag-Erling Smørgrav 	/* Success */
677545d5ecaSDag-Erling Smørgrav 	return (1);
678545d5ecaSDag-Erling Smørgrav }
679545d5ecaSDag-Erling Smørgrav 
680545d5ecaSDag-Erling Smørgrav void
6811ec0d754SDag-Erling Smørgrav mm_session_pty_cleanup2(Session *s)
682545d5ecaSDag-Erling Smørgrav {
683545d5ecaSDag-Erling Smørgrav 	Buffer m;
684545d5ecaSDag-Erling Smørgrav 
685545d5ecaSDag-Erling Smørgrav 	if (s->ttyfd == -1)
686545d5ecaSDag-Erling Smørgrav 		return;
687545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
688545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, s->tty);
689545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, &m);
690545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
691545d5ecaSDag-Erling Smørgrav 
692545d5ecaSDag-Erling Smørgrav 	/* closed dup'ed master */
693545d5ecaSDag-Erling Smørgrav 	if (close(s->ptymaster) < 0)
694545d5ecaSDag-Erling Smørgrav 		error("close(s->ptymaster): %s", strerror(errno));
695545d5ecaSDag-Erling Smørgrav 
696545d5ecaSDag-Erling Smørgrav 	/* unlink pty from session */
697545d5ecaSDag-Erling Smørgrav 	s->ttyfd = -1;
698545d5ecaSDag-Erling Smørgrav }
699545d5ecaSDag-Erling Smørgrav 
70083d2307dSDag-Erling Smørgrav #ifdef USE_PAM
70183d2307dSDag-Erling Smørgrav void
7025962c0e9SDag-Erling Smørgrav mm_start_pam(Authctxt *authctxt)
70383d2307dSDag-Erling Smørgrav {
70483d2307dSDag-Erling Smørgrav 	Buffer m;
70583d2307dSDag-Erling Smørgrav 
70683d2307dSDag-Erling Smørgrav 	debug3("%s entering", __func__);
707cf2b5f3bSDag-Erling Smørgrav 	if (!options.use_pam)
708cf2b5f3bSDag-Erling Smørgrav 		fatal("UsePAM=no, but ended up in %s anyway", __func__);
70983d2307dSDag-Erling Smørgrav 
71083d2307dSDag-Erling Smørgrav 	buffer_init(&m);
71183d2307dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_START, &m);
71283d2307dSDag-Erling Smørgrav 
71383d2307dSDag-Erling Smørgrav 	buffer_free(&m);
71483d2307dSDag-Erling Smørgrav }
715382d19eeSDag-Erling Smørgrav 
716cf2b5f3bSDag-Erling Smørgrav u_int
717cf2b5f3bSDag-Erling Smørgrav mm_do_pam_account(void)
718cf2b5f3bSDag-Erling Smørgrav {
719cf2b5f3bSDag-Erling Smørgrav 	Buffer m;
720cf2b5f3bSDag-Erling Smørgrav 	u_int ret;
721aa49c926SDag-Erling Smørgrav 	char *msg;
722cf2b5f3bSDag-Erling Smørgrav 
723cf2b5f3bSDag-Erling Smørgrav 	debug3("%s entering", __func__);
724cf2b5f3bSDag-Erling Smørgrav 	if (!options.use_pam)
725cf2b5f3bSDag-Erling Smørgrav 		fatal("UsePAM=no, but ended up in %s anyway", __func__);
726cf2b5f3bSDag-Erling Smørgrav 
727cf2b5f3bSDag-Erling Smørgrav 	buffer_init(&m);
728cf2b5f3bSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, &m);
729cf2b5f3bSDag-Erling Smørgrav 
730cf2b5f3bSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
731cf2b5f3bSDag-Erling Smørgrav 	    MONITOR_ANS_PAM_ACCOUNT, &m);
732cf2b5f3bSDag-Erling Smørgrav 	ret = buffer_get_int(&m);
733aa49c926SDag-Erling Smørgrav 	msg = buffer_get_string(&m, NULL);
734aa49c926SDag-Erling Smørgrav 	buffer_append(&loginmsg, msg, strlen(msg));
735aa49c926SDag-Erling Smørgrav 	xfree(msg);
736cf2b5f3bSDag-Erling Smørgrav 
737cf2b5f3bSDag-Erling Smørgrav 	buffer_free(&m);
738cf2b5f3bSDag-Erling Smørgrav 
739cf2b5f3bSDag-Erling Smørgrav 	debug3("%s returning %d", __func__, ret);
740cf2b5f3bSDag-Erling Smørgrav 
741cf2b5f3bSDag-Erling Smørgrav 	return (ret);
742cf2b5f3bSDag-Erling Smørgrav }
743cf2b5f3bSDag-Erling Smørgrav 
744382d19eeSDag-Erling Smørgrav void *
745cf2b5f3bSDag-Erling Smørgrav mm_sshpam_init_ctx(Authctxt *authctxt)
746382d19eeSDag-Erling Smørgrav {
747382d19eeSDag-Erling Smørgrav 	Buffer m;
748382d19eeSDag-Erling Smørgrav 	int success;
749382d19eeSDag-Erling Smørgrav 
750382d19eeSDag-Erling Smørgrav 	debug3("%s", __func__);
751382d19eeSDag-Erling Smørgrav 	buffer_init(&m);
752382d19eeSDag-Erling Smørgrav 	buffer_put_cstring(&m, authctxt->user);
753382d19eeSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_INIT_CTX, &m);
754382d19eeSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PAM_INIT_CTX", __func__);
755382d19eeSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_INIT_CTX, &m);
756382d19eeSDag-Erling Smørgrav 	success = buffer_get_int(&m);
757382d19eeSDag-Erling Smørgrav 	if (success == 0) {
758382d19eeSDag-Erling Smørgrav 		debug3("%s: pam_init_ctx failed", __func__);
759382d19eeSDag-Erling Smørgrav 		buffer_free(&m);
760382d19eeSDag-Erling Smørgrav 		return (NULL);
761382d19eeSDag-Erling Smørgrav 	}
762382d19eeSDag-Erling Smørgrav 	buffer_free(&m);
763382d19eeSDag-Erling Smørgrav 	return (authctxt);
764382d19eeSDag-Erling Smørgrav }
765382d19eeSDag-Erling Smørgrav 
766382d19eeSDag-Erling Smørgrav int
767cf2b5f3bSDag-Erling Smørgrav mm_sshpam_query(void *ctx, char **name, char **info,
768382d19eeSDag-Erling Smørgrav     u_int *num, char ***prompts, u_int **echo_on)
769382d19eeSDag-Erling Smørgrav {
770382d19eeSDag-Erling Smørgrav 	Buffer m;
771382d19eeSDag-Erling Smørgrav 	int i, ret;
772382d19eeSDag-Erling Smørgrav 
773382d19eeSDag-Erling Smørgrav 	debug3("%s", __func__);
774382d19eeSDag-Erling Smørgrav 	buffer_init(&m);
775382d19eeSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_QUERY, &m);
776382d19eeSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PAM_QUERY", __func__);
777382d19eeSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_QUERY, &m);
778382d19eeSDag-Erling Smørgrav 	ret = buffer_get_int(&m);
779382d19eeSDag-Erling Smørgrav 	debug3("%s: pam_query returned %d", __func__, ret);
780382d19eeSDag-Erling Smørgrav 	*name = buffer_get_string(&m, NULL);
781382d19eeSDag-Erling Smørgrav 	*info = buffer_get_string(&m, NULL);
782382d19eeSDag-Erling Smørgrav 	*num = buffer_get_int(&m);
783382d19eeSDag-Erling Smørgrav 	*prompts = xmalloc((*num + 1) * sizeof(char *));
784382d19eeSDag-Erling Smørgrav 	*echo_on = xmalloc((*num + 1) * sizeof(u_int));
785382d19eeSDag-Erling Smørgrav 	for (i = 0; i < *num; ++i) {
786382d19eeSDag-Erling Smørgrav 		(*prompts)[i] = buffer_get_string(&m, NULL);
787382d19eeSDag-Erling Smørgrav 		(*echo_on)[i] = buffer_get_int(&m);
788382d19eeSDag-Erling Smørgrav 	}
789382d19eeSDag-Erling Smørgrav 	buffer_free(&m);
790382d19eeSDag-Erling Smørgrav 	return (ret);
791382d19eeSDag-Erling Smørgrav }
792382d19eeSDag-Erling Smørgrav 
793382d19eeSDag-Erling Smørgrav int
794cf2b5f3bSDag-Erling Smørgrav mm_sshpam_respond(void *ctx, u_int num, char **resp)
795382d19eeSDag-Erling Smørgrav {
796382d19eeSDag-Erling Smørgrav 	Buffer m;
797382d19eeSDag-Erling Smørgrav 	int i, ret;
798382d19eeSDag-Erling Smørgrav 
799382d19eeSDag-Erling Smørgrav 	debug3("%s", __func__);
800382d19eeSDag-Erling Smørgrav 	buffer_init(&m);
801382d19eeSDag-Erling Smørgrav 	buffer_put_int(&m, num);
802382d19eeSDag-Erling Smørgrav 	for (i = 0; i < num; ++i)
803382d19eeSDag-Erling Smørgrav 		buffer_put_cstring(&m, resp[i]);
804382d19eeSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_RESPOND, &m);
805382d19eeSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__);
806382d19eeSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_RESPOND, &m);
807382d19eeSDag-Erling Smørgrav 	ret = buffer_get_int(&m);
808382d19eeSDag-Erling Smørgrav 	debug3("%s: pam_respond returned %d", __func__, ret);
809382d19eeSDag-Erling Smørgrav 	buffer_free(&m);
810382d19eeSDag-Erling Smørgrav 	return (ret);
811382d19eeSDag-Erling Smørgrav }
812382d19eeSDag-Erling Smørgrav 
813382d19eeSDag-Erling Smørgrav void
814cf2b5f3bSDag-Erling Smørgrav mm_sshpam_free_ctx(void *ctxtp)
815382d19eeSDag-Erling Smørgrav {
816382d19eeSDag-Erling Smørgrav 	Buffer m;
817382d19eeSDag-Erling Smørgrav 
818382d19eeSDag-Erling Smørgrav 	debug3("%s", __func__);
819382d19eeSDag-Erling Smørgrav 	buffer_init(&m);
820382d19eeSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_FREE_CTX, &m);
821382d19eeSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PAM_FREE_CTX", __func__);
822382d19eeSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_FREE_CTX, &m);
823382d19eeSDag-Erling Smørgrav 	buffer_free(&m);
824382d19eeSDag-Erling Smørgrav }
82583d2307dSDag-Erling Smørgrav #endif /* USE_PAM */
82683d2307dSDag-Erling Smørgrav 
827545d5ecaSDag-Erling Smørgrav /* Request process termination */
828545d5ecaSDag-Erling Smørgrav 
829545d5ecaSDag-Erling Smørgrav void
830545d5ecaSDag-Erling Smørgrav mm_terminate(void)
831545d5ecaSDag-Erling Smørgrav {
832545d5ecaSDag-Erling Smørgrav 	Buffer m;
833545d5ecaSDag-Erling Smørgrav 
834545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
835545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_TERM, &m);
836545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
837545d5ecaSDag-Erling Smørgrav }
838545d5ecaSDag-Erling Smørgrav 
839545d5ecaSDag-Erling Smørgrav int
840545d5ecaSDag-Erling Smørgrav mm_ssh1_session_key(BIGNUM *num)
841545d5ecaSDag-Erling Smørgrav {
842545d5ecaSDag-Erling Smørgrav 	int rsafail;
843545d5ecaSDag-Erling Smørgrav 	Buffer m;
844545d5ecaSDag-Erling Smørgrav 
845545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
846545d5ecaSDag-Erling Smørgrav 	buffer_put_bignum2(&m, num);
847545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSKEY, &m);
848545d5ecaSDag-Erling Smørgrav 
849545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SESSKEY, &m);
850545d5ecaSDag-Erling Smørgrav 
851545d5ecaSDag-Erling Smørgrav 	rsafail = buffer_get_int(&m);
852545d5ecaSDag-Erling Smørgrav 	buffer_get_bignum2(&m, num);
853545d5ecaSDag-Erling Smørgrav 
854545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
855545d5ecaSDag-Erling Smørgrav 
856545d5ecaSDag-Erling Smørgrav 	return (rsafail);
857545d5ecaSDag-Erling Smørgrav }
858545d5ecaSDag-Erling Smørgrav 
859545d5ecaSDag-Erling Smørgrav static void
860545d5ecaSDag-Erling Smørgrav mm_chall_setup(char **name, char **infotxt, u_int *numprompts,
861545d5ecaSDag-Erling Smørgrav     char ***prompts, u_int **echo_on)
862545d5ecaSDag-Erling Smørgrav {
863545d5ecaSDag-Erling Smørgrav 	*name = xstrdup("");
864545d5ecaSDag-Erling Smørgrav 	*infotxt = xstrdup("");
865545d5ecaSDag-Erling Smørgrav 	*numprompts = 1;
866545d5ecaSDag-Erling Smørgrav 	*prompts = xmalloc(*numprompts * sizeof(char *));
867545d5ecaSDag-Erling Smørgrav 	*echo_on = xmalloc(*numprompts * sizeof(u_int));
868545d5ecaSDag-Erling Smørgrav 	(*echo_on)[0] = 0;
869545d5ecaSDag-Erling Smørgrav }
870545d5ecaSDag-Erling Smørgrav 
871545d5ecaSDag-Erling Smørgrav int
872545d5ecaSDag-Erling Smørgrav mm_bsdauth_query(void *ctx, char **name, char **infotxt,
873545d5ecaSDag-Erling Smørgrav    u_int *numprompts, char ***prompts, u_int **echo_on)
874545d5ecaSDag-Erling Smørgrav {
875545d5ecaSDag-Erling Smørgrav 	Buffer m;
876e73e9afaSDag-Erling Smørgrav 	u_int success;
877545d5ecaSDag-Erling Smørgrav 	char *challenge;
878545d5ecaSDag-Erling Smørgrav 
879545d5ecaSDag-Erling Smørgrav 	debug3("%s: entering", __func__);
880545d5ecaSDag-Erling Smørgrav 
881545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
882545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHQUERY, &m);
883545d5ecaSDag-Erling Smørgrav 
884545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_BSDAUTHQUERY,
885545d5ecaSDag-Erling Smørgrav 	    &m);
886e73e9afaSDag-Erling Smørgrav 	success = buffer_get_int(&m);
887e73e9afaSDag-Erling Smørgrav 	if (success == 0) {
888545d5ecaSDag-Erling Smørgrav 		debug3("%s: no challenge", __func__);
889545d5ecaSDag-Erling Smørgrav 		buffer_free(&m);
890545d5ecaSDag-Erling Smørgrav 		return (-1);
891545d5ecaSDag-Erling Smørgrav 	}
892545d5ecaSDag-Erling Smørgrav 
893545d5ecaSDag-Erling Smørgrav 	/* Get the challenge, and format the response */
894545d5ecaSDag-Erling Smørgrav 	challenge  = buffer_get_string(&m, NULL);
895545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
896545d5ecaSDag-Erling Smørgrav 
897545d5ecaSDag-Erling Smørgrav 	mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
898545d5ecaSDag-Erling Smørgrav 	(*prompts)[0] = challenge;
899545d5ecaSDag-Erling Smørgrav 
900545d5ecaSDag-Erling Smørgrav 	debug3("%s: received challenge: %s", __func__, challenge);
901545d5ecaSDag-Erling Smørgrav 
902545d5ecaSDag-Erling Smørgrav 	return (0);
903545d5ecaSDag-Erling Smørgrav }
904545d5ecaSDag-Erling Smørgrav 
905545d5ecaSDag-Erling Smørgrav int
906545d5ecaSDag-Erling Smørgrav mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses)
907545d5ecaSDag-Erling Smørgrav {
908545d5ecaSDag-Erling Smørgrav 	Buffer m;
909545d5ecaSDag-Erling Smørgrav 	int authok;
910545d5ecaSDag-Erling Smørgrav 
911545d5ecaSDag-Erling Smørgrav 	debug3("%s: entering", __func__);
912545d5ecaSDag-Erling Smørgrav 	if (numresponses != 1)
913545d5ecaSDag-Erling Smørgrav 		return (-1);
914545d5ecaSDag-Erling Smørgrav 
915545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
916545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, responses[0]);
917545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHRESPOND, &m);
918545d5ecaSDag-Erling Smørgrav 
919545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
920545d5ecaSDag-Erling Smørgrav 	    MONITOR_ANS_BSDAUTHRESPOND, &m);
921545d5ecaSDag-Erling Smørgrav 
922545d5ecaSDag-Erling Smørgrav 	authok = buffer_get_int(&m);
923545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
924545d5ecaSDag-Erling Smørgrav 
925545d5ecaSDag-Erling Smørgrav 	return ((authok == 0) ? -1 : 0);
926545d5ecaSDag-Erling Smørgrav }
927545d5ecaSDag-Erling Smørgrav 
928edb557f8SDag-Erling Smørgrav #ifdef SKEY
929545d5ecaSDag-Erling Smørgrav int
930545d5ecaSDag-Erling Smørgrav mm_skey_query(void *ctx, char **name, char **infotxt,
931545d5ecaSDag-Erling Smørgrav    u_int *numprompts, char ***prompts, u_int **echo_on)
932545d5ecaSDag-Erling Smørgrav {
933545d5ecaSDag-Erling Smørgrav 	Buffer m;
934e73e9afaSDag-Erling Smørgrav 	int len;
935e73e9afaSDag-Erling Smørgrav 	u_int success;
936545d5ecaSDag-Erling Smørgrav 	char *p, *challenge;
937545d5ecaSDag-Erling Smørgrav 
938545d5ecaSDag-Erling Smørgrav 	debug3("%s: entering", __func__);
939545d5ecaSDag-Erling Smørgrav 
940545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
941545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYQUERY, &m);
942545d5ecaSDag-Erling Smørgrav 
943545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SKEYQUERY,
944545d5ecaSDag-Erling Smørgrav 	    &m);
945e73e9afaSDag-Erling Smørgrav 	success = buffer_get_int(&m);
946e73e9afaSDag-Erling Smørgrav 	if (success == 0) {
947545d5ecaSDag-Erling Smørgrav 		debug3("%s: no challenge", __func__);
948545d5ecaSDag-Erling Smørgrav 		buffer_free(&m);
949545d5ecaSDag-Erling Smørgrav 		return (-1);
950545d5ecaSDag-Erling Smørgrav 	}
951545d5ecaSDag-Erling Smørgrav 
952545d5ecaSDag-Erling Smørgrav 	/* Get the challenge, and format the response */
953545d5ecaSDag-Erling Smørgrav 	challenge  = buffer_get_string(&m, NULL);
954545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
955545d5ecaSDag-Erling Smørgrav 
956545d5ecaSDag-Erling Smørgrav 	debug3("%s: received challenge: %s", __func__, challenge);
957545d5ecaSDag-Erling Smørgrav 
958545d5ecaSDag-Erling Smørgrav 	mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
959545d5ecaSDag-Erling Smørgrav 
960545d5ecaSDag-Erling Smørgrav 	len = strlen(challenge) + strlen(SKEY_PROMPT) + 1;
961545d5ecaSDag-Erling Smørgrav 	p = xmalloc(len);
962545d5ecaSDag-Erling Smørgrav 	strlcpy(p, challenge, len);
963545d5ecaSDag-Erling Smørgrav 	strlcat(p, SKEY_PROMPT, len);
964545d5ecaSDag-Erling Smørgrav 	(*prompts)[0] = p;
965545d5ecaSDag-Erling Smørgrav 	xfree(challenge);
966545d5ecaSDag-Erling Smørgrav 
967545d5ecaSDag-Erling Smørgrav 	return (0);
968545d5ecaSDag-Erling Smørgrav }
969545d5ecaSDag-Erling Smørgrav 
970545d5ecaSDag-Erling Smørgrav int
971545d5ecaSDag-Erling Smørgrav mm_skey_respond(void *ctx, u_int numresponses, char **responses)
972545d5ecaSDag-Erling Smørgrav {
973545d5ecaSDag-Erling Smørgrav 	Buffer m;
974545d5ecaSDag-Erling Smørgrav 	int authok;
975545d5ecaSDag-Erling Smørgrav 
976545d5ecaSDag-Erling Smørgrav 	debug3("%s: entering", __func__);
977545d5ecaSDag-Erling Smørgrav 	if (numresponses != 1)
978545d5ecaSDag-Erling Smørgrav 		return (-1);
979545d5ecaSDag-Erling Smørgrav 
980545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
981545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, responses[0]);
982545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYRESPOND, &m);
983545d5ecaSDag-Erling Smørgrav 
984545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
985545d5ecaSDag-Erling Smørgrav 	    MONITOR_ANS_SKEYRESPOND, &m);
986545d5ecaSDag-Erling Smørgrav 
987545d5ecaSDag-Erling Smørgrav 	authok = buffer_get_int(&m);
988545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
989545d5ecaSDag-Erling Smørgrav 
990545d5ecaSDag-Erling Smørgrav 	return ((authok == 0) ? -1 : 0);
991545d5ecaSDag-Erling Smørgrav }
99221e764dfSDag-Erling Smørgrav #endif /* SKEY */
993545d5ecaSDag-Erling Smørgrav 
994545d5ecaSDag-Erling Smørgrav void
995545d5ecaSDag-Erling Smørgrav mm_ssh1_session_id(u_char session_id[16])
996545d5ecaSDag-Erling Smørgrav {
997545d5ecaSDag-Erling Smørgrav 	Buffer m;
998545d5ecaSDag-Erling Smørgrav 	int i;
999545d5ecaSDag-Erling Smørgrav 
1000545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
1001545d5ecaSDag-Erling Smørgrav 
1002545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
1003545d5ecaSDag-Erling Smørgrav 	for (i = 0; i < 16; i++)
1004545d5ecaSDag-Erling Smørgrav 		buffer_put_char(&m, session_id[i]);
1005545d5ecaSDag-Erling Smørgrav 
1006545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSID, &m);
1007545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
1008545d5ecaSDag-Erling Smørgrav }
1009545d5ecaSDag-Erling Smørgrav 
1010545d5ecaSDag-Erling Smørgrav int
1011545d5ecaSDag-Erling Smørgrav mm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
1012545d5ecaSDag-Erling Smørgrav {
1013545d5ecaSDag-Erling Smørgrav 	Buffer m;
1014545d5ecaSDag-Erling Smørgrav 	Key *key;
1015545d5ecaSDag-Erling Smørgrav 	u_char *blob;
1016545d5ecaSDag-Erling Smørgrav 	u_int blen;
1017e73e9afaSDag-Erling Smørgrav 	int allowed = 0, have_forced = 0;
1018545d5ecaSDag-Erling Smørgrav 
1019545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
1020545d5ecaSDag-Erling Smørgrav 
1021545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
1022545d5ecaSDag-Erling Smørgrav 	buffer_put_bignum2(&m, client_n);
1023545d5ecaSDag-Erling Smørgrav 
1024545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSAKEYALLOWED, &m);
1025545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSAKEYALLOWED, &m);
1026545d5ecaSDag-Erling Smørgrav 
1027545d5ecaSDag-Erling Smørgrav 	allowed = buffer_get_int(&m);
1028545d5ecaSDag-Erling Smørgrav 
1029e73e9afaSDag-Erling Smørgrav 	/* fake forced command */
1030e73e9afaSDag-Erling Smørgrav 	auth_clear_options();
1031e73e9afaSDag-Erling Smørgrav 	have_forced = buffer_get_int(&m);
1032e73e9afaSDag-Erling Smørgrav 	forced_command = have_forced ? xstrdup("true") : NULL;
1033e73e9afaSDag-Erling Smørgrav 
1034545d5ecaSDag-Erling Smørgrav 	if (allowed && rkey != NULL) {
1035545d5ecaSDag-Erling Smørgrav 		blob = buffer_get_string(&m, &blen);
1036545d5ecaSDag-Erling Smørgrav 		if ((key = key_from_blob(blob, blen)) == NULL)
1037545d5ecaSDag-Erling Smørgrav 			fatal("%s: key_from_blob failed", __func__);
1038545d5ecaSDag-Erling Smørgrav 		*rkey = key;
1039545d5ecaSDag-Erling Smørgrav 		xfree(blob);
1040545d5ecaSDag-Erling Smørgrav 	}
1041545d5ecaSDag-Erling Smørgrav 	mm_send_debug(&m);
1042545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
1043545d5ecaSDag-Erling Smørgrav 
1044545d5ecaSDag-Erling Smørgrav 	return (allowed);
1045545d5ecaSDag-Erling Smørgrav }
1046545d5ecaSDag-Erling Smørgrav 
1047545d5ecaSDag-Erling Smørgrav BIGNUM *
1048545d5ecaSDag-Erling Smørgrav mm_auth_rsa_generate_challenge(Key *key)
1049545d5ecaSDag-Erling Smørgrav {
1050545d5ecaSDag-Erling Smørgrav 	Buffer m;
1051545d5ecaSDag-Erling Smørgrav 	BIGNUM *challenge;
1052545d5ecaSDag-Erling Smørgrav 	u_char *blob;
1053545d5ecaSDag-Erling Smørgrav 	u_int blen;
1054545d5ecaSDag-Erling Smørgrav 
1055545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
1056545d5ecaSDag-Erling Smørgrav 
1057545d5ecaSDag-Erling Smørgrav 	if ((challenge = BN_new()) == NULL)
1058545d5ecaSDag-Erling Smørgrav 		fatal("%s: BN_new failed", __func__);
1059545d5ecaSDag-Erling Smørgrav 
1060545d5ecaSDag-Erling Smørgrav 	key->type = KEY_RSA;    /* XXX cheat for key_to_blob */
1061545d5ecaSDag-Erling Smørgrav 	if (key_to_blob(key, &blob, &blen) == 0)
1062545d5ecaSDag-Erling Smørgrav 		fatal("%s: key_to_blob failed", __func__);
1063545d5ecaSDag-Erling Smørgrav 	key->type = KEY_RSA1;
1064545d5ecaSDag-Erling Smørgrav 
1065545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
1066545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, blob, blen);
1067545d5ecaSDag-Erling Smørgrav 	xfree(blob);
1068545d5ecaSDag-Erling Smørgrav 
1069545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSACHALLENGE, &m);
1070545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSACHALLENGE, &m);
1071545d5ecaSDag-Erling Smørgrav 
1072545d5ecaSDag-Erling Smørgrav 	buffer_get_bignum2(&m, challenge);
1073545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
1074545d5ecaSDag-Erling Smørgrav 
1075545d5ecaSDag-Erling Smørgrav 	return (challenge);
1076545d5ecaSDag-Erling Smørgrav }
1077545d5ecaSDag-Erling Smørgrav 
1078545d5ecaSDag-Erling Smørgrav int
1079545d5ecaSDag-Erling Smørgrav mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16])
1080545d5ecaSDag-Erling Smørgrav {
1081545d5ecaSDag-Erling Smørgrav 	Buffer m;
1082545d5ecaSDag-Erling Smørgrav 	u_char *blob;
1083545d5ecaSDag-Erling Smørgrav 	u_int blen;
1084545d5ecaSDag-Erling Smørgrav 	int success = 0;
1085545d5ecaSDag-Erling Smørgrav 
1086545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
1087545d5ecaSDag-Erling Smørgrav 
1088545d5ecaSDag-Erling Smørgrav 	key->type = KEY_RSA;    /* XXX cheat for key_to_blob */
1089545d5ecaSDag-Erling Smørgrav 	if (key_to_blob(key, &blob, &blen) == 0)
1090545d5ecaSDag-Erling Smørgrav 		fatal("%s: key_to_blob failed", __func__);
1091545d5ecaSDag-Erling Smørgrav 	key->type = KEY_RSA1;
1092545d5ecaSDag-Erling Smørgrav 
1093545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
1094545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, blob, blen);
1095545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, response, 16);
1096545d5ecaSDag-Erling Smørgrav 	xfree(blob);
1097545d5ecaSDag-Erling Smørgrav 
1098545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSARESPONSE, &m);
1099545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSARESPONSE, &m);
1100545d5ecaSDag-Erling Smørgrav 
1101545d5ecaSDag-Erling Smørgrav 	success = buffer_get_int(&m);
1102545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
1103545d5ecaSDag-Erling Smørgrav 
1104545d5ecaSDag-Erling Smørgrav 	return (success);
1105545d5ecaSDag-Erling Smørgrav }
1106f388f5efSDag-Erling Smørgrav 
1107aa49c926SDag-Erling Smørgrav #ifdef SSH_AUDIT_EVENTS
1108aa49c926SDag-Erling Smørgrav void
1109aa49c926SDag-Erling Smørgrav mm_audit_event(ssh_audit_event_t event)
1110aa49c926SDag-Erling Smørgrav {
1111aa49c926SDag-Erling Smørgrav 	Buffer m;
1112aa49c926SDag-Erling Smørgrav 
1113aa49c926SDag-Erling Smørgrav 	debug3("%s entering", __func__);
1114aa49c926SDag-Erling Smørgrav 
1115aa49c926SDag-Erling Smørgrav 	buffer_init(&m);
1116aa49c926SDag-Erling Smørgrav 	buffer_put_int(&m, event);
1117aa49c926SDag-Erling Smørgrav 
1118aa49c926SDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_EVENT, &m);
1119aa49c926SDag-Erling Smørgrav 	buffer_free(&m);
1120aa49c926SDag-Erling Smørgrav }
1121aa49c926SDag-Erling Smørgrav 
1122aa49c926SDag-Erling Smørgrav void
1123aa49c926SDag-Erling Smørgrav mm_audit_run_command(const char *command)
1124aa49c926SDag-Erling Smørgrav {
1125aa49c926SDag-Erling Smørgrav 	Buffer m;
1126aa49c926SDag-Erling Smørgrav 
1127aa49c926SDag-Erling Smørgrav 	debug3("%s entering command %s", __func__, command);
1128aa49c926SDag-Erling Smørgrav 
1129aa49c926SDag-Erling Smørgrav 	buffer_init(&m);
1130aa49c926SDag-Erling Smørgrav 	buffer_put_cstring(&m, command);
1131aa49c926SDag-Erling Smørgrav 
1132aa49c926SDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m);
1133aa49c926SDag-Erling Smørgrav 	buffer_free(&m);
1134aa49c926SDag-Erling Smørgrav }
1135aa49c926SDag-Erling Smørgrav #endif /* SSH_AUDIT_EVENTS */
1136aa49c926SDag-Erling Smørgrav 
1137cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI
1138cf2b5f3bSDag-Erling Smørgrav OM_uint32
113921e764dfSDag-Erling Smørgrav mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid)
1140f388f5efSDag-Erling Smørgrav {
1141f388f5efSDag-Erling Smørgrav 	Buffer m;
1142cf2b5f3bSDag-Erling Smørgrav 	OM_uint32 major;
1143f388f5efSDag-Erling Smørgrav 
1144cf2b5f3bSDag-Erling Smørgrav 	/* Client doesn't get to see the context */
1145cf2b5f3bSDag-Erling Smørgrav 	*ctx = NULL;
1146f388f5efSDag-Erling Smørgrav 
1147f388f5efSDag-Erling Smørgrav 	buffer_init(&m);
114821e764dfSDag-Erling Smørgrav 	buffer_put_string(&m, goid->elements, goid->length);
1149f388f5efSDag-Erling Smørgrav 
1150cf2b5f3bSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, &m);
1151cf2b5f3bSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, &m);
1152f388f5efSDag-Erling Smørgrav 
1153cf2b5f3bSDag-Erling Smørgrav 	major = buffer_get_int(&m);
1154cf2b5f3bSDag-Erling Smørgrav 
1155f388f5efSDag-Erling Smørgrav 	buffer_free(&m);
1156cf2b5f3bSDag-Erling Smørgrav 	return (major);
1157f388f5efSDag-Erling Smørgrav }
1158f388f5efSDag-Erling Smørgrav 
1159cf2b5f3bSDag-Erling Smørgrav OM_uint32
1160cf2b5f3bSDag-Erling Smørgrav mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in,
1161cf2b5f3bSDag-Erling Smørgrav     gss_buffer_desc *out, OM_uint32 *flags)
1162f388f5efSDag-Erling Smørgrav {
1163f388f5efSDag-Erling Smørgrav 	Buffer m;
1164cf2b5f3bSDag-Erling Smørgrav 	OM_uint32 major;
1165f388f5efSDag-Erling Smørgrav 	u_int len;
1166f388f5efSDag-Erling Smørgrav 
1167cf2b5f3bSDag-Erling Smørgrav 	buffer_init(&m);
1168cf2b5f3bSDag-Erling Smørgrav 	buffer_put_string(&m, in->value, in->length);
1169cf2b5f3bSDag-Erling Smørgrav 
1170cf2b5f3bSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, &m);
1171cf2b5f3bSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, &m);
1172cf2b5f3bSDag-Erling Smørgrav 
1173cf2b5f3bSDag-Erling Smørgrav 	major = buffer_get_int(&m);
1174cf2b5f3bSDag-Erling Smørgrav 	out->value = buffer_get_string(&m, &len);
1175cf2b5f3bSDag-Erling Smørgrav 	out->length = len;
1176cf2b5f3bSDag-Erling Smørgrav 	if (flags)
1177cf2b5f3bSDag-Erling Smørgrav 		*flags = buffer_get_int(&m);
1178f388f5efSDag-Erling Smørgrav 
1179f388f5efSDag-Erling Smørgrav 	buffer_free(&m);
1180cf2b5f3bSDag-Erling Smørgrav 
1181cf2b5f3bSDag-Erling Smørgrav 	return (major);
1182f388f5efSDag-Erling Smørgrav }
1183cf2b5f3bSDag-Erling Smørgrav 
11841ec0d754SDag-Erling Smørgrav OM_uint32
11851ec0d754SDag-Erling Smørgrav mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
11861ec0d754SDag-Erling Smørgrav {
11871ec0d754SDag-Erling Smørgrav 	Buffer m;
11881ec0d754SDag-Erling Smørgrav 	OM_uint32 major;
11891ec0d754SDag-Erling Smørgrav 
11901ec0d754SDag-Erling Smørgrav 	buffer_init(&m);
11911ec0d754SDag-Erling Smørgrav 	buffer_put_string(&m, gssbuf->value, gssbuf->length);
11921ec0d754SDag-Erling Smørgrav 	buffer_put_string(&m, gssmic->value, gssmic->length);
11931ec0d754SDag-Erling Smørgrav 
11941ec0d754SDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, &m);
11951ec0d754SDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSCHECKMIC,
11961ec0d754SDag-Erling Smørgrav 	    &m);
11971ec0d754SDag-Erling Smørgrav 
11981ec0d754SDag-Erling Smørgrav 	major = buffer_get_int(&m);
11991ec0d754SDag-Erling Smørgrav 	buffer_free(&m);
12001ec0d754SDag-Erling Smørgrav 	return(major);
12011ec0d754SDag-Erling Smørgrav }
12021ec0d754SDag-Erling Smørgrav 
1203cf2b5f3bSDag-Erling Smørgrav int
1204cf2b5f3bSDag-Erling Smørgrav mm_ssh_gssapi_userok(char *user)
1205cf2b5f3bSDag-Erling Smørgrav {
1206cf2b5f3bSDag-Erling Smørgrav 	Buffer m;
1207cf2b5f3bSDag-Erling Smørgrav 	int authenticated = 0;
1208cf2b5f3bSDag-Erling Smørgrav 
1209cf2b5f3bSDag-Erling Smørgrav 	buffer_init(&m);
1210cf2b5f3bSDag-Erling Smørgrav 
1211cf2b5f3bSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m);
1212cf2b5f3bSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK,
1213cf2b5f3bSDag-Erling Smørgrav 				  &m);
1214cf2b5f3bSDag-Erling Smørgrav 
1215cf2b5f3bSDag-Erling Smørgrav 	authenticated = buffer_get_int(&m);
1216cf2b5f3bSDag-Erling Smørgrav 
1217cf2b5f3bSDag-Erling Smørgrav 	buffer_free(&m);
1218cf2b5f3bSDag-Erling Smørgrav 	debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not ");
1219cf2b5f3bSDag-Erling Smørgrav 	return (authenticated);
1220cf2b5f3bSDag-Erling Smørgrav }
1221cf2b5f3bSDag-Erling Smørgrav #endif /* GSSAPI */
1222