--- old/usr/src/cmd/ssh/sshd/auth2-gss.c	2016-08-16 20:42:23.471078568 -0400
+++ /dev/null	2016-08-16 20:42:23.000000000 -0400
@@ -1,533 +0,0 @@
-/*
- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include "includes.h"
-
-#ifdef GSSAPI
-#include "auth.h"
-#include "ssh2.h"
-#include "xmalloc.h"
-#include "log.h"
-#include "dispatch.h"
-#include "buffer.h"
-#include "servconf.h"
-#include "compat.h"
-#include "bufaux.h"
-#include "packet.h"
-
-#include <gssapi/gssapi.h>
-#include "ssh-gss.h"
-
-extern ServerOptions options;
-extern uchar_t *session_id2;
-extern int session_id2_len;
-extern Gssctxt *xxx_gssctxt;
-
-static void userauth_gssapi_finish(Authctxt *authctxt, Gssctxt *gssctxt);
-
-static void
-userauth_gssapi_keyex(Authctxt *authctxt)
-{
-	gss_buffer_desc g_mic_data, mic_tok;
-	Buffer mic_data;
-	OM_uint32 maj_status, min_status;
-
-	if (authctxt == NULL || authctxt->method == NULL)
-		fatal("No authentication context during gssapi-keyex userauth");
-
-	if (xxx_gssctxt == NULL || xxx_gssctxt->context == GSS_C_NO_CONTEXT) {
-		/* fatal()?  or return? */
-		debug("No GSS-API context during gssapi-keyex userauth");
-		return;
-	}
-
-	/* Make data buffer to verify MIC with */
-	buffer_init(&mic_data);
-	buffer_put_string(&mic_data, session_id2, session_id2_len);
-	buffer_put_char(&mic_data, SSH2_MSG_USERAUTH_REQUEST);
-	buffer_put_cstring(&mic_data, authctxt->user);
-	buffer_put_cstring(&mic_data, authctxt->service);
-	buffer_put_cstring(&mic_data, authctxt->method->name);
-
-	g_mic_data.value  = buffer_ptr(&mic_data);
-	g_mic_data.length = buffer_len(&mic_data);
-
-	mic_tok.value = packet_get_string(&mic_tok.length);
-
-	maj_status = gss_verify_mic(&min_status, xxx_gssctxt->context,
-	    &g_mic_data, &mic_tok, NULL);
-
-	packet_check_eom();
-	buffer_clear(&mic_data);
-
-	if (maj_status != GSS_S_COMPLETE)
-		debug2("MIC verification failed, GSSAPI userauth failed");
-	else
-		userauth_gssapi_finish(authctxt, xxx_gssctxt);
-
-	/* Leave Gssctxt around for ssh_gssapi_cleanup/storecreds() */
-	if (xxx_gssctxt->deleg_creds == GSS_C_NO_CREDENTIAL)
-		ssh_gssapi_delete_ctx(&xxx_gssctxt);
-}
-
-static void ssh_gssapi_userauth_error(Gssctxt *ctxt);
-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_errtok(int, u_int32_t, void *);
-static void input_gssapi_exchange_complete(int type, u_int32_t plen,
-    void *ctxt);
-
-static void
-userauth_gssapi_abandon(Authctxt *authctxt, Authmethod *method)
-{
-	ssh_gssapi_delete_ctx((Gssctxt **)&method->method_data);
-	xxx_gssctxt = NULL;
-	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
-	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
-	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
-	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
-}
-
-static void
-userauth_gssapi(Authctxt *authctxt)
-{
-	gss_OID_set supported_mechs;
-	int mechs, present = 0;
-	OM_uint32 min_status;
-	uint_t len;
-	char *doid = NULL;
-	gss_OID oid = GSS_C_NULL_OID;
-
-	if (datafellows & SSH_OLD_GSSAPI) {
-		debug("Early drafts of GSSAPI userauth not supported");
-		return;
-	}
-
-	mechs = packet_get_int();
-	if (mechs == 0) {
-		packet_check_eom();
-		debug("Mechanism negotiation is not supported");
-		return;
-	}
-
-	ssh_gssapi_server_mechs(&supported_mechs);
-
-	do {
-		mechs--;
-
-		if (oid != GSS_C_NULL_OID)
-			ssh_gssapi_release_oid(&oid);
-
-		doid = packet_get_string(&len);
-
-		/* ick */
-		if (doid[0] != 0x06 || (len > 2 && doid[1] != len - 2)) {
-			log("Mechanism OID received using the old "
-			    "encoding form");
-			oid = ssh_gssapi_make_oid(len, doid);
-		} else {
-			oid = ssh_gssapi_make_oid(len - 2, doid + 2);
-		}
-
-		(void) gss_test_oid_set_member(&min_status, oid,
-		    supported_mechs, &present);
-
-		debug("Client offered gssapi userauth with %s (%s)",
-		    ssh_gssapi_oid_to_str(oid),
-		    present ? "supported" : "unsupported");
-	} while (!present && (mechs > 0));
-
-	if (!present) {
-		/* userauth_finish() will send SSH2_MSG_USERAUTH_FAILURE */
-		debug2("No mechanism offered by the client is available");
-		ssh_gssapi_release_oid(&oid);
-		return;
-	}
-
-	ssh_gssapi_build_ctx((Gssctxt **)&authctxt->method->method_data,
-	    0, oid);
-	ssh_gssapi_release_oid(&oid);
-	/* Send SSH_MSG_USERAUTH_GSSAPI_RESPONSE */
-
-	packet_start(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE);
-
-	/* Just return whatever we found -- the matched mech does us no good */
-	packet_put_string(doid, len);
-	xfree(doid);
-
-	packet_send();
-	packet_write_wait();
-
-	/* Setup rest of gssapi userauth conversation */
-	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token);
-	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok);
-	authctxt->method->postponed = 1;
-}
-
-static void
-input_gssapi_token(int type, u_int32_t plen, void *ctxt)
-{
-	Authctxt *authctxt = ctxt;
-	Gssctxt *gssctxt;
-	gss_buffer_desc send_tok, recv_tok;
-	OM_uint32 maj_status, min_status;
-	uint_t len;
-
-	if (authctxt == NULL || authctxt->method == NULL ||
-	    (authctxt->method->method_data == NULL)) {
-		fatal("No authentication or GSSAPI context during "
-		    "gssapi-with-mic userauth");
-	}
-
-	gssctxt = authctxt->method->method_data;
-	recv_tok.value = packet_get_string(&len);
-	recv_tok.length = len; /* u_int vs. size_t */
-
-	maj_status = ssh_gssapi_accept_ctx(gssctxt, &recv_tok, &send_tok);
-	packet_check_eom();
-
-	if (GSS_ERROR(maj_status)) {
-		ssh_gssapi_userauth_error(gssctxt);
-		if (send_tok.length != 0) {
-			packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK);
-			packet_put_string(send_tok.value, send_tok.length);
-			packet_send();
-			packet_write_wait();
-		}
-		authctxt->method->postponed = 0;
-		dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
-		userauth_finish(authctxt, authctxt->method->name);
-	} else {
-		if (send_tok.length != 0) {
-			packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
-			packet_put_string(send_tok.value, send_tok.length);
-			packet_send();
-			packet_write_wait();
-		}
-		if (maj_status == GSS_S_COMPLETE) {
-			dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
-			dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC,
-			    &input_gssapi_mic);
-			dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
-			    &input_gssapi_exchange_complete);
-		}
-	}
-
-	gss_release_buffer(&min_status, &send_tok);
-}
-
-static void
-input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
-{
-	Authctxt *authctxt = ctxt;
-	Gssctxt *gssctxt;
-	gss_buffer_desc send_tok, recv_tok;
-
-	if (authctxt == NULL || authctxt->method == NULL ||
-	    (authctxt->method->method_data == NULL)) {
-		fatal("No authentication or GSSAPI context during "
-		    "gssapi-with-mic userauth");
-	}
-
-	gssctxt = authctxt->method->method_data;
-	recv_tok.value = packet_get_string(&recv_tok.length);
-	packet_check_eom();
-
-	/* Push the error token into GSSAPI to see what it says */
-	(void) ssh_gssapi_accept_ctx(gssctxt, &recv_tok, &send_tok);
-
-	debug("Client sent GSS-API error token during GSS userauth-- %s",
-	    ssh_gssapi_last_error(gssctxt, NULL, NULL));
-
-	/* We can't return anything to the client, even if we wanted to */
-	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
-	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
-
-
-	/*
-	 * The client will have already moved on to the next auth and
-	 * will send a new userauth request.  The spec says that the
-	 * server MUST NOT send a SSH_MSG_USERAUTH_FAILURE packet in
-	 * response to this.
-	 *
-	 * We leave authctxt->method->postponed == 1 here so that a call
-	 * to input_userauth_request() will detect this failure (as
-	 * userauth abandonment) and act accordingly.
-	 */
-}
-
-static void
-input_gssapi_mic(int type, u_int32_t plen, void *ctxt)
-{
-	Authctxt *authctxt = ctxt;
-	Gssctxt *gssctxt;
-	gss_buffer_desc g_mic_data, mic_tok;
-	Buffer mic_data;
-	OM_uint32 maj_status, min_status;
-
-	if (authctxt == NULL || authctxt->method == NULL ||
-	    (authctxt->method->method_data == NULL)) {
-		debug3("No authentication or GSSAPI context during "
-		    "gssapi-with-mic userauth");
-		return;
-	}
-
-	gssctxt = authctxt->method->method_data;
-
-	/* Make data buffer to verify MIC with */
-	buffer_init(&mic_data);
-	buffer_put_string(&mic_data, session_id2, session_id2_len);
-	buffer_put_char(&mic_data, SSH2_MSG_USERAUTH_REQUEST);
-	buffer_put_cstring(&mic_data, authctxt->user);
-	buffer_put_cstring(&mic_data, authctxt->service);
-	buffer_put_cstring(&mic_data, authctxt->method->name);
-
-	g_mic_data.value  = buffer_ptr(&mic_data);
-	g_mic_data.length = buffer_len(&mic_data);
-
-	mic_tok.value = packet_get_string(&mic_tok.length);
-
-	maj_status = gss_verify_mic(&min_status, gssctxt->context,
-	    &g_mic_data, &mic_tok, NULL);
-
-	packet_check_eom();
-	buffer_free(&mic_data);
-
-	if (maj_status != GSS_S_COMPLETE)
-		debug2("MIC verification failed, GSSAPI userauth failed");
-	else
-		userauth_gssapi_finish(authctxt, gssctxt);
-
-	/* Delete context from keyex */
-	if (xxx_gssctxt != gssctxt)
-		ssh_gssapi_delete_ctx(&xxx_gssctxt);
-
-	/* Leave Gssctxt around for ssh_gssapi_cleanup/storecreds() */
-	if (gssctxt->deleg_creds == GSS_C_NO_CREDENTIAL)
-		ssh_gssapi_delete_ctx(&gssctxt);
-
-	xxx_gssctxt = gssctxt;
-
-	authctxt->method->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);
-	userauth_finish(authctxt, authctxt->method->name);
-}
-
-/*
- * This is called when the client thinks we've completed authentication.
- * It should only be enabled in the dispatch handler by the function above,
- * which only enables it once the GSSAPI exchange is complete.
- */
-static void
-input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
-{
-	Authctxt *authctxt = ctxt;
-	Gssctxt *gssctxt;
-
-	packet_check_eom();
-
-	if (authctxt == NULL || authctxt->method == NULL ||
-	    (authctxt->method->method_data == NULL))
-		fatal("No authentication or GSSAPI context");
-
-	gssctxt = authctxt->method->method_data;
-
-	/*
-	 * SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE -> gssapi userauth
-	 * failure, the client should use SSH2_MSG_USERAUTH_GSSAPI_MIC
-	 * instead.
-	 *
-	 * There's two reasons for this:
-	 *
-	 * 1) we don't have GSS mechs that don't support integrity
-	 * protection, and even if we did we'd not want to use them with
-	 * SSHv2, and,
-	 *
-	 * 2) we currently have no way to dynamically detect whether a
-	 * given mechanism does or does not support integrity
-	 * protection, so when a context's flags do not indicate
-	 * integrity protection we can't know if the client simply
-	 * didn't request it, so we assume it didn't and reject the
-	 * userauth.
-	 *
-	 * We could fail partially (i.e., force the use of other
-	 * userauth methods without counting this one as failed).  But
-	 * this will do for now.
-	 */
-#if 0
-	authctxt->method->authenticated = ssh_gssapi_userok(gssctxt,
-	    authctxt->user);
-#endif
-
-	if (xxx_gssctxt != gssctxt)
-		ssh_gssapi_delete_ctx(&gssctxt);
-	ssh_gssapi_delete_ctx(&gssctxt);
-	authctxt->method->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, authctxt->method->name);
-}
-
-static void
-ssh_gssapi_userauth_error(Gssctxt *ctxt)
-{
-	char *errstr;
-	OM_uint32 maj, min;
-
-	errstr = ssh_gssapi_last_error(ctxt, &maj, &min);
-	if (errstr) {
-		packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERROR);
-		packet_put_int(maj);
-		packet_put_int(min);
-		packet_put_cstring(errstr);
-		packet_put_cstring("");
-		packet_send();
-		packet_write_wait();
-		xfree(errstr);
-	}
-}
-
-/*
- * Code common to gssapi-keyex and gssapi-with-mic userauth.
- *
- * Does authorization, figures out how to store delegated creds.
- */
-static void
-userauth_gssapi_finish(Authctxt *authctxt, Gssctxt *gssctxt)
-{
-	char *local_user = NULL;
-	gss_buffer_desc dispname;
-	OM_uint32 major;
-
-	if (*authctxt->user != '\0' &&
-	    ssh_gssapi_userok(gssctxt, authctxt->user)) {
-
-		/*
-		 * If the client princ did not map to the requested
-		 * username then we don't want to clobber existing creds
-		 * for the user with the delegated creds.
-		 */
-		local_user = ssh_gssapi_localname(gssctxt);
-		if (local_user == NULL ||
-		    strcmp(local_user, authctxt->user) == 0)
-			gssctxt->default_creds = 1; /* store creds as default */
-
-		authctxt->method->authenticated =
-		    do_pam_non_initial_userauth(authctxt);
-
-	} else if (*authctxt->user == '\0') {
-		/* Requested username == ""; derive username from princ name */
-		if ((local_user = ssh_gssapi_localname(gssctxt)) == NULL)
-			return;
-
-		/* Changed username (from implicit, '') */
-		userauth_user_svc_change(authctxt, local_user, NULL);
-
-		gssctxt->default_creds = 1; /* store creds as default */
-
-		authctxt->method->authenticated =
-		    do_pam_non_initial_userauth(authctxt);
-	}
-
-	if (local_user != NULL)
-		xfree(local_user);
-
-	if (*authctxt->user != '\0' && authctxt->method->authenticated != 0) {
-		major = gss_display_name(&gssctxt->minor, gssctxt->src_name,
-		    &dispname, NULL);
-		if (major == GSS_S_COMPLETE) {
-			log("Authorized principal %.*s, authenticated with "
-			    "GSS mechanism %s, to: %s",
-			    dispname.length, (char *)dispname.value,
-			    ssh_gssapi_oid_to_name(gssctxt->actual_mech),
-			    authctxt->user);
-		}
-		(void) gss_release_buffer(&gssctxt->minor, &dispname);
-	}
-}
-
-#if 0
-/* Deprecated userauths -- should not be enabled */
-Authmethod method_external = {
-	"external-keyx",
-	&options.gss_authentication,
-	userauth_gssapi_keyex,
-	NULL,	/* no abandon function */
-	NULL,
-	NULL,
-	/* State counters */
-	0, 0, 0, 0,
-	/* State flags */
-	0, 0, 0, 0, 0, 0
-};
-
-Authmethod method_gssapi = {
-	"gssapi",
-	&options.gss_authentication,
-	userauth_gssapi,
-	userauth_gssapi_abandon,
-	NULL,
-	NULL,
-	/* State counters */
-	0, 0, 0, 0,
-	/* State flags */
-	0, 0, 0, 0, 0, 0
-};
-#endif
-
-Authmethod method_external = {
-	"gssapi-keyex",
-	&options.gss_authentication,
-	userauth_gssapi_keyex,
-	NULL,	/* no abandon function */
-	NULL,
-	NULL,
-	/* State counters */
-	0, 0, 0, 0,
-	/* State flags */
-	0, 0, 0, 0, 0, 0
-};
-
-Authmethod method_gssapi = {
-	"gssapi-with-mic",
-	&options.gss_authentication,
-	userauth_gssapi,
-	userauth_gssapi_abandon,
-	NULL,
-	NULL,
-	/* State counters */
-	0, 0, 0, 0,
-	/* State flags */
-	0, 0, 0, 0, 0, 0
-};
-
-#endif /* GSSAPI */
