xref: /freebsd/crypto/openssh/monitor_wrap.c (revision d4af9e693f15f5155095f38c7650b24fe74ae351)
1d4af9e69SDag-Erling Smørgrav /* $OpenBSD: monitor_wrap.c,v 1.63 2008/07/10 18:08:11 markus Exp $ */
2545d5ecaSDag-Erling Smørgrav /*
3545d5ecaSDag-Erling Smørgrav  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4545d5ecaSDag-Erling Smørgrav  * Copyright 2002 Markus Friedl <markus@openbsd.org>
5545d5ecaSDag-Erling Smørgrav  * All rights reserved.
6545d5ecaSDag-Erling Smørgrav  *
7545d5ecaSDag-Erling Smørgrav  * Redistribution and use in source and binary forms, with or without
8545d5ecaSDag-Erling Smørgrav  * modification, are permitted provided that the following conditions
9545d5ecaSDag-Erling Smørgrav  * are met:
10545d5ecaSDag-Erling Smørgrav  * 1. Redistributions of source code must retain the above copyright
11545d5ecaSDag-Erling Smørgrav  *    notice, this list of conditions and the following disclaimer.
12545d5ecaSDag-Erling Smørgrav  * 2. Redistributions in binary form must reproduce the above copyright
13545d5ecaSDag-Erling Smørgrav  *    notice, this list of conditions and the following disclaimer in the
14545d5ecaSDag-Erling Smørgrav  *    documentation and/or other materials provided with the distribution.
15545d5ecaSDag-Erling Smørgrav  *
16545d5ecaSDag-Erling Smørgrav  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17545d5ecaSDag-Erling Smørgrav  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18545d5ecaSDag-Erling Smørgrav  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19545d5ecaSDag-Erling Smørgrav  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20545d5ecaSDag-Erling Smørgrav  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21545d5ecaSDag-Erling Smørgrav  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22545d5ecaSDag-Erling Smørgrav  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23545d5ecaSDag-Erling Smørgrav  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24545d5ecaSDag-Erling Smørgrav  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25545d5ecaSDag-Erling Smørgrav  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26545d5ecaSDag-Erling Smørgrav  */
27545d5ecaSDag-Erling Smørgrav 
28545d5ecaSDag-Erling Smørgrav #include "includes.h"
29333ee039SDag-Erling Smørgrav 
30333ee039SDag-Erling Smørgrav #include <sys/types.h>
31333ee039SDag-Erling Smørgrav #include <sys/uio.h>
32333ee039SDag-Erling Smørgrav 
33333ee039SDag-Erling Smørgrav #include <errno.h>
34333ee039SDag-Erling Smørgrav #include <pwd.h>
35333ee039SDag-Erling Smørgrav #include <signal.h>
36333ee039SDag-Erling Smørgrav #include <stdarg.h>
37333ee039SDag-Erling Smørgrav #include <stdio.h>
38333ee039SDag-Erling Smørgrav #include <string.h>
39333ee039SDag-Erling Smørgrav #include <unistd.h>
40545d5ecaSDag-Erling Smørgrav 
41545d5ecaSDag-Erling Smørgrav #include <openssl/bn.h>
42545d5ecaSDag-Erling Smørgrav #include <openssl/dh.h>
43545d5ecaSDag-Erling Smørgrav 
44d4af9e69SDag-Erling Smørgrav #include "openbsd-compat/sys-queue.h"
45333ee039SDag-Erling Smørgrav #include "xmalloc.h"
46545d5ecaSDag-Erling Smørgrav #include "ssh.h"
47545d5ecaSDag-Erling Smørgrav #include "dh.h"
48333ee039SDag-Erling Smørgrav #include "buffer.h"
49333ee039SDag-Erling Smørgrav #include "key.h"
50333ee039SDag-Erling Smørgrav #include "cipher.h"
51545d5ecaSDag-Erling Smørgrav #include "kex.h"
52333ee039SDag-Erling Smørgrav #include "hostfile.h"
53545d5ecaSDag-Erling Smørgrav #include "auth.h"
54e73e9afaSDag-Erling Smørgrav #include "auth-options.h"
55545d5ecaSDag-Erling Smørgrav #include "packet.h"
56545d5ecaSDag-Erling Smørgrav #include "mac.h"
57545d5ecaSDag-Erling Smørgrav #include "log.h"
585962c0e9SDag-Erling Smørgrav #ifdef TARGET_OS_MAC    /* XXX Broken krb5 headers on Mac */
595962c0e9SDag-Erling Smørgrav #undef TARGET_OS_MAC
60545d5ecaSDag-Erling Smørgrav #include "zlib.h"
615962c0e9SDag-Erling Smørgrav #define TARGET_OS_MAC 1
625962c0e9SDag-Erling Smørgrav #else
635962c0e9SDag-Erling Smørgrav #include "zlib.h"
645962c0e9SDag-Erling Smørgrav #endif
65545d5ecaSDag-Erling Smørgrav #include "monitor.h"
66cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI
67cf2b5f3bSDag-Erling Smørgrav #include "ssh-gss.h"
68cf2b5f3bSDag-Erling Smørgrav #endif
69333ee039SDag-Erling Smørgrav #include "monitor_wrap.h"
70333ee039SDag-Erling Smørgrav #include "atomicio.h"
71333ee039SDag-Erling Smørgrav #include "monitor_fdpass.h"
72333ee039SDag-Erling Smørgrav #include "misc.h"
73333ee039SDag-Erling Smørgrav #include "servconf.h"
74333ee039SDag-Erling Smørgrav 
75333ee039SDag-Erling Smørgrav #include "channels.h"
76333ee039SDag-Erling Smørgrav #include "session.h"
77d4af9e69SDag-Erling Smørgrav #include "servconf.h"
78cf2b5f3bSDag-Erling Smørgrav 
79545d5ecaSDag-Erling Smørgrav /* Imports */
80545d5ecaSDag-Erling Smørgrav extern int compat20;
81545d5ecaSDag-Erling Smørgrav extern Newkeys *newkeys[];
82545d5ecaSDag-Erling Smørgrav extern z_stream incoming_stream;
83545d5ecaSDag-Erling Smørgrav extern z_stream outgoing_stream;
84545d5ecaSDag-Erling Smørgrav extern struct monitor *pmonitor;
85545d5ecaSDag-Erling Smørgrav extern Buffer input, output;
8621e764dfSDag-Erling Smørgrav extern Buffer loginmsg;
87cf2b5f3bSDag-Erling Smørgrav extern ServerOptions options;
88545d5ecaSDag-Erling Smørgrav 
891ec0d754SDag-Erling Smørgrav int
901ec0d754SDag-Erling Smørgrav mm_is_monitor(void)
911ec0d754SDag-Erling Smørgrav {
921ec0d754SDag-Erling Smørgrav 	/*
931ec0d754SDag-Erling Smørgrav 	 * m_pid is only set in the privileged part, and
941ec0d754SDag-Erling Smørgrav 	 * points to the unprivileged child.
951ec0d754SDag-Erling Smørgrav 	 */
961ec0d754SDag-Erling Smørgrav 	return (pmonitor && pmonitor->m_pid > 0);
971ec0d754SDag-Erling Smørgrav }
981ec0d754SDag-Erling Smørgrav 
99545d5ecaSDag-Erling Smørgrav void
10021e764dfSDag-Erling Smørgrav mm_request_send(int sock, enum monitor_reqtype type, Buffer *m)
101545d5ecaSDag-Erling Smørgrav {
102545d5ecaSDag-Erling Smørgrav 	u_int mlen = buffer_len(m);
103f388f5efSDag-Erling Smørgrav 	u_char buf[5];
104545d5ecaSDag-Erling Smørgrav 
105545d5ecaSDag-Erling Smørgrav 	debug3("%s entering: type %d", __func__, type);
106545d5ecaSDag-Erling Smørgrav 
107333ee039SDag-Erling Smørgrav 	put_u32(buf, mlen + 1);
108545d5ecaSDag-Erling Smørgrav 	buf[4] = (u_char) type;		/* 1st byte of payload is mesg-type */
10921e764dfSDag-Erling Smørgrav 	if (atomicio(vwrite, sock, buf, sizeof(buf)) != sizeof(buf))
110d4ecd108SDag-Erling Smørgrav 		fatal("%s: write: %s", __func__, strerror(errno));
11121e764dfSDag-Erling Smørgrav 	if (atomicio(vwrite, sock, buffer_ptr(m), mlen) != mlen)
112d4ecd108SDag-Erling Smørgrav 		fatal("%s: write: %s", __func__, strerror(errno));
113545d5ecaSDag-Erling Smørgrav }
114545d5ecaSDag-Erling Smørgrav 
115545d5ecaSDag-Erling Smørgrav void
11621e764dfSDag-Erling Smørgrav mm_request_receive(int sock, Buffer *m)
117545d5ecaSDag-Erling Smørgrav {
118545d5ecaSDag-Erling Smørgrav 	u_char buf[4];
119545d5ecaSDag-Erling Smørgrav 	u_int msg_len;
120545d5ecaSDag-Erling Smørgrav 
121545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
122545d5ecaSDag-Erling Smørgrav 
123d4ecd108SDag-Erling Smørgrav 	if (atomicio(read, sock, buf, sizeof(buf)) != sizeof(buf)) {
124d4ecd108SDag-Erling Smørgrav 		if (errno == EPIPE)
1251ec0d754SDag-Erling Smørgrav 			cleanup_exit(255);
126d4ecd108SDag-Erling Smørgrav 		fatal("%s: read: %s", __func__, strerror(errno));
127545d5ecaSDag-Erling Smørgrav 	}
128333ee039SDag-Erling Smørgrav 	msg_len = get_u32(buf);
129545d5ecaSDag-Erling Smørgrav 	if (msg_len > 256 * 1024)
130545d5ecaSDag-Erling Smørgrav 		fatal("%s: read: bad msg_len %d", __func__, msg_len);
131545d5ecaSDag-Erling Smørgrav 	buffer_clear(m);
132545d5ecaSDag-Erling Smørgrav 	buffer_append_space(m, msg_len);
133d4ecd108SDag-Erling Smørgrav 	if (atomicio(read, sock, buffer_ptr(m), msg_len) != msg_len)
134d4ecd108SDag-Erling Smørgrav 		fatal("%s: read: %s", __func__, strerror(errno));
135545d5ecaSDag-Erling Smørgrav }
136545d5ecaSDag-Erling Smørgrav 
137545d5ecaSDag-Erling Smørgrav void
13821e764dfSDag-Erling Smørgrav mm_request_receive_expect(int sock, enum monitor_reqtype type, Buffer *m)
139545d5ecaSDag-Erling Smørgrav {
140545d5ecaSDag-Erling Smørgrav 	u_char rtype;
141545d5ecaSDag-Erling Smørgrav 
142545d5ecaSDag-Erling Smørgrav 	debug3("%s entering: type %d", __func__, type);
143545d5ecaSDag-Erling Smørgrav 
14421e764dfSDag-Erling Smørgrav 	mm_request_receive(sock, m);
145545d5ecaSDag-Erling Smørgrav 	rtype = buffer_get_char(m);
146545d5ecaSDag-Erling Smørgrav 	if (rtype != type)
147545d5ecaSDag-Erling Smørgrav 		fatal("%s: read: rtype %d != type %d", __func__,
148545d5ecaSDag-Erling Smørgrav 		    rtype, type);
149545d5ecaSDag-Erling Smørgrav }
150545d5ecaSDag-Erling Smørgrav 
151545d5ecaSDag-Erling Smørgrav DH *
152545d5ecaSDag-Erling Smørgrav mm_choose_dh(int min, int nbits, int max)
153545d5ecaSDag-Erling Smørgrav {
154545d5ecaSDag-Erling Smørgrav 	BIGNUM *p, *g;
155545d5ecaSDag-Erling Smørgrav 	int success = 0;
156545d5ecaSDag-Erling Smørgrav 	Buffer m;
157545d5ecaSDag-Erling Smørgrav 
158545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
159545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&m, min);
160545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&m, nbits);
161545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&m, max);
162545d5ecaSDag-Erling Smørgrav 
163545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_MODULI, &m);
164545d5ecaSDag-Erling Smørgrav 
165545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_MODULI", __func__);
166545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_MODULI, &m);
167545d5ecaSDag-Erling Smørgrav 
168545d5ecaSDag-Erling Smørgrav 	success = buffer_get_char(&m);
169545d5ecaSDag-Erling Smørgrav 	if (success == 0)
170545d5ecaSDag-Erling Smørgrav 		fatal("%s: MONITOR_ANS_MODULI failed", __func__);
171545d5ecaSDag-Erling Smørgrav 
172545d5ecaSDag-Erling Smørgrav 	if ((p = BN_new()) == NULL)
173545d5ecaSDag-Erling Smørgrav 		fatal("%s: BN_new failed", __func__);
174545d5ecaSDag-Erling Smørgrav 	if ((g = BN_new()) == NULL)
175545d5ecaSDag-Erling Smørgrav 		fatal("%s: BN_new failed", __func__);
176545d5ecaSDag-Erling Smørgrav 	buffer_get_bignum2(&m, p);
177545d5ecaSDag-Erling Smørgrav 	buffer_get_bignum2(&m, g);
178545d5ecaSDag-Erling Smørgrav 
179545d5ecaSDag-Erling Smørgrav 	debug3("%s: remaining %d", __func__, buffer_len(&m));
180545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
181545d5ecaSDag-Erling Smørgrav 
182545d5ecaSDag-Erling Smørgrav 	return (dh_new_group(g, p));
183545d5ecaSDag-Erling Smørgrav }
184545d5ecaSDag-Erling Smørgrav 
185545d5ecaSDag-Erling Smørgrav int
186545d5ecaSDag-Erling Smørgrav mm_key_sign(Key *key, u_char **sigp, u_int *lenp, u_char *data, u_int datalen)
187545d5ecaSDag-Erling Smørgrav {
188545d5ecaSDag-Erling Smørgrav 	Kex *kex = *pmonitor->m_pkex;
189545d5ecaSDag-Erling Smørgrav 	Buffer m;
190545d5ecaSDag-Erling Smørgrav 
191545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
192545d5ecaSDag-Erling Smørgrav 
193545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
194545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&m, kex->host_key_index(key));
195545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, data, datalen);
196545d5ecaSDag-Erling Smørgrav 
197545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, &m);
198545d5ecaSDag-Erling Smørgrav 
199545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_SIGN", __func__);
200545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SIGN, &m);
201545d5ecaSDag-Erling Smørgrav 	*sigp  = buffer_get_string(&m, lenp);
202545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
203545d5ecaSDag-Erling Smørgrav 
204545d5ecaSDag-Erling Smørgrav 	return (0);
205545d5ecaSDag-Erling Smørgrav }
206545d5ecaSDag-Erling Smørgrav 
207545d5ecaSDag-Erling Smørgrav struct passwd *
20821e764dfSDag-Erling Smørgrav mm_getpwnamallow(const char *username)
209545d5ecaSDag-Erling Smørgrav {
210545d5ecaSDag-Erling Smørgrav 	Buffer m;
211545d5ecaSDag-Erling Smørgrav 	struct passwd *pw;
212d4af9e69SDag-Erling Smørgrav 	u_int len;
213d4af9e69SDag-Erling Smørgrav 	ServerOptions *newopts;
214545d5ecaSDag-Erling Smørgrav 
215545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
216545d5ecaSDag-Erling Smørgrav 
217545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
21821e764dfSDag-Erling Smørgrav 	buffer_put_cstring(&m, username);
219545d5ecaSDag-Erling Smørgrav 
220545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, &m);
221545d5ecaSDag-Erling Smørgrav 
222545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PWNAM", __func__);
223545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m);
224545d5ecaSDag-Erling Smørgrav 
225545d5ecaSDag-Erling Smørgrav 	if (buffer_get_char(&m) == 0) {
226d4af9e69SDag-Erling Smørgrav 		pw = NULL;
227d4af9e69SDag-Erling Smørgrav 		goto out;
228545d5ecaSDag-Erling Smørgrav 	}
229d4af9e69SDag-Erling Smørgrav 	pw = buffer_get_string(&m, &len);
230d4af9e69SDag-Erling Smørgrav 	if (len != sizeof(struct passwd))
231545d5ecaSDag-Erling Smørgrav 		fatal("%s: struct passwd size mismatch", __func__);
232545d5ecaSDag-Erling Smørgrav 	pw->pw_name = buffer_get_string(&m, NULL);
233545d5ecaSDag-Erling Smørgrav 	pw->pw_passwd = buffer_get_string(&m, NULL);
234545d5ecaSDag-Erling Smørgrav 	pw->pw_gecos = buffer_get_string(&m, NULL);
23583d2307dSDag-Erling Smørgrav #ifdef HAVE_PW_CLASS_IN_PASSWD
236545d5ecaSDag-Erling Smørgrav 	pw->pw_class = buffer_get_string(&m, NULL);
23783d2307dSDag-Erling Smørgrav #endif
238545d5ecaSDag-Erling Smørgrav 	pw->pw_dir = buffer_get_string(&m, NULL);
239545d5ecaSDag-Erling Smørgrav 	pw->pw_shell = buffer_get_string(&m, NULL);
240d4af9e69SDag-Erling Smørgrav 
241d4af9e69SDag-Erling Smørgrav out:
242d4af9e69SDag-Erling Smørgrav 	/* copy options block as a Match directive may have changed some */
243d4af9e69SDag-Erling Smørgrav 	newopts = buffer_get_string(&m, &len);
244d4af9e69SDag-Erling Smørgrav 	if (len != sizeof(*newopts))
245d4af9e69SDag-Erling Smørgrav 		fatal("%s: option block size mismatch", __func__);
246d4af9e69SDag-Erling Smørgrav 	if (newopts->banner != NULL)
247d4af9e69SDag-Erling Smørgrav 		newopts->banner = buffer_get_string(&m, NULL);
248d4af9e69SDag-Erling Smørgrav 	copy_set_server_options(&options, newopts, 1);
249d4af9e69SDag-Erling Smørgrav 	xfree(newopts);
250d4af9e69SDag-Erling Smørgrav 
251545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
252545d5ecaSDag-Erling Smørgrav 
253545d5ecaSDag-Erling Smørgrav 	return (pw);
254545d5ecaSDag-Erling Smørgrav }
255545d5ecaSDag-Erling Smørgrav 
2561ec0d754SDag-Erling Smørgrav char *
2571ec0d754SDag-Erling Smørgrav mm_auth2_read_banner(void)
258545d5ecaSDag-Erling Smørgrav {
259545d5ecaSDag-Erling Smørgrav 	Buffer m;
260545d5ecaSDag-Erling Smørgrav 	char *banner;
261545d5ecaSDag-Erling Smørgrav 
262545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
263545d5ecaSDag-Erling Smørgrav 
264545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
265545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, &m);
266545d5ecaSDag-Erling Smørgrav 	buffer_clear(&m);
267545d5ecaSDag-Erling Smørgrav 
2681ec0d754SDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
2691ec0d754SDag-Erling Smørgrav 	    MONITOR_ANS_AUTH2_READ_BANNER, &m);
270545d5ecaSDag-Erling Smørgrav 	banner = buffer_get_string(&m, NULL);
271545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
272545d5ecaSDag-Erling Smørgrav 
2731ec0d754SDag-Erling Smørgrav 	/* treat empty banner as missing banner */
2741ec0d754SDag-Erling Smørgrav 	if (strlen(banner) == 0) {
2751ec0d754SDag-Erling Smørgrav 		xfree(banner);
2761ec0d754SDag-Erling Smørgrav 		banner = NULL;
2771ec0d754SDag-Erling Smørgrav 	}
278545d5ecaSDag-Erling Smørgrav 	return (banner);
279545d5ecaSDag-Erling Smørgrav }
280545d5ecaSDag-Erling Smørgrav 
281545d5ecaSDag-Erling Smørgrav /* Inform the privileged process about service and style */
282545d5ecaSDag-Erling Smørgrav 
283545d5ecaSDag-Erling Smørgrav void
284545d5ecaSDag-Erling Smørgrav mm_inform_authserv(char *service, char *style)
285545d5ecaSDag-Erling Smørgrav {
286545d5ecaSDag-Erling Smørgrav 	Buffer m;
287545d5ecaSDag-Erling Smørgrav 
288545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
289545d5ecaSDag-Erling Smørgrav 
290545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
291545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, service);
292545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, style ? style : "");
293545d5ecaSDag-Erling Smørgrav 
294545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m);
295545d5ecaSDag-Erling Smørgrav 
296545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
297545d5ecaSDag-Erling Smørgrav }
298545d5ecaSDag-Erling Smørgrav 
299545d5ecaSDag-Erling Smørgrav /* Do the password authentication */
300545d5ecaSDag-Erling Smørgrav int
301545d5ecaSDag-Erling Smørgrav mm_auth_password(Authctxt *authctxt, char *password)
302545d5ecaSDag-Erling Smørgrav {
303545d5ecaSDag-Erling Smørgrav 	Buffer m;
304545d5ecaSDag-Erling Smørgrav 	int authenticated = 0;
305545d5ecaSDag-Erling Smørgrav 
306545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
307545d5ecaSDag-Erling Smørgrav 
308545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
309545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, password);
310545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, &m);
311545d5ecaSDag-Erling Smørgrav 
312545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_AUTHPASSWORD", __func__);
313545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTHPASSWORD, &m);
314545d5ecaSDag-Erling Smørgrav 
315545d5ecaSDag-Erling Smørgrav 	authenticated = buffer_get_int(&m);
316545d5ecaSDag-Erling Smørgrav 
317545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
318545d5ecaSDag-Erling Smørgrav 
319545d5ecaSDag-Erling Smørgrav 	debug3("%s: user %sauthenticated",
320545d5ecaSDag-Erling Smørgrav 	    __func__, authenticated ? "" : "not ");
321545d5ecaSDag-Erling Smørgrav 	return (authenticated);
322545d5ecaSDag-Erling Smørgrav }
323545d5ecaSDag-Erling Smørgrav 
324545d5ecaSDag-Erling Smørgrav int
325545d5ecaSDag-Erling Smørgrav mm_user_key_allowed(struct passwd *pw, Key *key)
326545d5ecaSDag-Erling Smørgrav {
327545d5ecaSDag-Erling Smørgrav 	return (mm_key_allowed(MM_USERKEY, NULL, NULL, key));
328545d5ecaSDag-Erling Smørgrav }
329545d5ecaSDag-Erling Smørgrav 
330545d5ecaSDag-Erling Smørgrav int
331545d5ecaSDag-Erling Smørgrav mm_hostbased_key_allowed(struct passwd *pw, char *user, char *host,
332545d5ecaSDag-Erling Smørgrav     Key *key)
333545d5ecaSDag-Erling Smørgrav {
334545d5ecaSDag-Erling Smørgrav 	return (mm_key_allowed(MM_HOSTKEY, user, host, key));
335545d5ecaSDag-Erling Smørgrav }
336545d5ecaSDag-Erling Smørgrav 
337545d5ecaSDag-Erling Smørgrav int
338545d5ecaSDag-Erling Smørgrav mm_auth_rhosts_rsa_key_allowed(struct passwd *pw, char *user,
339545d5ecaSDag-Erling Smørgrav     char *host, Key *key)
340545d5ecaSDag-Erling Smørgrav {
341545d5ecaSDag-Erling Smørgrav 	int ret;
342545d5ecaSDag-Erling Smørgrav 
343545d5ecaSDag-Erling Smørgrav 	key->type = KEY_RSA; /* XXX hack for key_to_blob */
344545d5ecaSDag-Erling Smørgrav 	ret = mm_key_allowed(MM_RSAHOSTKEY, user, host, key);
345545d5ecaSDag-Erling Smørgrav 	key->type = KEY_RSA1;
346545d5ecaSDag-Erling Smørgrav 	return (ret);
347545d5ecaSDag-Erling Smørgrav }
348545d5ecaSDag-Erling Smørgrav 
349545d5ecaSDag-Erling Smørgrav static void
350545d5ecaSDag-Erling Smørgrav mm_send_debug(Buffer *m)
351545d5ecaSDag-Erling Smørgrav {
352545d5ecaSDag-Erling Smørgrav 	char *msg;
353545d5ecaSDag-Erling Smørgrav 
354545d5ecaSDag-Erling Smørgrav 	while (buffer_len(m)) {
355545d5ecaSDag-Erling Smørgrav 		msg = buffer_get_string(m, NULL);
356545d5ecaSDag-Erling Smørgrav 		debug3("%s: Sending debug: %s", __func__, msg);
357545d5ecaSDag-Erling Smørgrav 		packet_send_debug("%s", msg);
358545d5ecaSDag-Erling Smørgrav 		xfree(msg);
359545d5ecaSDag-Erling Smørgrav 	}
360545d5ecaSDag-Erling Smørgrav }
361545d5ecaSDag-Erling Smørgrav 
362545d5ecaSDag-Erling Smørgrav int
363545d5ecaSDag-Erling Smørgrav mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key)
364545d5ecaSDag-Erling Smørgrav {
365545d5ecaSDag-Erling Smørgrav 	Buffer m;
366545d5ecaSDag-Erling Smørgrav 	u_char *blob;
367545d5ecaSDag-Erling Smørgrav 	u_int len;
368e73e9afaSDag-Erling Smørgrav 	int allowed = 0, have_forced = 0;
369545d5ecaSDag-Erling Smørgrav 
370545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
371545d5ecaSDag-Erling Smørgrav 
372545d5ecaSDag-Erling Smørgrav 	/* Convert the key to a blob and the pass it over */
373545d5ecaSDag-Erling Smørgrav 	if (!key_to_blob(key, &blob, &len))
374545d5ecaSDag-Erling Smørgrav 		return (0);
375545d5ecaSDag-Erling Smørgrav 
376545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
377545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&m, type);
378545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, user ? user : "");
379545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, host ? host : "");
380545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, blob, len);
381545d5ecaSDag-Erling Smørgrav 	xfree(blob);
382545d5ecaSDag-Erling Smørgrav 
383545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, &m);
384545d5ecaSDag-Erling Smørgrav 
385545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_KEYALLOWED", __func__);
386545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYALLOWED, &m);
387545d5ecaSDag-Erling Smørgrav 
388545d5ecaSDag-Erling Smørgrav 	allowed = buffer_get_int(&m);
389545d5ecaSDag-Erling Smørgrav 
390e73e9afaSDag-Erling Smørgrav 	/* fake forced command */
391e73e9afaSDag-Erling Smørgrav 	auth_clear_options();
392e73e9afaSDag-Erling Smørgrav 	have_forced = buffer_get_int(&m);
393e73e9afaSDag-Erling Smørgrav 	forced_command = have_forced ? xstrdup("true") : NULL;
394e73e9afaSDag-Erling Smørgrav 
395545d5ecaSDag-Erling Smørgrav 	/* Send potential debug messages */
396545d5ecaSDag-Erling Smørgrav 	mm_send_debug(&m);
397545d5ecaSDag-Erling Smørgrav 
398545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
399545d5ecaSDag-Erling Smørgrav 
400545d5ecaSDag-Erling Smørgrav 	return (allowed);
401545d5ecaSDag-Erling Smørgrav }
402545d5ecaSDag-Erling Smørgrav 
403545d5ecaSDag-Erling Smørgrav /*
404545d5ecaSDag-Erling Smørgrav  * This key verify needs to send the key type along, because the
405545d5ecaSDag-Erling Smørgrav  * privileged parent makes the decision if the key is allowed
406545d5ecaSDag-Erling Smørgrav  * for authentication.
407545d5ecaSDag-Erling Smørgrav  */
408545d5ecaSDag-Erling Smørgrav 
409545d5ecaSDag-Erling Smørgrav int
410545d5ecaSDag-Erling Smørgrav mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
411545d5ecaSDag-Erling Smørgrav {
412545d5ecaSDag-Erling Smørgrav 	Buffer m;
413545d5ecaSDag-Erling Smørgrav 	u_char *blob;
414545d5ecaSDag-Erling Smørgrav 	u_int len;
415545d5ecaSDag-Erling Smørgrav 	int verified = 0;
416545d5ecaSDag-Erling Smørgrav 
417545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
418545d5ecaSDag-Erling Smørgrav 
419545d5ecaSDag-Erling Smørgrav 	/* Convert the key to a blob and the pass it over */
420545d5ecaSDag-Erling Smørgrav 	if (!key_to_blob(key, &blob, &len))
421545d5ecaSDag-Erling Smørgrav 		return (0);
422545d5ecaSDag-Erling Smørgrav 
423545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
424545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, blob, len);
425545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, sig, siglen);
426545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, data, datalen);
427545d5ecaSDag-Erling Smørgrav 	xfree(blob);
428545d5ecaSDag-Erling Smørgrav 
429545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m);
430545d5ecaSDag-Erling Smørgrav 
431545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__);
432545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m);
433545d5ecaSDag-Erling Smørgrav 
434545d5ecaSDag-Erling Smørgrav 	verified = buffer_get_int(&m);
435545d5ecaSDag-Erling Smørgrav 
436545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
437545d5ecaSDag-Erling Smørgrav 
438545d5ecaSDag-Erling Smørgrav 	return (verified);
439545d5ecaSDag-Erling Smørgrav }
440545d5ecaSDag-Erling Smørgrav 
441545d5ecaSDag-Erling Smørgrav /* Export key state after authentication */
442545d5ecaSDag-Erling Smørgrav Newkeys *
443545d5ecaSDag-Erling Smørgrav mm_newkeys_from_blob(u_char *blob, int blen)
444545d5ecaSDag-Erling Smørgrav {
445545d5ecaSDag-Erling Smørgrav 	Buffer b;
446545d5ecaSDag-Erling Smørgrav 	u_int len;
447545d5ecaSDag-Erling Smørgrav 	Newkeys *newkey = NULL;
448545d5ecaSDag-Erling Smørgrav 	Enc *enc;
449545d5ecaSDag-Erling Smørgrav 	Mac *mac;
450545d5ecaSDag-Erling Smørgrav 	Comp *comp;
451545d5ecaSDag-Erling Smørgrav 
452545d5ecaSDag-Erling Smørgrav 	debug3("%s: %p(%d)", __func__, blob, blen);
453545d5ecaSDag-Erling Smørgrav #ifdef DEBUG_PK
454545d5ecaSDag-Erling Smørgrav 	dump_base64(stderr, blob, blen);
455545d5ecaSDag-Erling Smørgrav #endif
456545d5ecaSDag-Erling Smørgrav 	buffer_init(&b);
457545d5ecaSDag-Erling Smørgrav 	buffer_append(&b, blob, blen);
458545d5ecaSDag-Erling Smørgrav 
459545d5ecaSDag-Erling Smørgrav 	newkey = xmalloc(sizeof(*newkey));
460545d5ecaSDag-Erling Smørgrav 	enc = &newkey->enc;
461545d5ecaSDag-Erling Smørgrav 	mac = &newkey->mac;
462545d5ecaSDag-Erling Smørgrav 	comp = &newkey->comp;
463545d5ecaSDag-Erling Smørgrav 
464545d5ecaSDag-Erling Smørgrav 	/* Enc structure */
465545d5ecaSDag-Erling Smørgrav 	enc->name = buffer_get_string(&b, NULL);
466545d5ecaSDag-Erling Smørgrav 	buffer_get(&b, &enc->cipher, sizeof(enc->cipher));
467545d5ecaSDag-Erling Smørgrav 	enc->enabled = buffer_get_int(&b);
468545d5ecaSDag-Erling Smørgrav 	enc->block_size = buffer_get_int(&b);
469545d5ecaSDag-Erling Smørgrav 	enc->key = buffer_get_string(&b, &enc->key_len);
470545d5ecaSDag-Erling Smørgrav 	enc->iv = buffer_get_string(&b, &len);
471545d5ecaSDag-Erling Smørgrav 	if (len != enc->block_size)
472f388f5efSDag-Erling Smørgrav 		fatal("%s: bad ivlen: expected %u != %u", __func__,
473545d5ecaSDag-Erling Smørgrav 		    enc->block_size, len);
474545d5ecaSDag-Erling Smørgrav 
475545d5ecaSDag-Erling Smørgrav 	if (enc->name == NULL || cipher_by_name(enc->name) != enc->cipher)
476545d5ecaSDag-Erling Smørgrav 		fatal("%s: bad cipher name %s or pointer %p", __func__,
477545d5ecaSDag-Erling Smørgrav 		    enc->name, enc->cipher);
478545d5ecaSDag-Erling Smørgrav 
479545d5ecaSDag-Erling Smørgrav 	/* Mac structure */
480545d5ecaSDag-Erling Smørgrav 	mac->name = buffer_get_string(&b, NULL);
481d4af9e69SDag-Erling Smørgrav 	if (mac->name == NULL || mac_setup(mac, mac->name) == -1)
482d4af9e69SDag-Erling Smørgrav 		fatal("%s: can not setup mac %s", __func__, mac->name);
483545d5ecaSDag-Erling Smørgrav 	mac->enabled = buffer_get_int(&b);
484545d5ecaSDag-Erling Smørgrav 	mac->key = buffer_get_string(&b, &len);
485545d5ecaSDag-Erling Smørgrav 	if (len > mac->key_len)
486f388f5efSDag-Erling Smørgrav 		fatal("%s: bad mac key length: %u > %d", __func__, len,
487545d5ecaSDag-Erling Smørgrav 		    mac->key_len);
488545d5ecaSDag-Erling Smørgrav 	mac->key_len = len;
489545d5ecaSDag-Erling Smørgrav 
490545d5ecaSDag-Erling Smørgrav 	/* Comp structure */
491545d5ecaSDag-Erling Smørgrav 	comp->type = buffer_get_int(&b);
492545d5ecaSDag-Erling Smørgrav 	comp->enabled = buffer_get_int(&b);
493545d5ecaSDag-Erling Smørgrav 	comp->name = buffer_get_string(&b, NULL);
494545d5ecaSDag-Erling Smørgrav 
495545d5ecaSDag-Erling Smørgrav 	len = buffer_len(&b);
496545d5ecaSDag-Erling Smørgrav 	if (len != 0)
497f388f5efSDag-Erling Smørgrav 		error("newkeys_from_blob: remaining bytes in blob %u", len);
498545d5ecaSDag-Erling Smørgrav 	buffer_free(&b);
499545d5ecaSDag-Erling Smørgrav 	return (newkey);
500545d5ecaSDag-Erling Smørgrav }
501545d5ecaSDag-Erling Smørgrav 
502545d5ecaSDag-Erling Smørgrav int
503545d5ecaSDag-Erling Smørgrav mm_newkeys_to_blob(int mode, u_char **blobp, u_int *lenp)
504545d5ecaSDag-Erling Smørgrav {
505545d5ecaSDag-Erling Smørgrav 	Buffer b;
506545d5ecaSDag-Erling Smørgrav 	int len;
507545d5ecaSDag-Erling Smørgrav 	Enc *enc;
508545d5ecaSDag-Erling Smørgrav 	Mac *mac;
509545d5ecaSDag-Erling Smørgrav 	Comp *comp;
510545d5ecaSDag-Erling Smørgrav 	Newkeys *newkey = newkeys[mode];
511545d5ecaSDag-Erling Smørgrav 
512545d5ecaSDag-Erling Smørgrav 	debug3("%s: converting %p", __func__, newkey);
513545d5ecaSDag-Erling Smørgrav 
514545d5ecaSDag-Erling Smørgrav 	if (newkey == NULL) {
515545d5ecaSDag-Erling Smørgrav 		error("%s: newkey == NULL", __func__);
516545d5ecaSDag-Erling Smørgrav 		return 0;
517545d5ecaSDag-Erling Smørgrav 	}
518545d5ecaSDag-Erling Smørgrav 	enc = &newkey->enc;
519545d5ecaSDag-Erling Smørgrav 	mac = &newkey->mac;
520545d5ecaSDag-Erling Smørgrav 	comp = &newkey->comp;
521545d5ecaSDag-Erling Smørgrav 
522545d5ecaSDag-Erling Smørgrav 	buffer_init(&b);
523545d5ecaSDag-Erling Smørgrav 	/* Enc structure */
524545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&b, enc->name);
525545d5ecaSDag-Erling Smørgrav 	/* The cipher struct is constant and shared, you export pointer */
526545d5ecaSDag-Erling Smørgrav 	buffer_append(&b, &enc->cipher, sizeof(enc->cipher));
527545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&b, enc->enabled);
528545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&b, enc->block_size);
529545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&b, enc->key, enc->key_len);
530545d5ecaSDag-Erling Smørgrav 	packet_get_keyiv(mode, enc->iv, enc->block_size);
531545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&b, enc->iv, enc->block_size);
532545d5ecaSDag-Erling Smørgrav 
533545d5ecaSDag-Erling Smørgrav 	/* Mac structure */
534545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&b, mac->name);
535545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&b, mac->enabled);
536545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&b, mac->key, mac->key_len);
537545d5ecaSDag-Erling Smørgrav 
538545d5ecaSDag-Erling Smørgrav 	/* Comp structure */
539545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&b, comp->type);
540545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&b, comp->enabled);
541545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&b, comp->name);
542545d5ecaSDag-Erling Smørgrav 
543545d5ecaSDag-Erling Smørgrav 	len = buffer_len(&b);
544545d5ecaSDag-Erling Smørgrav 	if (lenp != NULL)
545545d5ecaSDag-Erling Smørgrav 		*lenp = len;
546f388f5efSDag-Erling Smørgrav 	if (blobp != NULL) {
547f388f5efSDag-Erling Smørgrav 		*blobp = xmalloc(len);
548f388f5efSDag-Erling Smørgrav 		memcpy(*blobp, buffer_ptr(&b), len);
549f388f5efSDag-Erling Smørgrav 	}
550f388f5efSDag-Erling Smørgrav 	memset(buffer_ptr(&b), 0, len);
551f388f5efSDag-Erling Smørgrav 	buffer_free(&b);
552545d5ecaSDag-Erling Smørgrav 	return len;
553545d5ecaSDag-Erling Smørgrav }
554545d5ecaSDag-Erling Smørgrav 
555545d5ecaSDag-Erling Smørgrav static void
556545d5ecaSDag-Erling Smørgrav mm_send_kex(Buffer *m, Kex *kex)
557545d5ecaSDag-Erling Smørgrav {
558545d5ecaSDag-Erling Smørgrav 	buffer_put_string(m, kex->session_id, kex->session_id_len);
559545d5ecaSDag-Erling Smørgrav 	buffer_put_int(m, kex->we_need);
560545d5ecaSDag-Erling Smørgrav 	buffer_put_int(m, kex->hostkey_type);
561545d5ecaSDag-Erling Smørgrav 	buffer_put_int(m, kex->kex_type);
562545d5ecaSDag-Erling Smørgrav 	buffer_put_string(m, buffer_ptr(&kex->my), buffer_len(&kex->my));
563545d5ecaSDag-Erling Smørgrav 	buffer_put_string(m, buffer_ptr(&kex->peer), buffer_len(&kex->peer));
564545d5ecaSDag-Erling Smørgrav 	buffer_put_int(m, kex->flags);
565545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(m, kex->client_version_string);
566545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(m, kex->server_version_string);
567545d5ecaSDag-Erling Smørgrav }
568545d5ecaSDag-Erling Smørgrav 
569545d5ecaSDag-Erling Smørgrav void
57021e764dfSDag-Erling Smørgrav mm_send_keystate(struct monitor *monitor)
571545d5ecaSDag-Erling Smørgrav {
572545d5ecaSDag-Erling Smørgrav 	Buffer m;
573545d5ecaSDag-Erling Smørgrav 	u_char *blob, *p;
574545d5ecaSDag-Erling Smørgrav 	u_int bloblen, plen;
575cf2b5f3bSDag-Erling Smørgrav 	u_int32_t seqnr, packets;
576d4af9e69SDag-Erling Smørgrav 	u_int64_t blocks, bytes;
577545d5ecaSDag-Erling Smørgrav 
578545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
579545d5ecaSDag-Erling Smørgrav 
580545d5ecaSDag-Erling Smørgrav 	if (!compat20) {
581545d5ecaSDag-Erling Smørgrav 		u_char iv[24];
582545d5ecaSDag-Erling Smørgrav 		u_char *key;
583545d5ecaSDag-Erling Smørgrav 		u_int ivlen, keylen;
584545d5ecaSDag-Erling Smørgrav 
585545d5ecaSDag-Erling Smørgrav 		buffer_put_int(&m, packet_get_protocol_flags());
586545d5ecaSDag-Erling Smørgrav 
587545d5ecaSDag-Erling Smørgrav 		buffer_put_int(&m, packet_get_ssh1_cipher());
588545d5ecaSDag-Erling Smørgrav 
589545d5ecaSDag-Erling Smørgrav 		debug3("%s: Sending ssh1 KEY+IV", __func__);
590545d5ecaSDag-Erling Smørgrav 		keylen = packet_get_encryption_key(NULL);
591545d5ecaSDag-Erling Smørgrav 		key = xmalloc(keylen+1);	/* add 1 if keylen == 0 */
592545d5ecaSDag-Erling Smørgrav 		keylen = packet_get_encryption_key(key);
593545d5ecaSDag-Erling Smørgrav 		buffer_put_string(&m, key, keylen);
594545d5ecaSDag-Erling Smørgrav 		memset(key, 0, keylen);
595545d5ecaSDag-Erling Smørgrav 		xfree(key);
596545d5ecaSDag-Erling Smørgrav 
597545d5ecaSDag-Erling Smørgrav 		ivlen = packet_get_keyiv_len(MODE_OUT);
598545d5ecaSDag-Erling Smørgrav 		packet_get_keyiv(MODE_OUT, iv, ivlen);
599545d5ecaSDag-Erling Smørgrav 		buffer_put_string(&m, iv, ivlen);
600545d5ecaSDag-Erling Smørgrav 		ivlen = packet_get_keyiv_len(MODE_OUT);
601545d5ecaSDag-Erling Smørgrav 		packet_get_keyiv(MODE_IN, iv, ivlen);
602545d5ecaSDag-Erling Smørgrav 		buffer_put_string(&m, iv, ivlen);
603545d5ecaSDag-Erling Smørgrav 		goto skip;
604545d5ecaSDag-Erling Smørgrav 	} else {
605545d5ecaSDag-Erling Smørgrav 		/* Kex for rekeying */
60621e764dfSDag-Erling Smørgrav 		mm_send_kex(&m, *monitor->m_pkex);
607545d5ecaSDag-Erling Smørgrav 	}
608545d5ecaSDag-Erling Smørgrav 
609545d5ecaSDag-Erling Smørgrav 	debug3("%s: Sending new keys: %p %p",
610545d5ecaSDag-Erling Smørgrav 	    __func__, newkeys[MODE_OUT], newkeys[MODE_IN]);
611545d5ecaSDag-Erling Smørgrav 
612545d5ecaSDag-Erling Smørgrav 	/* Keys from Kex */
613545d5ecaSDag-Erling Smørgrav 	if (!mm_newkeys_to_blob(MODE_OUT, &blob, &bloblen))
614545d5ecaSDag-Erling Smørgrav 		fatal("%s: conversion of newkeys failed", __func__);
615545d5ecaSDag-Erling Smørgrav 
616545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, blob, bloblen);
617545d5ecaSDag-Erling Smørgrav 	xfree(blob);
618545d5ecaSDag-Erling Smørgrav 
619545d5ecaSDag-Erling Smørgrav 	if (!mm_newkeys_to_blob(MODE_IN, &blob, &bloblen))
620545d5ecaSDag-Erling Smørgrav 		fatal("%s: conversion of newkeys failed", __func__);
621545d5ecaSDag-Erling Smørgrav 
622545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, blob, bloblen);
623545d5ecaSDag-Erling Smørgrav 	xfree(blob);
624545d5ecaSDag-Erling Smørgrav 
625d4af9e69SDag-Erling Smørgrav 	packet_get_state(MODE_OUT, &seqnr, &blocks, &packets, &bytes);
626cf2b5f3bSDag-Erling Smørgrav 	buffer_put_int(&m, seqnr);
627cf2b5f3bSDag-Erling Smørgrav 	buffer_put_int64(&m, blocks);
628cf2b5f3bSDag-Erling Smørgrav 	buffer_put_int(&m, packets);
629d4af9e69SDag-Erling Smørgrav 	buffer_put_int64(&m, bytes);
630d4af9e69SDag-Erling Smørgrav 	packet_get_state(MODE_IN, &seqnr, &blocks, &packets, &bytes);
631cf2b5f3bSDag-Erling Smørgrav 	buffer_put_int(&m, seqnr);
632cf2b5f3bSDag-Erling Smørgrav 	buffer_put_int64(&m, blocks);
633cf2b5f3bSDag-Erling Smørgrav 	buffer_put_int(&m, packets);
634d4af9e69SDag-Erling Smørgrav 	buffer_put_int64(&m, bytes);
635545d5ecaSDag-Erling Smørgrav 
636545d5ecaSDag-Erling Smørgrav 	debug3("%s: New keys have been sent", __func__);
637545d5ecaSDag-Erling Smørgrav  skip:
638545d5ecaSDag-Erling Smørgrav 	/* More key context */
639545d5ecaSDag-Erling Smørgrav 	plen = packet_get_keycontext(MODE_OUT, NULL);
640545d5ecaSDag-Erling Smørgrav 	p = xmalloc(plen+1);
641545d5ecaSDag-Erling Smørgrav 	packet_get_keycontext(MODE_OUT, p);
642545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, p, plen);
643545d5ecaSDag-Erling Smørgrav 	xfree(p);
644545d5ecaSDag-Erling Smørgrav 
645545d5ecaSDag-Erling Smørgrav 	plen = packet_get_keycontext(MODE_IN, NULL);
646545d5ecaSDag-Erling Smørgrav 	p = xmalloc(plen+1);
647545d5ecaSDag-Erling Smørgrav 	packet_get_keycontext(MODE_IN, p);
648545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, p, plen);
649545d5ecaSDag-Erling Smørgrav 	xfree(p);
650545d5ecaSDag-Erling Smørgrav 
651545d5ecaSDag-Erling Smørgrav 	/* Compression state */
652545d5ecaSDag-Erling Smørgrav 	debug3("%s: Sending compression state", __func__);
653545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, &outgoing_stream, sizeof(outgoing_stream));
654545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, &incoming_stream, sizeof(incoming_stream));
655545d5ecaSDag-Erling Smørgrav 
656545d5ecaSDag-Erling Smørgrav 	/* Network I/O buffers */
657545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, buffer_ptr(&input), buffer_len(&input));
658545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, buffer_ptr(&output), buffer_len(&output));
659545d5ecaSDag-Erling Smørgrav 
66021e764dfSDag-Erling Smørgrav 	mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, &m);
661545d5ecaSDag-Erling Smørgrav 	debug3("%s: Finished sending state", __func__);
662545d5ecaSDag-Erling Smørgrav 
663545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
664545d5ecaSDag-Erling Smørgrav }
665545d5ecaSDag-Erling Smørgrav 
666545d5ecaSDag-Erling Smørgrav int
667333ee039SDag-Erling Smørgrav mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen)
668545d5ecaSDag-Erling Smørgrav {
669545d5ecaSDag-Erling Smørgrav 	Buffer m;
67021e764dfSDag-Erling Smørgrav 	char *p, *msg;
671d4af9e69SDag-Erling Smørgrav 	int success = 0, tmp1 = -1, tmp2 = -1;
672d4af9e69SDag-Erling Smørgrav 
673d4af9e69SDag-Erling Smørgrav 	/* Kludge: ensure there are fds free to receive the pty/tty */
674d4af9e69SDag-Erling Smørgrav 	if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 ||
675d4af9e69SDag-Erling Smørgrav 	    (tmp2 = dup(pmonitor->m_recvfd)) == -1) {
676d4af9e69SDag-Erling Smørgrav 		error("%s: cannot allocate fds for pty", __func__);
677d4af9e69SDag-Erling Smørgrav 		if (tmp1 > 0)
678d4af9e69SDag-Erling Smørgrav 			close(tmp1);
679d4af9e69SDag-Erling Smørgrav 		if (tmp2 > 0)
680d4af9e69SDag-Erling Smørgrav 			close(tmp2);
681d4af9e69SDag-Erling Smørgrav 		return 0;
682d4af9e69SDag-Erling Smørgrav 	}
683d4af9e69SDag-Erling Smørgrav 	close(tmp1);
684d4af9e69SDag-Erling Smørgrav 	close(tmp2);
685545d5ecaSDag-Erling Smørgrav 
686545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
687545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, &m);
688545d5ecaSDag-Erling Smørgrav 
689545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PTY", __func__);
690545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PTY, &m);
691545d5ecaSDag-Erling Smørgrav 
692545d5ecaSDag-Erling Smørgrav 	success = buffer_get_int(&m);
693545d5ecaSDag-Erling Smørgrav 	if (success == 0) {
694545d5ecaSDag-Erling Smørgrav 		debug3("%s: pty alloc failed", __func__);
695545d5ecaSDag-Erling Smørgrav 		buffer_free(&m);
696545d5ecaSDag-Erling Smørgrav 		return (0);
697545d5ecaSDag-Erling Smørgrav 	}
698545d5ecaSDag-Erling Smørgrav 	p = buffer_get_string(&m, NULL);
69921e764dfSDag-Erling Smørgrav 	msg = buffer_get_string(&m, NULL);
700545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
701545d5ecaSDag-Erling Smørgrav 
702545d5ecaSDag-Erling Smørgrav 	strlcpy(namebuf, p, namebuflen); /* Possible truncation */
703545d5ecaSDag-Erling Smørgrav 	xfree(p);
704545d5ecaSDag-Erling Smørgrav 
70521e764dfSDag-Erling Smørgrav 	buffer_append(&loginmsg, msg, strlen(msg));
70621e764dfSDag-Erling Smørgrav 	xfree(msg);
70721e764dfSDag-Erling Smørgrav 
708d4af9e69SDag-Erling Smørgrav 	if ((*ptyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1 ||
709d4af9e69SDag-Erling Smørgrav 	    (*ttyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1)
710d4af9e69SDag-Erling Smørgrav 		fatal("%s: receive fds failed", __func__);
711545d5ecaSDag-Erling Smørgrav 
712545d5ecaSDag-Erling Smørgrav 	/* Success */
713545d5ecaSDag-Erling Smørgrav 	return (1);
714545d5ecaSDag-Erling Smørgrav }
715545d5ecaSDag-Erling Smørgrav 
716545d5ecaSDag-Erling Smørgrav void
7171ec0d754SDag-Erling Smørgrav mm_session_pty_cleanup2(Session *s)
718545d5ecaSDag-Erling Smørgrav {
719545d5ecaSDag-Erling Smørgrav 	Buffer m;
720545d5ecaSDag-Erling Smørgrav 
721545d5ecaSDag-Erling Smørgrav 	if (s->ttyfd == -1)
722545d5ecaSDag-Erling Smørgrav 		return;
723545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
724545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, s->tty);
725545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, &m);
726545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
727545d5ecaSDag-Erling Smørgrav 
728545d5ecaSDag-Erling Smørgrav 	/* closed dup'ed master */
729d4af9e69SDag-Erling Smørgrav 	if (s->ptymaster != -1 && close(s->ptymaster) < 0)
730d4af9e69SDag-Erling Smørgrav 		error("close(s->ptymaster/%d): %s",
731d4af9e69SDag-Erling Smørgrav 		    s->ptymaster, strerror(errno));
732545d5ecaSDag-Erling Smørgrav 
733545d5ecaSDag-Erling Smørgrav 	/* unlink pty from session */
734545d5ecaSDag-Erling Smørgrav 	s->ttyfd = -1;
735545d5ecaSDag-Erling Smørgrav }
736545d5ecaSDag-Erling Smørgrav 
73783d2307dSDag-Erling Smørgrav #ifdef USE_PAM
73883d2307dSDag-Erling Smørgrav void
7395962c0e9SDag-Erling Smørgrav mm_start_pam(Authctxt *authctxt)
74083d2307dSDag-Erling Smørgrav {
74183d2307dSDag-Erling Smørgrav 	Buffer m;
74283d2307dSDag-Erling Smørgrav 
74383d2307dSDag-Erling Smørgrav 	debug3("%s entering", __func__);
744cf2b5f3bSDag-Erling Smørgrav 	if (!options.use_pam)
745cf2b5f3bSDag-Erling Smørgrav 		fatal("UsePAM=no, but ended up in %s anyway", __func__);
74683d2307dSDag-Erling Smørgrav 
74783d2307dSDag-Erling Smørgrav 	buffer_init(&m);
74883d2307dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_START, &m);
74983d2307dSDag-Erling Smørgrav 
75083d2307dSDag-Erling Smørgrav 	buffer_free(&m);
75183d2307dSDag-Erling Smørgrav }
752382d19eeSDag-Erling Smørgrav 
753cf2b5f3bSDag-Erling Smørgrav u_int
754cf2b5f3bSDag-Erling Smørgrav mm_do_pam_account(void)
755cf2b5f3bSDag-Erling Smørgrav {
756cf2b5f3bSDag-Erling Smørgrav 	Buffer m;
757cf2b5f3bSDag-Erling Smørgrav 	u_int ret;
758aa49c926SDag-Erling Smørgrav 	char *msg;
759cf2b5f3bSDag-Erling Smørgrav 
760cf2b5f3bSDag-Erling Smørgrav 	debug3("%s entering", __func__);
761cf2b5f3bSDag-Erling Smørgrav 	if (!options.use_pam)
762cf2b5f3bSDag-Erling Smørgrav 		fatal("UsePAM=no, but ended up in %s anyway", __func__);
763cf2b5f3bSDag-Erling Smørgrav 
764cf2b5f3bSDag-Erling Smørgrav 	buffer_init(&m);
765cf2b5f3bSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, &m);
766cf2b5f3bSDag-Erling Smørgrav 
767cf2b5f3bSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
768cf2b5f3bSDag-Erling Smørgrav 	    MONITOR_ANS_PAM_ACCOUNT, &m);
769cf2b5f3bSDag-Erling Smørgrav 	ret = buffer_get_int(&m);
770aa49c926SDag-Erling Smørgrav 	msg = buffer_get_string(&m, NULL);
771aa49c926SDag-Erling Smørgrav 	buffer_append(&loginmsg, msg, strlen(msg));
772aa49c926SDag-Erling Smørgrav 	xfree(msg);
773cf2b5f3bSDag-Erling Smørgrav 
774cf2b5f3bSDag-Erling Smørgrav 	buffer_free(&m);
775cf2b5f3bSDag-Erling Smørgrav 
776cf2b5f3bSDag-Erling Smørgrav 	debug3("%s returning %d", __func__, ret);
777cf2b5f3bSDag-Erling Smørgrav 
778cf2b5f3bSDag-Erling Smørgrav 	return (ret);
779cf2b5f3bSDag-Erling Smørgrav }
780cf2b5f3bSDag-Erling Smørgrav 
781382d19eeSDag-Erling Smørgrav void *
782cf2b5f3bSDag-Erling Smørgrav mm_sshpam_init_ctx(Authctxt *authctxt)
783382d19eeSDag-Erling Smørgrav {
784382d19eeSDag-Erling Smørgrav 	Buffer m;
785382d19eeSDag-Erling Smørgrav 	int success;
786382d19eeSDag-Erling Smørgrav 
787382d19eeSDag-Erling Smørgrav 	debug3("%s", __func__);
788382d19eeSDag-Erling Smørgrav 	buffer_init(&m);
789382d19eeSDag-Erling Smørgrav 	buffer_put_cstring(&m, authctxt->user);
790382d19eeSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_INIT_CTX, &m);
791382d19eeSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PAM_INIT_CTX", __func__);
792382d19eeSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_INIT_CTX, &m);
793382d19eeSDag-Erling Smørgrav 	success = buffer_get_int(&m);
794382d19eeSDag-Erling Smørgrav 	if (success == 0) {
795382d19eeSDag-Erling Smørgrav 		debug3("%s: pam_init_ctx failed", __func__);
796382d19eeSDag-Erling Smørgrav 		buffer_free(&m);
797382d19eeSDag-Erling Smørgrav 		return (NULL);
798382d19eeSDag-Erling Smørgrav 	}
799382d19eeSDag-Erling Smørgrav 	buffer_free(&m);
800382d19eeSDag-Erling Smørgrav 	return (authctxt);
801382d19eeSDag-Erling Smørgrav }
802382d19eeSDag-Erling Smørgrav 
803382d19eeSDag-Erling Smørgrav int
804cf2b5f3bSDag-Erling Smørgrav mm_sshpam_query(void *ctx, char **name, char **info,
805382d19eeSDag-Erling Smørgrav     u_int *num, char ***prompts, u_int **echo_on)
806382d19eeSDag-Erling Smørgrav {
807382d19eeSDag-Erling Smørgrav 	Buffer m;
808d4ecd108SDag-Erling Smørgrav 	u_int i;
809d4ecd108SDag-Erling Smørgrav 	int ret;
810382d19eeSDag-Erling Smørgrav 
811382d19eeSDag-Erling Smørgrav 	debug3("%s", __func__);
812382d19eeSDag-Erling Smørgrav 	buffer_init(&m);
813382d19eeSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_QUERY, &m);
814382d19eeSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PAM_QUERY", __func__);
815382d19eeSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_QUERY, &m);
816382d19eeSDag-Erling Smørgrav 	ret = buffer_get_int(&m);
817382d19eeSDag-Erling Smørgrav 	debug3("%s: pam_query returned %d", __func__, ret);
818382d19eeSDag-Erling Smørgrav 	*name = buffer_get_string(&m, NULL);
819382d19eeSDag-Erling Smørgrav 	*info = buffer_get_string(&m, NULL);
820382d19eeSDag-Erling Smørgrav 	*num = buffer_get_int(&m);
821333ee039SDag-Erling Smørgrav 	if (*num > PAM_MAX_NUM_MSG)
822333ee039SDag-Erling Smørgrav 		fatal("%s: recieved %u PAM messages, expected <= %u",
823333ee039SDag-Erling Smørgrav 		    __func__, *num, PAM_MAX_NUM_MSG);
824333ee039SDag-Erling Smørgrav 	*prompts = xcalloc((*num + 1), sizeof(char *));
825333ee039SDag-Erling Smørgrav 	*echo_on = xcalloc((*num + 1), sizeof(u_int));
826382d19eeSDag-Erling Smørgrav 	for (i = 0; i < *num; ++i) {
827382d19eeSDag-Erling Smørgrav 		(*prompts)[i] = buffer_get_string(&m, NULL);
828382d19eeSDag-Erling Smørgrav 		(*echo_on)[i] = buffer_get_int(&m);
829382d19eeSDag-Erling Smørgrav 	}
830382d19eeSDag-Erling Smørgrav 	buffer_free(&m);
831382d19eeSDag-Erling Smørgrav 	return (ret);
832382d19eeSDag-Erling Smørgrav }
833382d19eeSDag-Erling Smørgrav 
834382d19eeSDag-Erling Smørgrav int
835cf2b5f3bSDag-Erling Smørgrav mm_sshpam_respond(void *ctx, u_int num, char **resp)
836382d19eeSDag-Erling Smørgrav {
837382d19eeSDag-Erling Smørgrav 	Buffer m;
838d4ecd108SDag-Erling Smørgrav 	u_int i;
839d4ecd108SDag-Erling Smørgrav 	int ret;
840382d19eeSDag-Erling Smørgrav 
841382d19eeSDag-Erling Smørgrav 	debug3("%s", __func__);
842382d19eeSDag-Erling Smørgrav 	buffer_init(&m);
843382d19eeSDag-Erling Smørgrav 	buffer_put_int(&m, num);
844382d19eeSDag-Erling Smørgrav 	for (i = 0; i < num; ++i)
845382d19eeSDag-Erling Smørgrav 		buffer_put_cstring(&m, resp[i]);
846382d19eeSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_RESPOND, &m);
847382d19eeSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__);
848382d19eeSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_RESPOND, &m);
849382d19eeSDag-Erling Smørgrav 	ret = buffer_get_int(&m);
850382d19eeSDag-Erling Smørgrav 	debug3("%s: pam_respond returned %d", __func__, ret);
851382d19eeSDag-Erling Smørgrav 	buffer_free(&m);
852382d19eeSDag-Erling Smørgrav 	return (ret);
853382d19eeSDag-Erling Smørgrav }
854382d19eeSDag-Erling Smørgrav 
855382d19eeSDag-Erling Smørgrav void
856cf2b5f3bSDag-Erling Smørgrav mm_sshpam_free_ctx(void *ctxtp)
857382d19eeSDag-Erling Smørgrav {
858382d19eeSDag-Erling Smørgrav 	Buffer m;
859382d19eeSDag-Erling Smørgrav 
860382d19eeSDag-Erling Smørgrav 	debug3("%s", __func__);
861382d19eeSDag-Erling Smørgrav 	buffer_init(&m);
862382d19eeSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_FREE_CTX, &m);
863382d19eeSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PAM_FREE_CTX", __func__);
864382d19eeSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_FREE_CTX, &m);
865382d19eeSDag-Erling Smørgrav 	buffer_free(&m);
866382d19eeSDag-Erling Smørgrav }
86783d2307dSDag-Erling Smørgrav #endif /* USE_PAM */
86883d2307dSDag-Erling Smørgrav 
869545d5ecaSDag-Erling Smørgrav /* Request process termination */
870545d5ecaSDag-Erling Smørgrav 
871545d5ecaSDag-Erling Smørgrav void
872545d5ecaSDag-Erling Smørgrav mm_terminate(void)
873545d5ecaSDag-Erling Smørgrav {
874545d5ecaSDag-Erling Smørgrav 	Buffer m;
875545d5ecaSDag-Erling Smørgrav 
876545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
877545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_TERM, &m);
878545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
879545d5ecaSDag-Erling Smørgrav }
880545d5ecaSDag-Erling Smørgrav 
881545d5ecaSDag-Erling Smørgrav int
882545d5ecaSDag-Erling Smørgrav mm_ssh1_session_key(BIGNUM *num)
883545d5ecaSDag-Erling Smørgrav {
884545d5ecaSDag-Erling Smørgrav 	int rsafail;
885545d5ecaSDag-Erling Smørgrav 	Buffer m;
886545d5ecaSDag-Erling Smørgrav 
887545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
888545d5ecaSDag-Erling Smørgrav 	buffer_put_bignum2(&m, num);
889545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSKEY, &m);
890545d5ecaSDag-Erling Smørgrav 
891545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SESSKEY, &m);
892545d5ecaSDag-Erling Smørgrav 
893545d5ecaSDag-Erling Smørgrav 	rsafail = buffer_get_int(&m);
894545d5ecaSDag-Erling Smørgrav 	buffer_get_bignum2(&m, num);
895545d5ecaSDag-Erling Smørgrav 
896545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
897545d5ecaSDag-Erling Smørgrav 
898545d5ecaSDag-Erling Smørgrav 	return (rsafail);
899545d5ecaSDag-Erling Smørgrav }
900545d5ecaSDag-Erling Smørgrav 
901545d5ecaSDag-Erling Smørgrav static void
902545d5ecaSDag-Erling Smørgrav mm_chall_setup(char **name, char **infotxt, u_int *numprompts,
903545d5ecaSDag-Erling Smørgrav     char ***prompts, u_int **echo_on)
904545d5ecaSDag-Erling Smørgrav {
905545d5ecaSDag-Erling Smørgrav 	*name = xstrdup("");
906545d5ecaSDag-Erling Smørgrav 	*infotxt = xstrdup("");
907545d5ecaSDag-Erling Smørgrav 	*numprompts = 1;
908333ee039SDag-Erling Smørgrav 	*prompts = xcalloc(*numprompts, sizeof(char *));
909333ee039SDag-Erling Smørgrav 	*echo_on = xcalloc(*numprompts, sizeof(u_int));
910545d5ecaSDag-Erling Smørgrav 	(*echo_on)[0] = 0;
911545d5ecaSDag-Erling Smørgrav }
912545d5ecaSDag-Erling Smørgrav 
913545d5ecaSDag-Erling Smørgrav int
914545d5ecaSDag-Erling Smørgrav mm_bsdauth_query(void *ctx, char **name, char **infotxt,
915545d5ecaSDag-Erling Smørgrav    u_int *numprompts, char ***prompts, u_int **echo_on)
916545d5ecaSDag-Erling Smørgrav {
917545d5ecaSDag-Erling Smørgrav 	Buffer m;
918e73e9afaSDag-Erling Smørgrav 	u_int success;
919545d5ecaSDag-Erling Smørgrav 	char *challenge;
920545d5ecaSDag-Erling Smørgrav 
921545d5ecaSDag-Erling Smørgrav 	debug3("%s: entering", __func__);
922545d5ecaSDag-Erling Smørgrav 
923545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
924545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHQUERY, &m);
925545d5ecaSDag-Erling Smørgrav 
926545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_BSDAUTHQUERY,
927545d5ecaSDag-Erling Smørgrav 	    &m);
928e73e9afaSDag-Erling Smørgrav 	success = buffer_get_int(&m);
929e73e9afaSDag-Erling Smørgrav 	if (success == 0) {
930545d5ecaSDag-Erling Smørgrav 		debug3("%s: no challenge", __func__);
931545d5ecaSDag-Erling Smørgrav 		buffer_free(&m);
932545d5ecaSDag-Erling Smørgrav 		return (-1);
933545d5ecaSDag-Erling Smørgrav 	}
934545d5ecaSDag-Erling Smørgrav 
935545d5ecaSDag-Erling Smørgrav 	/* Get the challenge, and format the response */
936545d5ecaSDag-Erling Smørgrav 	challenge  = buffer_get_string(&m, NULL);
937545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
938545d5ecaSDag-Erling Smørgrav 
939545d5ecaSDag-Erling Smørgrav 	mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
940545d5ecaSDag-Erling Smørgrav 	(*prompts)[0] = challenge;
941545d5ecaSDag-Erling Smørgrav 
942545d5ecaSDag-Erling Smørgrav 	debug3("%s: received challenge: %s", __func__, challenge);
943545d5ecaSDag-Erling Smørgrav 
944545d5ecaSDag-Erling Smørgrav 	return (0);
945545d5ecaSDag-Erling Smørgrav }
946545d5ecaSDag-Erling Smørgrav 
947545d5ecaSDag-Erling Smørgrav int
948545d5ecaSDag-Erling Smørgrav mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses)
949545d5ecaSDag-Erling Smørgrav {
950545d5ecaSDag-Erling Smørgrav 	Buffer m;
951545d5ecaSDag-Erling Smørgrav 	int authok;
952545d5ecaSDag-Erling Smørgrav 
953545d5ecaSDag-Erling Smørgrav 	debug3("%s: entering", __func__);
954545d5ecaSDag-Erling Smørgrav 	if (numresponses != 1)
955545d5ecaSDag-Erling Smørgrav 		return (-1);
956545d5ecaSDag-Erling Smørgrav 
957545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
958545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, responses[0]);
959545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHRESPOND, &m);
960545d5ecaSDag-Erling Smørgrav 
961545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
962545d5ecaSDag-Erling Smørgrav 	    MONITOR_ANS_BSDAUTHRESPOND, &m);
963545d5ecaSDag-Erling Smørgrav 
964545d5ecaSDag-Erling Smørgrav 	authok = buffer_get_int(&m);
965545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
966545d5ecaSDag-Erling Smørgrav 
967545d5ecaSDag-Erling Smørgrav 	return ((authok == 0) ? -1 : 0);
968545d5ecaSDag-Erling Smørgrav }
969545d5ecaSDag-Erling Smørgrav 
970edb557f8SDag-Erling Smørgrav #ifdef SKEY
971545d5ecaSDag-Erling Smørgrav int
972545d5ecaSDag-Erling Smørgrav mm_skey_query(void *ctx, char **name, char **infotxt,
973545d5ecaSDag-Erling Smørgrav    u_int *numprompts, char ***prompts, u_int **echo_on)
974545d5ecaSDag-Erling Smørgrav {
975545d5ecaSDag-Erling Smørgrav 	Buffer m;
976e73e9afaSDag-Erling Smørgrav 	u_int success;
977333ee039SDag-Erling Smørgrav 	char *challenge;
978545d5ecaSDag-Erling Smørgrav 
979545d5ecaSDag-Erling Smørgrav 	debug3("%s: entering", __func__);
980545d5ecaSDag-Erling Smørgrav 
981545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
982545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYQUERY, &m);
983545d5ecaSDag-Erling Smørgrav 
984545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SKEYQUERY,
985545d5ecaSDag-Erling Smørgrav 	    &m);
986e73e9afaSDag-Erling Smørgrav 	success = buffer_get_int(&m);
987e73e9afaSDag-Erling Smørgrav 	if (success == 0) {
988545d5ecaSDag-Erling Smørgrav 		debug3("%s: no challenge", __func__);
989545d5ecaSDag-Erling Smørgrav 		buffer_free(&m);
990545d5ecaSDag-Erling Smørgrav 		return (-1);
991545d5ecaSDag-Erling Smørgrav 	}
992545d5ecaSDag-Erling Smørgrav 
993545d5ecaSDag-Erling Smørgrav 	/* Get the challenge, and format the response */
994545d5ecaSDag-Erling Smørgrav 	challenge  = buffer_get_string(&m, NULL);
995545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
996545d5ecaSDag-Erling Smørgrav 
997545d5ecaSDag-Erling Smørgrav 	debug3("%s: received challenge: %s", __func__, challenge);
998545d5ecaSDag-Erling Smørgrav 
999545d5ecaSDag-Erling Smørgrav 	mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
1000545d5ecaSDag-Erling Smørgrav 
1001333ee039SDag-Erling Smørgrav 	xasprintf(*prompts, "%s%s", challenge, SKEY_PROMPT);
1002545d5ecaSDag-Erling Smørgrav 	xfree(challenge);
1003545d5ecaSDag-Erling Smørgrav 
1004545d5ecaSDag-Erling Smørgrav 	return (0);
1005545d5ecaSDag-Erling Smørgrav }
1006545d5ecaSDag-Erling Smørgrav 
1007545d5ecaSDag-Erling Smørgrav int
1008545d5ecaSDag-Erling Smørgrav mm_skey_respond(void *ctx, u_int numresponses, char **responses)
1009545d5ecaSDag-Erling Smørgrav {
1010545d5ecaSDag-Erling Smørgrav 	Buffer m;
1011545d5ecaSDag-Erling Smørgrav 	int authok;
1012545d5ecaSDag-Erling Smørgrav 
1013545d5ecaSDag-Erling Smørgrav 	debug3("%s: entering", __func__);
1014545d5ecaSDag-Erling Smørgrav 	if (numresponses != 1)
1015545d5ecaSDag-Erling Smørgrav 		return (-1);
1016545d5ecaSDag-Erling Smørgrav 
1017545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
1018545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, responses[0]);
1019545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYRESPOND, &m);
1020545d5ecaSDag-Erling Smørgrav 
1021545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
1022545d5ecaSDag-Erling Smørgrav 	    MONITOR_ANS_SKEYRESPOND, &m);
1023545d5ecaSDag-Erling Smørgrav 
1024545d5ecaSDag-Erling Smørgrav 	authok = buffer_get_int(&m);
1025545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
1026545d5ecaSDag-Erling Smørgrav 
1027545d5ecaSDag-Erling Smørgrav 	return ((authok == 0) ? -1 : 0);
1028545d5ecaSDag-Erling Smørgrav }
102921e764dfSDag-Erling Smørgrav #endif /* SKEY */
1030545d5ecaSDag-Erling Smørgrav 
1031545d5ecaSDag-Erling Smørgrav void
1032545d5ecaSDag-Erling Smørgrav mm_ssh1_session_id(u_char session_id[16])
1033545d5ecaSDag-Erling Smørgrav {
1034545d5ecaSDag-Erling Smørgrav 	Buffer m;
1035545d5ecaSDag-Erling Smørgrav 	int i;
1036545d5ecaSDag-Erling Smørgrav 
1037545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
1038545d5ecaSDag-Erling Smørgrav 
1039545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
1040545d5ecaSDag-Erling Smørgrav 	for (i = 0; i < 16; i++)
1041545d5ecaSDag-Erling Smørgrav 		buffer_put_char(&m, session_id[i]);
1042545d5ecaSDag-Erling Smørgrav 
1043545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSID, &m);
1044545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
1045545d5ecaSDag-Erling Smørgrav }
1046545d5ecaSDag-Erling Smørgrav 
1047545d5ecaSDag-Erling Smørgrav int
1048545d5ecaSDag-Erling Smørgrav mm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
1049545d5ecaSDag-Erling Smørgrav {
1050545d5ecaSDag-Erling Smørgrav 	Buffer m;
1051545d5ecaSDag-Erling Smørgrav 	Key *key;
1052545d5ecaSDag-Erling Smørgrav 	u_char *blob;
1053545d5ecaSDag-Erling Smørgrav 	u_int blen;
1054e73e9afaSDag-Erling Smørgrav 	int allowed = 0, have_forced = 0;
1055545d5ecaSDag-Erling Smørgrav 
1056545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
1057545d5ecaSDag-Erling Smørgrav 
1058545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
1059545d5ecaSDag-Erling Smørgrav 	buffer_put_bignum2(&m, client_n);
1060545d5ecaSDag-Erling Smørgrav 
1061545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSAKEYALLOWED, &m);
1062545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSAKEYALLOWED, &m);
1063545d5ecaSDag-Erling Smørgrav 
1064545d5ecaSDag-Erling Smørgrav 	allowed = buffer_get_int(&m);
1065545d5ecaSDag-Erling Smørgrav 
1066e73e9afaSDag-Erling Smørgrav 	/* fake forced command */
1067e73e9afaSDag-Erling Smørgrav 	auth_clear_options();
1068e73e9afaSDag-Erling Smørgrav 	have_forced = buffer_get_int(&m);
1069e73e9afaSDag-Erling Smørgrav 	forced_command = have_forced ? xstrdup("true") : NULL;
1070e73e9afaSDag-Erling Smørgrav 
1071545d5ecaSDag-Erling Smørgrav 	if (allowed && rkey != NULL) {
1072545d5ecaSDag-Erling Smørgrav 		blob = buffer_get_string(&m, &blen);
1073545d5ecaSDag-Erling Smørgrav 		if ((key = key_from_blob(blob, blen)) == NULL)
1074545d5ecaSDag-Erling Smørgrav 			fatal("%s: key_from_blob failed", __func__);
1075545d5ecaSDag-Erling Smørgrav 		*rkey = key;
1076545d5ecaSDag-Erling Smørgrav 		xfree(blob);
1077545d5ecaSDag-Erling Smørgrav 	}
1078545d5ecaSDag-Erling Smørgrav 	mm_send_debug(&m);
1079545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
1080545d5ecaSDag-Erling Smørgrav 
1081545d5ecaSDag-Erling Smørgrav 	return (allowed);
1082545d5ecaSDag-Erling Smørgrav }
1083545d5ecaSDag-Erling Smørgrav 
1084545d5ecaSDag-Erling Smørgrav BIGNUM *
1085545d5ecaSDag-Erling Smørgrav mm_auth_rsa_generate_challenge(Key *key)
1086545d5ecaSDag-Erling Smørgrav {
1087545d5ecaSDag-Erling Smørgrav 	Buffer m;
1088545d5ecaSDag-Erling Smørgrav 	BIGNUM *challenge;
1089545d5ecaSDag-Erling Smørgrav 	u_char *blob;
1090545d5ecaSDag-Erling Smørgrav 	u_int blen;
1091545d5ecaSDag-Erling Smørgrav 
1092545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
1093545d5ecaSDag-Erling Smørgrav 
1094545d5ecaSDag-Erling Smørgrav 	if ((challenge = BN_new()) == NULL)
1095545d5ecaSDag-Erling Smørgrav 		fatal("%s: BN_new failed", __func__);
1096545d5ecaSDag-Erling Smørgrav 
1097545d5ecaSDag-Erling Smørgrav 	key->type = KEY_RSA;    /* XXX cheat for key_to_blob */
1098545d5ecaSDag-Erling Smørgrav 	if (key_to_blob(key, &blob, &blen) == 0)
1099545d5ecaSDag-Erling Smørgrav 		fatal("%s: key_to_blob failed", __func__);
1100545d5ecaSDag-Erling Smørgrav 	key->type = KEY_RSA1;
1101545d5ecaSDag-Erling Smørgrav 
1102545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
1103545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, blob, blen);
1104545d5ecaSDag-Erling Smørgrav 	xfree(blob);
1105545d5ecaSDag-Erling Smørgrav 
1106545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSACHALLENGE, &m);
1107545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSACHALLENGE, &m);
1108545d5ecaSDag-Erling Smørgrav 
1109545d5ecaSDag-Erling Smørgrav 	buffer_get_bignum2(&m, challenge);
1110545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
1111545d5ecaSDag-Erling Smørgrav 
1112545d5ecaSDag-Erling Smørgrav 	return (challenge);
1113545d5ecaSDag-Erling Smørgrav }
1114545d5ecaSDag-Erling Smørgrav 
1115545d5ecaSDag-Erling Smørgrav int
1116545d5ecaSDag-Erling Smørgrav mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16])
1117545d5ecaSDag-Erling Smørgrav {
1118545d5ecaSDag-Erling Smørgrav 	Buffer m;
1119545d5ecaSDag-Erling Smørgrav 	u_char *blob;
1120545d5ecaSDag-Erling Smørgrav 	u_int blen;
1121545d5ecaSDag-Erling Smørgrav 	int success = 0;
1122545d5ecaSDag-Erling Smørgrav 
1123545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
1124545d5ecaSDag-Erling Smørgrav 
1125545d5ecaSDag-Erling Smørgrav 	key->type = KEY_RSA;    /* XXX cheat for key_to_blob */
1126545d5ecaSDag-Erling Smørgrav 	if (key_to_blob(key, &blob, &blen) == 0)
1127545d5ecaSDag-Erling Smørgrav 		fatal("%s: key_to_blob failed", __func__);
1128545d5ecaSDag-Erling Smørgrav 	key->type = KEY_RSA1;
1129545d5ecaSDag-Erling Smørgrav 
1130545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
1131545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, blob, blen);
1132545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, response, 16);
1133545d5ecaSDag-Erling Smørgrav 	xfree(blob);
1134545d5ecaSDag-Erling Smørgrav 
1135545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSARESPONSE, &m);
1136545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSARESPONSE, &m);
1137545d5ecaSDag-Erling Smørgrav 
1138545d5ecaSDag-Erling Smørgrav 	success = buffer_get_int(&m);
1139545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
1140545d5ecaSDag-Erling Smørgrav 
1141545d5ecaSDag-Erling Smørgrav 	return (success);
1142545d5ecaSDag-Erling Smørgrav }
1143f388f5efSDag-Erling Smørgrav 
1144aa49c926SDag-Erling Smørgrav #ifdef SSH_AUDIT_EVENTS
1145aa49c926SDag-Erling Smørgrav void
1146aa49c926SDag-Erling Smørgrav mm_audit_event(ssh_audit_event_t event)
1147aa49c926SDag-Erling Smørgrav {
1148aa49c926SDag-Erling Smørgrav 	Buffer m;
1149aa49c926SDag-Erling Smørgrav 
1150aa49c926SDag-Erling Smørgrav 	debug3("%s entering", __func__);
1151aa49c926SDag-Erling Smørgrav 
1152aa49c926SDag-Erling Smørgrav 	buffer_init(&m);
1153aa49c926SDag-Erling Smørgrav 	buffer_put_int(&m, event);
1154aa49c926SDag-Erling Smørgrav 
1155aa49c926SDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_EVENT, &m);
1156aa49c926SDag-Erling Smørgrav 	buffer_free(&m);
1157aa49c926SDag-Erling Smørgrav }
1158aa49c926SDag-Erling Smørgrav 
1159aa49c926SDag-Erling Smørgrav void
1160aa49c926SDag-Erling Smørgrav mm_audit_run_command(const char *command)
1161aa49c926SDag-Erling Smørgrav {
1162aa49c926SDag-Erling Smørgrav 	Buffer m;
1163aa49c926SDag-Erling Smørgrav 
1164aa49c926SDag-Erling Smørgrav 	debug3("%s entering command %s", __func__, command);
1165aa49c926SDag-Erling Smørgrav 
1166aa49c926SDag-Erling Smørgrav 	buffer_init(&m);
1167aa49c926SDag-Erling Smørgrav 	buffer_put_cstring(&m, command);
1168aa49c926SDag-Erling Smørgrav 
1169aa49c926SDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m);
1170aa49c926SDag-Erling Smørgrav 	buffer_free(&m);
1171aa49c926SDag-Erling Smørgrav }
1172aa49c926SDag-Erling Smørgrav #endif /* SSH_AUDIT_EVENTS */
1173aa49c926SDag-Erling Smørgrav 
1174cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI
1175cf2b5f3bSDag-Erling Smørgrav OM_uint32
117621e764dfSDag-Erling Smørgrav mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid)
1177f388f5efSDag-Erling Smørgrav {
1178f388f5efSDag-Erling Smørgrav 	Buffer m;
1179cf2b5f3bSDag-Erling Smørgrav 	OM_uint32 major;
1180f388f5efSDag-Erling Smørgrav 
1181cf2b5f3bSDag-Erling Smørgrav 	/* Client doesn't get to see the context */
1182cf2b5f3bSDag-Erling Smørgrav 	*ctx = NULL;
1183f388f5efSDag-Erling Smørgrav 
1184f388f5efSDag-Erling Smørgrav 	buffer_init(&m);
118521e764dfSDag-Erling Smørgrav 	buffer_put_string(&m, goid->elements, goid->length);
1186f388f5efSDag-Erling Smørgrav 
1187cf2b5f3bSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, &m);
1188cf2b5f3bSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, &m);
1189f388f5efSDag-Erling Smørgrav 
1190cf2b5f3bSDag-Erling Smørgrav 	major = buffer_get_int(&m);
1191cf2b5f3bSDag-Erling Smørgrav 
1192f388f5efSDag-Erling Smørgrav 	buffer_free(&m);
1193cf2b5f3bSDag-Erling Smørgrav 	return (major);
1194f388f5efSDag-Erling Smørgrav }
1195f388f5efSDag-Erling Smørgrav 
1196cf2b5f3bSDag-Erling Smørgrav OM_uint32
1197cf2b5f3bSDag-Erling Smørgrav mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in,
1198cf2b5f3bSDag-Erling Smørgrav     gss_buffer_desc *out, OM_uint32 *flags)
1199f388f5efSDag-Erling Smørgrav {
1200f388f5efSDag-Erling Smørgrav 	Buffer m;
1201cf2b5f3bSDag-Erling Smørgrav 	OM_uint32 major;
1202f388f5efSDag-Erling Smørgrav 	u_int len;
1203f388f5efSDag-Erling Smørgrav 
1204cf2b5f3bSDag-Erling Smørgrav 	buffer_init(&m);
1205cf2b5f3bSDag-Erling Smørgrav 	buffer_put_string(&m, in->value, in->length);
1206cf2b5f3bSDag-Erling Smørgrav 
1207cf2b5f3bSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, &m);
1208cf2b5f3bSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, &m);
1209cf2b5f3bSDag-Erling Smørgrav 
1210cf2b5f3bSDag-Erling Smørgrav 	major = buffer_get_int(&m);
1211cf2b5f3bSDag-Erling Smørgrav 	out->value = buffer_get_string(&m, &len);
1212cf2b5f3bSDag-Erling Smørgrav 	out->length = len;
1213cf2b5f3bSDag-Erling Smørgrav 	if (flags)
1214cf2b5f3bSDag-Erling Smørgrav 		*flags = buffer_get_int(&m);
1215f388f5efSDag-Erling Smørgrav 
1216f388f5efSDag-Erling Smørgrav 	buffer_free(&m);
1217cf2b5f3bSDag-Erling Smørgrav 
1218cf2b5f3bSDag-Erling Smørgrav 	return (major);
1219f388f5efSDag-Erling Smørgrav }
1220cf2b5f3bSDag-Erling Smørgrav 
12211ec0d754SDag-Erling Smørgrav OM_uint32
12221ec0d754SDag-Erling Smørgrav mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
12231ec0d754SDag-Erling Smørgrav {
12241ec0d754SDag-Erling Smørgrav 	Buffer m;
12251ec0d754SDag-Erling Smørgrav 	OM_uint32 major;
12261ec0d754SDag-Erling Smørgrav 
12271ec0d754SDag-Erling Smørgrav 	buffer_init(&m);
12281ec0d754SDag-Erling Smørgrav 	buffer_put_string(&m, gssbuf->value, gssbuf->length);
12291ec0d754SDag-Erling Smørgrav 	buffer_put_string(&m, gssmic->value, gssmic->length);
12301ec0d754SDag-Erling Smørgrav 
12311ec0d754SDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, &m);
12321ec0d754SDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSCHECKMIC,
12331ec0d754SDag-Erling Smørgrav 	    &m);
12341ec0d754SDag-Erling Smørgrav 
12351ec0d754SDag-Erling Smørgrav 	major = buffer_get_int(&m);
12361ec0d754SDag-Erling Smørgrav 	buffer_free(&m);
12371ec0d754SDag-Erling Smørgrav 	return(major);
12381ec0d754SDag-Erling Smørgrav }
12391ec0d754SDag-Erling Smørgrav 
1240cf2b5f3bSDag-Erling Smørgrav int
1241cf2b5f3bSDag-Erling Smørgrav mm_ssh_gssapi_userok(char *user)
1242cf2b5f3bSDag-Erling Smørgrav {
1243cf2b5f3bSDag-Erling Smørgrav 	Buffer m;
1244cf2b5f3bSDag-Erling Smørgrav 	int authenticated = 0;
1245cf2b5f3bSDag-Erling Smørgrav 
1246cf2b5f3bSDag-Erling Smørgrav 	buffer_init(&m);
1247cf2b5f3bSDag-Erling Smørgrav 
1248cf2b5f3bSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m);
1249cf2b5f3bSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK,
1250cf2b5f3bSDag-Erling Smørgrav 				  &m);
1251cf2b5f3bSDag-Erling Smørgrav 
1252cf2b5f3bSDag-Erling Smørgrav 	authenticated = buffer_get_int(&m);
1253cf2b5f3bSDag-Erling Smørgrav 
1254cf2b5f3bSDag-Erling Smørgrav 	buffer_free(&m);
1255cf2b5f3bSDag-Erling Smørgrav 	debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not ");
1256cf2b5f3bSDag-Erling Smørgrav 	return (authenticated);
1257cf2b5f3bSDag-Erling Smørgrav }
1258cf2b5f3bSDag-Erling Smørgrav #endif /* GSSAPI */
1259