xref: /freebsd/crypto/openssh/monitor_wrap.c (revision 069ac18495ad8fde2748bc94b0f80a50250bb01d)
1*069ac184SEd Maste /* $OpenBSD: monitor_wrap.c,v 1.129 2023/12/18 14:45:49 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
53190cef3dSDag-Erling Smørgrav #include "sshbuf.h"
54190cef3dSDag-Erling Smørgrav #include "sshkey.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"
64545d5ecaSDag-Erling Smørgrav #include "monitor.h"
65cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI
66cf2b5f3bSDag-Erling Smørgrav #include "ssh-gss.h"
67cf2b5f3bSDag-Erling Smørgrav #endif
68333ee039SDag-Erling Smørgrav #include "monitor_wrap.h"
69333ee039SDag-Erling Smørgrav #include "atomicio.h"
70333ee039SDag-Erling Smørgrav #include "monitor_fdpass.h"
71333ee039SDag-Erling Smørgrav #include "misc.h"
72333ee039SDag-Erling Smørgrav 
73333ee039SDag-Erling Smørgrav #include "channels.h"
74333ee039SDag-Erling Smørgrav #include "session.h"
75d4af9e69SDag-Erling Smørgrav #include "servconf.h"
76cf2b5f3bSDag-Erling Smørgrav 
77bc5531deSDag-Erling Smørgrav #include "ssherr.h"
78bc5531deSDag-Erling Smørgrav 
79545d5ecaSDag-Erling Smørgrav /* Imports */
80545d5ecaSDag-Erling Smørgrav extern struct monitor *pmonitor;
81190cef3dSDag-Erling Smørgrav extern struct sshbuf *loginmsg;
82cf2b5f3bSDag-Erling Smørgrav extern ServerOptions options;
83545d5ecaSDag-Erling Smørgrav 
84e146993eSDag-Erling Smørgrav void
8519261079SEd Maste mm_log_handler(LogLevel level, int forced, const char *msg, void *ctx)
86e146993eSDag-Erling Smørgrav {
87190cef3dSDag-Erling Smørgrav 	struct sshbuf *log_msg;
88e146993eSDag-Erling Smørgrav 	struct monitor *mon = (struct monitor *)ctx;
89190cef3dSDag-Erling Smørgrav 	int r;
90190cef3dSDag-Erling Smørgrav 	size_t len;
91e146993eSDag-Erling Smørgrav 
92e146993eSDag-Erling Smørgrav 	if (mon->m_log_sendfd == -1)
9319261079SEd Maste 		fatal_f("no log channel");
94e146993eSDag-Erling Smørgrav 
95190cef3dSDag-Erling Smørgrav 	if ((log_msg = sshbuf_new()) == NULL)
9619261079SEd Maste 		fatal_f("sshbuf_new failed");
97e146993eSDag-Erling Smørgrav 
98190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_put_u32(log_msg, 0)) != 0 || /* length; filled below */
99190cef3dSDag-Erling Smørgrav 	    (r = sshbuf_put_u32(log_msg, level)) != 0 ||
10019261079SEd Maste 	    (r = sshbuf_put_u32(log_msg, forced)) != 0 ||
101190cef3dSDag-Erling Smørgrav 	    (r = sshbuf_put_cstring(log_msg, msg)) != 0)
10219261079SEd Maste 		fatal_fr(r, "assemble");
103190cef3dSDag-Erling Smørgrav 	if ((len = sshbuf_len(log_msg)) < 4 || len > 0xffffffff)
10419261079SEd Maste 		fatal_f("bad length %zu", len);
105190cef3dSDag-Erling Smørgrav 	POKE_U32(sshbuf_mutable_ptr(log_msg), len - 4);
106190cef3dSDag-Erling Smørgrav 	if (atomicio(vwrite, mon->m_log_sendfd,
107190cef3dSDag-Erling Smørgrav 	    sshbuf_mutable_ptr(log_msg), len) != len)
10819261079SEd Maste 		fatal_f("write: %s", strerror(errno));
109190cef3dSDag-Erling Smørgrav 	sshbuf_free(log_msg);
110e146993eSDag-Erling Smørgrav }
111e146993eSDag-Erling Smørgrav 
1121ec0d754SDag-Erling Smørgrav int
1131ec0d754SDag-Erling Smørgrav mm_is_monitor(void)
1141ec0d754SDag-Erling Smørgrav {
1151ec0d754SDag-Erling Smørgrav 	/*
1161ec0d754SDag-Erling Smørgrav 	 * m_pid is only set in the privileged part, and
1171ec0d754SDag-Erling Smørgrav 	 * points to the unprivileged child.
1181ec0d754SDag-Erling Smørgrav 	 */
1191ec0d754SDag-Erling Smørgrav 	return (pmonitor && pmonitor->m_pid > 0);
1201ec0d754SDag-Erling Smørgrav }
1211ec0d754SDag-Erling Smørgrav 
122545d5ecaSDag-Erling Smørgrav void
123190cef3dSDag-Erling Smørgrav mm_request_send(int sock, enum monitor_reqtype type, struct sshbuf *m)
124545d5ecaSDag-Erling Smørgrav {
125190cef3dSDag-Erling Smørgrav 	size_t mlen = sshbuf_len(m);
126f388f5efSDag-Erling Smørgrav 	u_char buf[5];
127545d5ecaSDag-Erling Smørgrav 
12819261079SEd Maste 	debug3_f("entering, type %d", type);
129545d5ecaSDag-Erling Smørgrav 
130190cef3dSDag-Erling Smørgrav 	if (mlen >= 0xffffffff)
13119261079SEd Maste 		fatal_f("bad length %zu", mlen);
132190cef3dSDag-Erling Smørgrav 	POKE_U32(buf, mlen + 1);
133545d5ecaSDag-Erling Smørgrav 	buf[4] = (u_char) type;		/* 1st byte of payload is mesg-type */
13421e764dfSDag-Erling Smørgrav 	if (atomicio(vwrite, sock, buf, sizeof(buf)) != sizeof(buf))
13519261079SEd Maste 		fatal_f("write: %s", strerror(errno));
136190cef3dSDag-Erling Smørgrav 	if (atomicio(vwrite, sock, sshbuf_mutable_ptr(m), mlen) != mlen)
13719261079SEd Maste 		fatal_f("write: %s", strerror(errno));
138545d5ecaSDag-Erling Smørgrav }
139545d5ecaSDag-Erling Smørgrav 
140545d5ecaSDag-Erling Smørgrav void
141190cef3dSDag-Erling Smørgrav mm_request_receive(int sock, struct sshbuf *m)
142545d5ecaSDag-Erling Smørgrav {
143190cef3dSDag-Erling Smørgrav 	u_char buf[4], *p = NULL;
144545d5ecaSDag-Erling Smørgrav 	u_int msg_len;
145190cef3dSDag-Erling Smørgrav 	int r;
146545d5ecaSDag-Erling Smørgrav 
14719261079SEd Maste 	debug3_f("entering");
148545d5ecaSDag-Erling Smørgrav 
149d4ecd108SDag-Erling Smørgrav 	if (atomicio(read, sock, buf, sizeof(buf)) != sizeof(buf)) {
150557f75e5SDag-Erling Smørgrav 		if (errno == EPIPE)
1511ec0d754SDag-Erling Smørgrav 			cleanup_exit(255);
15219261079SEd Maste 		fatal_f("read: %s", strerror(errno));
153545d5ecaSDag-Erling Smørgrav 	}
154190cef3dSDag-Erling Smørgrav 	msg_len = PEEK_U32(buf);
155545d5ecaSDag-Erling Smørgrav 	if (msg_len > 256 * 1024)
15619261079SEd Maste 		fatal_f("read: bad msg_len %d", msg_len);
157190cef3dSDag-Erling Smørgrav 	sshbuf_reset(m);
158190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_reserve(m, msg_len, &p)) != 0)
15919261079SEd Maste 		fatal_fr(r, "reserve");
160190cef3dSDag-Erling Smørgrav 	if (atomicio(read, sock, p, msg_len) != msg_len)
16119261079SEd Maste 		fatal_f("read: %s", strerror(errno));
162545d5ecaSDag-Erling Smørgrav }
163545d5ecaSDag-Erling Smørgrav 
164545d5ecaSDag-Erling Smørgrav void
165190cef3dSDag-Erling Smørgrav mm_request_receive_expect(int sock, enum monitor_reqtype type, struct sshbuf *m)
166545d5ecaSDag-Erling Smørgrav {
167545d5ecaSDag-Erling Smørgrav 	u_char rtype;
168190cef3dSDag-Erling Smørgrav 	int r;
169545d5ecaSDag-Erling Smørgrav 
17019261079SEd Maste 	debug3_f("entering, type %d", type);
171545d5ecaSDag-Erling Smørgrav 
17221e764dfSDag-Erling Smørgrav 	mm_request_receive(sock, m);
173190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_get_u8(m, &rtype)) != 0)
17419261079SEd Maste 		fatal_fr(r, "parse");
175545d5ecaSDag-Erling Smørgrav 	if (rtype != type)
17619261079SEd Maste 		fatal_f("read: rtype %d != type %d", rtype, type);
177545d5ecaSDag-Erling Smørgrav }
178545d5ecaSDag-Erling Smørgrav 
179a0ee8cc6SDag-Erling Smørgrav #ifdef WITH_OPENSSL
180545d5ecaSDag-Erling Smørgrav DH *
181545d5ecaSDag-Erling Smørgrav mm_choose_dh(int min, int nbits, int max)
182545d5ecaSDag-Erling Smørgrav {
183545d5ecaSDag-Erling Smørgrav 	BIGNUM *p, *g;
184190cef3dSDag-Erling Smørgrav 	int r;
185190cef3dSDag-Erling Smørgrav 	u_char success = 0;
186190cef3dSDag-Erling Smørgrav 	struct sshbuf *m;
187545d5ecaSDag-Erling Smørgrav 
188190cef3dSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
18919261079SEd Maste 		fatal_f("sshbuf_new failed");
190190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_put_u32(m, min)) != 0 ||
191190cef3dSDag-Erling Smørgrav 	    (r = sshbuf_put_u32(m, nbits)) != 0 ||
192190cef3dSDag-Erling Smørgrav 	    (r = sshbuf_put_u32(m, max)) != 0)
19319261079SEd Maste 		fatal_fr(r, "assemble");
194545d5ecaSDag-Erling Smørgrav 
195190cef3dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_MODULI, m);
196545d5ecaSDag-Erling Smørgrav 
19719261079SEd Maste 	debug3_f("waiting for MONITOR_ANS_MODULI");
198190cef3dSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_MODULI, m);
199545d5ecaSDag-Erling Smørgrav 
200190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_get_u8(m, &success)) != 0)
20119261079SEd Maste 		fatal_fr(r, "parse success");
202545d5ecaSDag-Erling Smørgrav 	if (success == 0)
20319261079SEd Maste 		fatal_f("MONITOR_ANS_MODULI failed");
204545d5ecaSDag-Erling Smørgrav 
20519261079SEd Maste 	if ((r = sshbuf_get_bignum2(m, &p)) != 0 ||
20619261079SEd Maste 	    (r = sshbuf_get_bignum2(m, &g)) != 0)
20719261079SEd Maste 		fatal_fr(r, "parse group");
208545d5ecaSDag-Erling Smørgrav 
20919261079SEd Maste 	debug3_f("remaining %zu", sshbuf_len(m));
210190cef3dSDag-Erling Smørgrav 	sshbuf_free(m);
211545d5ecaSDag-Erling Smørgrav 
212545d5ecaSDag-Erling Smørgrav 	return (dh_new_group(g, p));
213545d5ecaSDag-Erling Smørgrav }
214a0ee8cc6SDag-Erling Smørgrav #endif
215545d5ecaSDag-Erling Smørgrav 
216545d5ecaSDag-Erling Smørgrav int
21719261079SEd Maste mm_sshkey_sign(struct ssh *ssh, struct sshkey *key, u_char **sigp, size_t *lenp,
21819261079SEd Maste     const u_char *data, size_t datalen, const char *hostkey_alg,
21919261079SEd Maste     const char *sk_provider, const char *sk_pin, u_int compat)
220545d5ecaSDag-Erling Smørgrav {
221bc5531deSDag-Erling Smørgrav 	struct kex *kex = *pmonitor->m_pkex;
222190cef3dSDag-Erling Smørgrav 	struct sshbuf *m;
22319261079SEd Maste 	u_int ndx = kex->host_key_index(key, 0, ssh);
224190cef3dSDag-Erling Smørgrav 	int r;
225545d5ecaSDag-Erling Smørgrav 
22619261079SEd Maste 	debug3_f("entering");
227190cef3dSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
22819261079SEd Maste 		fatal_f("sshbuf_new failed");
229190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_put_u32(m, ndx)) != 0 ||
230190cef3dSDag-Erling Smørgrav 	    (r = sshbuf_put_string(m, data, datalen)) != 0 ||
231190cef3dSDag-Erling Smørgrav 	    (r = sshbuf_put_cstring(m, hostkey_alg)) != 0 ||
232190cef3dSDag-Erling Smørgrav 	    (r = sshbuf_put_u32(m, compat)) != 0)
23319261079SEd Maste 		fatal_fr(r, "assemble");
234545d5ecaSDag-Erling Smørgrav 
235190cef3dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, m);
236545d5ecaSDag-Erling Smørgrav 
23719261079SEd Maste 	debug3_f("waiting for MONITOR_ANS_SIGN");
238190cef3dSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SIGN, m);
239190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_get_string(m, sigp, lenp)) != 0)
24019261079SEd Maste 		fatal_fr(r, "parse");
241190cef3dSDag-Erling Smørgrav 	sshbuf_free(m);
242545d5ecaSDag-Erling Smørgrav 
243545d5ecaSDag-Erling Smørgrav 	return (0);
244545d5ecaSDag-Erling Smørgrav }
245545d5ecaSDag-Erling Smørgrav 
24619261079SEd Maste #define GETPW(b, id) \
24719261079SEd Maste 	do { \
24819261079SEd Maste 		if ((r = sshbuf_get_string_direct(b, &p, &len)) != 0) \
24919261079SEd Maste 			fatal_fr(r, "parse pw %s", #id); \
25019261079SEd Maste 		if (len != sizeof(pw->id)) \
25119261079SEd Maste 			fatal_fr(r, "bad length for %s", #id); \
25219261079SEd Maste 		memcpy(&pw->id, p, len); \
25319261079SEd Maste 	} while (0)
25419261079SEd Maste 
255545d5ecaSDag-Erling Smørgrav struct passwd *
25619261079SEd Maste mm_getpwnamallow(struct ssh *ssh, const char *username)
257545d5ecaSDag-Erling Smørgrav {
258190cef3dSDag-Erling Smørgrav 	struct sshbuf *m;
259545d5ecaSDag-Erling Smørgrav 	struct passwd *pw;
260190cef3dSDag-Erling Smørgrav 	size_t len;
261190cef3dSDag-Erling Smørgrav 	u_int i;
262d4af9e69SDag-Erling Smørgrav 	ServerOptions *newopts;
263190cef3dSDag-Erling Smørgrav 	int r;
264190cef3dSDag-Erling Smørgrav 	u_char ok;
265190cef3dSDag-Erling Smørgrav 	const u_char *p;
266545d5ecaSDag-Erling Smørgrav 
26719261079SEd Maste 	debug3_f("entering");
268545d5ecaSDag-Erling Smørgrav 
269190cef3dSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
27019261079SEd Maste 		fatal_f("sshbuf_new failed");
271190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_put_cstring(m, username)) != 0)
27219261079SEd Maste 		fatal_fr(r, "assemble");
273545d5ecaSDag-Erling Smørgrav 
274190cef3dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, m);
275545d5ecaSDag-Erling Smørgrav 
27619261079SEd Maste 	debug3_f("waiting for MONITOR_ANS_PWNAM");
277190cef3dSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, m);
278545d5ecaSDag-Erling Smørgrav 
279190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_get_u8(m, &ok)) != 0)
28019261079SEd Maste 		fatal_fr(r, "parse success");
281190cef3dSDag-Erling Smørgrav 	if (ok == 0) {
282d4af9e69SDag-Erling Smørgrav 		pw = NULL;
283d4af9e69SDag-Erling Smørgrav 		goto out;
284545d5ecaSDag-Erling Smørgrav 	}
285190cef3dSDag-Erling Smørgrav 
28627ceebbcSEd Maste 	/* XXX don't like passing struct passwd like this */
28727ceebbcSEd Maste 	pw = xcalloc(sizeof(*pw), 1);
28819261079SEd Maste 	GETPW(m, pw_uid);
28919261079SEd Maste 	GETPW(m, pw_gid);
29019261079SEd Maste #ifdef HAVE_STRUCT_PASSWD_PW_CHANGE
29119261079SEd Maste 	GETPW(m, pw_change);
29219261079SEd Maste #endif
29319261079SEd Maste #ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE
29419261079SEd Maste 	GETPW(m, pw_expire);
29519261079SEd Maste #endif
29627ceebbcSEd Maste 	if ((r = sshbuf_get_cstring(m, &pw->pw_name, NULL)) != 0 ||
29727ceebbcSEd Maste 	    (r = sshbuf_get_cstring(m, &pw->pw_passwd, NULL)) != 0 ||
29827ceebbcSEd Maste #ifdef HAVE_STRUCT_PASSWD_PW_GECOS
29927ceebbcSEd Maste 	    (r = sshbuf_get_cstring(m, &pw->pw_gecos, NULL)) != 0 ||
30027ceebbcSEd Maste #endif
30127ceebbcSEd Maste #ifdef HAVE_STRUCT_PASSWD_PW_CLASS
30227ceebbcSEd Maste 	    (r = sshbuf_get_cstring(m, &pw->pw_class, NULL)) != 0 ||
30327ceebbcSEd Maste #endif
30427ceebbcSEd Maste 	    (r = sshbuf_get_cstring(m, &pw->pw_dir, NULL)) != 0 ||
30527ceebbcSEd Maste 	    (r = sshbuf_get_cstring(m, &pw->pw_shell, NULL)) != 0)
30619261079SEd Maste 		fatal_fr(r, "parse pw");
307d4af9e69SDag-Erling Smørgrav 
308d4af9e69SDag-Erling Smørgrav out:
309d4af9e69SDag-Erling Smørgrav 	/* copy options block as a Match directive may have changed some */
310190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_get_string_direct(m, &p, &len)) != 0)
31119261079SEd Maste 		fatal_fr(r, "parse opts");
312d4af9e69SDag-Erling Smørgrav 	if (len != sizeof(*newopts))
31319261079SEd Maste 		fatal_f("option block size mismatch");
314190cef3dSDag-Erling Smørgrav 	newopts = xcalloc(sizeof(*newopts), 1);
315190cef3dSDag-Erling Smørgrav 	memcpy(newopts, p, sizeof(*newopts));
316e146993eSDag-Erling Smørgrav 
317e146993eSDag-Erling Smørgrav #define M_CP_STROPT(x) do { \
31819261079SEd Maste 		if (newopts->x != NULL && \
31919261079SEd Maste 		    (r = sshbuf_get_cstring(m, &newopts->x, NULL)) != 0) \
32019261079SEd Maste 			fatal_fr(r, "parse %s", #x); \
321e146993eSDag-Erling Smørgrav 	} while (0)
322e146993eSDag-Erling Smørgrav #define M_CP_STRARRAYOPT(x, nx) do { \
3234f52dfbbSDag-Erling Smørgrav 		newopts->x = newopts->nx == 0 ? \
3244f52dfbbSDag-Erling Smørgrav 		    NULL : xcalloc(newopts->nx, sizeof(*newopts->x)); \
325190cef3dSDag-Erling Smørgrav 		for (i = 0; i < newopts->nx; i++) { \
326190cef3dSDag-Erling Smørgrav 			if ((r = sshbuf_get_cstring(m, \
327190cef3dSDag-Erling Smørgrav 			    &newopts->x[i], NULL)) != 0) \
32819261079SEd Maste 				fatal_fr(r, "parse %s", #x); \
329190cef3dSDag-Erling Smørgrav 		} \
3304f52dfbbSDag-Erling Smørgrav 	} while (0)
331e146993eSDag-Erling Smørgrav 	/* See comment in servconf.h */
332e146993eSDag-Erling Smørgrav 	COPY_MATCH_STRING_OPTS();
333e146993eSDag-Erling Smørgrav #undef M_CP_STROPT
334e146993eSDag-Erling Smørgrav #undef M_CP_STRARRAYOPT
335e146993eSDag-Erling Smørgrav 
336d4af9e69SDag-Erling Smørgrav 	copy_set_server_options(&options, newopts, 1);
3374f52dfbbSDag-Erling Smørgrav 	log_change_level(options.log_level);
33819261079SEd Maste 	log_verbose_reset();
33919261079SEd Maste 	for (i = 0; i < options.num_log_verbose; i++)
34019261079SEd Maste 		log_verbose_add(options.log_verbose[i]);
3414f52dfbbSDag-Erling Smørgrav 	process_permitopen(ssh, &options);
342f374ba41SEd Maste 	process_channel_timeouts(ssh, &options);
343*069ac184SEd Maste 	kex_set_server_sig_algs(ssh, options.pubkey_accepted_algos);
344e4a9863fSDag-Erling Smørgrav 	free(newopts);
345190cef3dSDag-Erling Smørgrav 	sshbuf_free(m);
346545d5ecaSDag-Erling Smørgrav 
347545d5ecaSDag-Erling Smørgrav 	return (pw);
348545d5ecaSDag-Erling Smørgrav }
349545d5ecaSDag-Erling Smørgrav 
3501ec0d754SDag-Erling Smørgrav char *
3511ec0d754SDag-Erling Smørgrav mm_auth2_read_banner(void)
352545d5ecaSDag-Erling Smørgrav {
353190cef3dSDag-Erling Smørgrav 	struct sshbuf *m;
354545d5ecaSDag-Erling Smørgrav 	char *banner;
355190cef3dSDag-Erling Smørgrav 	int r;
356545d5ecaSDag-Erling Smørgrav 
35719261079SEd Maste 	debug3_f("entering");
358545d5ecaSDag-Erling Smørgrav 
359190cef3dSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
36019261079SEd Maste 		fatal_f("sshbuf_new failed");
361190cef3dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, m);
362190cef3dSDag-Erling Smørgrav 	sshbuf_reset(m);
363545d5ecaSDag-Erling Smørgrav 
3641ec0d754SDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
365190cef3dSDag-Erling Smørgrav 	    MONITOR_ANS_AUTH2_READ_BANNER, m);
366190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_get_cstring(m, &banner, NULL)) != 0)
36719261079SEd Maste 		fatal_fr(r, "parse");
368190cef3dSDag-Erling Smørgrav 	sshbuf_free(m);
369545d5ecaSDag-Erling Smørgrav 
3701ec0d754SDag-Erling Smørgrav 	/* treat empty banner as missing banner */
3711ec0d754SDag-Erling Smørgrav 	if (strlen(banner) == 0) {
372e4a9863fSDag-Erling Smørgrav 		free(banner);
3731ec0d754SDag-Erling Smørgrav 		banner = NULL;
3741ec0d754SDag-Erling Smørgrav 	}
375545d5ecaSDag-Erling Smørgrav 	return (banner);
376545d5ecaSDag-Erling Smørgrav }
377545d5ecaSDag-Erling Smørgrav 
378545d5ecaSDag-Erling Smørgrav /* Inform the privileged process about service and style */
379545d5ecaSDag-Erling Smørgrav 
380545d5ecaSDag-Erling Smørgrav void
381545d5ecaSDag-Erling Smørgrav mm_inform_authserv(char *service, char *style)
382545d5ecaSDag-Erling Smørgrav {
383190cef3dSDag-Erling Smørgrav 	struct sshbuf *m;
384190cef3dSDag-Erling Smørgrav 	int r;
385545d5ecaSDag-Erling Smørgrav 
38619261079SEd Maste 	debug3_f("entering");
387545d5ecaSDag-Erling Smørgrav 
388190cef3dSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
38919261079SEd Maste 		fatal_f("sshbuf_new failed");
390190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_put_cstring(m, service)) != 0 ||
391190cef3dSDag-Erling Smørgrav 	    (r = sshbuf_put_cstring(m, style ? style : "")) != 0)
39219261079SEd Maste 		fatal_fr(r, "assemble");
393545d5ecaSDag-Erling Smørgrav 
394190cef3dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, m);
395545d5ecaSDag-Erling Smørgrav 
396190cef3dSDag-Erling Smørgrav 	sshbuf_free(m);
397545d5ecaSDag-Erling Smørgrav }
398545d5ecaSDag-Erling Smørgrav 
399545d5ecaSDag-Erling Smørgrav /* Do the password authentication */
400545d5ecaSDag-Erling Smørgrav int
40147dd1d1bSDag-Erling Smørgrav mm_auth_password(struct ssh *ssh, char *password)
402545d5ecaSDag-Erling Smørgrav {
403190cef3dSDag-Erling Smørgrav 	struct sshbuf *m;
404190cef3dSDag-Erling Smørgrav 	int r, authenticated = 0;
405190cef3dSDag-Erling Smørgrav #ifdef USE_PAM
406190cef3dSDag-Erling Smørgrav 	u_int maxtries = 0;
407190cef3dSDag-Erling Smørgrav #endif
408545d5ecaSDag-Erling Smørgrav 
40919261079SEd Maste 	debug3_f("entering");
410545d5ecaSDag-Erling Smørgrav 
411190cef3dSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
41219261079SEd Maste 		fatal_f("sshbuf_new failed");
413190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_put_cstring(m, password)) != 0)
41419261079SEd Maste 		fatal_fr(r, "assemble");
415190cef3dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, m);
416545d5ecaSDag-Erling Smørgrav 
41719261079SEd Maste 	debug3_f("waiting for MONITOR_ANS_AUTHPASSWORD");
418190cef3dSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
419190cef3dSDag-Erling Smørgrav 	    MONITOR_ANS_AUTHPASSWORD, m);
420545d5ecaSDag-Erling Smørgrav 
421190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_get_u32(m, &authenticated)) != 0)
42219261079SEd Maste 		fatal_fr(r, "parse");
423076ad2f8SDag-Erling Smørgrav #ifdef USE_PAM
424190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_get_u32(m, &maxtries)) != 0)
42519261079SEd Maste 		fatal_fr(r, "parse PAM");
426190cef3dSDag-Erling Smørgrav 	if (maxtries > INT_MAX)
42719261079SEd Maste 		fatal_fr(r, "bad maxtries");
428190cef3dSDag-Erling Smørgrav 	sshpam_set_maxtries_reached(maxtries);
429076ad2f8SDag-Erling Smørgrav #endif
430545d5ecaSDag-Erling Smørgrav 
431190cef3dSDag-Erling Smørgrav 	sshbuf_free(m);
432545d5ecaSDag-Erling Smørgrav 
43319261079SEd Maste 	debug3_f("user %sauthenticated", authenticated ? "" : "not ");
434545d5ecaSDag-Erling Smørgrav 	return (authenticated);
435545d5ecaSDag-Erling Smørgrav }
436545d5ecaSDag-Erling Smørgrav 
437545d5ecaSDag-Erling Smørgrav int
43847dd1d1bSDag-Erling Smørgrav mm_user_key_allowed(struct ssh *ssh, struct passwd *pw, struct sshkey *key,
43947dd1d1bSDag-Erling Smørgrav     int pubkey_auth_attempt, struct sshauthopt **authoptp)
440545d5ecaSDag-Erling Smørgrav {
441557f75e5SDag-Erling Smørgrav 	return (mm_key_allowed(MM_USERKEY, NULL, NULL, key,
44247dd1d1bSDag-Erling Smørgrav 	    pubkey_auth_attempt, authoptp));
443545d5ecaSDag-Erling Smørgrav }
444545d5ecaSDag-Erling Smørgrav 
445545d5ecaSDag-Erling Smørgrav int
44619261079SEd Maste mm_hostbased_key_allowed(struct ssh *ssh, struct passwd *pw,
44719261079SEd Maste     const char *user, const char *host, struct sshkey *key)
448545d5ecaSDag-Erling Smørgrav {
44947dd1d1bSDag-Erling Smørgrav 	return (mm_key_allowed(MM_HOSTKEY, user, host, key, 0, NULL));
450545d5ecaSDag-Erling Smørgrav }
451545d5ecaSDag-Erling Smørgrav 
452545d5ecaSDag-Erling Smørgrav int
453076ad2f8SDag-Erling Smørgrav mm_key_allowed(enum mm_keytype type, const char *user, const char *host,
45447dd1d1bSDag-Erling Smørgrav     struct sshkey *key, int pubkey_auth_attempt, struct sshauthopt **authoptp)
455545d5ecaSDag-Erling Smørgrav {
456190cef3dSDag-Erling Smørgrav 	struct sshbuf *m;
45747dd1d1bSDag-Erling Smørgrav 	int r, allowed = 0;
45847dd1d1bSDag-Erling Smørgrav 	struct sshauthopt *opts = NULL;
459545d5ecaSDag-Erling Smørgrav 
46019261079SEd Maste 	debug3_f("entering");
461545d5ecaSDag-Erling Smørgrav 
46247dd1d1bSDag-Erling Smørgrav 	if (authoptp != NULL)
46347dd1d1bSDag-Erling Smørgrav 		*authoptp = NULL;
46447dd1d1bSDag-Erling Smørgrav 
465190cef3dSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
46619261079SEd Maste 		fatal_f("sshbuf_new failed");
467190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_put_u32(m, type)) != 0 ||
468190cef3dSDag-Erling Smørgrav 	    (r = sshbuf_put_cstring(m, user ? user : "")) != 0 ||
469190cef3dSDag-Erling Smørgrav 	    (r = sshbuf_put_cstring(m, host ? host : "")) != 0 ||
470190cef3dSDag-Erling Smørgrav 	    (r = sshkey_puts(key, m)) != 0 ||
471190cef3dSDag-Erling Smørgrav 	    (r = sshbuf_put_u32(m, pubkey_auth_attempt)) != 0)
47219261079SEd Maste 		fatal_fr(r, "assemble");
473545d5ecaSDag-Erling Smørgrav 
474190cef3dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, m);
475545d5ecaSDag-Erling Smørgrav 
47619261079SEd Maste 	debug3_f("waiting for MONITOR_ANS_KEYALLOWED");
47747dd1d1bSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
478190cef3dSDag-Erling Smørgrav 	    MONITOR_ANS_KEYALLOWED, m);
479545d5ecaSDag-Erling Smørgrav 
480190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_get_u32(m, &allowed)) != 0)
48119261079SEd Maste 		fatal_fr(r, "parse");
48219261079SEd Maste 	if (allowed && type == MM_USERKEY &&
48319261079SEd Maste 	    (r = sshauthopt_deserialise(m, &opts)) != 0)
48419261079SEd Maste 		fatal_fr(r, "sshauthopt_deserialise");
485190cef3dSDag-Erling Smørgrav 	sshbuf_free(m);
486545d5ecaSDag-Erling Smørgrav 
48747dd1d1bSDag-Erling Smørgrav 	if (authoptp != NULL) {
48847dd1d1bSDag-Erling Smørgrav 		*authoptp = opts;
48947dd1d1bSDag-Erling Smørgrav 		opts = NULL;
49047dd1d1bSDag-Erling Smørgrav 	}
49147dd1d1bSDag-Erling Smørgrav 	sshauthopt_free(opts);
49247dd1d1bSDag-Erling Smørgrav 
49347dd1d1bSDag-Erling Smørgrav 	return allowed;
494545d5ecaSDag-Erling Smørgrav }
495545d5ecaSDag-Erling Smørgrav 
496545d5ecaSDag-Erling Smørgrav /*
497545d5ecaSDag-Erling Smørgrav  * This key verify needs to send the key type along, because the
498545d5ecaSDag-Erling Smørgrav  * privileged parent makes the decision if the key is allowed
499545d5ecaSDag-Erling Smørgrav  * for authentication.
500545d5ecaSDag-Erling Smørgrav  */
501545d5ecaSDag-Erling Smørgrav 
502545d5ecaSDag-Erling Smørgrav int
5034f52dfbbSDag-Erling Smørgrav mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen,
50419261079SEd Maste     const u_char *data, size_t datalen, const char *sigalg, u_int compat,
50519261079SEd Maste     struct sshkey_sig_details **sig_detailsp)
506545d5ecaSDag-Erling Smørgrav {
507190cef3dSDag-Erling Smørgrav 	struct sshbuf *m;
5084f52dfbbSDag-Erling Smørgrav 	u_int encoded_ret = 0;
509190cef3dSDag-Erling Smørgrav 	int r;
51019261079SEd Maste 	u_char sig_details_present, flags;
51119261079SEd Maste 	u_int counter;
512545d5ecaSDag-Erling Smørgrav 
51319261079SEd Maste 	debug3_f("entering");
514545d5ecaSDag-Erling Smørgrav 
51519261079SEd Maste 	if (sig_detailsp != NULL)
51619261079SEd Maste 		*sig_detailsp = NULL;
517190cef3dSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
51819261079SEd Maste 		fatal_f("sshbuf_new failed");
519190cef3dSDag-Erling Smørgrav 	if ((r = sshkey_puts(key, m)) != 0 ||
520190cef3dSDag-Erling Smørgrav 	    (r = sshbuf_put_string(m, sig, siglen)) != 0 ||
521190cef3dSDag-Erling Smørgrav 	    (r = sshbuf_put_string(m, data, datalen)) != 0 ||
522190cef3dSDag-Erling Smørgrav 	    (r = sshbuf_put_cstring(m, sigalg == NULL ? "" : sigalg)) != 0)
52319261079SEd Maste 		fatal_fr(r, "assemble");
524545d5ecaSDag-Erling Smørgrav 
525190cef3dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, m);
526545d5ecaSDag-Erling Smørgrav 
52719261079SEd Maste 	debug3_f("waiting for MONITOR_ANS_KEYVERIFY");
528190cef3dSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
529190cef3dSDag-Erling Smørgrav 	    MONITOR_ANS_KEYVERIFY, m);
530545d5ecaSDag-Erling Smørgrav 
53119261079SEd Maste 	if ((r = sshbuf_get_u32(m, &encoded_ret)) != 0 ||
53219261079SEd Maste 	    (r = sshbuf_get_u8(m, &sig_details_present)) != 0)
53319261079SEd Maste 		fatal_fr(r, "parse");
53419261079SEd Maste 	if (sig_details_present && encoded_ret == 0) {
53519261079SEd Maste 		if ((r = sshbuf_get_u32(m, &counter)) != 0 ||
53619261079SEd Maste 		    (r = sshbuf_get_u8(m, &flags)) != 0)
53719261079SEd Maste 			fatal_fr(r, "parse sig_details");
53819261079SEd Maste 		if (sig_detailsp != NULL) {
53919261079SEd Maste 			*sig_detailsp = xcalloc(1, sizeof(**sig_detailsp));
54019261079SEd Maste 			(*sig_detailsp)->sk_counter = counter;
54119261079SEd Maste 			(*sig_detailsp)->sk_flags = flags;
54219261079SEd Maste 		}
54319261079SEd Maste 	}
544545d5ecaSDag-Erling Smørgrav 
545190cef3dSDag-Erling Smørgrav 	sshbuf_free(m);
546545d5ecaSDag-Erling Smørgrav 
5474f52dfbbSDag-Erling Smørgrav 	if (encoded_ret != 0)
5484f52dfbbSDag-Erling Smørgrav 		return SSH_ERR_SIGNATURE_INVALID;
5494f52dfbbSDag-Erling Smørgrav 	return 0;
550545d5ecaSDag-Erling Smørgrav }
551545d5ecaSDag-Erling Smørgrav 
552545d5ecaSDag-Erling Smørgrav void
55319261079SEd Maste mm_send_keystate(struct ssh *ssh, struct monitor *monitor)
554545d5ecaSDag-Erling Smørgrav {
555bc5531deSDag-Erling Smørgrav 	struct sshbuf *m;
556bc5531deSDag-Erling Smørgrav 	int r;
557545d5ecaSDag-Erling Smørgrav 
558bc5531deSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
55919261079SEd Maste 		fatal_f("sshbuf_new failed");
560bc5531deSDag-Erling Smørgrav 	if ((r = ssh_packet_get_state(ssh, m)) != 0)
56119261079SEd Maste 		fatal_fr(r, "ssh_packet_get_state");
562bc5531deSDag-Erling Smørgrav 	mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, m);
56319261079SEd Maste 	debug3_f("Finished sending state");
564bc5531deSDag-Erling Smørgrav 	sshbuf_free(m);
565545d5ecaSDag-Erling Smørgrav }
566545d5ecaSDag-Erling Smørgrav 
567545d5ecaSDag-Erling Smørgrav int
568333ee039SDag-Erling Smørgrav mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen)
569545d5ecaSDag-Erling Smørgrav {
570190cef3dSDag-Erling Smørgrav 	struct sshbuf *m;
57121e764dfSDag-Erling Smørgrav 	char *p, *msg;
572190cef3dSDag-Erling Smørgrav 	int success = 0, tmp1 = -1, tmp2 = -1, r;
573d4af9e69SDag-Erling Smørgrav 
574d4af9e69SDag-Erling Smørgrav 	/* Kludge: ensure there are fds free to receive the pty/tty */
575d4af9e69SDag-Erling Smørgrav 	if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 ||
576d4af9e69SDag-Erling Smørgrav 	    (tmp2 = dup(pmonitor->m_recvfd)) == -1) {
57719261079SEd Maste 		error_f("cannot allocate fds for pty");
578535af610SEd Maste 		if (tmp1 >= 0)
579d4af9e69SDag-Erling Smørgrav 			close(tmp1);
580d4af9e69SDag-Erling Smørgrav 		return 0;
581d4af9e69SDag-Erling Smørgrav 	}
582d4af9e69SDag-Erling Smørgrav 	close(tmp1);
583d4af9e69SDag-Erling Smørgrav 	close(tmp2);
584545d5ecaSDag-Erling Smørgrav 
585190cef3dSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
58619261079SEd Maste 		fatal_f("sshbuf_new failed");
587190cef3dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, m);
588545d5ecaSDag-Erling Smørgrav 
58919261079SEd Maste 	debug3_f("waiting for MONITOR_ANS_PTY");
590190cef3dSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PTY, m);
591545d5ecaSDag-Erling Smørgrav 
592190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_get_u32(m, &success)) != 0)
59319261079SEd Maste 		fatal_fr(r, "parse success");
594545d5ecaSDag-Erling Smørgrav 	if (success == 0) {
59519261079SEd Maste 		debug3_f("pty alloc failed");
596190cef3dSDag-Erling Smørgrav 		sshbuf_free(m);
597545d5ecaSDag-Erling Smørgrav 		return (0);
598545d5ecaSDag-Erling Smørgrav 	}
599190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_get_cstring(m, &p, NULL)) != 0 ||
600190cef3dSDag-Erling Smørgrav 	    (r = sshbuf_get_cstring(m, &msg, NULL)) != 0)
60119261079SEd Maste 		fatal_fr(r, "parse");
602190cef3dSDag-Erling Smørgrav 	sshbuf_free(m);
603545d5ecaSDag-Erling Smørgrav 
604545d5ecaSDag-Erling Smørgrav 	strlcpy(namebuf, p, namebuflen); /* Possible truncation */
605e4a9863fSDag-Erling Smørgrav 	free(p);
606545d5ecaSDag-Erling Smørgrav 
607190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_put(loginmsg, msg, strlen(msg))) != 0)
60819261079SEd Maste 		fatal_fr(r, "put loginmsg");
609e4a9863fSDag-Erling Smørgrav 	free(msg);
61021e764dfSDag-Erling Smørgrav 
611d4af9e69SDag-Erling Smørgrav 	if ((*ptyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1 ||
612d4af9e69SDag-Erling Smørgrav 	    (*ttyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1)
61319261079SEd Maste 		fatal_f("receive fds failed");
614545d5ecaSDag-Erling Smørgrav 
615545d5ecaSDag-Erling Smørgrav 	/* Success */
616545d5ecaSDag-Erling Smørgrav 	return (1);
617545d5ecaSDag-Erling Smørgrav }
618545d5ecaSDag-Erling Smørgrav 
619545d5ecaSDag-Erling Smørgrav void
6201ec0d754SDag-Erling Smørgrav mm_session_pty_cleanup2(Session *s)
621545d5ecaSDag-Erling Smørgrav {
622190cef3dSDag-Erling Smørgrav 	struct sshbuf *m;
623190cef3dSDag-Erling Smørgrav 	int r;
624545d5ecaSDag-Erling Smørgrav 
625545d5ecaSDag-Erling Smørgrav 	if (s->ttyfd == -1)
626545d5ecaSDag-Erling Smørgrav 		return;
627190cef3dSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
62819261079SEd Maste 		fatal_f("sshbuf_new failed");
629190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_put_cstring(m, s->tty)) != 0)
63019261079SEd Maste 		fatal_fr(r, "assmble");
631190cef3dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, m);
632190cef3dSDag-Erling Smørgrav 	sshbuf_free(m);
633545d5ecaSDag-Erling Smørgrav 
634545d5ecaSDag-Erling Smørgrav 	/* closed dup'ed master */
63519261079SEd Maste 	if (s->ptymaster != -1 && close(s->ptymaster) == -1)
636d4af9e69SDag-Erling Smørgrav 		error("close(s->ptymaster/%d): %s",
637d4af9e69SDag-Erling Smørgrav 		    s->ptymaster, strerror(errno));
638545d5ecaSDag-Erling Smørgrav 
639545d5ecaSDag-Erling Smørgrav 	/* unlink pty from session */
640545d5ecaSDag-Erling Smørgrav 	s->ttyfd = -1;
641545d5ecaSDag-Erling Smørgrav }
642545d5ecaSDag-Erling Smørgrav 
64383d2307dSDag-Erling Smørgrav #ifdef USE_PAM
64483d2307dSDag-Erling Smørgrav void
64519261079SEd Maste mm_start_pam(struct ssh *ssh)
64683d2307dSDag-Erling Smørgrav {
647190cef3dSDag-Erling Smørgrav 	struct sshbuf *m;
64883d2307dSDag-Erling Smørgrav 
64983d2307dSDag-Erling Smørgrav 	debug3("%s entering", __func__);
650cf2b5f3bSDag-Erling Smørgrav 	if (!options.use_pam)
651cf2b5f3bSDag-Erling Smørgrav 		fatal("UsePAM=no, but ended up in %s anyway", __func__);
652190cef3dSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
653190cef3dSDag-Erling Smørgrav 		fatal("%s: sshbuf_new failed", __func__);
654190cef3dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_START, m);
65583d2307dSDag-Erling Smørgrav 
656190cef3dSDag-Erling Smørgrav 	sshbuf_free(m);
65783d2307dSDag-Erling Smørgrav }
658382d19eeSDag-Erling Smørgrav 
659cf2b5f3bSDag-Erling Smørgrav u_int
660cf2b5f3bSDag-Erling Smørgrav mm_do_pam_account(void)
661cf2b5f3bSDag-Erling Smørgrav {
662190cef3dSDag-Erling Smørgrav 	struct sshbuf *m;
663cf2b5f3bSDag-Erling Smørgrav 	u_int ret;
664aa49c926SDag-Erling Smørgrav 	char *msg;
665190cef3dSDag-Erling Smørgrav 	size_t msglen;
666190cef3dSDag-Erling Smørgrav 	int r;
667cf2b5f3bSDag-Erling Smørgrav 
668cf2b5f3bSDag-Erling Smørgrav 	debug3("%s entering", __func__);
669cf2b5f3bSDag-Erling Smørgrav 	if (!options.use_pam)
670cf2b5f3bSDag-Erling Smørgrav 		fatal("UsePAM=no, but ended up in %s anyway", __func__);
671cf2b5f3bSDag-Erling Smørgrav 
672190cef3dSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
673190cef3dSDag-Erling Smørgrav 		fatal("%s: sshbuf_new failed", __func__);
674190cef3dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, m);
675cf2b5f3bSDag-Erling Smørgrav 
676cf2b5f3bSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
677190cef3dSDag-Erling Smørgrav 	    MONITOR_ANS_PAM_ACCOUNT, m);
678190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_get_u32(m, &ret)) != 0 ||
679190cef3dSDag-Erling Smørgrav 	    (r = sshbuf_get_cstring(m, &msg, &msglen)) != 0 ||
680190cef3dSDag-Erling Smørgrav 	    (r = sshbuf_put(loginmsg, msg, msglen)) != 0)
681190cef3dSDag-Erling Smørgrav 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
682cf2b5f3bSDag-Erling Smørgrav 
683190cef3dSDag-Erling Smørgrav 	free(msg);
684190cef3dSDag-Erling Smørgrav 	sshbuf_free(m);
685cf2b5f3bSDag-Erling Smørgrav 
686cf2b5f3bSDag-Erling Smørgrav 	debug3("%s returning %d", __func__, ret);
687cf2b5f3bSDag-Erling Smørgrav 
688cf2b5f3bSDag-Erling Smørgrav 	return (ret);
689cf2b5f3bSDag-Erling Smørgrav }
690cf2b5f3bSDag-Erling Smørgrav 
691382d19eeSDag-Erling Smørgrav void *
692cf2b5f3bSDag-Erling Smørgrav mm_sshpam_init_ctx(Authctxt *authctxt)
693382d19eeSDag-Erling Smørgrav {
694190cef3dSDag-Erling Smørgrav 	struct sshbuf *m;
695190cef3dSDag-Erling Smørgrav 	int r, success;
696382d19eeSDag-Erling Smørgrav 
697382d19eeSDag-Erling Smørgrav 	debug3("%s", __func__);
698190cef3dSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
699190cef3dSDag-Erling Smørgrav 		fatal("%s: sshbuf_new failed", __func__);
700190cef3dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_INIT_CTX, m);
701382d19eeSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PAM_INIT_CTX", __func__);
702190cef3dSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
703190cef3dSDag-Erling Smørgrav 	    MONITOR_ANS_PAM_INIT_CTX, m);
704190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_get_u32(m, &success)) != 0)
705190cef3dSDag-Erling Smørgrav 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
706382d19eeSDag-Erling Smørgrav 	if (success == 0) {
707382d19eeSDag-Erling Smørgrav 		debug3("%s: pam_init_ctx failed", __func__);
708190cef3dSDag-Erling Smørgrav 		sshbuf_free(m);
709382d19eeSDag-Erling Smørgrav 		return (NULL);
710382d19eeSDag-Erling Smørgrav 	}
711190cef3dSDag-Erling Smørgrav 	sshbuf_free(m);
712382d19eeSDag-Erling Smørgrav 	return (authctxt);
713382d19eeSDag-Erling Smørgrav }
714382d19eeSDag-Erling Smørgrav 
715382d19eeSDag-Erling Smørgrav int
716cf2b5f3bSDag-Erling Smørgrav mm_sshpam_query(void *ctx, char **name, char **info,
717382d19eeSDag-Erling Smørgrav     u_int *num, char ***prompts, u_int **echo_on)
718382d19eeSDag-Erling Smørgrav {
719190cef3dSDag-Erling Smørgrav 	struct sshbuf *m;
720190cef3dSDag-Erling Smørgrav 	u_int i, n;
721190cef3dSDag-Erling Smørgrav 	int r, ret;
722382d19eeSDag-Erling Smørgrav 
723382d19eeSDag-Erling Smørgrav 	debug3("%s", __func__);
724190cef3dSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
725190cef3dSDag-Erling Smørgrav 		fatal("%s: sshbuf_new failed", __func__);
726190cef3dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_QUERY, m);
727382d19eeSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PAM_QUERY", __func__);
728190cef3dSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_QUERY, m);
729190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_get_u32(m, &ret)) != 0 ||
730190cef3dSDag-Erling Smørgrav 	    (r = sshbuf_get_cstring(m, name, NULL)) != 0 ||
731190cef3dSDag-Erling Smørgrav 	    (r = sshbuf_get_cstring(m, info, NULL)) != 0 ||
732190cef3dSDag-Erling Smørgrav 	    (r = sshbuf_get_u32(m, &n)) != 0 ||
733190cef3dSDag-Erling Smørgrav 	    (r = sshbuf_get_u32(m, num)) != 0)
734190cef3dSDag-Erling Smørgrav 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
735382d19eeSDag-Erling Smørgrav 	debug3("%s: pam_query returned %d", __func__, ret);
736190cef3dSDag-Erling Smørgrav 	sshpam_set_maxtries_reached(n);
737333ee039SDag-Erling Smørgrav 	if (*num > PAM_MAX_NUM_MSG)
738190cef3dSDag-Erling Smørgrav 		fatal("%s: received %u PAM messages, expected <= %u",
739333ee039SDag-Erling Smørgrav 		    __func__, *num, PAM_MAX_NUM_MSG);
740333ee039SDag-Erling Smørgrav 	*prompts = xcalloc((*num + 1), sizeof(char *));
741333ee039SDag-Erling Smørgrav 	*echo_on = xcalloc((*num + 1), sizeof(u_int));
742382d19eeSDag-Erling Smørgrav 	for (i = 0; i < *num; ++i) {
743190cef3dSDag-Erling Smørgrav 		if ((r = sshbuf_get_cstring(m, &((*prompts)[i]), NULL)) != 0 ||
744190cef3dSDag-Erling Smørgrav 		    (r = sshbuf_get_u32(m, &((*echo_on)[i]))) != 0)
745190cef3dSDag-Erling Smørgrav 			fatal("%s: buffer error: %s", __func__, ssh_err(r));
746382d19eeSDag-Erling Smørgrav 	}
747190cef3dSDag-Erling Smørgrav 	sshbuf_free(m);
748382d19eeSDag-Erling Smørgrav 	return (ret);
749382d19eeSDag-Erling Smørgrav }
750382d19eeSDag-Erling Smørgrav 
751382d19eeSDag-Erling Smørgrav int
752cf2b5f3bSDag-Erling Smørgrav mm_sshpam_respond(void *ctx, u_int num, char **resp)
753382d19eeSDag-Erling Smørgrav {
754190cef3dSDag-Erling Smørgrav 	struct sshbuf *m;
755190cef3dSDag-Erling Smørgrav 	u_int n, i;
756190cef3dSDag-Erling Smørgrav 	int r, ret;
757382d19eeSDag-Erling Smørgrav 
758382d19eeSDag-Erling Smørgrav 	debug3("%s", __func__);
759190cef3dSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
760190cef3dSDag-Erling Smørgrav 		fatal("%s: sshbuf_new failed", __func__);
761190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_put_u32(m, num)) != 0)
762190cef3dSDag-Erling Smørgrav 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
763190cef3dSDag-Erling Smørgrav 	for (i = 0; i < num; ++i) {
764190cef3dSDag-Erling Smørgrav 		if ((r = sshbuf_put_cstring(m, resp[i])) != 0)
765190cef3dSDag-Erling Smørgrav 			fatal("%s: buffer error: %s", __func__, ssh_err(r));
766190cef3dSDag-Erling Smørgrav 	}
767190cef3dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_RESPOND, m);
768382d19eeSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__);
769190cef3dSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
770190cef3dSDag-Erling Smørgrav 	    MONITOR_ANS_PAM_RESPOND, m);
771190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_get_u32(m, &n)) != 0)
772190cef3dSDag-Erling Smørgrav 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
773190cef3dSDag-Erling Smørgrav 	ret = (int)n; /* XXX */
774382d19eeSDag-Erling Smørgrav 	debug3("%s: pam_respond returned %d", __func__, ret);
775190cef3dSDag-Erling Smørgrav 	sshbuf_free(m);
776382d19eeSDag-Erling Smørgrav 	return (ret);
777382d19eeSDag-Erling Smørgrav }
778382d19eeSDag-Erling Smørgrav 
779382d19eeSDag-Erling Smørgrav void
780cf2b5f3bSDag-Erling Smørgrav mm_sshpam_free_ctx(void *ctxtp)
781382d19eeSDag-Erling Smørgrav {
782190cef3dSDag-Erling Smørgrav 	struct sshbuf *m;
783382d19eeSDag-Erling Smørgrav 
784382d19eeSDag-Erling Smørgrav 	debug3("%s", __func__);
785190cef3dSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
786190cef3dSDag-Erling Smørgrav 		fatal("%s: sshbuf_new failed", __func__);
787190cef3dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_FREE_CTX, m);
788382d19eeSDag-Erling Smørgrav 	debug3("%s: waiting for MONITOR_ANS_PAM_FREE_CTX", __func__);
789190cef3dSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
790190cef3dSDag-Erling Smørgrav 	    MONITOR_ANS_PAM_FREE_CTX, m);
791190cef3dSDag-Erling Smørgrav 	sshbuf_free(m);
792382d19eeSDag-Erling Smørgrav }
79383d2307dSDag-Erling Smørgrav #endif /* USE_PAM */
79483d2307dSDag-Erling Smørgrav 
795545d5ecaSDag-Erling Smørgrav /* Request process termination */
796545d5ecaSDag-Erling Smørgrav 
797545d5ecaSDag-Erling Smørgrav void
798545d5ecaSDag-Erling Smørgrav mm_terminate(void)
799545d5ecaSDag-Erling Smørgrav {
800190cef3dSDag-Erling Smørgrav 	struct sshbuf *m;
801545d5ecaSDag-Erling Smørgrav 
802190cef3dSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
80319261079SEd Maste 		fatal_f("sshbuf_new failed");
804190cef3dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_TERM, m);
805190cef3dSDag-Erling Smørgrav 	sshbuf_free(m);
806545d5ecaSDag-Erling Smørgrav }
807545d5ecaSDag-Erling Smørgrav 
808545d5ecaSDag-Erling Smørgrav static void
809545d5ecaSDag-Erling Smørgrav mm_chall_setup(char **name, char **infotxt, u_int *numprompts,
810545d5ecaSDag-Erling Smørgrav     char ***prompts, u_int **echo_on)
811545d5ecaSDag-Erling Smørgrav {
812545d5ecaSDag-Erling Smørgrav 	*name = xstrdup("");
813545d5ecaSDag-Erling Smørgrav 	*infotxt = xstrdup("");
814545d5ecaSDag-Erling Smørgrav 	*numprompts = 1;
815333ee039SDag-Erling Smørgrav 	*prompts = xcalloc(*numprompts, sizeof(char *));
816333ee039SDag-Erling Smørgrav 	*echo_on = xcalloc(*numprompts, sizeof(u_int));
817545d5ecaSDag-Erling Smørgrav 	(*echo_on)[0] = 0;
818545d5ecaSDag-Erling Smørgrav }
819545d5ecaSDag-Erling Smørgrav 
820545d5ecaSDag-Erling Smørgrav int
821545d5ecaSDag-Erling Smørgrav mm_bsdauth_query(void *ctx, char **name, char **infotxt,
822545d5ecaSDag-Erling Smørgrav    u_int *numprompts, char ***prompts, u_int **echo_on)
823545d5ecaSDag-Erling Smørgrav {
824190cef3dSDag-Erling Smørgrav 	struct sshbuf *m;
825e73e9afaSDag-Erling Smørgrav 	u_int success;
826545d5ecaSDag-Erling Smørgrav 	char *challenge;
827190cef3dSDag-Erling Smørgrav 	int r;
828545d5ecaSDag-Erling Smørgrav 
82919261079SEd Maste 	debug3_f("entering");
830545d5ecaSDag-Erling Smørgrav 
831190cef3dSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
83219261079SEd Maste 		fatal_f("sshbuf_new failed");
833190cef3dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHQUERY, m);
834545d5ecaSDag-Erling Smørgrav 
835190cef3dSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
836190cef3dSDag-Erling Smørgrav 	    MONITOR_ANS_BSDAUTHQUERY, m);
837190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_get_u32(m, &success)) != 0)
83819261079SEd Maste 		fatal_fr(r, "parse success");
839e73e9afaSDag-Erling Smørgrav 	if (success == 0) {
84019261079SEd Maste 		debug3_f("no challenge");
841190cef3dSDag-Erling Smørgrav 		sshbuf_free(m);
842545d5ecaSDag-Erling Smørgrav 		return (-1);
843545d5ecaSDag-Erling Smørgrav 	}
844545d5ecaSDag-Erling Smørgrav 
845545d5ecaSDag-Erling Smørgrav 	/* Get the challenge, and format the response */
846190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_get_cstring(m, &challenge, NULL)) != 0)
84719261079SEd Maste 		fatal_fr(r, "parse challenge");
848190cef3dSDag-Erling Smørgrav 	sshbuf_free(m);
849545d5ecaSDag-Erling Smørgrav 
850545d5ecaSDag-Erling Smørgrav 	mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
851545d5ecaSDag-Erling Smørgrav 	(*prompts)[0] = challenge;
852545d5ecaSDag-Erling Smørgrav 
85319261079SEd Maste 	debug3_f("received challenge: %s", challenge);
854545d5ecaSDag-Erling Smørgrav 
855545d5ecaSDag-Erling Smørgrav 	return (0);
856545d5ecaSDag-Erling Smørgrav }
857545d5ecaSDag-Erling Smørgrav 
858545d5ecaSDag-Erling Smørgrav int
859545d5ecaSDag-Erling Smørgrav mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses)
860545d5ecaSDag-Erling Smørgrav {
861190cef3dSDag-Erling Smørgrav 	struct sshbuf *m;
862190cef3dSDag-Erling Smørgrav 	int r, authok;
863545d5ecaSDag-Erling Smørgrav 
86419261079SEd Maste 	debug3_f("entering");
865545d5ecaSDag-Erling Smørgrav 	if (numresponses != 1)
866545d5ecaSDag-Erling Smørgrav 		return (-1);
867545d5ecaSDag-Erling Smørgrav 
868190cef3dSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
86919261079SEd Maste 		fatal_f("sshbuf_new failed");
870190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_put_cstring(m, responses[0])) != 0)
87119261079SEd Maste 		fatal_fr(r, "assemble");
872190cef3dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHRESPOND, m);
873545d5ecaSDag-Erling Smørgrav 
874545d5ecaSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
875190cef3dSDag-Erling Smørgrav 	    MONITOR_ANS_BSDAUTHRESPOND, m);
876545d5ecaSDag-Erling Smørgrav 
877190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_get_u32(m, &authok)) != 0)
87819261079SEd Maste 		fatal_fr(r, "parse");
879190cef3dSDag-Erling Smørgrav 	sshbuf_free(m);
880545d5ecaSDag-Erling Smørgrav 
881545d5ecaSDag-Erling Smørgrav 	return ((authok == 0) ? -1 : 0);
882545d5ecaSDag-Erling Smørgrav }
883545d5ecaSDag-Erling Smørgrav 
884aa49c926SDag-Erling Smørgrav #ifdef SSH_AUDIT_EVENTS
885aa49c926SDag-Erling Smørgrav void
88619261079SEd Maste mm_audit_event(struct ssh *ssh, ssh_audit_event_t event)
887aa49c926SDag-Erling Smørgrav {
888190cef3dSDag-Erling Smørgrav 	struct sshbuf *m;
889190cef3dSDag-Erling Smørgrav 	int r;
890aa49c926SDag-Erling Smørgrav 
891aa49c926SDag-Erling Smørgrav 	debug3("%s entering", __func__);
892aa49c926SDag-Erling Smørgrav 
893190cef3dSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
894190cef3dSDag-Erling Smørgrav 		fatal("%s: sshbuf_new failed", __func__);
895190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_put_u32(m, event)) != 0)
896190cef3dSDag-Erling Smørgrav 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
897aa49c926SDag-Erling Smørgrav 
898190cef3dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_EVENT, m);
899190cef3dSDag-Erling Smørgrav 	sshbuf_free(m);
900aa49c926SDag-Erling Smørgrav }
901aa49c926SDag-Erling Smørgrav 
902aa49c926SDag-Erling Smørgrav void
903aa49c926SDag-Erling Smørgrav mm_audit_run_command(const char *command)
904aa49c926SDag-Erling Smørgrav {
905190cef3dSDag-Erling Smørgrav 	struct sshbuf *m;
906190cef3dSDag-Erling Smørgrav 	int r;
907aa49c926SDag-Erling Smørgrav 
908aa49c926SDag-Erling Smørgrav 	debug3("%s entering command %s", __func__, command);
909aa49c926SDag-Erling Smørgrav 
910190cef3dSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
911190cef3dSDag-Erling Smørgrav 		fatal("%s: sshbuf_new failed", __func__);
912190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_put_cstring(m, command)) != 0)
913190cef3dSDag-Erling Smørgrav 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
914aa49c926SDag-Erling Smørgrav 
915190cef3dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, m);
916190cef3dSDag-Erling Smørgrav 	sshbuf_free(m);
917aa49c926SDag-Erling Smørgrav }
918aa49c926SDag-Erling Smørgrav #endif /* SSH_AUDIT_EVENTS */
919aa49c926SDag-Erling Smørgrav 
920cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI
921cf2b5f3bSDag-Erling Smørgrav OM_uint32
92221e764dfSDag-Erling Smørgrav mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid)
923f388f5efSDag-Erling Smørgrav {
924190cef3dSDag-Erling Smørgrav 	struct sshbuf *m;
925cf2b5f3bSDag-Erling Smørgrav 	OM_uint32 major;
926190cef3dSDag-Erling Smørgrav 	int r;
927f388f5efSDag-Erling Smørgrav 
928cf2b5f3bSDag-Erling Smørgrav 	/* Client doesn't get to see the context */
929cf2b5f3bSDag-Erling Smørgrav 	*ctx = NULL;
930f388f5efSDag-Erling Smørgrav 
931190cef3dSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
93219261079SEd Maste 		fatal_f("sshbuf_new failed");
933190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_put_string(m, goid->elements, goid->length)) != 0)
93419261079SEd Maste 		fatal_fr(r, "assemble");
935f388f5efSDag-Erling Smørgrav 
936190cef3dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, m);
937190cef3dSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, m);
938f388f5efSDag-Erling Smørgrav 
939190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_get_u32(m, &major)) != 0)
94019261079SEd Maste 		fatal_fr(r, "parse");
941cf2b5f3bSDag-Erling Smørgrav 
942190cef3dSDag-Erling Smørgrav 	sshbuf_free(m);
943cf2b5f3bSDag-Erling Smørgrav 	return (major);
944f388f5efSDag-Erling Smørgrav }
945f388f5efSDag-Erling Smørgrav 
946cf2b5f3bSDag-Erling Smørgrav OM_uint32
947cf2b5f3bSDag-Erling Smørgrav mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in,
948190cef3dSDag-Erling Smørgrav     gss_buffer_desc *out, OM_uint32 *flagsp)
949f388f5efSDag-Erling Smørgrav {
950190cef3dSDag-Erling Smørgrav 	struct sshbuf *m;
951cf2b5f3bSDag-Erling Smørgrav 	OM_uint32 major;
952190cef3dSDag-Erling Smørgrav 	u_int flags;
953190cef3dSDag-Erling Smørgrav 	int r;
954f388f5efSDag-Erling Smørgrav 
955190cef3dSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
95619261079SEd Maste 		fatal_f("sshbuf_new failed");
957190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_put_string(m, in->value, in->length)) != 0)
95819261079SEd Maste 		fatal_fr(r, "assemble");
959cf2b5f3bSDag-Erling Smørgrav 
960190cef3dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, m);
961190cef3dSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, m);
962cf2b5f3bSDag-Erling Smørgrav 
963190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_get_u32(m, &major)) != 0 ||
964190cef3dSDag-Erling Smørgrav 	    (r = ssh_gssapi_get_buffer_desc(m, out)) != 0)
96519261079SEd Maste 		fatal_fr(r, "parse");
966190cef3dSDag-Erling Smørgrav 	if (flagsp != NULL) {
967190cef3dSDag-Erling Smørgrav 		if ((r = sshbuf_get_u32(m, &flags)) != 0)
96819261079SEd Maste 			fatal_fr(r, "parse flags");
969190cef3dSDag-Erling Smørgrav 		*flagsp = flags;
970190cef3dSDag-Erling Smørgrav 	}
971f388f5efSDag-Erling Smørgrav 
972190cef3dSDag-Erling Smørgrav 	sshbuf_free(m);
973cf2b5f3bSDag-Erling Smørgrav 
974cf2b5f3bSDag-Erling Smørgrav 	return (major);
975f388f5efSDag-Erling Smørgrav }
976cf2b5f3bSDag-Erling Smørgrav 
9771ec0d754SDag-Erling Smørgrav OM_uint32
9781ec0d754SDag-Erling Smørgrav mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
9791ec0d754SDag-Erling Smørgrav {
980190cef3dSDag-Erling Smørgrav 	struct sshbuf *m;
9811ec0d754SDag-Erling Smørgrav 	OM_uint32 major;
982190cef3dSDag-Erling Smørgrav 	int r;
9831ec0d754SDag-Erling Smørgrav 
984190cef3dSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
98519261079SEd Maste 		fatal_f("sshbuf_new failed");
986190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_put_string(m, gssbuf->value, gssbuf->length)) != 0 ||
987190cef3dSDag-Erling Smørgrav 	    (r = sshbuf_put_string(m, gssmic->value, gssmic->length)) != 0)
98819261079SEd Maste 		fatal_fr(r, "assemble");
9891ec0d754SDag-Erling Smørgrav 
990190cef3dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, m);
991190cef3dSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
992190cef3dSDag-Erling Smørgrav 	    MONITOR_ANS_GSSCHECKMIC, m);
9931ec0d754SDag-Erling Smørgrav 
994190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_get_u32(m, &major)) != 0)
99519261079SEd Maste 		fatal_fr(r, "parse");
996190cef3dSDag-Erling Smørgrav 	sshbuf_free(m);
9971ec0d754SDag-Erling Smørgrav 	return(major);
9981ec0d754SDag-Erling Smørgrav }
9991ec0d754SDag-Erling Smørgrav 
1000cf2b5f3bSDag-Erling Smørgrav int
1001cf2b5f3bSDag-Erling Smørgrav mm_ssh_gssapi_userok(char *user)
1002cf2b5f3bSDag-Erling Smørgrav {
1003190cef3dSDag-Erling Smørgrav 	struct sshbuf *m;
1004190cef3dSDag-Erling Smørgrav 	int r, authenticated = 0;
1005cf2b5f3bSDag-Erling Smørgrav 
1006190cef3dSDag-Erling Smørgrav 	if ((m = sshbuf_new()) == NULL)
100719261079SEd Maste 		fatal_f("sshbuf_new failed");
1008cf2b5f3bSDag-Erling Smørgrav 
1009190cef3dSDag-Erling Smørgrav 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, m);
1010190cef3dSDag-Erling Smørgrav 	mm_request_receive_expect(pmonitor->m_recvfd,
1011190cef3dSDag-Erling Smørgrav 	    MONITOR_ANS_GSSUSEROK, m);
1012cf2b5f3bSDag-Erling Smørgrav 
1013190cef3dSDag-Erling Smørgrav 	if ((r = sshbuf_get_u32(m, &authenticated)) != 0)
101419261079SEd Maste 		fatal_fr(r, "parse");
1015cf2b5f3bSDag-Erling Smørgrav 
1016190cef3dSDag-Erling Smørgrav 	sshbuf_free(m);
101719261079SEd Maste 	debug3_f("user %sauthenticated", authenticated ? "" : "not ");
1018cf2b5f3bSDag-Erling Smørgrav 	return (authenticated);
1019cf2b5f3bSDag-Erling Smørgrav }
1020cf2b5f3bSDag-Erling Smørgrav #endif /* GSSAPI */
1021