- markus@cvs.openbsd.org 2003/11/17 11:06:07
     [auth2-gss.c gss-genr.c gss-serv.c monitor.c monitor.h monitor_wrap.c]
     [monitor_wrap.h sshconnect2.c ssh-gss.h]
     replace "gssapi" with "gssapi-with-mic"; from Simon Wilkinson;
     test + ok jakob.
diff --git a/auth2-gss.c b/auth2-gss.c
index 84fb384..220862d 100644
--- a/auth2-gss.c
+++ b/auth2-gss.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: auth2-gss.c,v 1.5 2003/11/02 11:01:03 markus Exp $	*/
+/*	$OpenBSD: auth2-gss.c,v 1.6 2003/11/17 11:06:07 markus Exp $	*/
 
 /*
  * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@@ -43,6 +43,7 @@
 extern ServerOptions options;
 
 static void input_gssapi_token(int type, u_int32_t plen, void *ctxt);
+static void input_gssapi_mic(int type, u_int32_t plen, void *ctxt);
 static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt);
 static void input_gssapi_errtok(int, u_int32_t, void *);
 
@@ -129,7 +130,7 @@
 	Gssctxt *gssctxt;
 	gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
 	gss_buffer_desc recv_tok;
-	OM_uint32 maj_status, min_status;
+	OM_uint32 maj_status, min_status, flags;
 	u_int len;
 
 	if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
@@ -142,7 +143,7 @@
 	packet_check_eom();
 
 	maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok,
-	    &send_tok, NULL));
+	    &send_tok, &flags));
 
 	xfree(recv_tok.value);
 
@@ -154,7 +155,7 @@
 		}
 		authctxt->postponed = 0;
 		dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
-		userauth_finish(authctxt, 0, "gssapi");
+		userauth_finish(authctxt, 0, "gssapi-with-mic");
 	} else {
 		if (send_tok.length != 0) {
 			packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
@@ -163,8 +164,13 @@
 		}
 		if (maj_status == GSS_S_COMPLETE) {
 			dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
-			dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
-				     &input_gssapi_exchange_complete);
+			if (flags & GSS_C_INTEG_FLAG)
+				dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC,
+				    &input_gssapi_mic);
+			else
+				dispatch_set(
+				    SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
+				    &input_gssapi_exchange_complete);
 		}
 	}
 
@@ -224,9 +230,8 @@
 	gssctxt = authctxt->methoddata;
 
 	/*
-	 * We don't need to check the status, because the stored credentials
-	 * which userok uses are only populated once the context init step
-	 * has returned complete.
+	 * We don't need to check the status, because we're only enabled in
+	 * the dispatcher once the exchange is complete
 	 */
 
 	packet_check_eom();
@@ -236,12 +241,53 @@
 	authctxt->postponed = 0;
 	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
 	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
+	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
 	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
-	userauth_finish(authctxt, authenticated, "gssapi");
+	userauth_finish(authctxt, authenticated, "gssapi-with-mic");
+}
+
+static void
+input_gssapi_mic(int type, u_int32_t plen, void *ctxt)
+{
+	Authctxt *authctxt = ctxt;
+	Gssctxt *gssctxt;
+	int authenticated = 0;
+	Buffer b;
+	gss_buffer_desc mic, gssbuf;
+	u_int len;
+	
+	if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
+		fatal("No authentication or GSSAPI context");
+	
+	gssctxt = authctxt->methoddata;
+	
+	mic.value = packet_get_string(&len);
+	mic.length = len;
+	
+	ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service,
+	    "gssapi-with-mic");
+	
+	gssbuf.value = buffer_ptr(&b);
+	gssbuf.length = buffer_len(&b);
+	
+	if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic))))
+		authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
+	else
+		logit("GSSAPI MIC check failed");
+
+	buffer_free(&b);
+	xfree(mic.value);
+	
+	authctxt->postponed = 0;
+	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
+	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
+	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
+	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
+	userauth_finish(authctxt, authenticated, "gssapi-with-mic");
 }
 
 Authmethod method_gssapi = {
-	"gssapi",
+	"gssapi-with-mic",
 	userauth_gssapi,
 	&options.gss_authentication
 };