xref: /freebsd/crypto/openssh/monitor_wrap.c (revision bc5531debefeb54993d01d4f3c8b33ccbe0b4d95)
1*bc5531deSDag-Erling Smørgrav /* $OpenBSD: monitor_wrap.c,v 1.84 2015/02/16 22:13:32 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"
635962c0e9SDag-Erling Smørgrav #ifdef TARGET_OS_MAC    /* XXX Broken krb5 headers on Mac */
645962c0e9SDag-Erling Smørgrav #undef TARGET_OS_MAC
65545d5ecaSDag-Erling Smørgrav #include "zlib.h"
665962c0e9SDag-Erling Smørgrav #define TARGET_OS_MAC 1
675962c0e9SDag-Erling Smørgrav #else
685962c0e9SDag-Erling Smørgrav #include "zlib.h"
695962c0e9SDag-Erling Smørgrav #endif
70545d5ecaSDag-Erling Smørgrav #include "monitor.h"
71cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI
72cf2b5f3bSDag-Erling Smørgrav #include "ssh-gss.h"
73cf2b5f3bSDag-Erling Smørgrav #endif
74333ee039SDag-Erling Smørgrav #include "monitor_wrap.h"
75333ee039SDag-Erling Smørgrav #include "atomicio.h"
76333ee039SDag-Erling Smørgrav #include "monitor_fdpass.h"
77333ee039SDag-Erling Smørgrav #include "misc.h"
784a421b63SDag-Erling Smørgrav #include "uuencode.h"
79333ee039SDag-Erling Smørgrav 
80333ee039SDag-Erling Smørgrav #include "channels.h"
81333ee039SDag-Erling Smørgrav #include "session.h"
82d4af9e69SDag-Erling Smørgrav #include "servconf.h"
837aee6ffeSDag-Erling Smørgrav #include "roaming.h"
84cf2b5f3bSDag-Erling Smørgrav 
85*bc5531deSDag-Erling Smørgrav #include "ssherr.h"
86*bc5531deSDag-Erling Smørgrav 
87545d5ecaSDag-Erling Smørgrav /* Imports */
88545d5ecaSDag-Erling Smørgrav extern int compat20;
89545d5ecaSDag-Erling Smørgrav extern z_stream incoming_stream;
90545d5ecaSDag-Erling Smørgrav extern z_stream outgoing_stream;
91545d5ecaSDag-Erling Smørgrav extern struct monitor *pmonitor;
9221e764dfSDag-Erling Smørgrav extern Buffer loginmsg;
93cf2b5f3bSDag-Erling Smørgrav extern ServerOptions options;
94545d5ecaSDag-Erling Smørgrav 
95e146993eSDag-Erling Smørgrav void
96e146993eSDag-Erling Smørgrav mm_log_handler(LogLevel level, const char *msg, void *ctx)
97e146993eSDag-Erling Smørgrav {
98e146993eSDag-Erling Smørgrav 	Buffer log_msg;
99e146993eSDag-Erling Smørgrav 	struct monitor *mon = (struct monitor *)ctx;
100e146993eSDag-Erling Smørgrav 
101e146993eSDag-Erling Smørgrav 	if (mon->m_log_sendfd == -1)
102e146993eSDag-Erling Smørgrav 		fatal("%s: no log channel", __func__);
103e146993eSDag-Erling Smørgrav 
104e146993eSDag-Erling Smørgrav 	buffer_init(&log_msg);
105e146993eSDag-Erling Smørgrav 	/*
106e146993eSDag-Erling Smørgrav 	 * Placeholder for packet length. Will be filled in with the actual
107e146993eSDag-Erling Smørgrav 	 * packet length once the packet has been constucted. This saves
108e146993eSDag-Erling Smørgrav 	 * fragile math.
109e146993eSDag-Erling Smørgrav 	 */
110e146993eSDag-Erling Smørgrav 	buffer_put_int(&log_msg, 0);
111e146993eSDag-Erling Smørgrav 
112e146993eSDag-Erling Smørgrav 	buffer_put_int(&log_msg, level);
113e146993eSDag-Erling Smørgrav 	buffer_put_cstring(&log_msg, msg);
114e146993eSDag-Erling Smørgrav 	put_u32(buffer_ptr(&log_msg), buffer_len(&log_msg) - 4);
115e146993eSDag-Erling Smørgrav 	if (atomicio(vwrite, mon->m_log_sendfd, buffer_ptr(&log_msg),
116e146993eSDag-Erling Smørgrav 	    buffer_len(&log_msg)) != buffer_len(&log_msg))
117e146993eSDag-Erling Smørgrav 		fatal("%s: write: %s", __func__, strerror(errno));
118e146993eSDag-Erling Smørgrav 	buffer_free(&log_msg);
119e146993eSDag-Erling Smørgrav }
120e146993eSDag-Erling Smørgrav 
1211ec0d754SDag-Erling Smørgrav int
1221ec0d754SDag-Erling Smørgrav mm_is_monitor(void)
1231ec0d754SDag-Erling Smørgrav {
1241ec0d754SDag-Erling Smørgrav 	/*
1251ec0d754SDag-Erling Smørgrav 	 * m_pid is only set in the privileged part, and
1261ec0d754SDag-Erling Smørgrav 	 * points to the unprivileged child.
1271ec0d754SDag-Erling Smørgrav 	 */
1281ec0d754SDag-Erling Smørgrav 	return (pmonitor && pmonitor->m_pid > 0);
1291ec0d754SDag-Erling Smørgrav }
1301ec0d754SDag-Erling Smørgrav 
131545d5ecaSDag-Erling Smørgrav void
13221e764dfSDag-Erling Smørgrav mm_request_send(int sock, enum monitor_reqtype type, Buffer *m)
133545d5ecaSDag-Erling Smørgrav {
134545d5ecaSDag-Erling Smørgrav 	u_int mlen = buffer_len(m);
135f388f5efSDag-Erling Smørgrav 	u_char buf[5];
136545d5ecaSDag-Erling Smørgrav 
137545d5ecaSDag-Erling Smørgrav 	debug3("%s entering: type %d", __func__, type);
138545d5ecaSDag-Erling Smørgrav 
139333ee039SDag-Erling Smørgrav 	put_u32(buf, mlen + 1);
140545d5ecaSDag-Erling Smørgrav 	buf[4] = (u_char) type;		/* 1st byte of payload is mesg-type */
14121e764dfSDag-Erling Smørgrav 	if (atomicio(vwrite, sock, buf, sizeof(buf)) != sizeof(buf))
142d4ecd108SDag-Erling Smørgrav 		fatal("%s: write: %s", __func__, strerror(errno));
14321e764dfSDag-Erling Smørgrav 	if (atomicio(vwrite, sock, buffer_ptr(m), mlen) != mlen)
144d4ecd108SDag-Erling Smørgrav 		fatal("%s: write: %s", __func__, strerror(errno));
145545d5ecaSDag-Erling Smørgrav }
146545d5ecaSDag-Erling Smørgrav 
147545d5ecaSDag-Erling Smørgrav void
14821e764dfSDag-Erling Smørgrav mm_request_receive(int sock, Buffer *m)
149545d5ecaSDag-Erling Smørgrav {
150545d5ecaSDag-Erling Smørgrav 	u_char buf[4];
151545d5ecaSDag-Erling Smørgrav 	u_int msg_len;
152545d5ecaSDag-Erling Smørgrav 
153545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
154545d5ecaSDag-Erling Smørgrav 
155d4ecd108SDag-Erling Smørgrav 	if (atomicio(read, sock, buf, sizeof(buf)) != sizeof(buf)) {
156*bc5531deSDag-Erling Smørgrav 		if (errno == EPIPE) {
157*bc5531deSDag-Erling Smørgrav 			error("%s: socket closed", __func__);
1581ec0d754SDag-Erling Smørgrav 			cleanup_exit(255);
159*bc5531deSDag-Erling Smørgrav 		}
160d4ecd108SDag-Erling Smørgrav 		fatal("%s: read: %s", __func__, strerror(errno));
161545d5ecaSDag-Erling Smørgrav 	}
162333ee039SDag-Erling Smørgrav 	msg_len = get_u32(buf);
163545d5ecaSDag-Erling Smørgrav 	if (msg_len > 256 * 1024)
164545d5ecaSDag-Erling Smørgrav 		fatal("%s: read: bad msg_len %d", __func__, msg_len);
165545d5ecaSDag-Erling Smørgrav 	buffer_clear(m);
166545d5ecaSDag-Erling Smørgrav 	buffer_append_space(m, msg_len);
167d4ecd108SDag-Erling Smørgrav 	if (atomicio(read, sock, buffer_ptr(m), msg_len) != msg_len)
168d4ecd108SDag-Erling Smørgrav 		fatal("%s: read: %s", __func__, strerror(errno));
169545d5ecaSDag-Erling Smørgrav }
170545d5ecaSDag-Erling Smørgrav 
171545d5ecaSDag-Erling Smørgrav void
17221e764dfSDag-Erling Smørgrav mm_request_receive_expect(int sock, enum monitor_reqtype type, Buffer *m)
173545d5ecaSDag-Erling Smørgrav {
174545d5ecaSDag-Erling Smørgrav 	u_char rtype;
175545d5ecaSDag-Erling Smørgrav 
176545d5ecaSDag-Erling Smørgrav 	debug3("%s entering: type %d", __func__, type);
177545d5ecaSDag-Erling Smørgrav 
17821e764dfSDag-Erling Smørgrav 	mm_request_receive(sock, m);
179545d5ecaSDag-Erling Smørgrav 	rtype = buffer_get_char(m);
180545d5ecaSDag-Erling Smørgrav 	if (rtype != type)
181545d5ecaSDag-Erling Smørgrav 		fatal("%s: read: rtype %d != type %d", __func__,
182545d5ecaSDag-Erling Smørgrav 		    rtype, type);
183545d5ecaSDag-Erling Smørgrav }
184545d5ecaSDag-Erling Smørgrav 
185a0ee8cc6SDag-Erling Smørgrav #ifdef WITH_OPENSSL
186545d5ecaSDag-Erling Smørgrav DH *
187545d5ecaSDag-Erling Smørgrav mm_choose_dh(int min, int nbits, int max)
188545d5ecaSDag-Erling Smørgrav {
189545d5ecaSDag-Erling Smørgrav 	BIGNUM *p, *g;
190545d5ecaSDag-Erling Smørgrav 	int success = 0;
191545d5ecaSDag-Erling Smørgrav 	Buffer m;
192545d5ecaSDag-Erling Smørgrav 
193545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
194545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&m, min);
195545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&m, nbits);
196545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&m, max);
197545d5ecaSDag-Erling Smørgrav 
198545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_MODULI, &m);
199545d5ecaSDag-Erling Smørgrav 
200545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_MODULI", __func__);
201545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_MODULI, &m);
202545d5ecaSDag-Erling Smørgrav 
203545d5ecaSDag-Erling Smørgrav 	success = buffer_get_char(&m);
204545d5ecaSDag-Erling Smørgrav 	if (success == 0)
205545d5ecaSDag-Erling Smørgrav 		fatal("%s: MONITOR_ANS_MODULI failed", __func__);
206545d5ecaSDag-Erling Smørgrav 
207545d5ecaSDag-Erling Smørgrav 	if ((p = BN_new()) == NULL)
208545d5ecaSDag-Erling Smørgrav 		fatal("%s: BN_new failed", __func__);
209545d5ecaSDag-Erling Smørgrav 	if ((g = BN_new()) == NULL)
210545d5ecaSDag-Erling Smørgrav 		fatal("%s: BN_new failed", __func__);
211545d5ecaSDag-Erling Smørgrav 	buffer_get_bignum2(&m, p);
212545d5ecaSDag-Erling Smørgrav 	buffer_get_bignum2(&m, g);
213545d5ecaSDag-Erling Smørgrav 
214545d5ecaSDag-Erling Smørgrav 	debug3("%s: remaining %d", __func__, buffer_len(&m));
215545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
216545d5ecaSDag-Erling Smørgrav 
217545d5ecaSDag-Erling Smørgrav 	return (dh_new_group(g, p));
218545d5ecaSDag-Erling Smørgrav }
219a0ee8cc6SDag-Erling Smørgrav #endif
220545d5ecaSDag-Erling Smørgrav 
221545d5ecaSDag-Erling Smørgrav int
222*bc5531deSDag-Erling Smørgrav mm_key_sign(Key *key, u_char **sigp, u_int *lenp,
223*bc5531deSDag-Erling Smørgrav     const u_char *data, u_int datalen)
224545d5ecaSDag-Erling Smørgrav {
225*bc5531deSDag-Erling Smørgrav 	struct kex *kex = *pmonitor->m_pkex;
226545d5ecaSDag-Erling Smørgrav 	Buffer m;
227545d5ecaSDag-Erling Smørgrav 
228545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
229545d5ecaSDag-Erling Smørgrav 
230545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
231*bc5531deSDag-Erling Smørgrav 	buffer_put_int(&m, kex->host_key_index(key, 0, active_state));
232545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, data, datalen);
233545d5ecaSDag-Erling Smørgrav 
234545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, &m);
235545d5ecaSDag-Erling Smørgrav 
236545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_SIGN", __func__);
237545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SIGN, &m);
238545d5ecaSDag-Erling Smørgrav 	*sigp  = buffer_get_string(&m, lenp);
239545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
240545d5ecaSDag-Erling Smørgrav 
241545d5ecaSDag-Erling Smørgrav 	return (0);
242545d5ecaSDag-Erling Smørgrav }
243545d5ecaSDag-Erling Smørgrav 
244545d5ecaSDag-Erling Smørgrav struct passwd *
24521e764dfSDag-Erling Smørgrav mm_getpwnamallow(const char *username)
246545d5ecaSDag-Erling Smørgrav {
247545d5ecaSDag-Erling Smørgrav 	Buffer m;
248545d5ecaSDag-Erling Smørgrav 	struct passwd *pw;
249e146993eSDag-Erling Smørgrav 	u_int len, i;
250d4af9e69SDag-Erling Smørgrav 	ServerOptions *newopts;
251545d5ecaSDag-Erling Smørgrav 
252545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
253545d5ecaSDag-Erling Smørgrav 
254545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
25521e764dfSDag-Erling Smørgrav 	buffer_put_cstring(&m, username);
256545d5ecaSDag-Erling Smørgrav 
257545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, &m);
258545d5ecaSDag-Erling Smørgrav 
259545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PWNAM", __func__);
260545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m);
261545d5ecaSDag-Erling Smørgrav 
262545d5ecaSDag-Erling Smørgrav 	if (buffer_get_char(&m) == 0) {
263d4af9e69SDag-Erling Smørgrav 		pw = NULL;
264d4af9e69SDag-Erling Smørgrav 		goto out;
265545d5ecaSDag-Erling Smørgrav 	}
266d4af9e69SDag-Erling Smørgrav 	pw = buffer_get_string(&m, &len);
267d4af9e69SDag-Erling Smørgrav 	if (len != sizeof(struct passwd))
268545d5ecaSDag-Erling Smørgrav 		fatal("%s: struct passwd size mismatch", __func__);
269545d5ecaSDag-Erling Smørgrav 	pw->pw_name = buffer_get_string(&m, NULL);
270545d5ecaSDag-Erling Smørgrav 	pw->pw_passwd = buffer_get_string(&m, NULL);
271e4a9863fSDag-Erling Smørgrav #ifdef HAVE_STRUCT_PASSWD_PW_GECOS
272545d5ecaSDag-Erling Smørgrav 	pw->pw_gecos = buffer_get_string(&m, NULL);
273e4a9863fSDag-Erling Smørgrav #endif
274e4a9863fSDag-Erling Smørgrav #ifdef HAVE_STRUCT_PASSWD_PW_CLASS
275545d5ecaSDag-Erling Smørgrav 	pw->pw_class = buffer_get_string(&m, NULL);
27683d2307dSDag-Erling Smørgrav #endif
277545d5ecaSDag-Erling Smørgrav 	pw->pw_dir = buffer_get_string(&m, NULL);
278545d5ecaSDag-Erling Smørgrav 	pw->pw_shell = buffer_get_string(&m, NULL);
279d4af9e69SDag-Erling Smørgrav 
280d4af9e69SDag-Erling Smørgrav out:
281d4af9e69SDag-Erling Smørgrav 	/* copy options block as a Match directive may have changed some */
282d4af9e69SDag-Erling Smørgrav 	newopts = buffer_get_string(&m, &len);
283d4af9e69SDag-Erling Smørgrav 	if (len != sizeof(*newopts))
284d4af9e69SDag-Erling Smørgrav 		fatal("%s: option block size mismatch", __func__);
285e146993eSDag-Erling Smørgrav 
286e146993eSDag-Erling Smørgrav #define M_CP_STROPT(x) do { \
287e146993eSDag-Erling Smørgrav 		if (newopts->x != NULL) \
288e146993eSDag-Erling Smørgrav 			newopts->x = buffer_get_string(&m, NULL); \
289e146993eSDag-Erling Smørgrav 	} while (0)
290e146993eSDag-Erling Smørgrav #define M_CP_STRARRAYOPT(x, nx) do { \
291e146993eSDag-Erling Smørgrav 		for (i = 0; i < newopts->nx; i++) \
292e146993eSDag-Erling Smørgrav 			newopts->x[i] = buffer_get_string(&m, NULL); \
293e146993eSDag-Erling Smørgrav 	} while (0)
294e146993eSDag-Erling Smørgrav 	/* See comment in servconf.h */
295e146993eSDag-Erling Smørgrav 	COPY_MATCH_STRING_OPTS();
296e146993eSDag-Erling Smørgrav #undef M_CP_STROPT
297e146993eSDag-Erling Smørgrav #undef M_CP_STRARRAYOPT
298e146993eSDag-Erling Smørgrav 
299d4af9e69SDag-Erling Smørgrav 	copy_set_server_options(&options, newopts, 1);
300e4a9863fSDag-Erling Smørgrav 	free(newopts);
301d4af9e69SDag-Erling Smørgrav 
302545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
303545d5ecaSDag-Erling Smørgrav 
304545d5ecaSDag-Erling Smørgrav 	return (pw);
305545d5ecaSDag-Erling Smørgrav }
306545d5ecaSDag-Erling Smørgrav 
3071ec0d754SDag-Erling Smørgrav char *
3081ec0d754SDag-Erling Smørgrav mm_auth2_read_banner(void)
309545d5ecaSDag-Erling Smørgrav {
310545d5ecaSDag-Erling Smørgrav 	Buffer m;
311545d5ecaSDag-Erling Smørgrav 	char *banner;
312545d5ecaSDag-Erling Smørgrav 
313545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
314545d5ecaSDag-Erling Smørgrav 
315545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
316545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, &m);
317545d5ecaSDag-Erling Smørgrav 	buffer_clear(&m);
318545d5ecaSDag-Erling Smørgrav 
3191ec0d754SDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
3201ec0d754SDag-Erling Smørgrav 	    MONITOR_ANS_AUTH2_READ_BANNER, &m);
321545d5ecaSDag-Erling Smørgrav 	banner = buffer_get_string(&m, NULL);
322545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
323545d5ecaSDag-Erling Smørgrav 
3241ec0d754SDag-Erling Smørgrav 	/* treat empty banner as missing banner */
3251ec0d754SDag-Erling Smørgrav 	if (strlen(banner) == 0) {
326e4a9863fSDag-Erling Smørgrav 		free(banner);
3271ec0d754SDag-Erling Smørgrav 		banner = NULL;
3281ec0d754SDag-Erling Smørgrav 	}
329545d5ecaSDag-Erling Smørgrav 	return (banner);
330545d5ecaSDag-Erling Smørgrav }
331545d5ecaSDag-Erling Smørgrav 
332545d5ecaSDag-Erling Smørgrav /* Inform the privileged process about service and style */
333545d5ecaSDag-Erling Smørgrav 
334545d5ecaSDag-Erling Smørgrav void
335545d5ecaSDag-Erling Smørgrav mm_inform_authserv(char *service, char *style)
336545d5ecaSDag-Erling Smørgrav {
337545d5ecaSDag-Erling Smørgrav 	Buffer m;
338545d5ecaSDag-Erling Smørgrav 
339545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
340545d5ecaSDag-Erling Smørgrav 
341545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
342545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, service);
343545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, style ? style : "");
344545d5ecaSDag-Erling Smørgrav 
345545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m);
346545d5ecaSDag-Erling Smørgrav 
347545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
348545d5ecaSDag-Erling Smørgrav }
349545d5ecaSDag-Erling Smørgrav 
350545d5ecaSDag-Erling Smørgrav /* Do the password authentication */
351545d5ecaSDag-Erling Smørgrav int
352545d5ecaSDag-Erling Smørgrav mm_auth_password(Authctxt *authctxt, char *password)
353545d5ecaSDag-Erling Smørgrav {
354545d5ecaSDag-Erling Smørgrav 	Buffer m;
355545d5ecaSDag-Erling Smørgrav 	int authenticated = 0;
356545d5ecaSDag-Erling Smørgrav 
357545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
358545d5ecaSDag-Erling Smørgrav 
359545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
360545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, password);
361545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, &m);
362545d5ecaSDag-Erling Smørgrav 
363545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_AUTHPASSWORD", __func__);
364545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTHPASSWORD, &m);
365545d5ecaSDag-Erling Smørgrav 
366545d5ecaSDag-Erling Smørgrav 	authenticated = buffer_get_int(&m);
367545d5ecaSDag-Erling Smørgrav 
368545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
369545d5ecaSDag-Erling Smørgrav 
370545d5ecaSDag-Erling Smørgrav 	debug3("%s: user %sauthenticated",
371545d5ecaSDag-Erling Smørgrav 	    __func__, authenticated ? "" : "not ");
372545d5ecaSDag-Erling Smørgrav 	return (authenticated);
373545d5ecaSDag-Erling Smørgrav }
374545d5ecaSDag-Erling Smørgrav 
375545d5ecaSDag-Erling Smørgrav int
376545d5ecaSDag-Erling Smørgrav mm_user_key_allowed(struct passwd *pw, Key *key)
377545d5ecaSDag-Erling Smørgrav {
378545d5ecaSDag-Erling Smørgrav 	return (mm_key_allowed(MM_USERKEY, NULL, NULL, key));
379545d5ecaSDag-Erling Smørgrav }
380545d5ecaSDag-Erling Smørgrav 
381545d5ecaSDag-Erling Smørgrav int
382545d5ecaSDag-Erling Smørgrav mm_hostbased_key_allowed(struct passwd *pw, char *user, char *host,
383545d5ecaSDag-Erling Smørgrav     Key *key)
384545d5ecaSDag-Erling Smørgrav {
385545d5ecaSDag-Erling Smørgrav 	return (mm_key_allowed(MM_HOSTKEY, user, host, key));
386545d5ecaSDag-Erling Smørgrav }
387545d5ecaSDag-Erling Smørgrav 
388545d5ecaSDag-Erling Smørgrav int
389545d5ecaSDag-Erling Smørgrav mm_auth_rhosts_rsa_key_allowed(struct passwd *pw, char *user,
390545d5ecaSDag-Erling Smørgrav     char *host, Key *key)
391545d5ecaSDag-Erling Smørgrav {
392545d5ecaSDag-Erling Smørgrav 	int ret;
393545d5ecaSDag-Erling Smørgrav 
394545d5ecaSDag-Erling Smørgrav 	key->type = KEY_RSA; /* XXX hack for key_to_blob */
395545d5ecaSDag-Erling Smørgrav 	ret = mm_key_allowed(MM_RSAHOSTKEY, user, host, key);
396545d5ecaSDag-Erling Smørgrav 	key->type = KEY_RSA1;
397545d5ecaSDag-Erling Smørgrav 	return (ret);
398545d5ecaSDag-Erling Smørgrav }
399545d5ecaSDag-Erling Smørgrav 
400545d5ecaSDag-Erling Smørgrav int
401545d5ecaSDag-Erling Smørgrav mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key)
402545d5ecaSDag-Erling Smørgrav {
403545d5ecaSDag-Erling Smørgrav 	Buffer m;
404545d5ecaSDag-Erling Smørgrav 	u_char *blob;
405545d5ecaSDag-Erling Smørgrav 	u_int len;
406e73e9afaSDag-Erling Smørgrav 	int allowed = 0, have_forced = 0;
407545d5ecaSDag-Erling Smørgrav 
408545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
409545d5ecaSDag-Erling Smørgrav 
410545d5ecaSDag-Erling Smørgrav 	/* Convert the key to a blob and the pass it over */
411545d5ecaSDag-Erling Smørgrav 	if (!key_to_blob(key, &blob, &len))
412545d5ecaSDag-Erling Smørgrav 		return (0);
413545d5ecaSDag-Erling Smørgrav 
414545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
415545d5ecaSDag-Erling Smørgrav 	buffer_put_int(&m, type);
416545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, user ? user : "");
417545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, host ? host : "");
418545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, blob, len);
419e4a9863fSDag-Erling Smørgrav 	free(blob);
420545d5ecaSDag-Erling Smørgrav 
421545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, &m);
422545d5ecaSDag-Erling Smørgrav 
423545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_KEYALLOWED", __func__);
424545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYALLOWED, &m);
425545d5ecaSDag-Erling Smørgrav 
426545d5ecaSDag-Erling Smørgrav 	allowed = buffer_get_int(&m);
427545d5ecaSDag-Erling Smørgrav 
428e73e9afaSDag-Erling Smørgrav 	/* fake forced command */
429e73e9afaSDag-Erling Smørgrav 	auth_clear_options();
430e73e9afaSDag-Erling Smørgrav 	have_forced = buffer_get_int(&m);
431e73e9afaSDag-Erling Smørgrav 	forced_command = have_forced ? xstrdup("true") : NULL;
432e73e9afaSDag-Erling Smørgrav 
433545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
434545d5ecaSDag-Erling Smørgrav 
435545d5ecaSDag-Erling Smørgrav 	return (allowed);
436545d5ecaSDag-Erling Smørgrav }
437545d5ecaSDag-Erling Smørgrav 
438545d5ecaSDag-Erling Smørgrav /*
439545d5ecaSDag-Erling Smørgrav  * This key verify needs to send the key type along, because the
440545d5ecaSDag-Erling Smørgrav  * privileged parent makes the decision if the key is allowed
441545d5ecaSDag-Erling Smørgrav  * for authentication.
442545d5ecaSDag-Erling Smørgrav  */
443545d5ecaSDag-Erling Smørgrav 
444545d5ecaSDag-Erling Smørgrav int
445545d5ecaSDag-Erling Smørgrav mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
446545d5ecaSDag-Erling Smørgrav {
447545d5ecaSDag-Erling Smørgrav 	Buffer m;
448545d5ecaSDag-Erling Smørgrav 	u_char *blob;
449545d5ecaSDag-Erling Smørgrav 	u_int len;
450545d5ecaSDag-Erling Smørgrav 	int verified = 0;
451545d5ecaSDag-Erling Smørgrav 
452545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
453545d5ecaSDag-Erling Smørgrav 
454545d5ecaSDag-Erling Smørgrav 	/* Convert the key to a blob and the pass it over */
455545d5ecaSDag-Erling Smørgrav 	if (!key_to_blob(key, &blob, &len))
456545d5ecaSDag-Erling Smørgrav 		return (0);
457545d5ecaSDag-Erling Smørgrav 
458545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
459545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, blob, len);
460545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, sig, siglen);
461545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, data, datalen);
462e4a9863fSDag-Erling Smørgrav 	free(blob);
463545d5ecaSDag-Erling Smørgrav 
464545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m);
465545d5ecaSDag-Erling Smørgrav 
466545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__);
467545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m);
468545d5ecaSDag-Erling Smørgrav 
469545d5ecaSDag-Erling Smørgrav 	verified = buffer_get_int(&m);
470545d5ecaSDag-Erling Smørgrav 
471545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
472545d5ecaSDag-Erling Smørgrav 
473545d5ecaSDag-Erling Smørgrav 	return (verified);
474545d5ecaSDag-Erling Smørgrav }
475545d5ecaSDag-Erling Smørgrav 
476545d5ecaSDag-Erling Smørgrav void
47721e764dfSDag-Erling Smørgrav mm_send_keystate(struct monitor *monitor)
478545d5ecaSDag-Erling Smørgrav {
479*bc5531deSDag-Erling Smørgrav 	struct ssh *ssh = active_state;		/* XXX */
480*bc5531deSDag-Erling Smørgrav 	struct sshbuf *m;
481*bc5531deSDag-Erling Smørgrav 	int r;
482545d5ecaSDag-Erling Smørgrav 
483*bc5531deSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
484*bc5531deSDag-Erling Smørgrav 		fatal("%s: sshbuf_new failed", __func__);
485*bc5531deSDag-Erling Smørgrav 	if ((r = ssh_packet_get_state(ssh, m)) != 0)
486*bc5531deSDag-Erling Smørgrav 		fatal("%s: get_state failed: %s",
487*bc5531deSDag-Erling Smørgrav 		    __func__, ssh_err(r));
488*bc5531deSDag-Erling Smørgrav 	mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, m);
489545d5ecaSDag-Erling Smørgrav 	debug3("%s: Finished sending state", __func__);
490*bc5531deSDag-Erling Smørgrav 	sshbuf_free(m);
491545d5ecaSDag-Erling Smørgrav }
492545d5ecaSDag-Erling Smørgrav 
493545d5ecaSDag-Erling Smørgrav int
494333ee039SDag-Erling Smørgrav mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen)
495545d5ecaSDag-Erling Smørgrav {
496545d5ecaSDag-Erling Smørgrav 	Buffer m;
49721e764dfSDag-Erling Smørgrav 	char *p, *msg;
498d4af9e69SDag-Erling Smørgrav 	int success = 0, tmp1 = -1, tmp2 = -1;
499d4af9e69SDag-Erling Smørgrav 
500d4af9e69SDag-Erling Smørgrav 	/* Kludge: ensure there are fds free to receive the pty/tty */
501d4af9e69SDag-Erling Smørgrav 	if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 ||
502d4af9e69SDag-Erling Smørgrav 	    (tmp2 = dup(pmonitor->m_recvfd)) == -1) {
503d4af9e69SDag-Erling Smørgrav 		error("%s: cannot allocate fds for pty", __func__);
504d4af9e69SDag-Erling Smørgrav 		if (tmp1 > 0)
505d4af9e69SDag-Erling Smørgrav 			close(tmp1);
506d4af9e69SDag-Erling Smørgrav 		if (tmp2 > 0)
507d4af9e69SDag-Erling Smørgrav 			close(tmp2);
508d4af9e69SDag-Erling Smørgrav 		return 0;
509d4af9e69SDag-Erling Smørgrav 	}
510d4af9e69SDag-Erling Smørgrav 	close(tmp1);
511d4af9e69SDag-Erling Smørgrav 	close(tmp2);
512545d5ecaSDag-Erling Smørgrav 
513545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
514545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, &m);
515545d5ecaSDag-Erling Smørgrav 
516545d5ecaSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PTY", __func__);
517545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PTY, &m);
518545d5ecaSDag-Erling Smørgrav 
519545d5ecaSDag-Erling Smørgrav 	success = buffer_get_int(&m);
520545d5ecaSDag-Erling Smørgrav 	if (success == 0) {
521545d5ecaSDag-Erling Smørgrav 		debug3("%s: pty alloc failed", __func__);
522545d5ecaSDag-Erling Smørgrav 		buffer_free(&m);
523545d5ecaSDag-Erling Smørgrav 		return (0);
524545d5ecaSDag-Erling Smørgrav 	}
525545d5ecaSDag-Erling Smørgrav 	p = buffer_get_string(&m, NULL);
52621e764dfSDag-Erling Smørgrav 	msg = buffer_get_string(&m, NULL);
527545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
528545d5ecaSDag-Erling Smørgrav 
529545d5ecaSDag-Erling Smørgrav 	strlcpy(namebuf, p, namebuflen); /* Possible truncation */
530e4a9863fSDag-Erling Smørgrav 	free(p);
531545d5ecaSDag-Erling Smørgrav 
53221e764dfSDag-Erling Smørgrav 	buffer_append(&loginmsg, msg, strlen(msg));
533e4a9863fSDag-Erling Smørgrav 	free(msg);
53421e764dfSDag-Erling Smørgrav 
535d4af9e69SDag-Erling Smørgrav 	if ((*ptyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1 ||
536d4af9e69SDag-Erling Smørgrav 	    (*ttyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1)
537d4af9e69SDag-Erling Smørgrav 		fatal("%s: receive fds failed", __func__);
538545d5ecaSDag-Erling Smørgrav 
539545d5ecaSDag-Erling Smørgrav 	/* Success */
540545d5ecaSDag-Erling Smørgrav 	return (1);
541545d5ecaSDag-Erling Smørgrav }
542545d5ecaSDag-Erling Smørgrav 
543545d5ecaSDag-Erling Smørgrav void
5441ec0d754SDag-Erling Smørgrav mm_session_pty_cleanup2(Session *s)
545545d5ecaSDag-Erling Smørgrav {
546545d5ecaSDag-Erling Smørgrav 	Buffer m;
547545d5ecaSDag-Erling Smørgrav 
548545d5ecaSDag-Erling Smørgrav 	if (s->ttyfd == -1)
549545d5ecaSDag-Erling Smørgrav 		return;
550545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
551545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, s->tty);
552545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, &m);
553545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
554545d5ecaSDag-Erling Smørgrav 
555545d5ecaSDag-Erling Smørgrav 	/* closed dup'ed master */
556d4af9e69SDag-Erling Smørgrav 	if (s->ptymaster != -1 && close(s->ptymaster) < 0)
557d4af9e69SDag-Erling Smørgrav 		error("close(s->ptymaster/%d): %s",
558d4af9e69SDag-Erling Smørgrav 		    s->ptymaster, strerror(errno));
559545d5ecaSDag-Erling Smørgrav 
560545d5ecaSDag-Erling Smørgrav 	/* unlink pty from session */
561545d5ecaSDag-Erling Smørgrav 	s->ttyfd = -1;
562545d5ecaSDag-Erling Smørgrav }
563545d5ecaSDag-Erling Smørgrav 
56483d2307dSDag-Erling Smørgrav #ifdef USE_PAM
56583d2307dSDag-Erling Smørgrav void
5665962c0e9SDag-Erling Smørgrav mm_start_pam(Authctxt *authctxt)
56783d2307dSDag-Erling Smørgrav {
56883d2307dSDag-Erling Smørgrav 	Buffer m;
56983d2307dSDag-Erling Smørgrav 
57083d2307dSDag-Erling Smørgrav 	debug3("%s entering", __func__);
571cf2b5f3bSDag-Erling Smørgrav 	if (!options.use_pam)
572cf2b5f3bSDag-Erling Smørgrav 		fatal("UsePAM=no, but ended up in %s anyway", __func__);
57383d2307dSDag-Erling Smørgrav 
57483d2307dSDag-Erling Smørgrav 	buffer_init(&m);
57583d2307dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_START, &m);
57683d2307dSDag-Erling Smørgrav 
57783d2307dSDag-Erling Smørgrav 	buffer_free(&m);
57883d2307dSDag-Erling Smørgrav }
579382d19eeSDag-Erling Smørgrav 
580cf2b5f3bSDag-Erling Smørgrav u_int
581cf2b5f3bSDag-Erling Smørgrav mm_do_pam_account(void)
582cf2b5f3bSDag-Erling Smørgrav {
583cf2b5f3bSDag-Erling Smørgrav 	Buffer m;
584cf2b5f3bSDag-Erling Smørgrav 	u_int ret;
585aa49c926SDag-Erling Smørgrav 	char *msg;
586cf2b5f3bSDag-Erling Smørgrav 
587cf2b5f3bSDag-Erling Smørgrav 	debug3("%s entering", __func__);
588cf2b5f3bSDag-Erling Smørgrav 	if (!options.use_pam)
589cf2b5f3bSDag-Erling Smørgrav 		fatal("UsePAM=no, but ended up in %s anyway", __func__);
590cf2b5f3bSDag-Erling Smørgrav 
591cf2b5f3bSDag-Erling Smørgrav 	buffer_init(&m);
592cf2b5f3bSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, &m);
593cf2b5f3bSDag-Erling Smørgrav 
594cf2b5f3bSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
595cf2b5f3bSDag-Erling Smørgrav 	    MONITOR_ANS_PAM_ACCOUNT, &m);
596cf2b5f3bSDag-Erling Smørgrav 	ret = buffer_get_int(&m);
597aa49c926SDag-Erling Smørgrav 	msg = buffer_get_string(&m, NULL);
598aa49c926SDag-Erling Smørgrav 	buffer_append(&loginmsg, msg, strlen(msg));
599e4a9863fSDag-Erling Smørgrav 	free(msg);
600cf2b5f3bSDag-Erling Smørgrav 
601cf2b5f3bSDag-Erling Smørgrav 	buffer_free(&m);
602cf2b5f3bSDag-Erling Smørgrav 
603cf2b5f3bSDag-Erling Smørgrav 	debug3("%s returning %d", __func__, ret);
604cf2b5f3bSDag-Erling Smørgrav 
605cf2b5f3bSDag-Erling Smørgrav 	return (ret);
606cf2b5f3bSDag-Erling Smørgrav }
607cf2b5f3bSDag-Erling Smørgrav 
608382d19eeSDag-Erling Smørgrav void *
609cf2b5f3bSDag-Erling Smørgrav mm_sshpam_init_ctx(Authctxt *authctxt)
610382d19eeSDag-Erling Smørgrav {
611382d19eeSDag-Erling Smørgrav 	Buffer m;
612382d19eeSDag-Erling Smørgrav 	int success;
613382d19eeSDag-Erling Smørgrav 
614382d19eeSDag-Erling Smørgrav 	debug3("%s", __func__);
615382d19eeSDag-Erling Smørgrav 	buffer_init(&m);
616382d19eeSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_INIT_CTX, &m);
617382d19eeSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PAM_INIT_CTX", __func__);
618382d19eeSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_INIT_CTX, &m);
619382d19eeSDag-Erling Smørgrav 	success = buffer_get_int(&m);
620382d19eeSDag-Erling Smørgrav 	if (success == 0) {
621382d19eeSDag-Erling Smørgrav 		debug3("%s: pam_init_ctx failed", __func__);
622382d19eeSDag-Erling Smørgrav 		buffer_free(&m);
623382d19eeSDag-Erling Smørgrav 		return (NULL);
624382d19eeSDag-Erling Smørgrav 	}
625382d19eeSDag-Erling Smørgrav 	buffer_free(&m);
626382d19eeSDag-Erling Smørgrav 	return (authctxt);
627382d19eeSDag-Erling Smørgrav }
628382d19eeSDag-Erling Smørgrav 
629382d19eeSDag-Erling Smørgrav int
630cf2b5f3bSDag-Erling Smørgrav mm_sshpam_query(void *ctx, char **name, char **info,
631382d19eeSDag-Erling Smørgrav     u_int *num, char ***prompts, u_int **echo_on)
632382d19eeSDag-Erling Smørgrav {
633382d19eeSDag-Erling Smørgrav 	Buffer m;
634d4ecd108SDag-Erling Smørgrav 	u_int i;
635d4ecd108SDag-Erling Smørgrav 	int ret;
636382d19eeSDag-Erling Smørgrav 
637382d19eeSDag-Erling Smørgrav 	debug3("%s", __func__);
638382d19eeSDag-Erling Smørgrav 	buffer_init(&m);
639382d19eeSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_QUERY, &m);
640382d19eeSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PAM_QUERY", __func__);
641382d19eeSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_QUERY, &m);
642382d19eeSDag-Erling Smørgrav 	ret = buffer_get_int(&m);
643382d19eeSDag-Erling Smørgrav 	debug3("%s: pam_query returned %d", __func__, ret);
644382d19eeSDag-Erling Smørgrav 	*name = buffer_get_string(&m, NULL);
645382d19eeSDag-Erling Smørgrav 	*info = buffer_get_string(&m, NULL);
646382d19eeSDag-Erling Smørgrav 	*num = buffer_get_int(&m);
647333ee039SDag-Erling Smørgrav 	if (*num > PAM_MAX_NUM_MSG)
648333ee039SDag-Erling Smørgrav 		fatal("%s: recieved %u PAM messages, expected <= %u",
649333ee039SDag-Erling Smørgrav 		    __func__, *num, PAM_MAX_NUM_MSG);
650333ee039SDag-Erling Smørgrav 	*prompts = xcalloc((*num + 1), sizeof(char *));
651333ee039SDag-Erling Smørgrav 	*echo_on = xcalloc((*num + 1), sizeof(u_int));
652382d19eeSDag-Erling Smørgrav 	for (i = 0; i < *num; ++i) {
653382d19eeSDag-Erling Smørgrav 		(*prompts)[i] = buffer_get_string(&m, NULL);
654382d19eeSDag-Erling Smørgrav 		(*echo_on)[i] = buffer_get_int(&m);
655382d19eeSDag-Erling Smørgrav 	}
656382d19eeSDag-Erling Smørgrav 	buffer_free(&m);
657382d19eeSDag-Erling Smørgrav 	return (ret);
658382d19eeSDag-Erling Smørgrav }
659382d19eeSDag-Erling Smørgrav 
660382d19eeSDag-Erling Smørgrav int
661cf2b5f3bSDag-Erling Smørgrav mm_sshpam_respond(void *ctx, u_int num, char **resp)
662382d19eeSDag-Erling Smørgrav {
663382d19eeSDag-Erling Smørgrav 	Buffer m;
664d4ecd108SDag-Erling Smørgrav 	u_int i;
665d4ecd108SDag-Erling Smørgrav 	int ret;
666382d19eeSDag-Erling Smørgrav 
667382d19eeSDag-Erling Smørgrav 	debug3("%s", __func__);
668382d19eeSDag-Erling Smørgrav 	buffer_init(&m);
669382d19eeSDag-Erling Smørgrav 	buffer_put_int(&m, num);
670382d19eeSDag-Erling Smørgrav 	for (i = 0; i < num; ++i)
671382d19eeSDag-Erling Smørgrav 		buffer_put_cstring(&m, resp[i]);
672382d19eeSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_RESPOND, &m);
673382d19eeSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__);
674382d19eeSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_RESPOND, &m);
675382d19eeSDag-Erling Smørgrav 	ret = buffer_get_int(&m);
676382d19eeSDag-Erling Smørgrav 	debug3("%s: pam_respond returned %d", __func__, ret);
677382d19eeSDag-Erling Smørgrav 	buffer_free(&m);
678382d19eeSDag-Erling Smørgrav 	return (ret);
679382d19eeSDag-Erling Smørgrav }
680382d19eeSDag-Erling Smørgrav 
681382d19eeSDag-Erling Smørgrav void
682cf2b5f3bSDag-Erling Smørgrav mm_sshpam_free_ctx(void *ctxtp)
683382d19eeSDag-Erling Smørgrav {
684382d19eeSDag-Erling Smørgrav 	Buffer m;
685382d19eeSDag-Erling Smørgrav 
686382d19eeSDag-Erling Smørgrav 	debug3("%s", __func__);
687382d19eeSDag-Erling Smørgrav 	buffer_init(&m);
688382d19eeSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_FREE_CTX, &m);
689382d19eeSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PAM_FREE_CTX", __func__);
690382d19eeSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_FREE_CTX, &m);
691382d19eeSDag-Erling Smørgrav 	buffer_free(&m);
692382d19eeSDag-Erling Smørgrav }
69383d2307dSDag-Erling Smørgrav #endif /* USE_PAM */
69483d2307dSDag-Erling Smørgrav 
695545d5ecaSDag-Erling Smørgrav /* Request process termination */
696545d5ecaSDag-Erling Smørgrav 
697545d5ecaSDag-Erling Smørgrav void
698545d5ecaSDag-Erling Smørgrav mm_terminate(void)
699545d5ecaSDag-Erling Smørgrav {
700545d5ecaSDag-Erling Smørgrav 	Buffer m;
701545d5ecaSDag-Erling Smørgrav 
702545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
703545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_TERM, &m);
704545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
705545d5ecaSDag-Erling Smørgrav }
706545d5ecaSDag-Erling Smørgrav 
707a0ee8cc6SDag-Erling Smørgrav #ifdef WITH_SSH1
708545d5ecaSDag-Erling Smørgrav int
709545d5ecaSDag-Erling Smørgrav mm_ssh1_session_key(BIGNUM *num)
710545d5ecaSDag-Erling Smørgrav {
711545d5ecaSDag-Erling Smørgrav 	int rsafail;
712545d5ecaSDag-Erling Smørgrav 	Buffer m;
713545d5ecaSDag-Erling Smørgrav 
714545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
715545d5ecaSDag-Erling Smørgrav 	buffer_put_bignum2(&m, num);
716545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSKEY, &m);
717545d5ecaSDag-Erling Smørgrav 
718545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SESSKEY, &m);
719545d5ecaSDag-Erling Smørgrav 
720545d5ecaSDag-Erling Smørgrav 	rsafail = buffer_get_int(&m);
721545d5ecaSDag-Erling Smørgrav 	buffer_get_bignum2(&m, num);
722545d5ecaSDag-Erling Smørgrav 
723545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
724545d5ecaSDag-Erling Smørgrav 
725545d5ecaSDag-Erling Smørgrav 	return (rsafail);
726545d5ecaSDag-Erling Smørgrav }
727a0ee8cc6SDag-Erling Smørgrav #endif
728545d5ecaSDag-Erling Smørgrav 
729545d5ecaSDag-Erling Smørgrav static void
730545d5ecaSDag-Erling Smørgrav mm_chall_setup(char **name, char **infotxt, u_int *numprompts,
731545d5ecaSDag-Erling Smørgrav     char ***prompts, u_int **echo_on)
732545d5ecaSDag-Erling Smørgrav {
733545d5ecaSDag-Erling Smørgrav 	*name = xstrdup("");
734545d5ecaSDag-Erling Smørgrav 	*infotxt = xstrdup("");
735545d5ecaSDag-Erling Smørgrav 	*numprompts = 1;
736333ee039SDag-Erling Smørgrav 	*prompts = xcalloc(*numprompts, sizeof(char *));
737333ee039SDag-Erling Smørgrav 	*echo_on = xcalloc(*numprompts, sizeof(u_int));
738545d5ecaSDag-Erling Smørgrav 	(*echo_on)[0] = 0;
739545d5ecaSDag-Erling Smørgrav }
740545d5ecaSDag-Erling Smørgrav 
741545d5ecaSDag-Erling Smørgrav int
742545d5ecaSDag-Erling Smørgrav mm_bsdauth_query(void *ctx, char **name, char **infotxt,
743545d5ecaSDag-Erling Smørgrav    u_int *numprompts, char ***prompts, u_int **echo_on)
744545d5ecaSDag-Erling Smørgrav {
745545d5ecaSDag-Erling Smørgrav 	Buffer m;
746e73e9afaSDag-Erling Smørgrav 	u_int success;
747545d5ecaSDag-Erling Smørgrav 	char *challenge;
748545d5ecaSDag-Erling Smørgrav 
749545d5ecaSDag-Erling Smørgrav 	debug3("%s: entering", __func__);
750545d5ecaSDag-Erling Smørgrav 
751545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
752545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHQUERY, &m);
753545d5ecaSDag-Erling Smørgrav 
754545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_BSDAUTHQUERY,
755545d5ecaSDag-Erling Smørgrav 	    &m);
756e73e9afaSDag-Erling Smørgrav 	success = buffer_get_int(&m);
757e73e9afaSDag-Erling Smørgrav 	if (success == 0) {
758545d5ecaSDag-Erling Smørgrav 		debug3("%s: no challenge", __func__);
759545d5ecaSDag-Erling Smørgrav 		buffer_free(&m);
760545d5ecaSDag-Erling Smørgrav 		return (-1);
761545d5ecaSDag-Erling Smørgrav 	}
762545d5ecaSDag-Erling Smørgrav 
763545d5ecaSDag-Erling Smørgrav 	/* Get the challenge, and format the response */
764545d5ecaSDag-Erling Smørgrav 	challenge  = buffer_get_string(&m, NULL);
765545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
766545d5ecaSDag-Erling Smørgrav 
767545d5ecaSDag-Erling Smørgrav 	mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
768545d5ecaSDag-Erling Smørgrav 	(*prompts)[0] = challenge;
769545d5ecaSDag-Erling Smørgrav 
770545d5ecaSDag-Erling Smørgrav 	debug3("%s: received challenge: %s", __func__, challenge);
771545d5ecaSDag-Erling Smørgrav 
772545d5ecaSDag-Erling Smørgrav 	return (0);
773545d5ecaSDag-Erling Smørgrav }
774545d5ecaSDag-Erling Smørgrav 
775545d5ecaSDag-Erling Smørgrav int
776545d5ecaSDag-Erling Smørgrav mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses)
777545d5ecaSDag-Erling Smørgrav {
778545d5ecaSDag-Erling Smørgrav 	Buffer m;
779545d5ecaSDag-Erling Smørgrav 	int authok;
780545d5ecaSDag-Erling Smørgrav 
781545d5ecaSDag-Erling Smørgrav 	debug3("%s: entering", __func__);
782545d5ecaSDag-Erling Smørgrav 	if (numresponses != 1)
783545d5ecaSDag-Erling Smørgrav 		return (-1);
784545d5ecaSDag-Erling Smørgrav 
785545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
786545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, responses[0]);
787545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHRESPOND, &m);
788545d5ecaSDag-Erling Smørgrav 
789545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
790545d5ecaSDag-Erling Smørgrav 	    MONITOR_ANS_BSDAUTHRESPOND, &m);
791545d5ecaSDag-Erling Smørgrav 
792545d5ecaSDag-Erling Smørgrav 	authok = buffer_get_int(&m);
793545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
794545d5ecaSDag-Erling Smørgrav 
795545d5ecaSDag-Erling Smørgrav 	return ((authok == 0) ? -1 : 0);
796545d5ecaSDag-Erling Smørgrav }
797545d5ecaSDag-Erling Smørgrav 
798edb557f8SDag-Erling Smørgrav #ifdef SKEY
799545d5ecaSDag-Erling Smørgrav int
800545d5ecaSDag-Erling Smørgrav mm_skey_query(void *ctx, char **name, char **infotxt,
801545d5ecaSDag-Erling Smørgrav    u_int *numprompts, char ***prompts, u_int **echo_on)
802545d5ecaSDag-Erling Smørgrav {
803545d5ecaSDag-Erling Smørgrav 	Buffer m;
804e73e9afaSDag-Erling Smørgrav 	u_int success;
805333ee039SDag-Erling Smørgrav 	char *challenge;
806545d5ecaSDag-Erling Smørgrav 
807545d5ecaSDag-Erling Smørgrav 	debug3("%s: entering", __func__);
808545d5ecaSDag-Erling Smørgrav 
809545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
810545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYQUERY, &m);
811545d5ecaSDag-Erling Smørgrav 
812545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SKEYQUERY,
813545d5ecaSDag-Erling Smørgrav 	    &m);
814e73e9afaSDag-Erling Smørgrav 	success = buffer_get_int(&m);
815e73e9afaSDag-Erling Smørgrav 	if (success == 0) {
816545d5ecaSDag-Erling Smørgrav 		debug3("%s: no challenge", __func__);
817545d5ecaSDag-Erling Smørgrav 		buffer_free(&m);
818545d5ecaSDag-Erling Smørgrav 		return (-1);
819545d5ecaSDag-Erling Smørgrav 	}
820545d5ecaSDag-Erling Smørgrav 
821545d5ecaSDag-Erling Smørgrav 	/* Get the challenge, and format the response */
822545d5ecaSDag-Erling Smørgrav 	challenge  = buffer_get_string(&m, NULL);
823545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
824545d5ecaSDag-Erling Smørgrav 
825545d5ecaSDag-Erling Smørgrav 	debug3("%s: received challenge: %s", __func__, challenge);
826545d5ecaSDag-Erling Smørgrav 
827545d5ecaSDag-Erling Smørgrav 	mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
828545d5ecaSDag-Erling Smørgrav 
829333ee039SDag-Erling Smørgrav 	xasprintf(*prompts, "%s%s", challenge, SKEY_PROMPT);
830e4a9863fSDag-Erling Smørgrav 	free(challenge);
831545d5ecaSDag-Erling Smørgrav 
832545d5ecaSDag-Erling Smørgrav 	return (0);
833545d5ecaSDag-Erling Smørgrav }
834545d5ecaSDag-Erling Smørgrav 
835545d5ecaSDag-Erling Smørgrav int
836545d5ecaSDag-Erling Smørgrav mm_skey_respond(void *ctx, u_int numresponses, char **responses)
837545d5ecaSDag-Erling Smørgrav {
838545d5ecaSDag-Erling Smørgrav 	Buffer m;
839545d5ecaSDag-Erling Smørgrav 	int authok;
840545d5ecaSDag-Erling Smørgrav 
841545d5ecaSDag-Erling Smørgrav 	debug3("%s: entering", __func__);
842545d5ecaSDag-Erling Smørgrav 	if (numresponses != 1)
843545d5ecaSDag-Erling Smørgrav 		return (-1);
844545d5ecaSDag-Erling Smørgrav 
845545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
846545d5ecaSDag-Erling Smørgrav 	buffer_put_cstring(&m, responses[0]);
847545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYRESPOND, &m);
848545d5ecaSDag-Erling Smørgrav 
849545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
850545d5ecaSDag-Erling Smørgrav 	    MONITOR_ANS_SKEYRESPOND, &m);
851545d5ecaSDag-Erling Smørgrav 
852545d5ecaSDag-Erling Smørgrav 	authok = buffer_get_int(&m);
853545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
854545d5ecaSDag-Erling Smørgrav 
855545d5ecaSDag-Erling Smørgrav 	return ((authok == 0) ? -1 : 0);
856545d5ecaSDag-Erling Smørgrav }
85721e764dfSDag-Erling Smørgrav #endif /* SKEY */
858545d5ecaSDag-Erling Smørgrav 
859545d5ecaSDag-Erling Smørgrav void
860545d5ecaSDag-Erling Smørgrav mm_ssh1_session_id(u_char session_id[16])
861545d5ecaSDag-Erling Smørgrav {
862545d5ecaSDag-Erling Smørgrav 	Buffer m;
863545d5ecaSDag-Erling Smørgrav 	int i;
864545d5ecaSDag-Erling Smørgrav 
865545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
866545d5ecaSDag-Erling Smørgrav 
867545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
868545d5ecaSDag-Erling Smørgrav 	for (i = 0; i < 16; i++)
869545d5ecaSDag-Erling Smørgrav 		buffer_put_char(&m, session_id[i]);
870545d5ecaSDag-Erling Smørgrav 
871545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSID, &m);
872545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
873545d5ecaSDag-Erling Smørgrav }
874545d5ecaSDag-Erling Smørgrav 
875a0ee8cc6SDag-Erling Smørgrav #ifdef WITH_SSH1
876545d5ecaSDag-Erling Smørgrav int
877545d5ecaSDag-Erling Smørgrav mm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
878545d5ecaSDag-Erling Smørgrav {
879545d5ecaSDag-Erling Smørgrav 	Buffer m;
880545d5ecaSDag-Erling Smørgrav 	Key *key;
881545d5ecaSDag-Erling Smørgrav 	u_char *blob;
882545d5ecaSDag-Erling Smørgrav 	u_int blen;
883e73e9afaSDag-Erling Smørgrav 	int allowed = 0, have_forced = 0;
884545d5ecaSDag-Erling Smørgrav 
885545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
886545d5ecaSDag-Erling Smørgrav 
887545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
888545d5ecaSDag-Erling Smørgrav 	buffer_put_bignum2(&m, client_n);
889545d5ecaSDag-Erling Smørgrav 
890545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSAKEYALLOWED, &m);
891545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSAKEYALLOWED, &m);
892545d5ecaSDag-Erling Smørgrav 
893545d5ecaSDag-Erling Smørgrav 	allowed = buffer_get_int(&m);
894545d5ecaSDag-Erling Smørgrav 
895e73e9afaSDag-Erling Smørgrav 	/* fake forced command */
896e73e9afaSDag-Erling Smørgrav 	auth_clear_options();
897e73e9afaSDag-Erling Smørgrav 	have_forced = buffer_get_int(&m);
898e73e9afaSDag-Erling Smørgrav 	forced_command = have_forced ? xstrdup("true") : NULL;
899e73e9afaSDag-Erling Smørgrav 
900545d5ecaSDag-Erling Smørgrav 	if (allowed && rkey != NULL) {
901545d5ecaSDag-Erling Smørgrav 		blob = buffer_get_string(&m, &blen);
902545d5ecaSDag-Erling Smørgrav 		if ((key = key_from_blob(blob, blen)) == NULL)
903545d5ecaSDag-Erling Smørgrav 			fatal("%s: key_from_blob failed", __func__);
904545d5ecaSDag-Erling Smørgrav 		*rkey = key;
905e4a9863fSDag-Erling Smørgrav 		free(blob);
906545d5ecaSDag-Erling Smørgrav 	}
907545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
908545d5ecaSDag-Erling Smørgrav 
909545d5ecaSDag-Erling Smørgrav 	return (allowed);
910545d5ecaSDag-Erling Smørgrav }
911545d5ecaSDag-Erling Smørgrav 
912545d5ecaSDag-Erling Smørgrav BIGNUM *
913545d5ecaSDag-Erling Smørgrav mm_auth_rsa_generate_challenge(Key *key)
914545d5ecaSDag-Erling Smørgrav {
915545d5ecaSDag-Erling Smørgrav 	Buffer m;
916545d5ecaSDag-Erling Smørgrav 	BIGNUM *challenge;
917545d5ecaSDag-Erling Smørgrav 	u_char *blob;
918545d5ecaSDag-Erling Smørgrav 	u_int blen;
919545d5ecaSDag-Erling Smørgrav 
920545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
921545d5ecaSDag-Erling Smørgrav 
922545d5ecaSDag-Erling Smørgrav 	if ((challenge = BN_new()) == NULL)
923545d5ecaSDag-Erling Smørgrav 		fatal("%s: BN_new failed", __func__);
924545d5ecaSDag-Erling Smørgrav 
925545d5ecaSDag-Erling Smørgrav 	key->type = KEY_RSA;    /* XXX cheat for key_to_blob */
926545d5ecaSDag-Erling Smørgrav 	if (key_to_blob(key, &blob, &blen) == 0)
927545d5ecaSDag-Erling Smørgrav 		fatal("%s: key_to_blob failed", __func__);
928545d5ecaSDag-Erling Smørgrav 	key->type = KEY_RSA1;
929545d5ecaSDag-Erling Smørgrav 
930545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
931545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, blob, blen);
932e4a9863fSDag-Erling Smørgrav 	free(blob);
933545d5ecaSDag-Erling Smørgrav 
934545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSACHALLENGE, &m);
935545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSACHALLENGE, &m);
936545d5ecaSDag-Erling Smørgrav 
937545d5ecaSDag-Erling Smørgrav 	buffer_get_bignum2(&m, challenge);
938545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
939545d5ecaSDag-Erling Smørgrav 
940545d5ecaSDag-Erling Smørgrav 	return (challenge);
941545d5ecaSDag-Erling Smørgrav }
942545d5ecaSDag-Erling Smørgrav 
943545d5ecaSDag-Erling Smørgrav int
944545d5ecaSDag-Erling Smørgrav mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16])
945545d5ecaSDag-Erling Smørgrav {
946545d5ecaSDag-Erling Smørgrav 	Buffer m;
947545d5ecaSDag-Erling Smørgrav 	u_char *blob;
948545d5ecaSDag-Erling Smørgrav 	u_int blen;
949545d5ecaSDag-Erling Smørgrav 	int success = 0;
950545d5ecaSDag-Erling Smørgrav 
951545d5ecaSDag-Erling Smørgrav 	debug3("%s entering", __func__);
952545d5ecaSDag-Erling Smørgrav 
953545d5ecaSDag-Erling Smørgrav 	key->type = KEY_RSA;    /* XXX cheat for key_to_blob */
954545d5ecaSDag-Erling Smørgrav 	if (key_to_blob(key, &blob, &blen) == 0)
955545d5ecaSDag-Erling Smørgrav 		fatal("%s: key_to_blob failed", __func__);
956545d5ecaSDag-Erling Smørgrav 	key->type = KEY_RSA1;
957545d5ecaSDag-Erling Smørgrav 
958545d5ecaSDag-Erling Smørgrav 	buffer_init(&m);
959545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, blob, blen);
960545d5ecaSDag-Erling Smørgrav 	buffer_put_string(&m, response, 16);
961e4a9863fSDag-Erling Smørgrav 	free(blob);
962545d5ecaSDag-Erling Smørgrav 
963545d5ecaSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSARESPONSE, &m);
964545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSARESPONSE, &m);
965545d5ecaSDag-Erling Smørgrav 
966545d5ecaSDag-Erling Smørgrav 	success = buffer_get_int(&m);
967545d5ecaSDag-Erling Smørgrav 	buffer_free(&m);
968545d5ecaSDag-Erling Smørgrav 
969545d5ecaSDag-Erling Smørgrav 	return (success);
970545d5ecaSDag-Erling Smørgrav }
971a0ee8cc6SDag-Erling Smørgrav #endif
972f388f5efSDag-Erling Smørgrav 
973aa49c926SDag-Erling Smørgrav #ifdef SSH_AUDIT_EVENTS
974aa49c926SDag-Erling Smørgrav void
975aa49c926SDag-Erling Smørgrav mm_audit_event(ssh_audit_event_t event)
976aa49c926SDag-Erling Smørgrav {
977aa49c926SDag-Erling Smørgrav 	Buffer m;
978aa49c926SDag-Erling Smørgrav 
979aa49c926SDag-Erling Smørgrav 	debug3("%s entering", __func__);
980aa49c926SDag-Erling Smørgrav 
981aa49c926SDag-Erling Smørgrav 	buffer_init(&m);
982aa49c926SDag-Erling Smørgrav 	buffer_put_int(&m, event);
983aa49c926SDag-Erling Smørgrav 
984aa49c926SDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_EVENT, &m);
985aa49c926SDag-Erling Smørgrav 	buffer_free(&m);
986aa49c926SDag-Erling Smørgrav }
987aa49c926SDag-Erling Smørgrav 
988aa49c926SDag-Erling Smørgrav void
989aa49c926SDag-Erling Smørgrav mm_audit_run_command(const char *command)
990aa49c926SDag-Erling Smørgrav {
991aa49c926SDag-Erling Smørgrav 	Buffer m;
992aa49c926SDag-Erling Smørgrav 
993aa49c926SDag-Erling Smørgrav 	debug3("%s entering command %s", __func__, command);
994aa49c926SDag-Erling Smørgrav 
995aa49c926SDag-Erling Smørgrav 	buffer_init(&m);
996aa49c926SDag-Erling Smørgrav 	buffer_put_cstring(&m, command);
997aa49c926SDag-Erling Smørgrav 
998aa49c926SDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m);
999aa49c926SDag-Erling Smørgrav 	buffer_free(&m);
1000aa49c926SDag-Erling Smørgrav }
1001aa49c926SDag-Erling Smørgrav #endif /* SSH_AUDIT_EVENTS */
1002aa49c926SDag-Erling Smørgrav 
1003cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI
1004cf2b5f3bSDag-Erling Smørgrav OM_uint32
100521e764dfSDag-Erling Smørgrav mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid)
1006f388f5efSDag-Erling Smørgrav {
1007f388f5efSDag-Erling Smørgrav 	Buffer m;
1008cf2b5f3bSDag-Erling Smørgrav 	OM_uint32 major;
1009f388f5efSDag-Erling Smørgrav 
1010cf2b5f3bSDag-Erling Smørgrav 	/* Client doesn't get to see the context */
1011cf2b5f3bSDag-Erling Smørgrav 	*ctx = NULL;
1012f388f5efSDag-Erling Smørgrav 
1013f388f5efSDag-Erling Smørgrav 	buffer_init(&m);
101421e764dfSDag-Erling Smørgrav 	buffer_put_string(&m, goid->elements, goid->length);
1015f388f5efSDag-Erling Smørgrav 
1016cf2b5f3bSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, &m);
1017cf2b5f3bSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, &m);
1018f388f5efSDag-Erling Smørgrav 
1019cf2b5f3bSDag-Erling Smørgrav 	major = buffer_get_int(&m);
1020cf2b5f3bSDag-Erling Smørgrav 
1021f388f5efSDag-Erling Smørgrav 	buffer_free(&m);
1022cf2b5f3bSDag-Erling Smørgrav 	return (major);
1023f388f5efSDag-Erling Smørgrav }
1024f388f5efSDag-Erling Smørgrav 
1025cf2b5f3bSDag-Erling Smørgrav OM_uint32
1026cf2b5f3bSDag-Erling Smørgrav mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in,
1027cf2b5f3bSDag-Erling Smørgrav     gss_buffer_desc *out, OM_uint32 *flags)
1028f388f5efSDag-Erling Smørgrav {
1029f388f5efSDag-Erling Smørgrav 	Buffer m;
1030cf2b5f3bSDag-Erling Smørgrav 	OM_uint32 major;
1031f388f5efSDag-Erling Smørgrav 	u_int len;
1032f388f5efSDag-Erling Smørgrav 
1033cf2b5f3bSDag-Erling Smørgrav 	buffer_init(&m);
1034cf2b5f3bSDag-Erling Smørgrav 	buffer_put_string(&m, in->value, in->length);
1035cf2b5f3bSDag-Erling Smørgrav 
1036cf2b5f3bSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, &m);
1037cf2b5f3bSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, &m);
1038cf2b5f3bSDag-Erling Smørgrav 
1039cf2b5f3bSDag-Erling Smørgrav 	major = buffer_get_int(&m);
1040cf2b5f3bSDag-Erling Smørgrav 	out->value = buffer_get_string(&m, &len);
1041cf2b5f3bSDag-Erling Smørgrav 	out->length = len;
1042cf2b5f3bSDag-Erling Smørgrav 	if (flags)
1043cf2b5f3bSDag-Erling Smørgrav 		*flags = buffer_get_int(&m);
1044f388f5efSDag-Erling Smørgrav 
1045f388f5efSDag-Erling Smørgrav 	buffer_free(&m);
1046cf2b5f3bSDag-Erling Smørgrav 
1047cf2b5f3bSDag-Erling Smørgrav 	return (major);
1048f388f5efSDag-Erling Smørgrav }
1049cf2b5f3bSDag-Erling Smørgrav 
10501ec0d754SDag-Erling Smørgrav OM_uint32
10511ec0d754SDag-Erling Smørgrav mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
10521ec0d754SDag-Erling Smørgrav {
10531ec0d754SDag-Erling Smørgrav 	Buffer m;
10541ec0d754SDag-Erling Smørgrav 	OM_uint32 major;
10551ec0d754SDag-Erling Smørgrav 
10561ec0d754SDag-Erling Smørgrav 	buffer_init(&m);
10571ec0d754SDag-Erling Smørgrav 	buffer_put_string(&m, gssbuf->value, gssbuf->length);
10581ec0d754SDag-Erling Smørgrav 	buffer_put_string(&m, gssmic->value, gssmic->length);
10591ec0d754SDag-Erling Smørgrav 
10601ec0d754SDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, &m);
10611ec0d754SDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSCHECKMIC,
10621ec0d754SDag-Erling Smørgrav 	    &m);
10631ec0d754SDag-Erling Smørgrav 
10641ec0d754SDag-Erling Smørgrav 	major = buffer_get_int(&m);
10651ec0d754SDag-Erling Smørgrav 	buffer_free(&m);
10661ec0d754SDag-Erling Smørgrav 	return(major);
10671ec0d754SDag-Erling Smørgrav }
10681ec0d754SDag-Erling Smørgrav 
1069cf2b5f3bSDag-Erling Smørgrav int
1070cf2b5f3bSDag-Erling Smørgrav mm_ssh_gssapi_userok(char *user)
1071cf2b5f3bSDag-Erling Smørgrav {
1072cf2b5f3bSDag-Erling Smørgrav 	Buffer m;
1073cf2b5f3bSDag-Erling Smørgrav 	int authenticated = 0;
1074cf2b5f3bSDag-Erling Smørgrav 
1075cf2b5f3bSDag-Erling Smørgrav 	buffer_init(&m);
1076cf2b5f3bSDag-Erling Smørgrav 
1077cf2b5f3bSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m);
1078cf2b5f3bSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK,
1079cf2b5f3bSDag-Erling Smørgrav 				  &m);
1080cf2b5f3bSDag-Erling Smørgrav 
1081cf2b5f3bSDag-Erling Smørgrav 	authenticated = buffer_get_int(&m);
1082cf2b5f3bSDag-Erling Smørgrav 
1083cf2b5f3bSDag-Erling Smørgrav 	buffer_free(&m);
1084cf2b5f3bSDag-Erling Smørgrav 	debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not ");
1085cf2b5f3bSDag-Erling Smørgrav 	return (authenticated);
1086cf2b5f3bSDag-Erling Smørgrav }
1087cf2b5f3bSDag-Erling Smørgrav #endif /* GSSAPI */
1088cce7d346SDag-Erling Smørgrav 
1089