xref: /freebsd/crypto/openssh/auth2-gss.c (revision 535af610a4fdace6d50960c0ad9be0597eea7a1b)
1*535af610SEd Maste /* $OpenBSD: auth2-gss.c,v 1.34 2023/03/31 04:22:27 djm Exp $ */
2d95e11bfSDag-Erling Smørgrav 
3d95e11bfSDag-Erling Smørgrav /*
4d95e11bfSDag-Erling Smørgrav  * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
5d95e11bfSDag-Erling Smørgrav  *
6d95e11bfSDag-Erling Smørgrav  * Redistribution and use in source and binary forms, with or without
7d95e11bfSDag-Erling Smørgrav  * modification, are permitted provided that the following conditions
8d95e11bfSDag-Erling Smørgrav  * are met:
9d95e11bfSDag-Erling Smørgrav  * 1. Redistributions of source code must retain the above copyright
10d95e11bfSDag-Erling Smørgrav  *    notice, this list of conditions and the following disclaimer.
11d95e11bfSDag-Erling Smørgrav  * 2. Redistributions in binary form must reproduce the above copyright
12d95e11bfSDag-Erling Smørgrav  *    notice, this list of conditions and the following disclaimer in the
13d95e11bfSDag-Erling Smørgrav  *    documentation and/or other materials provided with the distribution.
14d95e11bfSDag-Erling Smørgrav  *
15d95e11bfSDag-Erling Smørgrav  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR
16d95e11bfSDag-Erling Smørgrav  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17d95e11bfSDag-Erling Smørgrav  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18d95e11bfSDag-Erling Smørgrav  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19d95e11bfSDag-Erling Smørgrav  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20d95e11bfSDag-Erling Smørgrav  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21d95e11bfSDag-Erling Smørgrav  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22d95e11bfSDag-Erling Smørgrav  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23d95e11bfSDag-Erling Smørgrav  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24d95e11bfSDag-Erling Smørgrav  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25d95e11bfSDag-Erling Smørgrav  */
26d95e11bfSDag-Erling Smørgrav 
27d95e11bfSDag-Erling Smørgrav #include "includes.h"
28d95e11bfSDag-Erling Smørgrav 
29d95e11bfSDag-Erling Smørgrav #ifdef GSSAPI
30d95e11bfSDag-Erling Smørgrav 
31761efaa7SDag-Erling Smørgrav #include <sys/types.h>
32761efaa7SDag-Erling Smørgrav 
33761efaa7SDag-Erling Smørgrav #include <stdarg.h>
34761efaa7SDag-Erling Smørgrav 
35761efaa7SDag-Erling Smørgrav #include "xmalloc.h"
36190cef3dSDag-Erling Smørgrav #include "sshkey.h"
37761efaa7SDag-Erling Smørgrav #include "hostfile.h"
38d95e11bfSDag-Erling Smørgrav #include "auth.h"
39d95e11bfSDag-Erling Smørgrav #include "ssh2.h"
40d95e11bfSDag-Erling Smørgrav #include "log.h"
41d95e11bfSDag-Erling Smørgrav #include "dispatch.h"
42190cef3dSDag-Erling Smørgrav #include "sshbuf.h"
43190cef3dSDag-Erling Smørgrav #include "ssherr.h"
44a0ee8cc6SDag-Erling Smørgrav #include "misc.h"
45d95e11bfSDag-Erling Smørgrav #include "servconf.h"
46d95e11bfSDag-Erling Smørgrav #include "packet.h"
4719261079SEd Maste #include "kex.h"
48d95e11bfSDag-Erling Smørgrav #include "ssh-gss.h"
49761efaa7SDag-Erling Smørgrav #include "monitor_wrap.h"
50d95e11bfSDag-Erling Smørgrav 
51*535af610SEd Maste #define SSH_GSSAPI_MAX_MECHS	2048
52*535af610SEd Maste 
53d95e11bfSDag-Erling Smørgrav extern ServerOptions options;
54d95e11bfSDag-Erling Smørgrav 
554f52dfbbSDag-Erling Smørgrav static int input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh);
564f52dfbbSDag-Erling Smørgrav static int input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh);
574f52dfbbSDag-Erling Smørgrav static int input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh);
584f52dfbbSDag-Erling Smørgrav static int input_gssapi_errtok(int, u_int32_t, struct ssh *);
59d95e11bfSDag-Erling Smørgrav 
60d95e11bfSDag-Erling Smørgrav /*
61d95e11bfSDag-Erling Smørgrav  * We only support those mechanisms that we know about (ie ones that we know
62021d409fSDag-Erling Smørgrav  * how to check local user kuserok and the like)
63d95e11bfSDag-Erling Smørgrav  */
64d95e11bfSDag-Erling Smørgrav static int
userauth_gssapi(struct ssh * ssh,const char * method)651323ec57SEd Maste userauth_gssapi(struct ssh *ssh, const char *method)
66d95e11bfSDag-Erling Smørgrav {
674f52dfbbSDag-Erling Smørgrav 	Authctxt *authctxt = ssh->authctxt;
68d74d50a8SDag-Erling Smørgrav 	gss_OID_desc goid = {0, NULL};
69d95e11bfSDag-Erling Smørgrav 	Gssctxt *ctxt = NULL;
70190cef3dSDag-Erling Smørgrav 	int r, present;
71190cef3dSDag-Erling Smørgrav 	u_int mechs;
72d95e11bfSDag-Erling Smørgrav 	OM_uint32 ms;
73190cef3dSDag-Erling Smørgrav 	size_t len;
74043840dfSDag-Erling Smørgrav 	u_char *doid = NULL;
75d95e11bfSDag-Erling Smørgrav 
76190cef3dSDag-Erling Smørgrav 	if ((r = sshpkt_get_u32(ssh, &mechs)) != 0)
7719261079SEd Maste 		fatal_fr(r, "parse packet");
78d95e11bfSDag-Erling Smørgrav 
79d95e11bfSDag-Erling Smørgrav 	if (mechs == 0) {
80*535af610SEd Maste 		logit_f("mechanism negotiation is not supported");
81*535af610SEd Maste 		return (0);
82*535af610SEd Maste 	} else if (mechs > SSH_GSSAPI_MAX_MECHS) {
83*535af610SEd Maste 		logit_f("too many mechanisms requested %u > %u", mechs,
84*535af610SEd Maste 		    SSH_GSSAPI_MAX_MECHS);
85d95e11bfSDag-Erling Smørgrav 		return (0);
86d95e11bfSDag-Erling Smørgrav 	}
87d95e11bfSDag-Erling Smørgrav 
88d95e11bfSDag-Erling Smørgrav 	do {
89d95e11bfSDag-Erling Smørgrav 		mechs--;
90d95e11bfSDag-Erling Smørgrav 
91e4a9863fSDag-Erling Smørgrav 		free(doid);
92d95e11bfSDag-Erling Smørgrav 
93efcad6b7SDag-Erling Smørgrav 		present = 0;
94190cef3dSDag-Erling Smørgrav 		if ((r = sshpkt_get_string(ssh, &doid, &len)) != 0)
9519261079SEd Maste 			fatal_fr(r, "parse oid");
96d95e11bfSDag-Erling Smørgrav 
97043840dfSDag-Erling Smørgrav 		if (len > 2 && doid[0] == SSH_GSS_OIDTYPE &&
98efcad6b7SDag-Erling Smørgrav 		    doid[1] == len - 2) {
99d74d50a8SDag-Erling Smørgrav 			goid.elements = doid + 2;
100d74d50a8SDag-Erling Smørgrav 			goid.length   = len - 2;
101b83788ffSDag-Erling Smørgrav 			ssh_gssapi_test_oid_supported(&ms, &goid, &present);
102efcad6b7SDag-Erling Smørgrav 		} else {
103*535af610SEd Maste 			logit_f("badly formed OID received");
104d95e11bfSDag-Erling Smørgrav 		}
105d95e11bfSDag-Erling Smørgrav 	} while (mechs > 0 && !present);
106d95e11bfSDag-Erling Smørgrav 
107d95e11bfSDag-Erling Smørgrav 	if (!present) {
108e4a9863fSDag-Erling Smørgrav 		free(doid);
109e146993eSDag-Erling Smørgrav 		authctxt->server_caused_failure = 1;
110d95e11bfSDag-Erling Smørgrav 		return (0);
111d95e11bfSDag-Erling Smørgrav 	}
112d95e11bfSDag-Erling Smørgrav 
113190cef3dSDag-Erling Smørgrav 	if (!authctxt->valid || authctxt->user == NULL) {
11419261079SEd Maste 		debug2_f("disabled because of invalid user");
115190cef3dSDag-Erling Smørgrav 		free(doid);
116190cef3dSDag-Erling Smørgrav 		return (0);
117190cef3dSDag-Erling Smørgrav 	}
118190cef3dSDag-Erling Smørgrav 
119d74d50a8SDag-Erling Smørgrav 	if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, &goid)))) {
120761efaa7SDag-Erling Smørgrav 		if (ctxt != NULL)
121761efaa7SDag-Erling Smørgrav 			ssh_gssapi_delete_ctx(&ctxt);
122e4a9863fSDag-Erling Smørgrav 		free(doid);
123e146993eSDag-Erling Smørgrav 		authctxt->server_caused_failure = 1;
124d95e11bfSDag-Erling Smørgrav 		return (0);
125d95e11bfSDag-Erling Smørgrav 	}
126d95e11bfSDag-Erling Smørgrav 
127d95e11bfSDag-Erling Smørgrav 	authctxt->methoddata = (void *)ctxt;
128d95e11bfSDag-Erling Smørgrav 
129efcad6b7SDag-Erling Smørgrav 	/* Return the OID that we received */
130190cef3dSDag-Erling Smørgrav 	if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_GSSAPI_RESPONSE)) != 0 ||
131190cef3dSDag-Erling Smørgrav 	    (r = sshpkt_put_string(ssh, doid, len)) != 0 ||
132190cef3dSDag-Erling Smørgrav 	    (r = sshpkt_send(ssh)) != 0)
13319261079SEd Maste 		fatal_fr(r, "send packet");
134d95e11bfSDag-Erling Smørgrav 
135e4a9863fSDag-Erling Smørgrav 	free(doid);
136d95e11bfSDag-Erling Smørgrav 
1374f52dfbbSDag-Erling Smørgrav 	ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token);
1384f52dfbbSDag-Erling Smørgrav 	ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok);
139d95e11bfSDag-Erling Smørgrav 	authctxt->postponed = 1;
140d95e11bfSDag-Erling Smørgrav 
141d95e11bfSDag-Erling Smørgrav 	return (0);
142d95e11bfSDag-Erling Smørgrav }
143d95e11bfSDag-Erling Smørgrav 
144bc5531deSDag-Erling Smørgrav static int
input_gssapi_token(int type,u_int32_t plen,struct ssh * ssh)1454f52dfbbSDag-Erling Smørgrav input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh)
146d95e11bfSDag-Erling Smørgrav {
1474f52dfbbSDag-Erling Smørgrav 	Authctxt *authctxt = ssh->authctxt;
148d95e11bfSDag-Erling Smørgrav 	Gssctxt *gssctxt;
149d95e11bfSDag-Erling Smørgrav 	gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
150d95e11bfSDag-Erling Smørgrav 	gss_buffer_desc recv_tok;
151efcad6b7SDag-Erling Smørgrav 	OM_uint32 maj_status, min_status, flags;
152190cef3dSDag-Erling Smørgrav 	u_char *p;
153190cef3dSDag-Erling Smørgrav 	size_t len;
154190cef3dSDag-Erling Smørgrav 	int r;
155d95e11bfSDag-Erling Smørgrav 
156d95e11bfSDag-Erling Smørgrav 	if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
157d95e11bfSDag-Erling Smørgrav 		fatal("No authentication or GSSAPI context");
158d95e11bfSDag-Erling Smørgrav 
159d95e11bfSDag-Erling Smørgrav 	gssctxt = authctxt->methoddata;
160190cef3dSDag-Erling Smørgrav 	if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 ||
161190cef3dSDag-Erling Smørgrav 	    (r = sshpkt_get_end(ssh)) != 0)
16219261079SEd Maste 		fatal_fr(r, "parse packet");
163d95e11bfSDag-Erling Smørgrav 
164190cef3dSDag-Erling Smørgrav 	recv_tok.value = p;
165190cef3dSDag-Erling Smørgrav 	recv_tok.length = len;
166d95e11bfSDag-Erling Smørgrav 	maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok,
167efcad6b7SDag-Erling Smørgrav 	    &send_tok, &flags));
168d95e11bfSDag-Erling Smørgrav 
169190cef3dSDag-Erling Smørgrav 	free(p);
170d95e11bfSDag-Erling Smørgrav 
171d95e11bfSDag-Erling Smørgrav 	if (GSS_ERROR(maj_status)) {
172d95e11bfSDag-Erling Smørgrav 		if (send_tok.length != 0) {
173190cef3dSDag-Erling Smørgrav 			if ((r = sshpkt_start(ssh,
174190cef3dSDag-Erling Smørgrav 			    SSH2_MSG_USERAUTH_GSSAPI_ERRTOK)) != 0 ||
175190cef3dSDag-Erling Smørgrav 			    (r = sshpkt_put_string(ssh, send_tok.value,
176190cef3dSDag-Erling Smørgrav 			    send_tok.length)) != 0 ||
177190cef3dSDag-Erling Smørgrav 			    (r = sshpkt_send(ssh)) != 0)
17819261079SEd Maste 				fatal_fr(r, "send ERRTOK packet");
179d95e11bfSDag-Erling Smørgrav 		}
180d95e11bfSDag-Erling Smørgrav 		authctxt->postponed = 0;
1814f52dfbbSDag-Erling Smørgrav 		ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
1824f52dfbbSDag-Erling Smørgrav 		userauth_finish(ssh, 0, "gssapi-with-mic", NULL);
183d95e11bfSDag-Erling Smørgrav 	} else {
184d95e11bfSDag-Erling Smørgrav 		if (send_tok.length != 0) {
185190cef3dSDag-Erling Smørgrav 			if ((r = sshpkt_start(ssh,
186190cef3dSDag-Erling Smørgrav 			    SSH2_MSG_USERAUTH_GSSAPI_TOKEN)) != 0 ||
187190cef3dSDag-Erling Smørgrav 			    (r = sshpkt_put_string(ssh, send_tok.value,
188190cef3dSDag-Erling Smørgrav 			    send_tok.length)) != 0 ||
189190cef3dSDag-Erling Smørgrav 			    (r = sshpkt_send(ssh)) != 0)
19019261079SEd Maste 				fatal_fr(r, "send TOKEN packet");
191d95e11bfSDag-Erling Smørgrav 		}
192d95e11bfSDag-Erling Smørgrav 		if (maj_status == GSS_S_COMPLETE) {
1934f52dfbbSDag-Erling Smørgrav 			ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
194efcad6b7SDag-Erling Smørgrav 			if (flags & GSS_C_INTEG_FLAG)
1954f52dfbbSDag-Erling Smørgrav 				ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_MIC,
196efcad6b7SDag-Erling Smørgrav 				    &input_gssapi_mic);
197efcad6b7SDag-Erling Smørgrav 			else
1984f52dfbbSDag-Erling Smørgrav 				ssh_dispatch_set(ssh,
199efcad6b7SDag-Erling Smørgrav 				    SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
200d95e11bfSDag-Erling Smørgrav 				    &input_gssapi_exchange_complete);
201d95e11bfSDag-Erling Smørgrav 		}
202d95e11bfSDag-Erling Smørgrav 	}
203d95e11bfSDag-Erling Smørgrav 
204d95e11bfSDag-Erling Smørgrav 	gss_release_buffer(&min_status, &send_tok);
205bc5531deSDag-Erling Smørgrav 	return 0;
206d95e11bfSDag-Erling Smørgrav }
207d95e11bfSDag-Erling Smørgrav 
208bc5531deSDag-Erling Smørgrav static int
input_gssapi_errtok(int type,u_int32_t plen,struct ssh * ssh)2094f52dfbbSDag-Erling Smørgrav input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh)
210d95e11bfSDag-Erling Smørgrav {
2114f52dfbbSDag-Erling Smørgrav 	Authctxt *authctxt = ssh->authctxt;
212d95e11bfSDag-Erling Smørgrav 	Gssctxt *gssctxt;
213d95e11bfSDag-Erling Smørgrav 	gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
214d95e11bfSDag-Erling Smørgrav 	gss_buffer_desc recv_tok;
215d95e11bfSDag-Erling Smørgrav 	OM_uint32 maj_status;
216190cef3dSDag-Erling Smørgrav 	int r;
217190cef3dSDag-Erling Smørgrav 	u_char *p;
218190cef3dSDag-Erling Smørgrav 	size_t len;
219d95e11bfSDag-Erling Smørgrav 
220d95e11bfSDag-Erling Smørgrav 	if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
221d95e11bfSDag-Erling Smørgrav 		fatal("No authentication or GSSAPI context");
222d95e11bfSDag-Erling Smørgrav 
223d95e11bfSDag-Erling Smørgrav 	gssctxt = authctxt->methoddata;
224190cef3dSDag-Erling Smørgrav 	if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 ||
225190cef3dSDag-Erling Smørgrav 	    (r = sshpkt_get_end(ssh)) != 0)
22619261079SEd Maste 		fatal_fr(r, "parse packet");
227190cef3dSDag-Erling Smørgrav 	recv_tok.value = p;
228d95e11bfSDag-Erling Smørgrav 	recv_tok.length = len;
229d95e11bfSDag-Erling Smørgrav 
230d95e11bfSDag-Erling Smørgrav 	/* Push the error token into GSSAPI to see what it says */
231d95e11bfSDag-Erling Smørgrav 	maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok,
232d95e11bfSDag-Erling Smørgrav 	    &send_tok, NULL));
233d95e11bfSDag-Erling Smørgrav 
234e4a9863fSDag-Erling Smørgrav 	free(recv_tok.value);
235d95e11bfSDag-Erling Smørgrav 
236d95e11bfSDag-Erling Smørgrav 	/* We can't return anything to the client, even if we wanted to */
2374f52dfbbSDag-Erling Smørgrav 	ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
2384f52dfbbSDag-Erling Smørgrav 	ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
239d95e11bfSDag-Erling Smørgrav 
240d95e11bfSDag-Erling Smørgrav 	/* The client will have already moved on to the next auth */
241d95e11bfSDag-Erling Smørgrav 
242d95e11bfSDag-Erling Smørgrav 	gss_release_buffer(&maj_status, &send_tok);
243bc5531deSDag-Erling Smørgrav 	return 0;
244d95e11bfSDag-Erling Smørgrav }
245d95e11bfSDag-Erling Smørgrav 
246d95e11bfSDag-Erling Smørgrav /*
247d95e11bfSDag-Erling Smørgrav  * This is called when the client thinks we've completed authentication.
248d95e11bfSDag-Erling Smørgrav  * It should only be enabled in the dispatch handler by the function above,
249d95e11bfSDag-Erling Smørgrav  * which only enables it once the GSSAPI exchange is complete.
250d95e11bfSDag-Erling Smørgrav  */
251d95e11bfSDag-Erling Smørgrav 
252bc5531deSDag-Erling Smørgrav static int
input_gssapi_exchange_complete(int type,u_int32_t plen,struct ssh * ssh)2534f52dfbbSDag-Erling Smørgrav input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh)
254d95e11bfSDag-Erling Smørgrav {
2554f52dfbbSDag-Erling Smørgrav 	Authctxt *authctxt = ssh->authctxt;
256190cef3dSDag-Erling Smørgrav 	int r, authenticated;
2574f52dfbbSDag-Erling Smørgrav 	const char *displayname;
258d95e11bfSDag-Erling Smørgrav 
259d95e11bfSDag-Erling Smørgrav 	if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
260d95e11bfSDag-Erling Smørgrav 		fatal("No authentication or GSSAPI context");
261d95e11bfSDag-Erling Smørgrav 
262d95e11bfSDag-Erling Smørgrav 	/*
263efcad6b7SDag-Erling Smørgrav 	 * We don't need to check the status, because we're only enabled in
264efcad6b7SDag-Erling Smørgrav 	 * the dispatcher once the exchange is complete
265d95e11bfSDag-Erling Smørgrav 	 */
266d95e11bfSDag-Erling Smørgrav 
267190cef3dSDag-Erling Smørgrav 	if ((r = sshpkt_get_end(ssh)) != 0)
26819261079SEd Maste 		fatal_fr(r, "parse packet");
269d95e11bfSDag-Erling Smørgrav 
270d95e11bfSDag-Erling Smørgrav 	authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
271d95e11bfSDag-Erling Smørgrav 
2724f52dfbbSDag-Erling Smørgrav 	if ((!use_privsep || mm_is_monitor()) &&
2734f52dfbbSDag-Erling Smørgrav 	    (displayname = ssh_gssapi_displayname()) != NULL)
2744f52dfbbSDag-Erling Smørgrav 		auth2_record_info(authctxt, "%s", displayname);
2754f52dfbbSDag-Erling Smørgrav 
276d95e11bfSDag-Erling Smørgrav 	authctxt->postponed = 0;
2774f52dfbbSDag-Erling Smørgrav 	ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
2784f52dfbbSDag-Erling Smørgrav 	ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
2794f52dfbbSDag-Erling Smørgrav 	ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
2804f52dfbbSDag-Erling Smørgrav 	ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
2814f52dfbbSDag-Erling Smørgrav 	userauth_finish(ssh, authenticated, "gssapi-with-mic", NULL);
282bc5531deSDag-Erling Smørgrav 	return 0;
283efcad6b7SDag-Erling Smørgrav }
284efcad6b7SDag-Erling Smørgrav 
285bc5531deSDag-Erling Smørgrav static int
input_gssapi_mic(int type,u_int32_t plen,struct ssh * ssh)2864f52dfbbSDag-Erling Smørgrav input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
287efcad6b7SDag-Erling Smørgrav {
2884f52dfbbSDag-Erling Smørgrav 	Authctxt *authctxt = ssh->authctxt;
289efcad6b7SDag-Erling Smørgrav 	Gssctxt *gssctxt;
290190cef3dSDag-Erling Smørgrav 	int r, authenticated = 0;
291190cef3dSDag-Erling Smørgrav 	struct sshbuf *b;
292efcad6b7SDag-Erling Smørgrav 	gss_buffer_desc mic, gssbuf;
2934f52dfbbSDag-Erling Smørgrav 	const char *displayname;
294190cef3dSDag-Erling Smørgrav 	u_char *p;
295190cef3dSDag-Erling Smørgrav 	size_t len;
296efcad6b7SDag-Erling Smørgrav 
297efcad6b7SDag-Erling Smørgrav 	if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
298efcad6b7SDag-Erling Smørgrav 		fatal("No authentication or GSSAPI context");
299efcad6b7SDag-Erling Smørgrav 
300efcad6b7SDag-Erling Smørgrav 	gssctxt = authctxt->methoddata;
301efcad6b7SDag-Erling Smørgrav 
302190cef3dSDag-Erling Smørgrav 	if ((r = sshpkt_get_string(ssh, &p, &len)) != 0)
30319261079SEd Maste 		fatal_fr(r, "parse packet");
304190cef3dSDag-Erling Smørgrav 	if ((b = sshbuf_new()) == NULL)
30519261079SEd Maste 		fatal_f("sshbuf_new failed");
306190cef3dSDag-Erling Smørgrav 	mic.value = p;
307efcad6b7SDag-Erling Smørgrav 	mic.length = len;
308190cef3dSDag-Erling Smørgrav 	ssh_gssapi_buildmic(b, authctxt->user, authctxt->service,
30919261079SEd Maste 	    "gssapi-with-mic", ssh->kex->session_id);
310efcad6b7SDag-Erling Smørgrav 
311190cef3dSDag-Erling Smørgrav 	if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL)
31219261079SEd Maste 		fatal_f("sshbuf_mutable_ptr failed");
313190cef3dSDag-Erling Smørgrav 	gssbuf.length = sshbuf_len(b);
314efcad6b7SDag-Erling Smørgrav 
315efcad6b7SDag-Erling Smørgrav 	if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic))))
316efcad6b7SDag-Erling Smørgrav 		authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
317efcad6b7SDag-Erling Smørgrav 	else
318efcad6b7SDag-Erling Smørgrav 		logit("GSSAPI MIC check failed");
319efcad6b7SDag-Erling Smørgrav 
320190cef3dSDag-Erling Smørgrav 	sshbuf_free(b);
321e4a9863fSDag-Erling Smørgrav 	free(mic.value);
322efcad6b7SDag-Erling Smørgrav 
3234f52dfbbSDag-Erling Smørgrav 	if ((!use_privsep || mm_is_monitor()) &&
3244f52dfbbSDag-Erling Smørgrav 	    (displayname = ssh_gssapi_displayname()) != NULL)
3254f52dfbbSDag-Erling Smørgrav 		auth2_record_info(authctxt, "%s", displayname);
3264f52dfbbSDag-Erling Smørgrav 
327efcad6b7SDag-Erling Smørgrav 	authctxt->postponed = 0;
3284f52dfbbSDag-Erling Smørgrav 	ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
3294f52dfbbSDag-Erling Smørgrav 	ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
3304f52dfbbSDag-Erling Smørgrav 	ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
3314f52dfbbSDag-Erling Smørgrav 	ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
3324f52dfbbSDag-Erling Smørgrav 	userauth_finish(ssh, authenticated, "gssapi-with-mic", NULL);
333bc5531deSDag-Erling Smørgrav 	return 0;
334d95e11bfSDag-Erling Smørgrav }
335d95e11bfSDag-Erling Smørgrav 
336d95e11bfSDag-Erling Smørgrav Authmethod method_gssapi = {
337efcad6b7SDag-Erling Smørgrav 	"gssapi-with-mic",
3381323ec57SEd Maste 	NULL,
339d95e11bfSDag-Erling Smørgrav 	userauth_gssapi,
340d95e11bfSDag-Erling Smørgrav 	&options.gss_authentication
341d95e11bfSDag-Erling Smørgrav };
342d95e11bfSDag-Erling Smørgrav 
343d95e11bfSDag-Erling Smørgrav #endif /* GSSAPI */
344