xref: /freebsd/crypto/openssh/monitor_wrap.c (revision 4f52dfbb8d6c4d446500c5b097e3806ec219fbd4)
1*4f52dfbbSDag-Erling Smørgrav /* $OpenBSD: monitor_wrap.c,v 1.94 2017/10/02 19:33:20 djm 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 
41a0ee8cc6SDag-Erling Smørgrav #ifdef WITH_OPENSSL
42545d5ecaSDag-Erling Smørgrav #include <openssl/bn.h>
43545d5ecaSDag-Erling Smørgrav #include <openssl/dh.h>
44cce7d346SDag-Erling Smørgrav #include <openssl/evp.h>
45a0ee8cc6SDag-Erling Smørgrav #endif
46545d5ecaSDag-Erling Smørgrav 
47d4af9e69SDag-Erling Smørgrav #include "openbsd-compat/sys-queue.h"
48333ee039SDag-Erling Smørgrav #include "xmalloc.h"
49545d5ecaSDag-Erling Smørgrav #include "ssh.h"
50a0ee8cc6SDag-Erling Smørgrav #ifdef WITH_OPENSSL
51545d5ecaSDag-Erling Smørgrav #include "dh.h"
52a0ee8cc6SDag-Erling Smørgrav #endif
53333ee039SDag-Erling Smørgrav #include "buffer.h"
54333ee039SDag-Erling Smørgrav #include "key.h"
55333ee039SDag-Erling Smørgrav #include "cipher.h"
56545d5ecaSDag-Erling Smørgrav #include "kex.h"
57333ee039SDag-Erling Smørgrav #include "hostfile.h"
58545d5ecaSDag-Erling Smørgrav #include "auth.h"
59e73e9afaSDag-Erling Smørgrav #include "auth-options.h"
60545d5ecaSDag-Erling Smørgrav #include "packet.h"
61545d5ecaSDag-Erling Smørgrav #include "mac.h"
62545d5ecaSDag-Erling Smørgrav #include "log.h"
63076ad2f8SDag-Erling Smørgrav #include "auth-pam.h"
645962c0e9SDag-Erling Smørgrav #ifdef TARGET_OS_MAC    /* XXX Broken krb5 headers on Mac */
655962c0e9SDag-Erling Smørgrav #undef TARGET_OS_MAC
66545d5ecaSDag-Erling Smørgrav #include "zlib.h"
675962c0e9SDag-Erling Smørgrav #define TARGET_OS_MAC 1
685962c0e9SDag-Erling Smørgrav #else
695962c0e9SDag-Erling Smørgrav #include "zlib.h"
705962c0e9SDag-Erling Smørgrav #endif
71545d5ecaSDag-Erling Smørgrav #include "monitor.h"
72cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI
73cf2b5f3bSDag-Erling Smørgrav #include "ssh-gss.h"
74cf2b5f3bSDag-Erling Smørgrav #endif
75333ee039SDag-Erling Smørgrav #include "monitor_wrap.h"
76333ee039SDag-Erling Smørgrav #include "atomicio.h"
77333ee039SDag-Erling Smørgrav #include "monitor_fdpass.h"
78333ee039SDag-Erling Smørgrav #include "misc.h"
794a421b63SDag-Erling Smørgrav #include "uuencode.h"
80333ee039SDag-Erling Smørgrav 
81333ee039SDag-Erling Smørgrav #include "channels.h"
82333ee039SDag-Erling Smørgrav #include "session.h"
83d4af9e69SDag-Erling Smørgrav #include "servconf.h"
84cf2b5f3bSDag-Erling Smørgrav 
85bc5531deSDag-Erling Smørgrav #include "ssherr.h"
86bc5531deSDag-Erling Smørgrav 
87545d5ecaSDag-Erling Smørgrav /* Imports */
88545d5ecaSDag-Erling Smørgrav extern z_stream incoming_stream;
89545d5ecaSDag-Erling Smørgrav extern z_stream outgoing_stream;
90545d5ecaSDag-Erling Smørgrav extern struct monitor *pmonitor;
9121e764dfSDag-Erling Smørgrav extern Buffer loginmsg;
92cf2b5f3bSDag-Erling Smørgrav extern ServerOptions options;
93545d5ecaSDag-Erling Smørgrav 
94e146993eSDag-Erling Smørgrav void
95e146993eSDag-Erling Smørgrav mm_log_handler(LogLevel level, const char *msg, void *ctx)
96e146993eSDag-Erling Smørgrav {
97e146993eSDag-Erling Smørgrav 	Buffer log_msg;
98e146993eSDag-Erling Smørgrav 	struct monitor *mon = (struct monitor *)ctx;
99e146993eSDag-Erling Smørgrav 
100e146993eSDag-Erling Smørgrav 	if (mon->m_log_sendfd == -1)
101e146993eSDag-Erling Smørgrav 		fatal("%s: no log channel", __func__);
102e146993eSDag-Erling Smørgrav 
103e146993eSDag-Erling Smørgrav 	buffer_init(&log_msg);
104e146993eSDag-Erling Smørgrav 	/*
105e146993eSDag-Erling Smørgrav 	 * Placeholder for packet length. Will be filled in with the actual
106e146993eSDag-Erling Smørgrav 	 * packet length once the packet has been constucted. This saves
107e146993eSDag-Erling Smørgrav 	 * fragile math.
108e146993eSDag-Erling Smørgrav 	 */
109e146993eSDag-Erling Smørgrav 	buffer_put_int(&log_msg, 0);
110e146993eSDag-Erling Smørgrav 
111e146993eSDag-Erling Smørgrav 	buffer_put_int(&log_msg, level);
112e146993eSDag-Erling Smørgrav 	buffer_put_cstring(&log_msg, msg);
113e146993eSDag-Erling Smørgrav 	put_u32(buffer_ptr(&log_msg), buffer_len(&log_msg) - 4);
114e146993eSDag-Erling Smørgrav 	if (atomicio(vwrite, mon->m_log_sendfd, buffer_ptr(&log_msg),
115e146993eSDag-Erling Smørgrav 	    buffer_len(&log_msg)) != buffer_len(&log_msg))
116e146993eSDag-Erling Smørgrav 		fatal("%s: write: %s", __func__, strerror(errno));
117e146993eSDag-Erling Smørgrav 	buffer_free(&log_msg);
118e146993eSDag-Erling Smørgrav }
119e146993eSDag-Erling Smørgrav 
1201ec0d754SDag-Erling Smørgrav int
1211ec0d754SDag-Erling Smørgrav mm_is_monitor(void)
1221ec0d754SDag-Erling Smørgrav {
1231ec0d754SDag-Erling Smørgrav 	/*
1241ec0d754SDag-Erling Smørgrav 	 * m_pid is only set in the privileged part, and
1251ec0d754SDag-Erling Smørgrav 	 * points to the unprivileged child.
1261ec0d754SDag-Erling Smørgrav 	 */
1271ec0d754SDag-Erling Smørgrav 	return (pmonitor && pmonitor->m_pid > 0);
1281ec0d754SDag-Erling Smørgrav }
1291ec0d754SDag-Erling Smørgrav 
130545d5ecaSDag-Erling Smørgrav void
13121e764dfSDag-Erling Smørgrav mm_request_send(int sock, enum monitor_reqtype type, Buffer *m)
132545d5ecaSDag-Erling Smørgrav {
133545d5ecaSDag-Erling Smørgrav 	u_int mlen = buffer_len(m);
134f388f5efSDag-Erling Smørgrav 	u_char buf[5];
135545d5ecaSDag-Erling Smørgrav 
136545d5ecaSDag-Erling Smørgrav 	debug3("%s entering: type %d", __func__, type);
137545d5ecaSDag-Erling Smørgrav 
138333ee039SDag-Erling Smørgrav 	put_u32(buf, mlen + 1);
139545d5ecaSDag-Erling Smørgrav 	buf[4] = (u_char) type;		/* 1st byte of payload is mesg-type */
14021e764dfSDag-Erling Smørgrav 	if (atomicio(vwrite, sock, buf, sizeof(buf)) != sizeof(buf))
141d4ecd108SDag-Erling Smørgrav 		fatal("%s: write: %s", __func__, strerror(errno));
14221e764dfSDag-Erling Smørgrav 	if (atomicio(vwrite, sock, buffer_ptr(m), mlen) != mlen)
143d4ecd108SDag-Erling Smørgrav 		fatal("%s: write: %s", __func__, strerror(errno));
144545d5ecaSDag-Erling Smørgrav }
145545d5ecaSDag-Erling Smørgrav 
146545d5ecaSDag-Erling Smørgrav void
14721e764dfSDag-Erling Smørgrav mm_request_receive(int sock, Buffer *m)
148545d5ecaSDag-Erling Smørgrav {
149545d5ecaSDag-Erling Smørgrav 	u_char buf[4];
150545d5ecaSDag-Erling Smørgrav 	u_int msg_len;
151545d5ecaSDag-Erling Smørgrav 
152545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
153545d5ecaSDag-Erling Smørgrav 
154d4ecd108SDag-Erling Smørgrav 	if (atomicio(read, sock, buf, sizeof(buf)) != sizeof(buf)) {
155557f75e5SDag-Erling Smørgrav 		if (errno == EPIPE)
1561ec0d754SDag-Erling Smørgrav 			cleanup_exit(255);
157d4ecd108SDag-Erling Smørgrav 		fatal("%s: read: %s", __func__, strerror(errno));
158545d5ecaSDag-Erling Smørgrav 	}
159333ee039SDag-Erling Smørgrav 	msg_len = get_u32(buf);
160545d5ecaSDag-Erling Smørgrav 	if (msg_len > 256 * 1024)
161545d5ecaSDag-Erling Smørgrav 		fatal("%s: read: bad msg_len %d", __func__, msg_len);
162545d5ecaSDag-Erling Smørgrav 	buffer_clear(m);
163545d5ecaSDag-Erling Smørgrav 	buffer_append_space(m, msg_len);
164d4ecd108SDag-Erling Smørgrav 	if (atomicio(read, sock, buffer_ptr(m), msg_len) != msg_len)
165d4ecd108SDag-Erling Smørgrav 		fatal("%s: read: %s", __func__, strerror(errno));
166545d5ecaSDag-Erling Smørgrav }
167545d5ecaSDag-Erling Smørgrav 
168545d5ecaSDag-Erling Smørgrav void
16921e764dfSDag-Erling Smørgrav mm_request_receive_expect(int sock, enum monitor_reqtype type, Buffer *m)
170545d5ecaSDag-Erling Smørgrav {
171545d5ecaSDag-Erling Smørgrav 	u_char rtype;
172545d5ecaSDag-Erling Smørgrav 
173545d5ecaSDag-Erling Smørgrav 	debug3("%s entering: type %d", __func__, type);
174545d5ecaSDag-Erling Smørgrav 
17521e764dfSDag-Erling Smørgrav 	mm_request_receive(sock, m);
176545d5ecaSDag-Erling Smørgrav 	rtype = buffer_get_char(m);
177545d5ecaSDag-Erling Smørgrav 	if (rtype != type)
178545d5ecaSDag-Erling Smørgrav 		fatal("%s: read: rtype %d != type %d", __func__,
179545d5ecaSDag-Erling Smørgrav 		    rtype, type);
180545d5ecaSDag-Erling Smørgrav }
181545d5ecaSDag-Erling Smørgrav 
182a0ee8cc6SDag-Erling Smørgrav #ifdef WITH_OPENSSL
183545d5ecaSDag-Erling Smørgrav DH *
184545d5ecaSDag-Erling Smørgrav mm_choose_dh(int min, int nbits, int max)
185545d5ecaSDag-Erling Smørgrav {
186545d5ecaSDag-Erling Smørgrav 	BIGNUM *p, *g;
187545d5ecaSDag-Erling Smørgrav 	int success = 0;
188545d5ecaSDag-Erling Smørgrav 	Buffer m;
189545d5ecaSDag-Erling Smørgrav 
190545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
191545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&m, min);
192545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&m, nbits);
193545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&m, max);
194545d5ecaSDag-Erling Smørgrav 
195545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_MODULI, &m);
196545d5ecaSDag-Erling Smørgrav 
197545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_MODULI", __func__);
198545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_MODULI, &m);
199545d5ecaSDag-Erling Smørgrav 
200545d5ecaSDag-Erling Smørgrav 	success = buffer_get_char(&m);
201545d5ecaSDag-Erling Smørgrav 	if (success == 0)
202545d5ecaSDag-Erling Smørgrav 		fatal("%s: MONITOR_ANS_MODULI failed", __func__);
203545d5ecaSDag-Erling Smørgrav 
204545d5ecaSDag-Erling Smørgrav 	if ((p = BN_new()) == NULL)
205545d5ecaSDag-Erling Smørgrav 		fatal("%s: BN_new failed", __func__);
206545d5ecaSDag-Erling Smørgrav 	if ((g = BN_new()) == NULL)
207545d5ecaSDag-Erling Smørgrav 		fatal("%s: BN_new failed", __func__);
208545d5ecaSDag-Erling Smørgrav 	buffer_get_bignum2(&m, p);
209545d5ecaSDag-Erling Smørgrav 	buffer_get_bignum2(&m, g);
210545d5ecaSDag-Erling Smørgrav 
211545d5ecaSDag-Erling Smørgrav 	debug3("%s: remaining %d", __func__, buffer_len(&m));
212545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
213545d5ecaSDag-Erling Smørgrav 
214545d5ecaSDag-Erling Smørgrav 	return (dh_new_group(g, p));
215545d5ecaSDag-Erling Smørgrav }
216a0ee8cc6SDag-Erling Smørgrav #endif
217545d5ecaSDag-Erling Smørgrav 
218545d5ecaSDag-Erling Smørgrav int
219*4f52dfbbSDag-Erling Smørgrav mm_key_sign(struct sshkey *key, u_char **sigp, u_int *lenp,
220acc1a9efSDag-Erling Smørgrav     const u_char *data, u_int datalen, const char *hostkey_alg)
221545d5ecaSDag-Erling Smørgrav {
222bc5531deSDag-Erling Smørgrav 	struct kex *kex = *pmonitor->m_pkex;
223545d5ecaSDag-Erling Smørgrav 	Buffer m;
224545d5ecaSDag-Erling Smørgrav 
225545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
226545d5ecaSDag-Erling Smørgrav 
227545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
228bc5531deSDag-Erling Smørgrav 	buffer_put_int(&m, kex->host_key_index(key, 0, active_state));
229545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, data, datalen);
230acc1a9efSDag-Erling Smørgrav 	buffer_put_cstring(&m, hostkey_alg);
231545d5ecaSDag-Erling Smørgrav 
232545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, &m);
233545d5ecaSDag-Erling Smørgrav 
234545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_SIGN", __func__);
235545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SIGN, &m);
236545d5ecaSDag-Erling Smørgrav 	*sigp  = buffer_get_string(&m, lenp);
237545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
238545d5ecaSDag-Erling Smørgrav 
239545d5ecaSDag-Erling Smørgrav 	return (0);
240545d5ecaSDag-Erling Smørgrav }
241545d5ecaSDag-Erling Smørgrav 
242545d5ecaSDag-Erling Smørgrav struct passwd *
24321e764dfSDag-Erling Smørgrav mm_getpwnamallow(const char *username)
244545d5ecaSDag-Erling Smørgrav {
245*4f52dfbbSDag-Erling Smørgrav 	struct ssh *ssh = active_state;		/* XXX */
246545d5ecaSDag-Erling Smørgrav 	Buffer m;
247545d5ecaSDag-Erling Smørgrav 	struct passwd *pw;
248e146993eSDag-Erling Smørgrav 	u_int len, i;
249d4af9e69SDag-Erling Smørgrav 	ServerOptions *newopts;
250545d5ecaSDag-Erling Smørgrav 
251545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
252545d5ecaSDag-Erling Smørgrav 
253545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
25421e764dfSDag-Erling Smørgrav 	buffer_put_cstring(&m, username);
255545d5ecaSDag-Erling Smørgrav 
256545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, &m);
257545d5ecaSDag-Erling Smørgrav 
258545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PWNAM", __func__);
259545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m);
260545d5ecaSDag-Erling Smørgrav 
261545d5ecaSDag-Erling Smørgrav 	if (buffer_get_char(&m) == 0) {
262d4af9e69SDag-Erling Smørgrav 		pw = NULL;
263d4af9e69SDag-Erling Smørgrav 		goto out;
264545d5ecaSDag-Erling Smørgrav 	}
265d4af9e69SDag-Erling Smørgrav 	pw = buffer_get_string(&m, &len);
266d4af9e69SDag-Erling Smørgrav 	if (len != sizeof(struct passwd))
267545d5ecaSDag-Erling Smørgrav 		fatal("%s: struct passwd size mismatch", __func__);
268545d5ecaSDag-Erling Smørgrav 	pw->pw_name = buffer_get_string(&m, NULL);
269545d5ecaSDag-Erling Smørgrav 	pw->pw_passwd = buffer_get_string(&m, NULL);
270e4a9863fSDag-Erling Smørgrav #ifdef HAVE_STRUCT_PASSWD_PW_GECOS
271545d5ecaSDag-Erling Smørgrav 	pw->pw_gecos = buffer_get_string(&m, NULL);
272e4a9863fSDag-Erling Smørgrav #endif
273e4a9863fSDag-Erling Smørgrav #ifdef HAVE_STRUCT_PASSWD_PW_CLASS
274545d5ecaSDag-Erling Smørgrav 	pw->pw_class = buffer_get_string(&m, NULL);
27583d2307dSDag-Erling Smørgrav #endif
276545d5ecaSDag-Erling Smørgrav 	pw->pw_dir = buffer_get_string(&m, NULL);
277545d5ecaSDag-Erling Smørgrav 	pw->pw_shell = buffer_get_string(&m, NULL);
278d4af9e69SDag-Erling Smørgrav 
279d4af9e69SDag-Erling Smørgrav out:
280d4af9e69SDag-Erling Smørgrav 	/* copy options block as a Match directive may have changed some */
281d4af9e69SDag-Erling Smørgrav 	newopts = buffer_get_string(&m, &len);
282d4af9e69SDag-Erling Smørgrav 	if (len != sizeof(*newopts))
283d4af9e69SDag-Erling Smørgrav 		fatal("%s: option block size mismatch", __func__);
284e146993eSDag-Erling Smørgrav 
285e146993eSDag-Erling Smørgrav #define M_CP_STROPT(x) do { \
286e146993eSDag-Erling Smørgrav 		if (newopts->x != NULL) \
287e146993eSDag-Erling Smørgrav 			newopts->x = buffer_get_string(&m, NULL); \
288e146993eSDag-Erling Smørgrav 	} while (0)
289e146993eSDag-Erling Smørgrav #define M_CP_STRARRAYOPT(x, nx) do { \
290e146993eSDag-Erling Smørgrav 		for (i = 0; i < newopts->nx; i++) \
291e146993eSDag-Erling Smørgrav 			newopts->x[i] = buffer_get_string(&m, NULL); \
292e146993eSDag-Erling Smørgrav 	} while (0)
293*4f52dfbbSDag-Erling Smørgrav #define M_CP_STRARRAYOPT_ALLOC(x, nx) do { \
294*4f52dfbbSDag-Erling Smørgrav 		newopts->x = newopts->nx == 0 ? \
295*4f52dfbbSDag-Erling Smørgrav 		    NULL : xcalloc(newopts->nx, sizeof(*newopts->x)); \
296*4f52dfbbSDag-Erling Smørgrav 		M_CP_STRARRAYOPT(x, nx); \
297*4f52dfbbSDag-Erling Smørgrav 	} while (0)
298e146993eSDag-Erling Smørgrav 	/* See comment in servconf.h */
299e146993eSDag-Erling Smørgrav 	COPY_MATCH_STRING_OPTS();
300e146993eSDag-Erling Smørgrav #undef M_CP_STROPT
301e146993eSDag-Erling Smørgrav #undef M_CP_STRARRAYOPT
302*4f52dfbbSDag-Erling Smørgrav #undef M_CP_STRARRAYOPT_ALLOC
303e146993eSDag-Erling Smørgrav 
304d4af9e69SDag-Erling Smørgrav 	copy_set_server_options(&options, newopts, 1);
305*4f52dfbbSDag-Erling Smørgrav 	log_change_level(options.log_level);
306*4f52dfbbSDag-Erling Smørgrav 	process_permitopen(ssh, &options);
307e4a9863fSDag-Erling Smørgrav 	free(newopts);
308d4af9e69SDag-Erling Smørgrav 
309545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
310545d5ecaSDag-Erling Smørgrav 
311545d5ecaSDag-Erling Smørgrav 	return (pw);
312545d5ecaSDag-Erling Smørgrav }
313545d5ecaSDag-Erling Smørgrav 
3141ec0d754SDag-Erling Smørgrav char *
3151ec0d754SDag-Erling Smørgrav mm_auth2_read_banner(void)
316545d5ecaSDag-Erling Smørgrav {
317545d5ecaSDag-Erling Smørgrav 	Buffer m;
318545d5ecaSDag-Erling Smørgrav 	char *banner;
319545d5ecaSDag-Erling Smørgrav 
320545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
321545d5ecaSDag-Erling Smørgrav 
322545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
323545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, &m);
324545d5ecaSDag-Erling Smørgrav 	buffer_clear(&m);
325545d5ecaSDag-Erling Smørgrav 
3261ec0d754SDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
3271ec0d754SDag-Erling Smørgrav 	    MONITOR_ANS_AUTH2_READ_BANNER, &m);
328545d5ecaSDag-Erling Smørgrav 	banner = buffer_get_string(&m, NULL);
329545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
330545d5ecaSDag-Erling Smørgrav 
3311ec0d754SDag-Erling Smørgrav 	/* treat empty banner as missing banner */
3321ec0d754SDag-Erling Smørgrav 	if (strlen(banner) == 0) {
333e4a9863fSDag-Erling Smørgrav 		free(banner);
3341ec0d754SDag-Erling Smørgrav 		banner = NULL;
3351ec0d754SDag-Erling Smørgrav 	}
336545d5ecaSDag-Erling Smørgrav 	return (banner);
337545d5ecaSDag-Erling Smørgrav }
338545d5ecaSDag-Erling Smørgrav 
339545d5ecaSDag-Erling Smørgrav /* Inform the privileged process about service and style */
340545d5ecaSDag-Erling Smørgrav 
341545d5ecaSDag-Erling Smørgrav void
342545d5ecaSDag-Erling Smørgrav mm_inform_authserv(char *service, char *style)
343545d5ecaSDag-Erling Smørgrav {
344545d5ecaSDag-Erling Smørgrav 	Buffer m;
345545d5ecaSDag-Erling Smørgrav 
346545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
347545d5ecaSDag-Erling Smørgrav 
348545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
349545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, service);
350545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, style ? style : "");
351545d5ecaSDag-Erling Smørgrav 
352545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m);
353545d5ecaSDag-Erling Smørgrav 
354545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
355545d5ecaSDag-Erling Smørgrav }
356545d5ecaSDag-Erling Smørgrav 
357545d5ecaSDag-Erling Smørgrav /* Do the password authentication */
358545d5ecaSDag-Erling Smørgrav int
359545d5ecaSDag-Erling Smørgrav mm_auth_password(Authctxt *authctxt, char *password)
360545d5ecaSDag-Erling Smørgrav {
361545d5ecaSDag-Erling Smørgrav 	Buffer m;
362545d5ecaSDag-Erling Smørgrav 	int authenticated = 0;
363545d5ecaSDag-Erling Smørgrav 
364545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
365545d5ecaSDag-Erling Smørgrav 
366545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
367545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, password);
368545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, &m);
369545d5ecaSDag-Erling Smørgrav 
370545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_AUTHPASSWORD", __func__);
371545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTHPASSWORD, &m);
372545d5ecaSDag-Erling Smørgrav 
373545d5ecaSDag-Erling Smørgrav 	authenticated = buffer_get_int(&m);
374076ad2f8SDag-Erling Smørgrav #ifdef USE_PAM
375076ad2f8SDag-Erling Smørgrav 	sshpam_set_maxtries_reached(buffer_get_int(&m));
376076ad2f8SDag-Erling Smørgrav #endif
377545d5ecaSDag-Erling Smørgrav 
378545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
379545d5ecaSDag-Erling Smørgrav 
380545d5ecaSDag-Erling Smørgrav 	debug3("%s: user %sauthenticated",
381545d5ecaSDag-Erling Smørgrav 	    __func__, authenticated ? "" : "not ");
382545d5ecaSDag-Erling Smørgrav 	return (authenticated);
383545d5ecaSDag-Erling Smørgrav }
384545d5ecaSDag-Erling Smørgrav 
385545d5ecaSDag-Erling Smørgrav int
386*4f52dfbbSDag-Erling Smørgrav mm_user_key_allowed(struct passwd *pw, struct sshkey *key,
387*4f52dfbbSDag-Erling Smørgrav     int pubkey_auth_attempt)
388545d5ecaSDag-Erling Smørgrav {
389557f75e5SDag-Erling Smørgrav 	return (mm_key_allowed(MM_USERKEY, NULL, NULL, key,
390557f75e5SDag-Erling Smørgrav 	    pubkey_auth_attempt));
391545d5ecaSDag-Erling Smørgrav }
392545d5ecaSDag-Erling Smørgrav 
393545d5ecaSDag-Erling Smørgrav int
394076ad2f8SDag-Erling Smørgrav mm_hostbased_key_allowed(struct passwd *pw, const char *user, const char *host,
395*4f52dfbbSDag-Erling Smørgrav     struct sshkey *key)
396545d5ecaSDag-Erling Smørgrav {
397557f75e5SDag-Erling Smørgrav 	return (mm_key_allowed(MM_HOSTKEY, user, host, key, 0));
398545d5ecaSDag-Erling Smørgrav }
399545d5ecaSDag-Erling Smørgrav 
400545d5ecaSDag-Erling Smørgrav int
401076ad2f8SDag-Erling Smørgrav mm_key_allowed(enum mm_keytype type, const char *user, const char *host,
402*4f52dfbbSDag-Erling Smørgrav     struct sshkey *key, int pubkey_auth_attempt)
403545d5ecaSDag-Erling Smørgrav {
404545d5ecaSDag-Erling Smørgrav 	Buffer m;
405545d5ecaSDag-Erling Smørgrav 	u_char *blob;
406545d5ecaSDag-Erling Smørgrav 	u_int len;
407e73e9afaSDag-Erling Smørgrav 	int allowed = 0, have_forced = 0;
408545d5ecaSDag-Erling Smørgrav 
409545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
410545d5ecaSDag-Erling Smørgrav 
411545d5ecaSDag-Erling Smørgrav 	/* Convert the key to a blob and the pass it over */
412545d5ecaSDag-Erling Smørgrav 	if (!key_to_blob(key, &blob, &len))
413545d5ecaSDag-Erling Smørgrav 		return (0);
414545d5ecaSDag-Erling Smørgrav 
415545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
416545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&m, type);
417545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, user ? user : "");
418545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, host ? host : "");
419545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, blob, len);
420557f75e5SDag-Erling Smørgrav 	buffer_put_int(&m, pubkey_auth_attempt);
421e4a9863fSDag-Erling Smørgrav 	free(blob);
422545d5ecaSDag-Erling Smørgrav 
423545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, &m);
424545d5ecaSDag-Erling Smørgrav 
425545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_KEYALLOWED", __func__);
426545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYALLOWED, &m);
427545d5ecaSDag-Erling Smørgrav 
428545d5ecaSDag-Erling Smørgrav 	allowed = buffer_get_int(&m);
429545d5ecaSDag-Erling Smørgrav 
430e73e9afaSDag-Erling Smørgrav 	/* fake forced command */
431e73e9afaSDag-Erling Smørgrav 	auth_clear_options();
432e73e9afaSDag-Erling Smørgrav 	have_forced = buffer_get_int(&m);
433e73e9afaSDag-Erling Smørgrav 	forced_command = have_forced ? xstrdup("true") : NULL;
434e73e9afaSDag-Erling Smørgrav 
435545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
436545d5ecaSDag-Erling Smørgrav 
437545d5ecaSDag-Erling Smørgrav 	return (allowed);
438545d5ecaSDag-Erling Smørgrav }
439545d5ecaSDag-Erling Smørgrav 
440545d5ecaSDag-Erling Smørgrav /*
441545d5ecaSDag-Erling Smørgrav  * This key verify needs to send the key type along, because the
442545d5ecaSDag-Erling Smørgrav  * privileged parent makes the decision if the key is allowed
443545d5ecaSDag-Erling Smørgrav  * for authentication.
444545d5ecaSDag-Erling Smørgrav  */
445545d5ecaSDag-Erling Smørgrav 
446545d5ecaSDag-Erling Smørgrav int
447*4f52dfbbSDag-Erling Smørgrav mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen,
448*4f52dfbbSDag-Erling Smørgrav     const u_char *data, size_t datalen, u_int compat)
449545d5ecaSDag-Erling Smørgrav {
450545d5ecaSDag-Erling Smørgrav 	Buffer m;
451545d5ecaSDag-Erling Smørgrav 	u_char *blob;
452545d5ecaSDag-Erling Smørgrav 	u_int len;
453*4f52dfbbSDag-Erling Smørgrav 	u_int encoded_ret = 0;
454545d5ecaSDag-Erling Smørgrav 
455545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
456545d5ecaSDag-Erling Smørgrav 
457545d5ecaSDag-Erling Smørgrav 	/* Convert the key to a blob and the pass it over */
458545d5ecaSDag-Erling Smørgrav 	if (!key_to_blob(key, &blob, &len))
459545d5ecaSDag-Erling Smørgrav 		return (0);
460545d5ecaSDag-Erling Smørgrav 
461545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
462545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, blob, len);
463545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, sig, siglen);
464545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, data, datalen);
465e4a9863fSDag-Erling Smørgrav 	free(blob);
466545d5ecaSDag-Erling Smørgrav 
467545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m);
468545d5ecaSDag-Erling Smørgrav 
469545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__);
470545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m);
471545d5ecaSDag-Erling Smørgrav 
472*4f52dfbbSDag-Erling Smørgrav 	encoded_ret = buffer_get_int(&m);
473545d5ecaSDag-Erling Smørgrav 
474545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
475545d5ecaSDag-Erling Smørgrav 
476*4f52dfbbSDag-Erling Smørgrav 	if (encoded_ret != 0)
477*4f52dfbbSDag-Erling Smørgrav 		return SSH_ERR_SIGNATURE_INVALID;
478*4f52dfbbSDag-Erling Smørgrav 	return 0;
479545d5ecaSDag-Erling Smørgrav }
480545d5ecaSDag-Erling Smørgrav 
481545d5ecaSDag-Erling Smørgrav void
48221e764dfSDag-Erling Smørgrav mm_send_keystate(struct monitor *monitor)
483545d5ecaSDag-Erling Smørgrav {
484bc5531deSDag-Erling Smørgrav 	struct ssh *ssh = active_state;		/* XXX */
485bc5531deSDag-Erling Smørgrav 	struct sshbuf *m;
486bc5531deSDag-Erling Smørgrav 	int r;
487545d5ecaSDag-Erling Smørgrav 
488bc5531deSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
489bc5531deSDag-Erling Smørgrav 		fatal("%s: sshbuf_new failed", __func__);
490bc5531deSDag-Erling Smørgrav 	if ((r = ssh_packet_get_state(ssh, m)) != 0)
491bc5531deSDag-Erling Smørgrav 		fatal("%s: get_state failed: %s",
492bc5531deSDag-Erling Smørgrav 		    __func__, ssh_err(r));
493bc5531deSDag-Erling Smørgrav 	mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, m);
494545d5ecaSDag-Erling Smørgrav 	debug3("%s: Finished sending state", __func__);
495bc5531deSDag-Erling Smørgrav 	sshbuf_free(m);
496545d5ecaSDag-Erling Smørgrav }
497545d5ecaSDag-Erling Smørgrav 
498545d5ecaSDag-Erling Smørgrav int
499333ee039SDag-Erling Smørgrav mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen)
500545d5ecaSDag-Erling Smørgrav {
501545d5ecaSDag-Erling Smørgrav 	Buffer m;
50221e764dfSDag-Erling Smørgrav 	char *p, *msg;
503d4af9e69SDag-Erling Smørgrav 	int success = 0, tmp1 = -1, tmp2 = -1;
504d4af9e69SDag-Erling Smørgrav 
505d4af9e69SDag-Erling Smørgrav 	/* Kludge: ensure there are fds free to receive the pty/tty */
506d4af9e69SDag-Erling Smørgrav 	if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 ||
507d4af9e69SDag-Erling Smørgrav 	    (tmp2 = dup(pmonitor->m_recvfd)) == -1) {
508d4af9e69SDag-Erling Smørgrav 		error("%s: cannot allocate fds for pty", __func__);
509d4af9e69SDag-Erling Smørgrav 		if (tmp1 > 0)
510d4af9e69SDag-Erling Smørgrav 			close(tmp1);
511d4af9e69SDag-Erling Smørgrav 		if (tmp2 > 0)
512d4af9e69SDag-Erling Smørgrav 			close(tmp2);
513d4af9e69SDag-Erling Smørgrav 		return 0;
514d4af9e69SDag-Erling Smørgrav 	}
515d4af9e69SDag-Erling Smørgrav 	close(tmp1);
516d4af9e69SDag-Erling Smørgrav 	close(tmp2);
517545d5ecaSDag-Erling Smørgrav 
518545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
519545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, &m);
520545d5ecaSDag-Erling Smørgrav 
521545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PTY", __func__);
522545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PTY, &m);
523545d5ecaSDag-Erling Smørgrav 
524545d5ecaSDag-Erling Smørgrav 	success = buffer_get_int(&m);
525545d5ecaSDag-Erling Smørgrav 	if (success == 0) {
526545d5ecaSDag-Erling Smørgrav 		debug3("%s: pty alloc failed", __func__);
527545d5ecaSDag-Erling Smørgrav 		buffer_free(&m);
528545d5ecaSDag-Erling Smørgrav 		return (0);
529545d5ecaSDag-Erling Smørgrav 	}
530545d5ecaSDag-Erling Smørgrav 	p = buffer_get_string(&m, NULL);
53121e764dfSDag-Erling Smørgrav 	msg = buffer_get_string(&m, NULL);
532545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
533545d5ecaSDag-Erling Smørgrav 
534545d5ecaSDag-Erling Smørgrav 	strlcpy(namebuf, p, namebuflen); /* Possible truncation */
535e4a9863fSDag-Erling Smørgrav 	free(p);
536545d5ecaSDag-Erling Smørgrav 
53721e764dfSDag-Erling Smørgrav 	buffer_append(&loginmsg, msg, strlen(msg));
538e4a9863fSDag-Erling Smørgrav 	free(msg);
53921e764dfSDag-Erling Smørgrav 
540d4af9e69SDag-Erling Smørgrav 	if ((*ptyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1 ||
541d4af9e69SDag-Erling Smørgrav 	    (*ttyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1)
542d4af9e69SDag-Erling Smørgrav 		fatal("%s: receive fds failed", __func__);
543545d5ecaSDag-Erling Smørgrav 
544545d5ecaSDag-Erling Smørgrav 	/* Success */
545545d5ecaSDag-Erling Smørgrav 	return (1);
546545d5ecaSDag-Erling Smørgrav }
547545d5ecaSDag-Erling Smørgrav 
548545d5ecaSDag-Erling Smørgrav void
5491ec0d754SDag-Erling Smørgrav mm_session_pty_cleanup2(Session *s)
550545d5ecaSDag-Erling Smørgrav {
551545d5ecaSDag-Erling Smørgrav 	Buffer m;
552545d5ecaSDag-Erling Smørgrav 
553545d5ecaSDag-Erling Smørgrav 	if (s->ttyfd == -1)
554545d5ecaSDag-Erling Smørgrav 		return;
555545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
556545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, s->tty);
557545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, &m);
558545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
559545d5ecaSDag-Erling Smørgrav 
560545d5ecaSDag-Erling Smørgrav 	/* closed dup'ed master */
561d4af9e69SDag-Erling Smørgrav 	if (s->ptymaster != -1 && close(s->ptymaster) < 0)
562d4af9e69SDag-Erling Smørgrav 		error("close(s->ptymaster/%d): %s",
563d4af9e69SDag-Erling Smørgrav 		    s->ptymaster, strerror(errno));
564545d5ecaSDag-Erling Smørgrav 
565545d5ecaSDag-Erling Smørgrav 	/* unlink pty from session */
566545d5ecaSDag-Erling Smørgrav 	s->ttyfd = -1;
567545d5ecaSDag-Erling Smørgrav }
568545d5ecaSDag-Erling Smørgrav 
56983d2307dSDag-Erling Smørgrav #ifdef USE_PAM
57083d2307dSDag-Erling Smørgrav void
5715962c0e9SDag-Erling Smørgrav mm_start_pam(Authctxt *authctxt)
57283d2307dSDag-Erling Smørgrav {
57383d2307dSDag-Erling Smørgrav 	Buffer m;
57483d2307dSDag-Erling Smørgrav 
57583d2307dSDag-Erling Smørgrav 	debug3("%s entering", __func__);
576cf2b5f3bSDag-Erling Smørgrav 	if (!options.use_pam)
577cf2b5f3bSDag-Erling Smørgrav 		fatal("UsePAM=no, but ended up in %s anyway", __func__);
57883d2307dSDag-Erling Smørgrav 
57983d2307dSDag-Erling Smørgrav 	buffer_init(&m);
58083d2307dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_START, &m);
58183d2307dSDag-Erling Smørgrav 
58283d2307dSDag-Erling Smørgrav 	buffer_free(&m);
58383d2307dSDag-Erling Smørgrav }
584382d19eeSDag-Erling Smørgrav 
585cf2b5f3bSDag-Erling Smørgrav u_int
586cf2b5f3bSDag-Erling Smørgrav mm_do_pam_account(void)
587cf2b5f3bSDag-Erling Smørgrav {
588cf2b5f3bSDag-Erling Smørgrav 	Buffer m;
589cf2b5f3bSDag-Erling Smørgrav 	u_int ret;
590aa49c926SDag-Erling Smørgrav 	char *msg;
591cf2b5f3bSDag-Erling Smørgrav 
592cf2b5f3bSDag-Erling Smørgrav 	debug3("%s entering", __func__);
593cf2b5f3bSDag-Erling Smørgrav 	if (!options.use_pam)
594cf2b5f3bSDag-Erling Smørgrav 		fatal("UsePAM=no, but ended up in %s anyway", __func__);
595cf2b5f3bSDag-Erling Smørgrav 
596cf2b5f3bSDag-Erling Smørgrav 	buffer_init(&m);
597cf2b5f3bSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, &m);
598cf2b5f3bSDag-Erling Smørgrav 
599cf2b5f3bSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
600cf2b5f3bSDag-Erling Smørgrav 	    MONITOR_ANS_PAM_ACCOUNT, &m);
601cf2b5f3bSDag-Erling Smørgrav 	ret = buffer_get_int(&m);
602aa49c926SDag-Erling Smørgrav 	msg = buffer_get_string(&m, NULL);
603aa49c926SDag-Erling Smørgrav 	buffer_append(&loginmsg, msg, strlen(msg));
604e4a9863fSDag-Erling Smørgrav 	free(msg);
605cf2b5f3bSDag-Erling Smørgrav 
606cf2b5f3bSDag-Erling Smørgrav 	buffer_free(&m);
607cf2b5f3bSDag-Erling Smørgrav 
608cf2b5f3bSDag-Erling Smørgrav 	debug3("%s returning %d", __func__, ret);
609cf2b5f3bSDag-Erling Smørgrav 
610cf2b5f3bSDag-Erling Smørgrav 	return (ret);
611cf2b5f3bSDag-Erling Smørgrav }
612cf2b5f3bSDag-Erling Smørgrav 
613382d19eeSDag-Erling Smørgrav void *
614cf2b5f3bSDag-Erling Smørgrav mm_sshpam_init_ctx(Authctxt *authctxt)
615382d19eeSDag-Erling Smørgrav {
616382d19eeSDag-Erling Smørgrav 	Buffer m;
617382d19eeSDag-Erling Smørgrav 	int success;
618382d19eeSDag-Erling Smørgrav 
619382d19eeSDag-Erling Smørgrav 	debug3("%s", __func__);
620382d19eeSDag-Erling Smørgrav 	buffer_init(&m);
621382d19eeSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_INIT_CTX, &m);
622382d19eeSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PAM_INIT_CTX", __func__);
623382d19eeSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_INIT_CTX, &m);
624382d19eeSDag-Erling Smørgrav 	success = buffer_get_int(&m);
625382d19eeSDag-Erling Smørgrav 	if (success == 0) {
626382d19eeSDag-Erling Smørgrav 		debug3("%s: pam_init_ctx failed", __func__);
627382d19eeSDag-Erling Smørgrav 		buffer_free(&m);
628382d19eeSDag-Erling Smørgrav 		return (NULL);
629382d19eeSDag-Erling Smørgrav 	}
630382d19eeSDag-Erling Smørgrav 	buffer_free(&m);
631382d19eeSDag-Erling Smørgrav 	return (authctxt);
632382d19eeSDag-Erling Smørgrav }
633382d19eeSDag-Erling Smørgrav 
634382d19eeSDag-Erling Smørgrav int
635cf2b5f3bSDag-Erling Smørgrav mm_sshpam_query(void *ctx, char **name, char **info,
636382d19eeSDag-Erling Smørgrav     u_int *num, char ***prompts, u_int **echo_on)
637382d19eeSDag-Erling Smørgrav {
638382d19eeSDag-Erling Smørgrav 	Buffer m;
639d4ecd108SDag-Erling Smørgrav 	u_int i;
640d4ecd108SDag-Erling Smørgrav 	int ret;
641382d19eeSDag-Erling Smørgrav 
642382d19eeSDag-Erling Smørgrav 	debug3("%s", __func__);
643382d19eeSDag-Erling Smørgrav 	buffer_init(&m);
644382d19eeSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_QUERY, &m);
645382d19eeSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PAM_QUERY", __func__);
646382d19eeSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_QUERY, &m);
647382d19eeSDag-Erling Smørgrav 	ret = buffer_get_int(&m);
648382d19eeSDag-Erling Smørgrav 	debug3("%s: pam_query returned %d", __func__, ret);
649382d19eeSDag-Erling Smørgrav 	*name = buffer_get_string(&m, NULL);
650382d19eeSDag-Erling Smørgrav 	*info = buffer_get_string(&m, NULL);
651076ad2f8SDag-Erling Smørgrav 	sshpam_set_maxtries_reached(buffer_get_int(&m));
652382d19eeSDag-Erling Smørgrav 	*num = buffer_get_int(&m);
653333ee039SDag-Erling Smørgrav 	if (*num > PAM_MAX_NUM_MSG)
654333ee039SDag-Erling Smørgrav 		fatal("%s: recieved %u PAM messages, expected <= %u",
655333ee039SDag-Erling Smørgrav 		    __func__, *num, PAM_MAX_NUM_MSG);
656333ee039SDag-Erling Smørgrav 	*prompts = xcalloc((*num + 1), sizeof(char *));
657333ee039SDag-Erling Smørgrav 	*echo_on = xcalloc((*num + 1), sizeof(u_int));
658382d19eeSDag-Erling Smørgrav 	for (i = 0; i < *num; ++i) {
659382d19eeSDag-Erling Smørgrav 		(*prompts)[i] = buffer_get_string(&m, NULL);
660382d19eeSDag-Erling Smørgrav 		(*echo_on)[i] = buffer_get_int(&m);
661382d19eeSDag-Erling Smørgrav 	}
662382d19eeSDag-Erling Smørgrav 	buffer_free(&m);
663382d19eeSDag-Erling Smørgrav 	return (ret);
664382d19eeSDag-Erling Smørgrav }
665382d19eeSDag-Erling Smørgrav 
666382d19eeSDag-Erling Smørgrav int
667cf2b5f3bSDag-Erling Smørgrav mm_sshpam_respond(void *ctx, u_int num, char **resp)
668382d19eeSDag-Erling Smørgrav {
669382d19eeSDag-Erling Smørgrav 	Buffer m;
670d4ecd108SDag-Erling Smørgrav 	u_int i;
671d4ecd108SDag-Erling Smørgrav 	int ret;
672382d19eeSDag-Erling Smørgrav 
673382d19eeSDag-Erling Smørgrav 	debug3("%s", __func__);
674382d19eeSDag-Erling Smørgrav 	buffer_init(&m);
675382d19eeSDag-Erling Smørgrav 	buffer_put_int(&m, num);
676382d19eeSDag-Erling Smørgrav 	for (i = 0; i < num; ++i)
677382d19eeSDag-Erling Smørgrav 		buffer_put_cstring(&m, resp[i]);
678382d19eeSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_RESPOND, &m);
679382d19eeSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__);
680382d19eeSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_RESPOND, &m);
681382d19eeSDag-Erling Smørgrav 	ret = buffer_get_int(&m);
682382d19eeSDag-Erling Smørgrav 	debug3("%s: pam_respond returned %d", __func__, ret);
683382d19eeSDag-Erling Smørgrav 	buffer_free(&m);
684382d19eeSDag-Erling Smørgrav 	return (ret);
685382d19eeSDag-Erling Smørgrav }
686382d19eeSDag-Erling Smørgrav 
687382d19eeSDag-Erling Smørgrav void
688cf2b5f3bSDag-Erling Smørgrav mm_sshpam_free_ctx(void *ctxtp)
689382d19eeSDag-Erling Smørgrav {
690382d19eeSDag-Erling Smørgrav 	Buffer m;
691382d19eeSDag-Erling Smørgrav 
692382d19eeSDag-Erling Smørgrav 	debug3("%s", __func__);
693382d19eeSDag-Erling Smørgrav 	buffer_init(&m);
694382d19eeSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_FREE_CTX, &m);
695382d19eeSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PAM_FREE_CTX", __func__);
696382d19eeSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_FREE_CTX, &m);
697382d19eeSDag-Erling Smørgrav 	buffer_free(&m);
698382d19eeSDag-Erling Smørgrav }
69983d2307dSDag-Erling Smørgrav #endif /* USE_PAM */
70083d2307dSDag-Erling Smørgrav 
701545d5ecaSDag-Erling Smørgrav /* Request process termination */
702545d5ecaSDag-Erling Smørgrav 
703545d5ecaSDag-Erling Smørgrav void
704545d5ecaSDag-Erling Smørgrav mm_terminate(void)
705545d5ecaSDag-Erling Smørgrav {
706545d5ecaSDag-Erling Smørgrav 	Buffer m;
707545d5ecaSDag-Erling Smørgrav 
708545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
709545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_TERM, &m);
710545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
711545d5ecaSDag-Erling Smørgrav }
712545d5ecaSDag-Erling Smørgrav 
713545d5ecaSDag-Erling Smørgrav static void
714545d5ecaSDag-Erling Smørgrav mm_chall_setup(char **name, char **infotxt, u_int *numprompts,
715545d5ecaSDag-Erling Smørgrav     char ***prompts, u_int **echo_on)
716545d5ecaSDag-Erling Smørgrav {
717545d5ecaSDag-Erling Smørgrav 	*name = xstrdup("");
718545d5ecaSDag-Erling Smørgrav 	*infotxt = xstrdup("");
719545d5ecaSDag-Erling Smørgrav 	*numprompts = 1;
720333ee039SDag-Erling Smørgrav 	*prompts = xcalloc(*numprompts, sizeof(char *));
721333ee039SDag-Erling Smørgrav 	*echo_on = xcalloc(*numprompts, sizeof(u_int));
722545d5ecaSDag-Erling Smørgrav 	(*echo_on)[0] = 0;
723545d5ecaSDag-Erling Smørgrav }
724545d5ecaSDag-Erling Smørgrav 
725545d5ecaSDag-Erling Smørgrav int
726545d5ecaSDag-Erling Smørgrav mm_bsdauth_query(void *ctx, char **name, char **infotxt,
727545d5ecaSDag-Erling Smørgrav    u_int *numprompts, char ***prompts, u_int **echo_on)
728545d5ecaSDag-Erling Smørgrav {
729545d5ecaSDag-Erling Smørgrav 	Buffer m;
730e73e9afaSDag-Erling Smørgrav 	u_int success;
731545d5ecaSDag-Erling Smørgrav 	char *challenge;
732545d5ecaSDag-Erling Smørgrav 
733545d5ecaSDag-Erling Smørgrav 	debug3("%s: entering", __func__);
734545d5ecaSDag-Erling Smørgrav 
735545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
736545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHQUERY, &m);
737545d5ecaSDag-Erling Smørgrav 
738545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_BSDAUTHQUERY,
739545d5ecaSDag-Erling Smørgrav 	    &m);
740e73e9afaSDag-Erling Smørgrav 	success = buffer_get_int(&m);
741e73e9afaSDag-Erling Smørgrav 	if (success == 0) {
742545d5ecaSDag-Erling Smørgrav 		debug3("%s: no challenge", __func__);
743545d5ecaSDag-Erling Smørgrav 		buffer_free(&m);
744545d5ecaSDag-Erling Smørgrav 		return (-1);
745545d5ecaSDag-Erling Smørgrav 	}
746545d5ecaSDag-Erling Smørgrav 
747545d5ecaSDag-Erling Smørgrav 	/* Get the challenge, and format the response */
748545d5ecaSDag-Erling Smørgrav 	challenge  = buffer_get_string(&m, NULL);
749545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
750545d5ecaSDag-Erling Smørgrav 
751545d5ecaSDag-Erling Smørgrav 	mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
752545d5ecaSDag-Erling Smørgrav 	(*prompts)[0] = challenge;
753545d5ecaSDag-Erling Smørgrav 
754545d5ecaSDag-Erling Smørgrav 	debug3("%s: received challenge: %s", __func__, challenge);
755545d5ecaSDag-Erling Smørgrav 
756545d5ecaSDag-Erling Smørgrav 	return (0);
757545d5ecaSDag-Erling Smørgrav }
758545d5ecaSDag-Erling Smørgrav 
759545d5ecaSDag-Erling Smørgrav int
760545d5ecaSDag-Erling Smørgrav mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses)
761545d5ecaSDag-Erling Smørgrav {
762545d5ecaSDag-Erling Smørgrav 	Buffer m;
763545d5ecaSDag-Erling Smørgrav 	int authok;
764545d5ecaSDag-Erling Smørgrav 
765545d5ecaSDag-Erling Smørgrav 	debug3("%s: entering", __func__);
766545d5ecaSDag-Erling Smørgrav 	if (numresponses != 1)
767545d5ecaSDag-Erling Smørgrav 		return (-1);
768545d5ecaSDag-Erling Smørgrav 
769545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
770545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, responses[0]);
771545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHRESPOND, &m);
772545d5ecaSDag-Erling Smørgrav 
773545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
774545d5ecaSDag-Erling Smørgrav 	    MONITOR_ANS_BSDAUTHRESPOND, &m);
775545d5ecaSDag-Erling Smørgrav 
776545d5ecaSDag-Erling Smørgrav 	authok = buffer_get_int(&m);
777545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
778545d5ecaSDag-Erling Smørgrav 
779545d5ecaSDag-Erling Smørgrav 	return ((authok == 0) ? -1 : 0);
780545d5ecaSDag-Erling Smørgrav }
781545d5ecaSDag-Erling Smørgrav 
782edb557f8SDag-Erling Smørgrav #ifdef SKEY
783545d5ecaSDag-Erling Smørgrav int
784545d5ecaSDag-Erling Smørgrav mm_skey_query(void *ctx, char **name, char **infotxt,
785545d5ecaSDag-Erling Smørgrav    u_int *numprompts, char ***prompts, u_int **echo_on)
786545d5ecaSDag-Erling Smørgrav {
787545d5ecaSDag-Erling Smørgrav 	Buffer m;
788e73e9afaSDag-Erling Smørgrav 	u_int success;
789333ee039SDag-Erling Smørgrav 	char *challenge;
790545d5ecaSDag-Erling Smørgrav 
791545d5ecaSDag-Erling Smørgrav 	debug3("%s: entering", __func__);
792545d5ecaSDag-Erling Smørgrav 
793545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
794545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYQUERY, &m);
795545d5ecaSDag-Erling Smørgrav 
796545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SKEYQUERY,
797545d5ecaSDag-Erling Smørgrav 	    &m);
798e73e9afaSDag-Erling Smørgrav 	success = buffer_get_int(&m);
799e73e9afaSDag-Erling Smørgrav 	if (success == 0) {
800545d5ecaSDag-Erling Smørgrav 		debug3("%s: no challenge", __func__);
801545d5ecaSDag-Erling Smørgrav 		buffer_free(&m);
802545d5ecaSDag-Erling Smørgrav 		return (-1);
803545d5ecaSDag-Erling Smørgrav 	}
804545d5ecaSDag-Erling Smørgrav 
805545d5ecaSDag-Erling Smørgrav 	/* Get the challenge, and format the response */
806545d5ecaSDag-Erling Smørgrav 	challenge  = buffer_get_string(&m, NULL);
807545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
808545d5ecaSDag-Erling Smørgrav 
809545d5ecaSDag-Erling Smørgrav 	debug3("%s: received challenge: %s", __func__, challenge);
810545d5ecaSDag-Erling Smørgrav 
811545d5ecaSDag-Erling Smørgrav 	mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
812545d5ecaSDag-Erling Smørgrav 
813333ee039SDag-Erling Smørgrav 	xasprintf(*prompts, "%s%s", challenge, SKEY_PROMPT);
814e4a9863fSDag-Erling Smørgrav 	free(challenge);
815545d5ecaSDag-Erling Smørgrav 
816545d5ecaSDag-Erling Smørgrav 	return (0);
817545d5ecaSDag-Erling Smørgrav }
818545d5ecaSDag-Erling Smørgrav 
819545d5ecaSDag-Erling Smørgrav int
820545d5ecaSDag-Erling Smørgrav mm_skey_respond(void *ctx, u_int numresponses, char **responses)
821545d5ecaSDag-Erling Smørgrav {
822545d5ecaSDag-Erling Smørgrav 	Buffer m;
823545d5ecaSDag-Erling Smørgrav 	int authok;
824545d5ecaSDag-Erling Smørgrav 
825545d5ecaSDag-Erling Smørgrav 	debug3("%s: entering", __func__);
826545d5ecaSDag-Erling Smørgrav 	if (numresponses != 1)
827545d5ecaSDag-Erling Smørgrav 		return (-1);
828545d5ecaSDag-Erling Smørgrav 
829545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
830545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, responses[0]);
831545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYRESPOND, &m);
832545d5ecaSDag-Erling Smørgrav 
833545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
834545d5ecaSDag-Erling Smørgrav 	    MONITOR_ANS_SKEYRESPOND, &m);
835545d5ecaSDag-Erling Smørgrav 
836545d5ecaSDag-Erling Smørgrav 	authok = buffer_get_int(&m);
837545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
838545d5ecaSDag-Erling Smørgrav 
839545d5ecaSDag-Erling Smørgrav 	return ((authok == 0) ? -1 : 0);
840545d5ecaSDag-Erling Smørgrav }
84121e764dfSDag-Erling Smørgrav #endif /* SKEY */
842545d5ecaSDag-Erling Smørgrav 
843aa49c926SDag-Erling Smørgrav #ifdef SSH_AUDIT_EVENTS
844aa49c926SDag-Erling Smørgrav void
845aa49c926SDag-Erling Smørgrav mm_audit_event(ssh_audit_event_t event)
846aa49c926SDag-Erling Smørgrav {
847aa49c926SDag-Erling Smørgrav 	Buffer m;
848aa49c926SDag-Erling Smørgrav 
849aa49c926SDag-Erling Smørgrav 	debug3("%s entering", __func__);
850aa49c926SDag-Erling Smørgrav 
851aa49c926SDag-Erling Smørgrav 	buffer_init(&m);
852aa49c926SDag-Erling Smørgrav 	buffer_put_int(&m, event);
853aa49c926SDag-Erling Smørgrav 
854aa49c926SDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_EVENT, &m);
855aa49c926SDag-Erling Smørgrav 	buffer_free(&m);
856aa49c926SDag-Erling Smørgrav }
857aa49c926SDag-Erling Smørgrav 
858aa49c926SDag-Erling Smørgrav void
859aa49c926SDag-Erling Smørgrav mm_audit_run_command(const char *command)
860aa49c926SDag-Erling Smørgrav {
861aa49c926SDag-Erling Smørgrav 	Buffer m;
862aa49c926SDag-Erling Smørgrav 
863aa49c926SDag-Erling Smørgrav 	debug3("%s entering command %s", __func__, command);
864aa49c926SDag-Erling Smørgrav 
865aa49c926SDag-Erling Smørgrav 	buffer_init(&m);
866aa49c926SDag-Erling Smørgrav 	buffer_put_cstring(&m, command);
867aa49c926SDag-Erling Smørgrav 
868aa49c926SDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m);
869aa49c926SDag-Erling Smørgrav 	buffer_free(&m);
870aa49c926SDag-Erling Smørgrav }
871aa49c926SDag-Erling Smørgrav #endif /* SSH_AUDIT_EVENTS */
872aa49c926SDag-Erling Smørgrav 
873cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI
874cf2b5f3bSDag-Erling Smørgrav OM_uint32
87521e764dfSDag-Erling Smørgrav mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid)
876f388f5efSDag-Erling Smørgrav {
877f388f5efSDag-Erling Smørgrav 	Buffer m;
878cf2b5f3bSDag-Erling Smørgrav 	OM_uint32 major;
879f388f5efSDag-Erling Smørgrav 
880cf2b5f3bSDag-Erling Smørgrav 	/* Client doesn't get to see the context */
881cf2b5f3bSDag-Erling Smørgrav 	*ctx = NULL;
882f388f5efSDag-Erling Smørgrav 
883f388f5efSDag-Erling Smørgrav 	buffer_init(&m);
88421e764dfSDag-Erling Smørgrav 	buffer_put_string(&m, goid->elements, goid->length);
885f388f5efSDag-Erling Smørgrav 
886cf2b5f3bSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, &m);
887cf2b5f3bSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, &m);
888f388f5efSDag-Erling Smørgrav 
889cf2b5f3bSDag-Erling Smørgrav 	major = buffer_get_int(&m);
890cf2b5f3bSDag-Erling Smørgrav 
891f388f5efSDag-Erling Smørgrav 	buffer_free(&m);
892cf2b5f3bSDag-Erling Smørgrav 	return (major);
893f388f5efSDag-Erling Smørgrav }
894f388f5efSDag-Erling Smørgrav 
895cf2b5f3bSDag-Erling Smørgrav OM_uint32
896cf2b5f3bSDag-Erling Smørgrav mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in,
897cf2b5f3bSDag-Erling Smørgrav     gss_buffer_desc *out, OM_uint32 *flags)
898f388f5efSDag-Erling Smørgrav {
899f388f5efSDag-Erling Smørgrav 	Buffer m;
900cf2b5f3bSDag-Erling Smørgrav 	OM_uint32 major;
901f388f5efSDag-Erling Smørgrav 	u_int len;
902f388f5efSDag-Erling Smørgrav 
903cf2b5f3bSDag-Erling Smørgrav 	buffer_init(&m);
904cf2b5f3bSDag-Erling Smørgrav 	buffer_put_string(&m, in->value, in->length);
905cf2b5f3bSDag-Erling Smørgrav 
906cf2b5f3bSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, &m);
907cf2b5f3bSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, &m);
908cf2b5f3bSDag-Erling Smørgrav 
909cf2b5f3bSDag-Erling Smørgrav 	major = buffer_get_int(&m);
910cf2b5f3bSDag-Erling Smørgrav 	out->value = buffer_get_string(&m, &len);
911cf2b5f3bSDag-Erling Smørgrav 	out->length = len;
912cf2b5f3bSDag-Erling Smørgrav 	if (flags)
913cf2b5f3bSDag-Erling Smørgrav 		*flags = buffer_get_int(&m);
914f388f5efSDag-Erling Smørgrav 
915f388f5efSDag-Erling Smørgrav 	buffer_free(&m);
916cf2b5f3bSDag-Erling Smørgrav 
917cf2b5f3bSDag-Erling Smørgrav 	return (major);
918f388f5efSDag-Erling Smørgrav }
919cf2b5f3bSDag-Erling Smørgrav 
9201ec0d754SDag-Erling Smørgrav OM_uint32
9211ec0d754SDag-Erling Smørgrav mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
9221ec0d754SDag-Erling Smørgrav {
9231ec0d754SDag-Erling Smørgrav 	Buffer m;
9241ec0d754SDag-Erling Smørgrav 	OM_uint32 major;
9251ec0d754SDag-Erling Smørgrav 
9261ec0d754SDag-Erling Smørgrav 	buffer_init(&m);
9271ec0d754SDag-Erling Smørgrav 	buffer_put_string(&m, gssbuf->value, gssbuf->length);
9281ec0d754SDag-Erling Smørgrav 	buffer_put_string(&m, gssmic->value, gssmic->length);
9291ec0d754SDag-Erling Smørgrav 
9301ec0d754SDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, &m);
9311ec0d754SDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSCHECKMIC,
9321ec0d754SDag-Erling Smørgrav 	    &m);
9331ec0d754SDag-Erling Smørgrav 
9341ec0d754SDag-Erling Smørgrav 	major = buffer_get_int(&m);
9351ec0d754SDag-Erling Smørgrav 	buffer_free(&m);
9361ec0d754SDag-Erling Smørgrav 	return(major);
9371ec0d754SDag-Erling Smørgrav }
9381ec0d754SDag-Erling Smørgrav 
939cf2b5f3bSDag-Erling Smørgrav int
940cf2b5f3bSDag-Erling Smørgrav mm_ssh_gssapi_userok(char *user)
941cf2b5f3bSDag-Erling Smørgrav {
942cf2b5f3bSDag-Erling Smørgrav 	Buffer m;
943cf2b5f3bSDag-Erling Smørgrav 	int authenticated = 0;
944cf2b5f3bSDag-Erling Smørgrav 
945cf2b5f3bSDag-Erling Smørgrav 	buffer_init(&m);
946cf2b5f3bSDag-Erling Smørgrav 
947cf2b5f3bSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m);
948cf2b5f3bSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK,
949cf2b5f3bSDag-Erling Smørgrav 				  &m);
950cf2b5f3bSDag-Erling Smørgrav 
951cf2b5f3bSDag-Erling Smørgrav 	authenticated = buffer_get_int(&m);
952cf2b5f3bSDag-Erling Smørgrav 
953cf2b5f3bSDag-Erling Smørgrav 	buffer_free(&m);
954cf2b5f3bSDag-Erling Smørgrav 	debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not ");
955cf2b5f3bSDag-Erling Smørgrav 	return (authenticated);
956cf2b5f3bSDag-Erling Smørgrav }
957cf2b5f3bSDag-Erling Smørgrav #endif /* GSSAPI */
958cce7d346SDag-Erling Smørgrav 
959