vishalmishra434 / rpms / openssh

Forked from rpms/openssh a month ago
Clone
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/auth2.c.gsskex openssh-6.2p1/auth2.c
Petr Lautrbach 8a29de
--- openssh-6.2p1/auth2.c.gsskex	2013-03-27 13:19:11.062624591 +0100
Petr Lautrbach 8a29de
+++ openssh-6.2p1/auth2.c	2013-03-27 13:19:11.140624271 +0100
Petr Lautrbach 5039c7
@@ -69,6 +69,7 @@ extern Authmethod method_passwd;
Petr Lautrbach 5039c7
 extern Authmethod method_kbdint;
Petr Lautrbach 5039c7
 extern Authmethod method_hostbased;
Petr Lautrbach 5039c7
 #ifdef GSSAPI
Petr Lautrbach 5039c7
+extern Authmethod method_gsskeyex;
Petr Lautrbach 5039c7
 extern Authmethod method_gssapi;
Petr Lautrbach 5039c7
 #endif
Petr Lautrbach 5039c7
 #ifdef JPAKE
Petr Lautrbach 5039c7
@@ -79,6 +80,7 @@ Authmethod *authmethods[] = {
Petr Lautrbach 5039c7
 	&method_none,
Petr Lautrbach 5039c7
 	&method_pubkey,
Petr Lautrbach 5039c7
 #ifdef GSSAPI
Petr Lautrbach 5039c7
+	&method_gsskeyex,
Petr Lautrbach 5039c7
 	&method_gssapi,
Petr Lautrbach 5039c7
 #endif
Petr Lautrbach 5039c7
 #ifdef JPAKE
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/auth2-gss.c.gsskex openssh-6.2p1/auth2-gss.c
Petr Lautrbach 8a29de
--- openssh-6.2p1/auth2-gss.c.gsskex	2013-03-27 13:19:11.062624591 +0100
Petr Lautrbach 8a29de
+++ openssh-6.2p1/auth2-gss.c	2013-03-27 13:19:11.141624267 +0100
Petr Lautrbach 5039c7
@@ -52,6 +52,40 @@ static void input_gssapi_mic(int type, u
Petr Lautrbach 5039c7
 static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt);
Petr Lautrbach 5039c7
 static void input_gssapi_errtok(int, u_int32_t, void *);
Petr Lautrbach 5039c7
 
Petr Lautrbach 5039c7
+/* 
Petr Lautrbach 5039c7
+ * The 'gssapi_keyex' userauth mechanism.
Petr Lautrbach 5039c7
+ */
Petr Lautrbach 5039c7
+static int
Petr Lautrbach 5039c7
+userauth_gsskeyex(Authctxt *authctxt)
Petr Lautrbach 5039c7
+{
Petr Lautrbach 5039c7
+	int authenticated = 0;
Petr Lautrbach 5039c7
+	Buffer b;
Petr Lautrbach 5039c7
+	gss_buffer_desc mic, gssbuf;
Petr Lautrbach 5039c7
+	u_int len;
Petr Lautrbach 5039c7
+
Petr Lautrbach 5039c7
+	mic.value = packet_get_string(&len;;
Petr Lautrbach 5039c7
+	mic.length = len;
Petr Lautrbach 5039c7
+
Petr Lautrbach 5039c7
+	packet_check_eom();
Petr Lautrbach 5039c7
+
Petr Lautrbach 5039c7
+	ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service,
Petr Lautrbach 5039c7
+	    "gssapi-keyex");
Petr Lautrbach 5039c7
+
Petr Lautrbach 5039c7
+	gssbuf.value = buffer_ptr(&b);
Petr Lautrbach 5039c7
+	gssbuf.length = buffer_len(&b);
Petr Lautrbach 5039c7
+
Petr Lautrbach 5039c7
+	/* gss_kex_context is NULL with privsep, so we can't check it here */
Petr Lautrbach 5039c7
+	if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, 
Petr Lautrbach 5039c7
+	    &gssbuf, &mic))))
Petr Lautrbach 5039c7
+		authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user,
Petr Lautrbach 5039c7
+		    authctxt->pw));
Petr Lautrbach 5039c7
+	
Petr Lautrbach 5039c7
+	buffer_free(&b);
Petr Lautrbach 5039c7
+	xfree(mic.value);
Petr Lautrbach 5039c7
+
Petr Lautrbach 5039c7
+	return (authenticated);
Petr Lautrbach 5039c7
+}
Petr Lautrbach 5039c7
+
Petr Lautrbach 5039c7
 /*
Petr Lautrbach 5039c7
  * We only support those mechanisms that we know about (ie ones that we know
Petr Lautrbach 5039c7
  * how to check local user kuserok and the like)
Petr Lautrbach 5039c7
@@ -244,7 +278,8 @@ input_gssapi_exchange_complete(int type,
Petr Lautrbach 5039c7
 
Petr Lautrbach 5039c7
 	packet_check_eom();
Petr Lautrbach 5039c7
 
Petr Lautrbach 5039c7
-	authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
Petr Lautrbach 5039c7
+	authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user,
Petr Lautrbach 5039c7
+	    authctxt->pw));
Petr Lautrbach 5039c7
 
Petr Lautrbach 5039c7
 	authctxt->postponed = 0;
Petr Lautrbach 5039c7
 	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
Petr Lautrbach 5039c7
@@ -286,7 +321,8 @@ input_gssapi_mic(int type, u_int32_t ple
Petr Lautrbach 5039c7
 	gssbuf.length = buffer_len(&b);
Petr Lautrbach 5039c7
 
Petr Lautrbach 5039c7
 	if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic))))
Petr Lautrbach 5039c7
-		authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
Petr Lautrbach 5039c7
+		authenticated = 
Petr Lautrbach 5039c7
+		    PRIVSEP(ssh_gssapi_userok(authctxt->user, authctxt->pw));
Petr Lautrbach 5039c7
 	else
Petr Lautrbach 5039c7
 		logit("GSSAPI MIC check failed");
Petr Lautrbach 5039c7
 
Petr Lautrbach 5039c7
@@ -303,6 +339,12 @@ input_gssapi_mic(int type, u_int32_t ple
Petr Lautrbach 5039c7
 	userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL);
Petr Lautrbach 5039c7
 }
Petr Lautrbach 5039c7
 
Petr Lautrbach 5039c7
+Authmethod method_gsskeyex = {
Petr Lautrbach 5039c7
+	"gssapi-keyex",
Petr Lautrbach 5039c7
+	userauth_gsskeyex,
Petr Lautrbach 5039c7
+	&options.gss_authentication
Petr Lautrbach 5039c7
+};
Petr Lautrbach 5039c7
+
Petr Lautrbach 5039c7
 Authmethod method_gssapi = {
Petr Lautrbach 5039c7
 	"gssapi-with-mic",
Petr Lautrbach 5039c7
 	userauth_gssapi,
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/auth-krb5.c.gsskex openssh-6.2p1/auth-krb5.c
Petr Lautrbach 8a29de
--- openssh-6.2p1/auth-krb5.c.gsskex	2012-04-26 01:52:15.000000000 +0200
Petr Lautrbach 8a29de
+++ openssh-6.2p1/auth-krb5.c	2013-03-27 13:19:11.140624271 +0100
Petr Lautrbach 51ca3b
@@ -50,6 +50,7 @@
Petr Lautrbach 51ca3b
 #include <errno.h>
Petr Lautrbach 51ca3b
 #include <unistd.h>
Petr Lautrbach 51ca3b
 #include <string.h>
Petr Lautrbach 51ca3b
+#include <sys/stat.h>
Petr Lautrbach 51ca3b
 #include <krb5.h>
Petr Lautrbach 51ca3b
 
Petr Lautrbach 51ca3b
 extern ServerOptions	 options;
Petr Lautrbach aacd01
@@ -77,6 +78,7 @@ auth_krb5_password(Authctxt *authctxt, c
Petr Lautrbach aacd01
 #endif
Petr Lautrbach aacd01
 	krb5_error_code problem;
Petr Lautrbach aacd01
 	krb5_ccache ccache = NULL;
Petr Lautrbach aacd01
+	const char *ccache_type;
Petr Lautrbach aacd01
 	int len;
Petr Lautrbach aacd01
 	char *client, *platform_client;
Petr Lautrbach aacd01
 
Petr Lautrbach aacd01
@@ -166,12 +168,30 @@ auth_krb5_password(Authctxt *authctxt, c
Petr Lautrbach aacd01
 		goto out;
Petr Lautrbach aacd01
 #endif
Petr Lautrbach aacd01
 
Petr Lautrbach aacd01
+	ccache_type = krb5_cc_get_type(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
Petr Lautrbach aacd01
 	authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
Petr Lautrbach 51ca3b
 
Petr Lautrbach aacd01
-	len = strlen(authctxt->krb5_ticket_file) + 6;
Petr Lautrbach aacd01
+	if (authctxt->krb5_ticket_file[0] == ':')
Petr Lautrbach aacd01
+		authctxt->krb5_ticket_file++;
Petr Lautrbach aacd01
+
Petr Lautrbach aacd01
+	len = strlen(authctxt->krb5_ticket_file) + strlen(ccache_type);
Petr Lautrbach 51ca3b
 	authctxt->krb5_ccname = xmalloc(len);
Petr Lautrbach 51ca3b
-	snprintf(authctxt->krb5_ccname, len, "FILE:%s",
Petr Lautrbach aacd01
+
Petr Lautrbach 51ca3b
+#ifdef USE_CCAPI
Petr Lautrbach 51ca3b
+	snprintf(authctxt->krb5_ccname, len, "API:%s",
Petr Lautrbach 51ca3b
 	    authctxt->krb5_ticket_file);
Petr Lautrbach 51ca3b
+#else
Petr Lautrbach aacd01
+	snprintf(authctxt->krb5_ccname, len, "%s:%s",
Petr Lautrbach aacd01
+	    ccache_type, authctxt->krb5_ticket_file);
Petr Lautrbach 51ca3b
+#endif
Petr Lautrbach aacd01
+
Petr Lautrbach aacd01
+	if (strcmp(ccache_type, "DIR") == 0) {
Petr Lautrbach aacd01
+		char *p;
Petr Lautrbach aacd01
+		p = strrchr(authctxt->krb5_ccname, '/');
Petr Lautrbach aacd01
+		if (p)
Petr Lautrbach aacd01
+			*p = '\0';
Petr Lautrbach aacd01
+	}
Petr Lautrbach aacd01
+
Petr Lautrbach 51ca3b
 
Petr Lautrbach 51ca3b
 #ifdef USE_PAM
Petr Lautrbach 51ca3b
 	if (options.use_pam)
Petr Lautrbach aacd01
@@ -208,10 +228,30 @@ auth_krb5_password(Authctxt *authctxt, c
Petr Lautrbach 51ca3b
 void
Petr Lautrbach 51ca3b
 krb5_cleanup_proc(Authctxt *authctxt)
Petr Lautrbach 51ca3b
 {
Petr Lautrbach 51ca3b
+	struct stat krb5_ccname_stat;
Petr Lautrbach aacd01
+	char krb5_ccname[128], *krb5_ccname_dir_start, *krb5_ccname_dir_end;
Petr Lautrbach 51ca3b
+
Petr Lautrbach 51ca3b
 	debug("krb5_cleanup_proc called");
Petr Lautrbach 51ca3b
 	if (authctxt->krb5_fwd_ccache) {
Petr Lautrbach 51ca3b
 		krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
Petr Lautrbach 51ca3b
 		authctxt->krb5_fwd_ccache = NULL;
Petr Lautrbach 51ca3b
+
Petr Lautrbach aacd01
+		strncpy(krb5_ccname, authctxt->krb5_ccname, sizeof(krb5_ccname) - 10);
Petr Lautrbach aacd01
+		krb5_ccname_dir_start = strchr(krb5_ccname, ':') + 1;
Petr Lautrbach aacd01
+		strcat(krb5_ccname_dir_start, "/primary");
Petr Lautrbach 51ca3b
+
Petr Lautrbach aacd01
+		if (stat(krb5_ccname_dir_start, &krb5_ccname_stat) == 0) {
Petr Lautrbach aacd01
+			if (unlink(krb5_ccname_dir_start) == 0) {
Petr Lautrbach aacd01
+				krb5_ccname_dir_end = strrchr(krb5_ccname_dir_start, '/');
Petr Lautrbach aacd01
+				*krb5_ccname_dir_end = '\0';
Petr Lautrbach aacd01
+				if (rmdir(krb5_ccname_dir_start) == -1)
Petr Lautrbach aacd01
+					debug("cache dir '%s' remove failed: %s", krb5_ccname_dir_start, strerror(errno));
Petr Lautrbach 51ca3b
+			}
Petr Lautrbach aacd01
+			else
Petr Lautrbach aacd01
+				debug("cache primary file '%s', remove failed: %s",
Petr Lautrbach aacd01
+					krb5_ccname_dir_start, strerror(errno)
Petr Lautrbach aacd01
+					);
Petr Lautrbach 51ca3b
+		}
Petr Lautrbach 51ca3b
 	}
Petr Lautrbach 51ca3b
 	if (authctxt->krb5_user) {
Petr Lautrbach 51ca3b
 		krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user);
Petr Lautrbach aacd01
@@ -226,31 +266,45 @@ krb5_cleanup_proc(Authctxt *authctxt)
Petr Lautrbach 51ca3b
 #ifndef HEIMDAL
Petr Lautrbach 51ca3b
 krb5_error_code
Petr Lautrbach 51ca3b
 ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) {
Petr Lautrbach 9fe1af
-	int tmpfd, ret, oerrno;
Petr Lautrbach 9fe1af
-	char ccname[40];
Petr Lautrbach 9fe1af
+	int ret, oerrno;
Petr Lautrbach 9fe1af
+	char ccname[128];
Petr Lautrbach 51ca3b
+#ifdef USE_CCAPI
Petr Lautrbach 51ca3b
+	char cctemplate[] = "API:krb5cc_%d";
Petr Lautrbach 51ca3b
+#else
Petr Lautrbach aacd01
 	mode_t old_umask;
Petr Lautrbach aacd01
+	char cctemplate[] = "DIR:/run/user/%d/krb5cc_XXXXXXXXXX";
Petr Lautrbach 51ca3b
+	char *tmpdir;
Petr Lautrbach 51ca3b
+#endif
Petr Lautrbach 51ca3b
 
Petr Lautrbach aacd01
-	ret = snprintf(ccname, sizeof(ccname),
Petr Lautrbach 51ca3b
-	    "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid());
Petr Lautrbach aacd01
+	ret = snprintf(ccname, sizeof(ccname), cctemplate, geteuid());
Petr Lautrbach 51ca3b
 	if (ret < 0 || (size_t)ret >= sizeof(ccname))
Petr Lautrbach 51ca3b
 		return ENOMEM;
Petr Lautrbach 51ca3b
 
Petr Lautrbach 51ca3b
-	old_umask = umask(0177);
Petr Lautrbach 51ca3b
-	tmpfd = mkstemp(ccname + strlen("FILE:"));
Petr Lautrbach 51ca3b
+#ifndef USE_CCAPI
Petr Lautrbach 51ca3b
+	old_umask = umask(0077);
Petr Lautrbach 51ca3b
+	tmpdir = mkdtemp(ccname + strlen("DIR:"));
Petr Lautrbach 9fe1af
 	oerrno = errno;
Petr Lautrbach aacd01
+	if (tmpdir == NULL && errno == ENOENT) {
Petr Lautrbach aacd01
+		/* /run/user/uid doesn't exist -> fallback to /tmp */
Petr Lautrbach aacd01
+		ret = snprintf(ccname, sizeof(ccname), "DIR:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid());
Petr Lautrbach aacd01
+		if (ret < 0 || (size_t)ret >= sizeof(ccname))
Petr Lautrbach aacd01
+			return ENOMEM;
Petr Lautrbach aacd01
+		tmpdir = mkdtemp(ccname + strlen("DIR:"));
Petr Lautrbach aacd01
+		oerrno = errno;
Petr Lautrbach aacd01
+	}
Petr Lautrbach aacd01
+
Petr Lautrbach 51ca3b
 	umask(old_umask);
Petr Lautrbach 51ca3b
-	if (tmpfd == -1) {
Petr Lautrbach 9fe1af
-		logit("mkstemp(): %.100s", strerror(oerrno));
Petr Lautrbach 51ca3b
+	if (tmpdir == NULL) {
Petr Lautrbach aacd01
+		logit("mkdtemp(): %s - %.100s", ccname, strerror(oerrno));
Petr Lautrbach 9fe1af
 		return oerrno;
Petr Lautrbach 51ca3b
 	}
Petr Lautrbach 9fe1af
 
Petr Lautrbach 51ca3b
-	if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
Petr Lautrbach 51ca3b
+	if (chmod(tmpdir, S_IRUSR | S_IWUSR | S_IXUSR) == -1) {
Petr Lautrbach 9fe1af
 		oerrno = errno;
Petr Lautrbach 9fe1af
-		logit("fchmod(): %.100s", strerror(oerrno));
Petr Lautrbach 9fe1af
-		close(tmpfd);
Petr Lautrbach aacd01
+		logit("chmod(): %s - %.100s", ccname, strerror(oerrno));
Petr Lautrbach 9fe1af
 		return oerrno;
Petr Lautrbach 51ca3b
 	}
Petr Lautrbach 51ca3b
-	close(tmpfd);
Petr Lautrbach 51ca3b
+#endif
Petr Lautrbach 51ca3b
 
Petr Lautrbach 51ca3b
 	return (krb5_cc_resolve(ctx, ccname, ccache));
Petr Lautrbach 51ca3b
 }
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/ChangeLog.gssapi.gsskex openssh-6.2p1/ChangeLog.gssapi
Petr Lautrbach 8a29de
--- openssh-6.2p1/ChangeLog.gssapi.gsskex	2013-03-27 13:19:11.143624259 +0100
Petr Lautrbach 8a29de
+++ openssh-6.2p1/ChangeLog.gssapi	2013-03-27 13:19:11.143624259 +0100
Petr Lautrbach 5039c7
@@ -0,0 +1,113 @@
Petr Lautrbach 5039c7
+20110101
Petr Lautrbach 5039c7
+  - Finally update for OpenSSH 5.6p1
Petr Lautrbach 5039c7
+  - Add GSSAPIServerIdentity option from Jim Basney
Petr Lautrbach 5039c7
+ 
Petr Lautrbach 5039c7
+20100308
Petr Lautrbach 5039c7
+  - [ Makefile.in, key.c, key.h ]
Petr Lautrbach 5039c7
+    Updates for OpenSSH 5.4p1
Petr Lautrbach 5039c7
+  - [ servconf.c ]
Petr Lautrbach 5039c7
+    Include GSSAPI options in the sshd -T configuration dump, and flag
Petr Lautrbach 5039c7
+    some older configuration options as being unsupported. Thanks to Colin 
Petr Lautrbach 5039c7
+    Watson.
Petr Lautrbach 5039c7
+  -
Petr Lautrbach 51ca3b
+
Petr Lautrbach 5039c7
+20100124
Petr Lautrbach 5039c7
+  - [ sshconnect2.c ]
Petr Lautrbach 5039c7
+    Adapt to deal with additional element in Authmethod structure. Thanks to
Petr Lautrbach 5039c7
+    Colin Watson
Petr Lautrbach 51ca3b
+
Petr Lautrbach 5039c7
+20090615
Petr Lautrbach 5039c7
+  - [ gss-genr.c gss-serv.c kexgssc.c kexgsss.c monitor.c sshconnect2.c
Petr Lautrbach 5039c7
+      sshd.c ]
Petr Lautrbach 5039c7
+    Fix issues identified by Greg Hudson following a code review
Petr Lautrbach 5039c7
+	Check return value of gss_indicate_mechs
Petr Lautrbach 5039c7
+	Protect GSSAPI calls in monitor, so they can only be used if enabled
Petr Lautrbach 5039c7
+	Check return values of bignum functions in key exchange
Petr Lautrbach 5039c7
+	Use BN_clear_free to clear other side's DH value
Petr Lautrbach 5039c7
+	Make ssh_gssapi_id_kex more robust
Petr Lautrbach 5039c7
+	Only configure kex table pointers if GSSAPI is enabled
Petr Lautrbach 5039c7
+	Don't leak mechanism list, or gss mechanism list
Petr Lautrbach 5039c7
+	Cast data.length before printing
Petr Lautrbach 5039c7
+	If serverkey isn't provided, use an empty string, rather than NULL
Petr Lautrbach 51ca3b
+
Petr Lautrbach 5039c7
+20090201
Petr Lautrbach 5039c7
+  - [ gss-genr.c gss-serv.c kex.h kexgssc.c readconf.c readconf.h ssh-gss.h
Petr Lautrbach 5039c7
+      ssh_config.5 sshconnet2.c ]
Petr Lautrbach 5039c7
+    Add support for the GSSAPIClientIdentity option, which allows the user
Petr Lautrbach 5039c7
+    to specify which GSSAPI identity to use to contact a given server
Petr Lautrbach 51ca3b
+
Petr Lautrbach 5039c7
+20080404
Petr Lautrbach 5039c7
+  - [ gss-serv.c ]
Petr Lautrbach 5039c7
+    Add code to actually implement GSSAPIStrictAcceptCheck, which had somehow
Petr Lautrbach 5039c7
+    been omitted from a previous version of this patch. Reported by Borislav
Petr Lautrbach 5039c7
+    Stoichkov
Petr Lautrbach 51ca3b
+
Petr Lautrbach 5039c7
+20070317
Petr Lautrbach 5039c7
+  - [ gss-serv-krb5.c ]
Petr Lautrbach 5039c7
+    Remove C99ism, where new_ccname was being declared in the middle of a 
Petr Lautrbach 5039c7
+    function
Petr Lautrbach 51ca3b
+
Petr Lautrbach 5039c7
+20061220
Petr Lautrbach 5039c7
+  - [ servconf.c ]
Petr Lautrbach 5039c7
+    Make default for GSSAPIStrictAcceptorCheck be Yes, to match previous, and 
Petr Lautrbach 5039c7
+    documented, behaviour. Reported by Dan Watson.
Petr Lautrbach 51ca3b
+
Petr Lautrbach 5039c7
+20060910
Petr Lautrbach 5039c7
+  - [ gss-genr.c kexgssc.c kexgsss.c kex.h monitor.c sshconnect2.c sshd.c
Petr Lautrbach 5039c7
+      ssh-gss.h ]
Petr Lautrbach 5039c7
+    add support for gss-group14-sha1 key exchange mechanisms
Petr Lautrbach 5039c7
+  - [ gss-serv.c servconf.c servconf.h sshd_config sshd_config.5 ]
Petr Lautrbach 5039c7
+    Add GSSAPIStrictAcceptorCheck option to allow the disabling of
Petr Lautrbach 5039c7
+    acceptor principal checking on multi-homed machines.
Petr Lautrbach 5039c7
+    <Bugzilla #928>
Petr Lautrbach 5039c7
+  - [ sshd_config ssh_config ]
Petr Lautrbach 5039c7
+    Add settings for GSSAPIKeyExchange and GSSAPITrustDNS to the sample
Petr Lautrbach 5039c7
+    configuration files
Petr Lautrbach 5039c7
+  - [ kexgss.c kegsss.c sshconnect2.c sshd.c ]
Petr Lautrbach 5039c7
+    Code cleanup. Replace strlen/xmalloc/snprintf sequences with xasprintf()
Petr Lautrbach 5039c7
+    Limit length of error messages displayed by client
Petr Lautrbach 51ca3b
+
Petr Lautrbach 5039c7
+20060909
Petr Lautrbach 5039c7
+  - [ gss-genr.c gss-serv.c ]
Petr Lautrbach 5039c7
+    move ssh_gssapi_acquire_cred() and ssh_gssapi_server_ctx to be server
Petr Lautrbach 5039c7
+    only, where they belong 
Petr Lautrbach 5039c7
+    <Bugzilla #1225>
Petr Lautrbach 5039c7
+
Petr Lautrbach 5039c7
+20060829
Petr Lautrbach 5039c7
+  - [ gss-serv-krb5.c ]
Petr Lautrbach 5039c7
+    Fix CCAPI credentials cache name when creating KRB5CCNAME environment 
Petr Lautrbach 5039c7
+    variable
Petr Lautrbach 5039c7
+
Petr Lautrbach 5039c7
+20060828
Petr Lautrbach 5039c7
+  - [ gss-genr.c ]
Petr Lautrbach 5039c7
+    Avoid Heimdal context freeing problem
Petr Lautrbach 5039c7
+    <Fixed upstream 20060829>
Petr Lautrbach 5039c7
+
Petr Lautrbach 5039c7
+20060818
Petr Lautrbach 5039c7
+  - [ gss-genr.c ssh-gss.h sshconnect2.c ]
Petr Lautrbach 5039c7
+    Make sure that SPENGO is disabled 
Petr Lautrbach 5039c7
+    <Bugzilla #1218 - Fixed upstream 20060818>
Petr Lautrbach 5039c7
+
Petr Lautrbach 5039c7
+20060421
Petr Lautrbach 5039c7
+  - [ gssgenr.c, sshconnect2.c ]
Petr Lautrbach 5039c7
+    a few type changes (signed versus unsigned, int versus size_t) to
Petr Lautrbach 5039c7
+    fix compiler errors/warnings 
Petr Lautrbach 5039c7
+    (from jbasney AT ncsa.uiuc.edu)
Petr Lautrbach 5039c7
+  - [ kexgssc.c, sshconnect2.c ]
Petr Lautrbach 5039c7
+    fix uninitialized variable warnings
Petr Lautrbach 5039c7
+    (from jbasney AT ncsa.uiuc.edu)
Petr Lautrbach 5039c7
+  - [ gssgenr.c ]
Petr Lautrbach 5039c7
+    pass oid to gss_display_status (helpful when using GSSAPI mechglue)
Petr Lautrbach 5039c7
+    (from jbasney AT ncsa.uiuc.edu)
Petr Lautrbach 5039c7
+    <Bugzilla #1220 >
Petr Lautrbach 5039c7
+  - [ gss-serv-krb5.c ]
Petr Lautrbach 5039c7
+    #ifdef HAVE_GSSAPI_KRB5 should be #ifdef HAVE_GSSAPI_KRB5_H
Petr Lautrbach 5039c7
+    (from jbasney AT ncsa.uiuc.edu)
Petr Lautrbach 5039c7
+    <Fixed upstream 20060304>
Petr Lautrbach 5039c7
+  - [ readconf.c, readconf.h, ssh_config.5, sshconnect2.c 
Petr Lautrbach 5039c7
+    add client-side GssapiKeyExchange option
Petr Lautrbach 5039c7
+    (from jbasney AT ncsa.uiuc.edu)
Petr Lautrbach 5039c7
+  - [ sshconnect2.c ]
Petr Lautrbach 5039c7
+    add support for GssapiTrustDns option for gssapi-with-mic
Petr Lautrbach 5039c7
+    (from jbasney AT ncsa.uiuc.edu)
Petr Lautrbach 5039c7
+    <gssapi-with-mic support is Bugzilla #1008>
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/clientloop.c.gsskex openssh-6.2p1/clientloop.c
Petr Lautrbach 8a29de
--- openssh-6.2p1/clientloop.c.gsskex	2013-03-27 13:19:11.001624842 +0100
Petr Lautrbach 8a29de
+++ openssh-6.2p1/clientloop.c	2013-03-27 13:19:11.141624267 +0100
Jan F. Chadima 69dd72
@@ -111,6 +111,10 @@
Jan F. Chadima 69dd72
 #include "msg.h"
Jan F. Chadima 69dd72
 #include "roaming.h"
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
+#ifdef GSSAPI
Jan F. Chadima 69dd72
+#include "ssh-gss.h"
Jan F. Chadima 69dd72
+#endif
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 /* import options */
Jan F. Chadima 69dd72
 extern Options options;
Jan F. Chadima 69dd72
 
Petr Lautrbach 8a29de
@@ -1599,6 +1603,15 @@ client_loop(int have_pty, int escape_cha
Jan F. Chadima 69dd72
 		/* Do channel operations unless rekeying in progress. */
Jan F. Chadima 69dd72
 		if (!rekeying) {
Jan F. Chadima 69dd72
 			channel_after_select(readset, writeset);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+#ifdef GSSAPI
Jan F. Chadima 69dd72
+			if (options.gss_renewal_rekey &&
Jan F. Chadima 69dd72
+			    ssh_gssapi_credentials_updated(GSS_C_NO_CONTEXT)) {
Jan F. Chadima 69dd72
+				debug("credentials updated - forcing rekey");
Jan F. Chadima 69dd72
+				need_rekeying = 1;
Jan F. Chadima 69dd72
+			}
Jan F. Chadima 69dd72
+#endif
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 			if (need_rekeying || packet_need_rekeying()) {
Jan F. Chadima 69dd72
 				debug("need rekeying");
Jan F. Chadima 69dd72
 				xxx_kex->done = 0;
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/configure.ac.gsskex openssh-6.2p1/configure.ac
Petr Lautrbach 8a29de
--- openssh-6.2p1/configure.ac.gsskex	2013-03-27 13:19:11.128624320 +0100
Petr Lautrbach 8a29de
+++ openssh-6.2p1/configure.ac	2013-03-27 13:19:11.142624263 +0100
Petr Lautrbach 8a29de
@@ -533,6 +533,30 @@ main() { if (NSVersionOfRunTimeLibrary("
Jan F. Chadima 69dd72
 	    [Use tunnel device compatibility to OpenBSD])
Jan F. Chadima 69dd72
 	AC_DEFINE([SSH_TUN_PREPEND_AF], [1],
Jan F. Chadima 69dd72
 	    [Prepend the address family to IP tunnel traffic])
Jan F. Chadima 69dd72
+	AC_MSG_CHECKING(if we have the Security Authorization Session API)
Jan F. Chadima 69dd72
+	AC_TRY_COMPILE([#include <Security/AuthSession.h>],
Jan F. Chadima 69dd72
+		[SessionCreate(0, 0);],
Jan F. Chadima 69dd72
+		[ac_cv_use_security_session_api="yes"
Jan F. Chadima 69dd72
+		 AC_DEFINE(USE_SECURITY_SESSION_API, 1, 
Jan F. Chadima 69dd72
+			[platform has the Security Authorization Session API])
Jan F. Chadima 69dd72
+		 LIBS="$LIBS -framework Security"
Jan F. Chadima 69dd72
+		 AC_MSG_RESULT(yes)],
Jan F. Chadima 69dd72
+		[ac_cv_use_security_session_api="no"
Jan F. Chadima 69dd72
+		 AC_MSG_RESULT(no)])
Jan F. Chadima 69dd72
+	AC_MSG_CHECKING(if we have an in-memory credentials cache)
Jan F. Chadima 69dd72
+	AC_TRY_COMPILE(
Jan F. Chadima 69dd72
+		[#include <Kerberos/Kerberos.h>],
Jan F. Chadima 69dd72
+		[cc_context_t c;
Jan F. Chadima 69dd72
+		 (void) cc_initialize (&c, 0, NULL, NULL);],
Jan F. Chadima 69dd72
+		[AC_DEFINE(USE_CCAPI, 1, 
Jan F. Chadima 69dd72
+			[platform uses an in-memory credentials cache])
Jan F. Chadima 69dd72
+		 LIBS="$LIBS -framework Security"
Jan F. Chadima 69dd72
+		 AC_MSG_RESULT(yes)
Jan F. Chadima 69dd72
+		 if test "x$ac_cv_use_security_session_api" = "xno"; then
Jan F. Chadima 69dd72
+			AC_MSG_ERROR(*** Need a security framework to use the credentials cache API ***)
Jan F. Chadima 69dd72
+		fi],
Jan F. Chadima 69dd72
+		[AC_MSG_RESULT(no)]
Jan F. Chadima 69dd72
+	)
Jan F. Chadima 69dd72
 	m4_pattern_allow([AU_IPv])
Jan F. Chadima 69dd72
 	AC_CHECK_DECL([AU_IPv4], [], 
Jan F. Chadima 69dd72
 	    AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records])
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/gss-genr.c.gsskex openssh-6.2p1/gss-genr.c
Petr Lautrbach 8a29de
--- openssh-6.2p1/gss-genr.c.gsskex	2009-06-22 08:11:07.000000000 +0200
Petr Lautrbach 8a29de
+++ openssh-6.2p1/gss-genr.c	2013-03-27 13:19:11.142624263 +0100
Jan F. Chadima 69dd72
@@ -1,7 +1,7 @@
Jan F. Chadima 69dd72
 /* $OpenBSD: gss-genr.c,v 1.20 2009/06/22 05:39:28 dtucker Exp $ */
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 /*
Jan F. Chadima 69dd72
- * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved.
Jan F. Chadima 69dd72
+ * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
Jan F. Chadima 69dd72
  *
Jan F. Chadima 69dd72
  * Redistribution and use in source and binary forms, with or without
Jan F. Chadima 69dd72
  * modification, are permitted provided that the following conditions
Jan F. Chadima 69dd72
@@ -39,12 +39,167 @@
Jan F. Chadima 69dd72
 #include "buffer.h"
Jan F. Chadima 69dd72
 #include "log.h"
Jan F. Chadima 69dd72
 #include "ssh2.h"
Jan F. Chadima 69dd72
+#include "cipher.h"
Jan F. Chadima 69dd72
+#include "key.h"
Jan F. Chadima 69dd72
+#include "kex.h"
Jan F. Chadima 69dd72
+#include <openssl/evp.h>
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 #include "ssh-gss.h"
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 extern u_char *session_id2;
Jan F. Chadima 69dd72
 extern u_int session_id2_len;
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
+typedef struct {
Jan F. Chadima 69dd72
+	char *encoded;
Jan F. Chadima 69dd72
+	gss_OID oid;
Jan F. Chadima 69dd72
+} ssh_gss_kex_mapping;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+/*
Jan F. Chadima 69dd72
+ * XXX - It would be nice to find a more elegant way of handling the
Jan F. Chadima 69dd72
+ * XXX   passing of the key exchange context to the userauth routines
Jan F. Chadima 69dd72
+ */
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+Gssctxt *gss_kex_context = NULL;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+static ssh_gss_kex_mapping *gss_enc2oid = NULL;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+int 
Jan F. Chadima 69dd72
+ssh_gssapi_oid_table_ok() {
Jan F. Chadima 69dd72
+	return (gss_enc2oid != NULL);
Jan F. Chadima 69dd72
+}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+/*
Jan F. Chadima 69dd72
+ * Return a list of the gss-group1-sha1 mechanisms supported by this program
Jan F. Chadima 69dd72
+ *
Jan F. Chadima 69dd72
+ * We test mechanisms to ensure that we can use them, to avoid starting
Jan F. Chadima 69dd72
+ * a key exchange with a bad mechanism
Jan F. Chadima 69dd72
+ */
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+char *
Jan F. Chadima 69dd72
+ssh_gssapi_client_mechanisms(const char *host, const char *client) {
Jan F. Chadima 69dd72
+	gss_OID_set gss_supported;
Jan F. Chadima 69dd72
+	OM_uint32 min_status;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (GSS_ERROR(gss_indicate_mechs(&min_status, &gss_supported)))
Jan F. Chadima 69dd72
+		return NULL;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	return(ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism,
Jan F. Chadima 69dd72
+	    host, client));
Jan F. Chadima 69dd72
+}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+char *
Jan F. Chadima 69dd72
+ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check,
Jan F. Chadima 69dd72
+    const char *host, const char *client) {
Jan F. Chadima 69dd72
+	Buffer buf;
Jan F. Chadima 69dd72
+	size_t i;
Jan F. Chadima 69dd72
+	int oidpos, enclen;
Jan F. Chadima 69dd72
+	char *mechs, *encoded;
Jan F. Chadima 69dd72
+	u_char digest[EVP_MAX_MD_SIZE];
Jan F. Chadima 69dd72
+	char deroid[2];
Jan F. Chadima 69dd72
+	const EVP_MD *evp_md = EVP_md5();
Jan F. Chadima 69dd72
+	EVP_MD_CTX md;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (gss_enc2oid != NULL) {
Jan F. Chadima 69dd72
+		for (i = 0; gss_enc2oid[i].encoded != NULL; i++)
Jan F. Chadima 69dd72
+			xfree(gss_enc2oid[i].encoded);
Jan F. Chadima 69dd72
+		xfree(gss_enc2oid);
Jan F. Chadima 69dd72
+	}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	gss_enc2oid = xmalloc(sizeof(ssh_gss_kex_mapping) *
Jan F. Chadima 69dd72
+	    (gss_supported->count + 1));
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	buffer_init(&buf;;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	oidpos = 0;
Jan F. Chadima 69dd72
+	for (i = 0; i < gss_supported->count; i++) {
Jan F. Chadima 69dd72
+		if (gss_supported->elements[i].length < 128 &&
Jan F. Chadima 69dd72
+		    (*check)(NULL, &(gss_supported->elements[i]), host, client)) {
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+			deroid[0] = SSH_GSS_OIDTYPE;
Jan F. Chadima 69dd72
+			deroid[1] = gss_supported->elements[i].length;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+			EVP_DigestInit(&md, evp_md);
Jan F. Chadima 69dd72
+			EVP_DigestUpdate(&md, deroid, 2);
Jan F. Chadima 69dd72
+			EVP_DigestUpdate(&md,
Jan F. Chadima 69dd72
+			    gss_supported->elements[i].elements,
Jan F. Chadima 69dd72
+			    gss_supported->elements[i].length);
Jan F. Chadima 69dd72
+			EVP_DigestFinal(&md, digest, NULL);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+			encoded = xmalloc(EVP_MD_size(evp_md) * 2);
Jan F. Chadima 69dd72
+			enclen = __b64_ntop(digest, EVP_MD_size(evp_md),
Jan F. Chadima 69dd72
+			    encoded, EVP_MD_size(evp_md) * 2);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+			if (oidpos != 0)
Jan F. Chadima 69dd72
+				buffer_put_char(&buf, ',');
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+			buffer_append(&buf, KEX_GSS_GEX_SHA1_ID,
Jan F. Chadima 69dd72
+			    sizeof(KEX_GSS_GEX_SHA1_ID) - 1);
Jan F. Chadima 69dd72
+			buffer_append(&buf, encoded, enclen);
Jan F. Chadima 69dd72
+			buffer_put_char(&buf, ',');
Jan F. Chadima 69dd72
+			buffer_append(&buf, KEX_GSS_GRP1_SHA1_ID, 
Jan F. Chadima 69dd72
+			    sizeof(KEX_GSS_GRP1_SHA1_ID) - 1);
Jan F. Chadima 69dd72
+			buffer_append(&buf, encoded, enclen);
Jan F. Chadima 69dd72
+			buffer_put_char(&buf, ',');
Jan F. Chadima 69dd72
+			buffer_append(&buf, KEX_GSS_GRP14_SHA1_ID,
Jan F. Chadima 69dd72
+			    sizeof(KEX_GSS_GRP14_SHA1_ID) - 1);
Jan F. Chadima 69dd72
+			buffer_append(&buf, encoded, enclen);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+			gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]);
Jan F. Chadima 69dd72
+			gss_enc2oid[oidpos].encoded = encoded;
Jan F. Chadima 69dd72
+			oidpos++;
Jan F. Chadima 69dd72
+		}
Jan F. Chadima 69dd72
+	}
Jan F. Chadima 69dd72
+	gss_enc2oid[oidpos].oid = NULL;
Jan F. Chadima 69dd72
+	gss_enc2oid[oidpos].encoded = NULL;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	buffer_put_char(&buf, '\0');
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	mechs = xmalloc(buffer_len(&buf));
Jan F. Chadima 69dd72
+	buffer_get(&buf, mechs, buffer_len(&buf));
Jan F. Chadima 69dd72
+	buffer_free(&buf;;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (strlen(mechs) == 0) {
Jan F. Chadima 69dd72
+		xfree(mechs);
Jan F. Chadima 69dd72
+		mechs = NULL;
Jan F. Chadima 69dd72
+	}
Jan F. Chadima 69dd72
+	
Jan F. Chadima 69dd72
+	return (mechs);
Jan F. Chadima 69dd72
+}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+gss_OID
Jan F. Chadima 69dd72
+ssh_gssapi_id_kex(Gssctxt *ctx, char *name, int kex_type) {
Jan F. Chadima 69dd72
+	int i = 0;
Jan F. Chadima 69dd72
+	
Jan F. Chadima 69dd72
+	switch (kex_type) {
Jan F. Chadima 69dd72
+	case KEX_GSS_GRP1_SHA1:
Jan F. Chadima 69dd72
+		if (strlen(name) < sizeof(KEX_GSS_GRP1_SHA1_ID))
Jan F. Chadima 69dd72
+			return GSS_C_NO_OID;
Jan F. Chadima 69dd72
+		name += sizeof(KEX_GSS_GRP1_SHA1_ID) - 1;
Jan F. Chadima 69dd72
+		break;
Jan F. Chadima 69dd72
+	case KEX_GSS_GRP14_SHA1:
Jan F. Chadima 69dd72
+		if (strlen(name) < sizeof(KEX_GSS_GRP14_SHA1_ID))
Jan F. Chadima 69dd72
+			return GSS_C_NO_OID;
Jan F. Chadima 69dd72
+		name += sizeof(KEX_GSS_GRP14_SHA1_ID) - 1;
Jan F. Chadima 69dd72
+		break;
Jan F. Chadima 69dd72
+	case KEX_GSS_GEX_SHA1:
Jan F. Chadima 69dd72
+		if (strlen(name) < sizeof(KEX_GSS_GEX_SHA1_ID))
Jan F. Chadima 69dd72
+			return GSS_C_NO_OID;
Jan F. Chadima 69dd72
+		name += sizeof(KEX_GSS_GEX_SHA1_ID) - 1;
Jan F. Chadima 69dd72
+		break;
Jan F. Chadima 69dd72
+	default:
Jan F. Chadima 69dd72
+		return GSS_C_NO_OID;
Jan F. Chadima 69dd72
+	}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	while (gss_enc2oid[i].encoded != NULL &&
Jan F. Chadima 69dd72
+	    strcmp(name, gss_enc2oid[i].encoded) != 0)
Jan F. Chadima 69dd72
+		i++;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (gss_enc2oid[i].oid != NULL && ctx != NULL)
Jan F. Chadima 69dd72
+		ssh_gssapi_set_oid(ctx, gss_enc2oid[i].oid);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	return gss_enc2oid[i].oid;
Jan F. Chadima 69dd72
+}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 /* Check that the OID in a data stream matches that in the context */
Jan F. Chadima 69dd72
 int
Jan F. Chadima 69dd72
 ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len)
Jan F. Chadima 69dd72
@@ -197,7 +352,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int de
Jan F. Chadima 69dd72
 	}
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 	ctx->major = gss_init_sec_context(&ctx->minor,
Jan F. Chadima 69dd72
-	    GSS_C_NO_CREDENTIAL, &ctx->context, ctx->name, ctx->oid,
Jan F. Chadima 69dd72
+	    ctx->client_creds, &ctx->context, ctx->name, ctx->oid,
Jan F. Chadima 69dd72
 	    GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag,
Jan F. Chadima 69dd72
 	    0, NULL, recv_tok, NULL, send_tok, flags, NULL);
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
@@ -227,8 +382,42 @@ ssh_gssapi_import_name(Gssctxt *ctx, con
Jan F. Chadima 69dd72
 }
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 OM_uint32
Jan F. Chadima 69dd72
+ssh_gssapi_client_identity(Gssctxt *ctx, const char *name)
Jan F. Chadima 69dd72
+{
Jan F. Chadima 69dd72
+	gss_buffer_desc gssbuf;
Jan F. Chadima 69dd72
+	gss_name_t gssname;
Jan F. Chadima 69dd72
+	OM_uint32 status;
Jan F. Chadima 69dd72
+	gss_OID_set oidset;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	gssbuf.value = (void *) name;
Jan F. Chadima 69dd72
+	gssbuf.length = strlen(gssbuf.value);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	gss_create_empty_oid_set(&status, &oidset);
Jan F. Chadima 69dd72
+	gss_add_oid_set_member(&status, ctx->oid, &oidset);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	ctx->major = gss_import_name(&ctx->minor, &gssbuf,
Jan F. Chadima 69dd72
+	    GSS_C_NT_USER_NAME, &gssname);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (!ctx->major)
Jan F. Chadima 69dd72
+		ctx->major = gss_acquire_cred(&ctx->minor, 
Jan F. Chadima 69dd72
+		    gssname, 0, oidset, GSS_C_INITIATE, 
Jan F. Chadima 69dd72
+		    &ctx->client_creds, NULL, NULL);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	gss_release_name(&status, &gssname);
Jan F. Chadima 69dd72
+	gss_release_oid_set(&status, &oidset);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (ctx->major)
Jan F. Chadima 69dd72
+		ssh_gssapi_error(ctx);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	return(ctx->major);
Jan F. Chadima 69dd72
+}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+OM_uint32
Jan F. Chadima 69dd72
 ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash)
Jan F. Chadima 69dd72
 {
Jan F. Chadima 69dd72
+	if (ctx == NULL) 
Jan F. Chadima 69dd72
+		return -1;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 	if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context,
Jan F. Chadima 69dd72
 	    GSS_C_QOP_DEFAULT, buffer, hash)))
Jan F. Chadima 69dd72
 		ssh_gssapi_error(ctx);
Jan F. Chadima 69dd72
@@ -236,6 +425,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer
Jan F. Chadima 69dd72
 	return (ctx->major);
Jan F. Chadima 69dd72
 }
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
+/* Priviledged when used by server */
Jan F. Chadima 69dd72
+OM_uint32
Jan F. Chadima 69dd72
+ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
Jan F. Chadima 69dd72
+{
Jan F. Chadima 69dd72
+	if (ctx == NULL)
Jan F. Chadima 69dd72
+		return -1;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	ctx->major = gss_verify_mic(&ctx->minor, ctx->context,
Jan F. Chadima 69dd72
+	    gssbuf, gssmic, NULL);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	return (ctx->major);
Jan F. Chadima 69dd72
+}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 void
Jan F. Chadima 69dd72
 ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service,
Jan F. Chadima 69dd72
     const char *context)
Jan F. Chadima 69dd72
@@ -249,11 +451,16 @@ ssh_gssapi_buildmic(Buffer *b, const cha
Jan F. Chadima 69dd72
 }
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 int
Jan F. Chadima 69dd72
-ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host)
Jan F. Chadima 69dd72
+ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host, 
Jan F. Chadima 69dd72
+    const char *client)
Jan F. Chadima 69dd72
 {
Jan F. Chadima 69dd72
 	gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
Jan F. Chadima 69dd72
 	OM_uint32 major, minor;
Jan F. Chadima 69dd72
 	gss_OID_desc spnego_oid = {6, (void *)"\x2B\x06\x01\x05\x05\x02"};
Jan F. Chadima 69dd72
+	Gssctxt *intctx = NULL;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (ctx == NULL)
Jan F. Chadima 69dd72
+		ctx = &intct;;
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 	/* RFC 4462 says we MUST NOT do SPNEGO */
Jan F. Chadima 69dd72
 	if (oid->length == spnego_oid.length && 
Jan F. Chadima 69dd72
@@ -263,6 +470,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx
Jan F. Chadima 69dd72
 	ssh_gssapi_build_ctx(ctx);
Jan F. Chadima 69dd72
 	ssh_gssapi_set_oid(*ctx, oid);
Jan F. Chadima 69dd72
 	major = ssh_gssapi_import_name(*ctx, host);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (!GSS_ERROR(major) && client)
Jan F. Chadima 69dd72
+		major = ssh_gssapi_client_identity(*ctx, client);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 	if (!GSS_ERROR(major)) {
Jan F. Chadima 69dd72
 		major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, 
Jan F. Chadima 69dd72
 		    NULL);
Jan F. Chadima 69dd72
@@ -272,10 +483,67 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx
Jan F. Chadima 69dd72
 			    GSS_C_NO_BUFFER);
Jan F. Chadima 69dd72
 	}
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
-	if (GSS_ERROR(major)) 
Jan F. Chadima 69dd72
+	if (GSS_ERROR(major) || intctx != NULL) 
Jan F. Chadima 69dd72
 		ssh_gssapi_delete_ctx(ctx);
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 	return (!GSS_ERROR(major));
Jan F. Chadima 69dd72
 }
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
+int
Jan F. Chadima 69dd72
+ssh_gssapi_credentials_updated(Gssctxt *ctxt) {
Jan F. Chadima 69dd72
+	static gss_name_t saved_name = GSS_C_NO_NAME;
Jan F. Chadima 69dd72
+	static OM_uint32 saved_lifetime = 0;
Jan F. Chadima 69dd72
+	static gss_OID saved_mech = GSS_C_NO_OID;
Jan F. Chadima 69dd72
+	static gss_name_t name;
Jan F. Chadima 69dd72
+	static OM_uint32 last_call = 0;
Jan F. Chadima 69dd72
+	OM_uint32 lifetime, now, major, minor;
Jan F. Chadima 69dd72
+	int equal;
Jan F. Chadima 69dd72
+	gss_cred_usage_t usage = GSS_C_INITIATE;
Jan F. Chadima 69dd72
+	
Jan F. Chadima 69dd72
+	now = time(NULL);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (ctxt) {
Jan F. Chadima 69dd72
+		debug("Rekey has happened - updating saved versions");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		if (saved_name != GSS_C_NO_NAME)
Jan F. Chadima 69dd72
+			gss_release_name(&minor, &saved_name);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		major = gss_inquire_cred(&minor, GSS_C_NO_CREDENTIAL,
Jan F. Chadima 69dd72
+		    &saved_name, &saved_lifetime, NULL, NULL);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		if (!GSS_ERROR(major)) {
Jan F. Chadima 69dd72
+			saved_mech = ctxt->oid;
Jan F. Chadima 69dd72
+		        saved_lifetime+= now;
Jan F. Chadima 69dd72
+		} else {
Jan F. Chadima 69dd72
+			/* Handle the error */
Jan F. Chadima 69dd72
+		}
Jan F. Chadima 69dd72
+		return 0;
Jan F. Chadima 69dd72
+	}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (now - last_call < 10)
Jan F. Chadima 69dd72
+		return 0;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	last_call = now;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (saved_mech == GSS_C_NO_OID)
Jan F. Chadima 69dd72
+		return 0;
Jan F. Chadima 69dd72
+	
Jan F. Chadima 69dd72
+	major = gss_inquire_cred(&minor, GSS_C_NO_CREDENTIAL, 
Jan F. Chadima 69dd72
+	    &name, &lifetime, NULL, NULL);
Jan F. Chadima 69dd72
+	if (major == GSS_S_CREDENTIALS_EXPIRED)
Jan F. Chadima 69dd72
+		return 0;
Jan F. Chadima 69dd72
+	else if (GSS_ERROR(major))
Jan F. Chadima 69dd72
+		return 0;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	major = gss_compare_name(&minor, saved_name, name, &equal);
Jan F. Chadima 69dd72
+	gss_release_name(&minor, &name);
Jan F. Chadima 69dd72
+	if (GSS_ERROR(major))
Jan F. Chadima 69dd72
+		return 0;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (equal && (saved_lifetime < lifetime + now - 10))
Jan F. Chadima 69dd72
+		return 1;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	return 0;
Jan F. Chadima 69dd72
+}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 #endif /* GSSAPI */
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/gss-serv.c.gsskex openssh-6.2p1/gss-serv.c
Petr Lautrbach 8a29de
--- openssh-6.2p1/gss-serv.c.gsskex	2011-08-05 22:16:46.000000000 +0200
Petr Lautrbach 8a29de
+++ openssh-6.2p1/gss-serv.c	2013-03-27 13:19:11.142624263 +0100
Jan F. Chadima 69dd72
@@ -45,15 +45,20 @@
Jan F. Chadima 69dd72
 #include "channels.h"
Jan F. Chadima 69dd72
 #include "session.h"
Jan F. Chadima 69dd72
 #include "misc.h"
Jan F. Chadima 69dd72
+#include "servconf.h"
Jan F. Chadima 69dd72
+#include "uidswap.h"
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 #include "ssh-gss.h"
Jan F. Chadima 69dd72
+#include "monitor_wrap.h"
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+extern ServerOptions options;
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 static ssh_gssapi_client gssapi_client =
Jan F. Chadima 69dd72
     { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER,
Jan F. Chadima 69dd72
-    GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL}};
Jan F. Chadima 69dd72
+    GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME,  NULL, {NULL, NULL, NULL}, 0, 0};
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 ssh_gssapi_mech gssapi_null_mech =
Jan F. Chadima 69dd72
-    { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL};
Jan F. Chadima 69dd72
+    { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL, NULL};
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 #ifdef KRB5
Jan F. Chadima 69dd72
 extern ssh_gssapi_mech gssapi_kerberos_mech;
Jan F. Chadima 69dd72
@@ -81,25 +86,32 @@ ssh_gssapi_acquire_cred(Gssctxt *ctx)
Jan F. Chadima 69dd72
 	char lname[MAXHOSTNAMELEN];
Jan F. Chadima 69dd72
 	gss_OID_set oidset;
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
-	gss_create_empty_oid_set(&status, &oidset);
Jan F. Chadima 69dd72
-	gss_add_oid_set_member(&status, ctx->oid, &oidset);
Jan F. Chadima 69dd72
+	if (options.gss_strict_acceptor) {
Jan F. Chadima 69dd72
+		gss_create_empty_oid_set(&status, &oidset);
Jan F. Chadima 69dd72
+		gss_add_oid_set_member(&status, ctx->oid, &oidset);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		if (gethostname(lname, MAXHOSTNAMELEN)) {
Jan F. Chadima 69dd72
+			gss_release_oid_set(&status, &oidset);
Jan F. Chadima 69dd72
+			return (-1);
Jan F. Chadima 69dd72
+		}
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
-	if (gethostname(lname, MAXHOSTNAMELEN)) {
Jan F. Chadima 69dd72
-		gss_release_oid_set(&status, &oidset);
Jan F. Chadima 69dd72
-		return (-1);
Jan F. Chadima 69dd72
-	}
Jan F. Chadima 69dd72
+		if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) {
Jan F. Chadima 69dd72
+			gss_release_oid_set(&status, &oidset);
Jan F. Chadima 69dd72
+			return (ctx->major);
Jan F. Chadima 69dd72
+		}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		if ((ctx->major = gss_acquire_cred(&ctx->minor,
Jan F. Chadima 69dd72
+		    ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, 
Jan F. Chadima 69dd72
+		    NULL, NULL)))
Jan F. Chadima 69dd72
+			ssh_gssapi_error(ctx);
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
-	if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) {
Jan F. Chadima 69dd72
 		gss_release_oid_set(&status, &oidset);
Jan F. Chadima 69dd72
 		return (ctx->major);
Jan F. Chadima 69dd72
+	} else {
Jan F. Chadima 69dd72
+		ctx->name = GSS_C_NO_NAME;
Jan F. Chadima 69dd72
+		ctx->creds = GSS_C_NO_CREDENTIAL;
Jan F. Chadima 69dd72
 	}
Jan F. Chadima 69dd72
-
Jan F. Chadima 69dd72
-	if ((ctx->major = gss_acquire_cred(&ctx->minor,
Jan F. Chadima 69dd72
-	    ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL)))
Jan F. Chadima 69dd72
-		ssh_gssapi_error(ctx);
Jan F. Chadima 69dd72
-
Jan F. Chadima 69dd72
-	gss_release_oid_set(&status, &oidset);
Jan F. Chadima 69dd72
-	return (ctx->major);
Jan F. Chadima 69dd72
+	return GSS_S_COMPLETE;
Jan F. Chadima 69dd72
 }
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 /* Privileged */
Jan F. Chadima 69dd72
@@ -114,6 +126,29 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss
Jan F. Chadima 69dd72
 }
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 /* Unprivileged */
Jan F. Chadima 69dd72
+char *
Jan F. Chadima 69dd72
+ssh_gssapi_server_mechanisms() {
Jan F. Chadima 69dd72
+	gss_OID_set	supported;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	ssh_gssapi_supported_oids(&supported);
Jan F. Chadima 69dd72
+	return (ssh_gssapi_kex_mechs(supported, &ssh_gssapi_server_check_mech,
Jan F. Chadima 69dd72
+	    NULL, NULL));
Jan F. Chadima 69dd72
+}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+/* Unprivileged */
Jan F. Chadima 69dd72
+int
Jan F. Chadima 69dd72
+ssh_gssapi_server_check_mech(Gssctxt **dum, gss_OID oid, const char *data,
Jan F. Chadima 69dd72
+    const char *dummy) {
Jan F. Chadima 69dd72
+	Gssctxt *ctx = NULL;
Jan F. Chadima 69dd72
+	int res;
Jan F. Chadima 69dd72
+ 
Jan F. Chadima 69dd72
+	res = !GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx, oid)));
Jan F. Chadima 69dd72
+	ssh_gssapi_delete_ctx(&ctx;;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	return (res);
Jan F. Chadima 69dd72
+}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+/* Unprivileged */
Jan F. Chadima 69dd72
 void
Jan F. Chadima 69dd72
 ssh_gssapi_supported_oids(gss_OID_set *oidset)
Jan F. Chadima 69dd72
 {
Jan F. Chadima 69dd72
@@ -123,7 +158,9 @@ ssh_gssapi_supported_oids(gss_OID_set *o
Jan F. Chadima 69dd72
 	gss_OID_set supported;
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 	gss_create_empty_oid_set(&min_status, oidset);
Jan F. Chadima 69dd72
-	gss_indicate_mechs(&min_status, &supported);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (GSS_ERROR(gss_indicate_mechs(&min_status, &supported)))
Jan F. Chadima 69dd72
+		return;
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 	while (supported_mechs[i]->name != NULL) {
Jan F. Chadima 69dd72
 		if (GSS_ERROR(gss_test_oid_set_member(&min_status,
Jan F. Chadima 69dd72
@@ -249,8 +286,48 @@ OM_uint32
Jan F. Chadima 69dd72
 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
Jan F. Chadima 69dd72
 {
Jan F. Chadima 69dd72
 	int i = 0;
Jan F. Chadima 69dd72
+	int equal = 0;
Jan F. Chadima 69dd72
+	gss_name_t new_name = GSS_C_NO_NAME;
Jan F. Chadima 69dd72
+	gss_buffer_desc ename = GSS_C_EMPTY_BUFFER;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (options.gss_store_rekey && client->used && ctx->client_creds) {
Jan F. Chadima 69dd72
+		if (client->mech->oid.length != ctx->oid->length ||
Jan F. Chadima 69dd72
+		    (memcmp(client->mech->oid.elements,
Jan F. Chadima 69dd72
+		     ctx->oid->elements, ctx->oid->length) !=0)) {
Jan F. Chadima 69dd72
+			debug("Rekeyed credentials have different mechanism");
Jan F. Chadima 69dd72
+			return GSS_S_COMPLETE;
Jan F. Chadima 69dd72
+		}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		if ((ctx->major = gss_inquire_cred_by_mech(&ctx->minor, 
Jan F. Chadima 69dd72
+		    ctx->client_creds, ctx->oid, &new_name, 
Jan F. Chadima 69dd72
+		    NULL, NULL, NULL))) {
Jan F. Chadima 69dd72
+			ssh_gssapi_error(ctx);
Jan F. Chadima 69dd72
+			return (ctx->major);
Jan F. Chadima 69dd72
+		}
Petr Lautrbach 51ca3b
 
Petr Lautrbach 51ca3b
-	gss_buffer_desc ename;
Jan F. Chadima 69dd72
+		ctx->major = gss_compare_name(&ctx->minor, client->name, 
Jan F. Chadima 69dd72
+		    new_name, &equal);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		if (GSS_ERROR(ctx->major)) {
Jan F. Chadima 69dd72
+			ssh_gssapi_error(ctx);
Jan F. Chadima 69dd72
+			return (ctx->major);
Jan F. Chadima 69dd72
+		}
Jan F. Chadima 69dd72
+ 
Jan F. Chadima 69dd72
+		if (!equal) {
Jan F. Chadima 69dd72
+			debug("Rekeyed credentials have different name");
Jan F. Chadima 69dd72
+			return GSS_S_COMPLETE;
Jan F. Chadima 69dd72
+		}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		debug("Marking rekeyed credentials for export");
Petr Lautrbach 51ca3b
+
Jan F. Chadima 69dd72
+		gss_release_name(&ctx->minor, &client->name);
Jan F. Chadima 69dd72
+		gss_release_cred(&ctx->minor, &client->creds);
Jan F. Chadima 69dd72
+		client->name = new_name;
Jan F. Chadima 69dd72
+		client->creds = ctx->client_creds;
Jan F. Chadima 69dd72
+        	ctx->client_creds = GSS_C_NO_CREDENTIAL;
Jan F. Chadima 69dd72
+		client->updated = 1;
Jan F. Chadima 69dd72
+		return GSS_S_COMPLETE;
Jan F. Chadima 69dd72
+	}
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 	client->mech = NULL;
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
@@ -265,6 +342,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g
Jan F. Chadima 69dd72
 	if (client->mech == NULL)
Jan F. Chadima 69dd72
 		return GSS_S_FAILURE;
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
+	if (ctx->client_creds &&
Jan F. Chadima 69dd72
+	    (ctx->major = gss_inquire_cred_by_mech(&ctx->minor,
Jan F. Chadima 69dd72
+	     ctx->client_creds, ctx->oid, &client->name, NULL, NULL, NULL))) {
Jan F. Chadima 69dd72
+		ssh_gssapi_error(ctx);
Jan F. Chadima 69dd72
+		return (ctx->major);
Jan F. Chadima 69dd72
+	}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 	if ((ctx->major = gss_display_name(&ctx->minor, ctx->client,
Jan F. Chadima 69dd72
 	    &client->displayname, NULL))) {
Jan F. Chadima 69dd72
 		ssh_gssapi_error(ctx);
Jan F. Chadima 69dd72
@@ -282,6 +366,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g
Jan F. Chadima 69dd72
 		return (ctx->major);
Jan F. Chadima 69dd72
 	}
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
+	gss_release_buffer(&ctx->minor, &ename);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 	/* We can't copy this structure, so we just move the pointer to it */
Jan F. Chadima 69dd72
 	client->creds = ctx->client_creds;
Jan F. Chadima 69dd72
 	ctx->client_creds = GSS_C_NO_CREDENTIAL;
Petr Lautrbach 51ca3b
@@ -292,11 +378,33 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g
Petr Lautrbach 51ca3b
 void
Petr Lautrbach 51ca3b
 ssh_gssapi_cleanup_creds(void)
Petr Lautrbach 51ca3b
 {
Petr Lautrbach 51ca3b
+	struct stat krb5_ccname_stat;
Petr Lautrbach 51ca3b
+	char krb5_ccname[128], *krb5_ccname_dir_end;
Petr Lautrbach 51ca3b
+
Petr Lautrbach 51ca3b
 	if (gssapi_client.store.filename != NULL) {
Petr Lautrbach 51ca3b
 		/* Unlink probably isn't sufficient */
Petr Lautrbach 51ca3b
 		debug("removing gssapi cred file\"%s\"",
Petr Lautrbach 51ca3b
 		    gssapi_client.store.filename);
Petr Lautrbach 51ca3b
 		unlink(gssapi_client.store.filename);
Petr Lautrbach 51ca3b
+
Petr Lautrbach aacd01
+		/* Ticket cache: DIR::/run/user/13558/krb5cc_T9eDKSQvzb/tkt */
Petr Lautrbach 51ca3b
+		/* same code as in auth-krb5.c:krb5_cleanup_proc */
Petr Lautrbach 51ca3b
+		strncpy(krb5_ccname, gssapi_client.store.filename, sizeof(krb5_ccname) - 10);
Petr Lautrbach 51ca3b
+		krb5_ccname_dir_end = strrchr(krb5_ccname, '/');
Petr Lautrbach 51ca3b
+		if (krb5_ccname_dir_end != NULL)
Petr Lautrbach 51ca3b
+			strcpy(krb5_ccname_dir_end, "/primary");
Petr Lautrbach 51ca3b
+
Petr Lautrbach 51ca3b
+		if (stat(krb5_ccname, &krb5_ccname_stat) == 0) {
Petr Lautrbach 51ca3b
+			if (unlink(krb5_ccname) == 0) {
Petr Lautrbach 51ca3b
+				*krb5_ccname_dir_end = '\0';
Petr Lautrbach 51ca3b
+				if (rmdir(krb5_ccname) == -1)
Petr Lautrbach 51ca3b
+					debug("cache dir '%s' remove failed: %s", krb5_ccname, strerror(errno));
Petr Lautrbach 51ca3b
+			}
Petr Lautrbach 51ca3b
+			else
Petr Lautrbach 51ca3b
+				debug("cache primary file '%s', remove failed: %s",
Petr Lautrbach 51ca3b
+					krb5_ccname, strerror(errno)
Petr Lautrbach 51ca3b
+				);
Petr Lautrbach 51ca3b
+		}
Petr Lautrbach 51ca3b
 	}
Petr Lautrbach 51ca3b
 }
Petr Lautrbach 51ca3b
 
Petr Lautrbach 51ca3b
@@ -329,7 +437,7 @@ ssh_gssapi_do_child(char ***envp, u_int
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 /* Privileged */
Jan F. Chadima 69dd72
 int
Jan F. Chadima 69dd72
-ssh_gssapi_userok(char *user)
Jan F. Chadima 69dd72
+ssh_gssapi_userok(char *user, struct passwd *pw)
Jan F. Chadima 69dd72
 {
Jan F. Chadima 69dd72
 	OM_uint32 lmin;
Jan F. Chadima 69dd72
 
Petr Lautrbach 51ca3b
@@ -339,9 +447,11 @@ ssh_gssapi_userok(char *user)
Jan F. Chadima 69dd72
 		return 0;
Jan F. Chadima 69dd72
 	}
Jan F. Chadima 69dd72
 	if (gssapi_client.mech && gssapi_client.mech->userok)
Jan F. Chadima 69dd72
-		if ((*gssapi_client.mech->userok)(&gssapi_client, user))
Jan F. Chadima 69dd72
+		if ((*gssapi_client.mech->userok)(&gssapi_client, user)) {
Jan F. Chadima 69dd72
+			gssapi_client.used = 1;
Jan F. Chadima 69dd72
+			gssapi_client.store.owner = pw;
Jan F. Chadima 69dd72
 			return 1;
Jan F. Chadima 69dd72
-		else {
Jan F. Chadima 69dd72
+		} else {
Jan F. Chadima 69dd72
 			/* Destroy delegated credentials if userok fails */
Jan F. Chadima 69dd72
 			gss_release_buffer(&lmin, &gssapi_client.displayname);
Jan F. Chadima 69dd72
 			gss_release_buffer(&lmin, &gssapi_client.exportedname);
Petr Lautrbach 51ca3b
@@ -354,14 +464,90 @@ ssh_gssapi_userok(char *user)
Jan F. Chadima 69dd72
 	return (0);
Jan F. Chadima 69dd72
 }
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
-/* Privileged */
Jan F. Chadima 69dd72
-OM_uint32
Jan F. Chadima 69dd72
-ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
Jan F. Chadima 69dd72
+/* These bits are only used for rekeying. The unpriviledged child is running 
Jan F. Chadima 69dd72
+ * as the user, the monitor is root.
Jan F. Chadima 69dd72
+ *
Jan F. Chadima 69dd72
+ * In the child, we want to :
Jan F. Chadima 69dd72
+ *    *) Ask the monitor to store our credentials into the store we specify
Jan F. Chadima 69dd72
+ *    *) If it succeeds, maybe do a PAM update
Jan F. Chadima 69dd72
+ */
Jan F. Chadima 69dd72
+
Petr Lautrbach d9e618
+/* Stuff for PAM */
Petr Lautrbach d9e618
+
Petr Lautrbach d9e618
+#ifdef USE_PAM
Petr Lautrbach d9e618
+static int ssh_gssapi_simple_conv(int n, const struct pam_message **msg, 
Petr Lautrbach d9e618
+    struct pam_response **resp, void *data)
Petr Lautrbach d9e618
 {
Petr Lautrbach d9e618
-	ctx->major = gss_verify_mic(&ctx->minor, ctx->context,
Petr Lautrbach d9e618
-	    gssbuf, gssmic, NULL);
Petr Lautrbach d9e618
+	return (PAM_CONV_ERR);
Petr Lautrbach d9e618
+}
Petr Lautrbach d9e618
+#endif
Petr Lautrbach d9e618
 
Petr Lautrbach d9e618
-	return (ctx->major);
Petr Lautrbach d9e618
+void
Petr Lautrbach d9e618
+ssh_gssapi_rekey_creds() {
Petr Lautrbach d9e618
+	int ok;
Petr Lautrbach d9e618
+	int ret;
Petr Lautrbach d9e618
+#ifdef USE_PAM
Petr Lautrbach d9e618
+	pam_handle_t *pamh = NULL;
Petr Lautrbach d9e618
+	struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL};
Petr Lautrbach d9e618
+	char *envstr;
Petr Lautrbach d9e618
+#endif
Petr Lautrbach d9e618
+
Petr Lautrbach d9e618
+	if (gssapi_client.store.filename == NULL && 
Petr Lautrbach d9e618
+	    gssapi_client.store.envval == NULL &&
Petr Lautrbach d9e618
+	    gssapi_client.store.envvar == NULL)
Petr Lautrbach d9e618
+		return;
Petr Lautrbach d9e618
+ 
Petr Lautrbach d9e618
+	ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store));
Petr Lautrbach d9e618
+
Petr Lautrbach d9e618
+	if (!ok)
Petr Lautrbach d9e618
+		return;
Petr Lautrbach d9e618
+
Petr Lautrbach d9e618
+	debug("Rekeyed credentials stored successfully");
Petr Lautrbach d9e618
+
Petr Lautrbach d9e618
+	/* Actually managing to play with the ssh pam stack from here will
Petr Lautrbach d9e618
+	 * be next to impossible. In any case, we may want different options
Petr Lautrbach d9e618
+	 * for rekeying. So, use our own :)
Petr Lautrbach d9e618
+	 */
Petr Lautrbach d9e618
+#ifdef USE_PAM	
Petr Lautrbach d9e618
+	if (!use_privsep) {
Petr Lautrbach d9e618
+		debug("Not even going to try and do PAM with privsep disabled");
Petr Lautrbach d9e618
+		return;
Petr Lautrbach d9e618
+	}
Petr Lautrbach d9e618
+
Petr Lautrbach d9e618
+	ret = pam_start("sshd-rekey", gssapi_client.store.owner->pw_name,
Petr Lautrbach d9e618
+ 	    &pamconv, &pamh);
Petr Lautrbach d9e618
+	if (ret)
Petr Lautrbach d9e618
+		return;
Petr Lautrbach d9e618
+
Petr Lautrbach d9e618
+	xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, 
Petr Lautrbach d9e618
+	    gssapi_client.store.envval);
Petr Lautrbach d9e618
+
Petr Lautrbach d9e618
+	ret = pam_putenv(pamh, envstr);
Petr Lautrbach d9e618
+	if (!ret)
Petr Lautrbach d9e618
+		pam_setcred(pamh, PAM_REINITIALIZE_CRED);
Petr Lautrbach d9e618
+	pam_end(pamh, PAM_SUCCESS);
Petr Lautrbach d9e618
+#endif
Petr Lautrbach d9e618
+}
Petr Lautrbach d9e618
+
Petr Lautrbach d9e618
+int 
Petr Lautrbach d9e618
+ssh_gssapi_update_creds(ssh_gssapi_ccache *store) {
Petr Lautrbach d9e618
+	int ok = 0;
Petr Lautrbach d9e618
+
Petr Lautrbach d9e618
+	/* Check we've got credentials to store */
Petr Lautrbach d9e618
+	if (!gssapi_client.updated)
Petr Lautrbach d9e618
+		return 0;
Petr Lautrbach d9e618
+
Petr Lautrbach d9e618
+	gssapi_client.updated = 0;
Petr Lautrbach d9e618
+
Petr Lautrbach d9e618
+	temporarily_use_uid(gssapi_client.store.owner);
Petr Lautrbach d9e618
+	if (gssapi_client.mech && gssapi_client.mech->updatecreds)
Petr Lautrbach d9e618
+		ok = (*gssapi_client.mech->updatecreds)(store, &gssapi_client);
Petr Lautrbach d9e618
+	else
Petr Lautrbach d9e618
+		debug("No update function for this mechanism");
Petr Lautrbach d9e618
+
Petr Lautrbach d9e618
+	restore_uid();
Petr Lautrbach d9e618
+
Petr Lautrbach d9e618
+	return ok;
Petr Lautrbach d9e618
 }
Petr Lautrbach d9e618
 
Petr Lautrbach d9e618
 #endif
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/gss-serv-krb5.c.gsskex openssh-6.2p1/gss-serv-krb5.c
Petr Lautrbach 8a29de
--- openssh-6.2p1/gss-serv-krb5.c.gsskex	2006-09-01 07:38:36.000000000 +0200
Petr Lautrbach 8a29de
+++ openssh-6.2p1/gss-serv-krb5.c	2013-03-27 13:19:11.143624259 +0100
Petr Lautrbach d9e618
@@ -1,7 +1,7 @@
Petr Lautrbach d9e618
 /* $OpenBSD: gss-serv-krb5.c,v 1.7 2006/08/03 03:34:42 deraadt Exp $ */
Petr Lautrbach d9e618
 
Petr Lautrbach d9e618
 /*
Petr Lautrbach d9e618
- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
Petr Lautrbach d9e618
+ * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved.
Petr Lautrbach d9e618
  *
Petr Lautrbach d9e618
  * Redistribution and use in source and binary forms, with or without
Petr Lautrbach d9e618
  * modification, are permitted provided that the following conditions
Petr Lautrbach aacd01
@@ -119,7 +119,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
Petr Lautrbach aacd01
 	krb5_error_code problem;
Petr Lautrbach d9e618
 	krb5_principal princ;
Petr Lautrbach d9e618
 	OM_uint32 maj_status, min_status;
Petr Lautrbach aacd01
-	int len;
Petr Lautrbach aacd01
+	const char *new_ccname, *new_cctype;
Petr Lautrbach d9e618
 
Petr Lautrbach d9e618
 	if (client->creds == NULL) {
Petr Lautrbach d9e618
 		debug("No credentials stored");
Petr Lautrbach aacd01
@@ -168,11 +168,25 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
Petr Lautrbach d9e618
 		return;
Petr Lautrbach d9e618
 	}
Petr Lautrbach d9e618
 
Petr Lautrbach d9e618
-	client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache));
Petr Lautrbach aacd01
+	new_cctype = krb5_cc_get_type(krb_context, ccache);
Petr Lautrbach d9e618
+	new_ccname = krb5_cc_get_name(krb_context, ccache);
Petr Lautrbach d9e618
+
Petr Lautrbach d9e618
 	client->store.envvar = "KRB5CCNAME";
Petr Lautrbach d9e618
-	len = strlen(client->store.filename) + 6;
Petr Lautrbach d9e618
-	client->store.envval = xmalloc(len);
Petr Lautrbach d9e618
-	snprintf(client->store.envval, len, "FILE:%s", client->store.filename);
Petr Lautrbach d9e618
+#ifdef USE_CCAPI
Petr Lautrbach d9e618
+	xasprintf(&client->store.envval, "API:%s", new_ccname);
Petr Lautrbach d9e618
+	client->store.filename = NULL;
Petr Lautrbach d9e618
+#else
Petr Lautrbach 51ca3b
+	if (new_ccname[0] == ':')
Petr Lautrbach 51ca3b
+		new_ccname++;
Petr Lautrbach aacd01
+	xasprintf(&client->store.envval, "%s:%s", new_cctype, new_ccname);
Petr Lautrbach aacd01
+	if (strcmp(new_cctype, "DIR") == 0) {
Petr Lautrbach aacd01
+		char *p;
Petr Lautrbach aacd01
+		p = strrchr(client->store.envval, '/');
Petr Lautrbach aacd01
+		if (p)
Petr Lautrbach aacd01
+			*p = '\0';
Petr Lautrbach aacd01
+	}
Petr Lautrbach d9e618
+	client->store.filename = xstrdup(new_ccname);
Petr Lautrbach d9e618
+#endif
Petr Lautrbach d9e618
 
Petr Lautrbach d9e618
 #ifdef USE_PAM
Petr Lautrbach d9e618
 	if (options.use_pam)
Petr Lautrbach aacd01
@@ -184,6 +198,71 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
Petr Lautrbach d9e618
 	return;
Petr Lautrbach d9e618
 }
Petr Lautrbach d9e618
 
Petr Lautrbach d9e618
+int
Petr Lautrbach d9e618
+ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, 
Petr Lautrbach d9e618
+    ssh_gssapi_client *client)
Petr Lautrbach d9e618
+{
Petr Lautrbach d9e618
+	krb5_ccache ccache = NULL;
Petr Lautrbach d9e618
+	krb5_principal principal = NULL;
Petr Lautrbach d9e618
+	char *name = NULL;
Petr Lautrbach d9e618
+	krb5_error_code problem;
Petr Lautrbach d9e618
+	OM_uint32 maj_status, min_status;
Petr Lautrbach d9e618
+
Petr Lautrbach d9e618
+   	if ((problem = krb5_cc_resolve(krb_context, store->envval, &ccache))) {
Petr Lautrbach d9e618
+                logit("krb5_cc_resolve(): %.100s",
Petr Lautrbach d9e618
+                    krb5_get_err_text(krb_context, problem));
Petr Lautrbach d9e618
+                return 0;
Petr Lautrbach d9e618
+       	}
Petr Lautrbach d9e618
+	
Petr Lautrbach d9e618
+	/* Find out who the principal in this cache is */
Petr Lautrbach d9e618
+	if ((problem = krb5_cc_get_principal(krb_context, ccache, 
Petr Lautrbach d9e618
+	    &principal))) {
Petr Lautrbach d9e618
+		logit("krb5_cc_get_principal(): %.100s",
Petr Lautrbach d9e618
+		    krb5_get_err_text(krb_context, problem));
Petr Lautrbach d9e618
+		krb5_cc_close(krb_context, ccache);
Petr Lautrbach d9e618
+		return 0;
Petr Lautrbach d9e618
+	}
Petr Lautrbach d9e618
+
Petr Lautrbach d9e618
+	if ((problem = krb5_unparse_name(krb_context, principal, &name))) {
Petr Lautrbach d9e618
+		logit("krb5_unparse_name(): %.100s",
Petr Lautrbach d9e618
+		    krb5_get_err_text(krb_context, problem));
Petr Lautrbach d9e618
+		krb5_free_principal(krb_context, principal);
Petr Lautrbach d9e618
+		krb5_cc_close(krb_context, ccache);
Petr Lautrbach d9e618
+		return 0;
Petr Lautrbach d9e618
+	}
Petr Lautrbach d9e618
+
Petr Lautrbach d9e618
+
Petr Lautrbach d9e618
+	if (strcmp(name,client->exportedname.value)!=0) {
Petr Lautrbach d9e618
+		debug("Name in local credentials cache differs. Not storing");
Petr Lautrbach d9e618
+		krb5_free_principal(krb_context, principal);
Petr Lautrbach d9e618
+		krb5_cc_close(krb_context, ccache);
Petr Lautrbach d9e618
+		krb5_free_unparsed_name(krb_context, name);
Petr Lautrbach d9e618
+		return 0;
Petr Lautrbach d9e618
+	}
Petr Lautrbach d9e618
+	krb5_free_unparsed_name(krb_context, name);
Petr Lautrbach d9e618
+
Petr Lautrbach d9e618
+	/* Name matches, so lets get on with it! */
Petr Lautrbach d9e618
+
Petr Lautrbach d9e618
+	if ((problem = krb5_cc_initialize(krb_context, ccache, principal))) {
Petr Lautrbach d9e618
+		logit("krb5_cc_initialize(): %.100s",
Petr Lautrbach d9e618
+		    krb5_get_err_text(krb_context, problem));
Petr Lautrbach d9e618
+		krb5_free_principal(krb_context, principal);
Petr Lautrbach d9e618
+		krb5_cc_close(krb_context, ccache);
Petr Lautrbach d9e618
+		return 0;
Petr Lautrbach d9e618
+	}
Petr Lautrbach d9e618
+
Petr Lautrbach d9e618
+	krb5_free_principal(krb_context, principal);
Petr Lautrbach d9e618
+
Petr Lautrbach d9e618
+	if ((maj_status = gss_krb5_copy_ccache(&min_status, client->creds,
Petr Lautrbach d9e618
+	    ccache))) {
Petr Lautrbach d9e618
+		logit("gss_krb5_copy_ccache() failed. Sorry!");
Petr Lautrbach d9e618
+		krb5_cc_close(krb_context, ccache);
Petr Lautrbach d9e618
+		return 0;
Petr Lautrbach d9e618
+	}
Jan F. Chadima 69dd72
+
Petr Lautrbach d9e618
+	return 1;
Jan F. Chadima 69dd72
+}
Jan F. Chadima 69dd72
+
Petr Lautrbach d9e618
 ssh_gssapi_mech gssapi_kerberos_mech = {
Petr Lautrbach d9e618
 	"toWM5Slw5Ew8Mqkay+al2g==",
Petr Lautrbach d9e618
 	"Kerberos",
Petr Lautrbach aacd01
@@ -191,7 +270,8 @@ ssh_gssapi_mech gssapi_kerberos_mech = {
Petr Lautrbach d9e618
 	NULL,
Petr Lautrbach d9e618
 	&ssh_gssapi_krb5_userok,
Petr Lautrbach d9e618
 	NULL,
Petr Lautrbach d9e618
-	&ssh_gssapi_krb5_storecreds
Petr Lautrbach d9e618
+	&ssh_gssapi_krb5_storecreds,
Petr Lautrbach d9e618
+	&ssh_gssapi_krb5_updatecreds
Petr Lautrbach d9e618
 };
Petr Lautrbach d9e618
 
Petr Lautrbach d9e618
 #endif /* KRB5 */
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/kex.c.gsskex openssh-6.2p1/kex.c
Petr Lautrbach 8a29de
--- openssh-6.2p1/kex.c.gsskex	2013-03-27 13:19:11.039624686 +0100
Petr Lautrbach 8a29de
+++ openssh-6.2p1/kex.c	2013-03-27 13:19:11.143624259 +0100
Jan F. Chadima 69dd72
@@ -51,6 +51,10 @@
Jan F. Chadima 69dd72
 #include "roaming.h"
Jan F. Chadima 69dd72
 #include "audit.h"
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
+#ifdef GSSAPI
Jan F. Chadima 69dd72
+#include "ssh-gss.h"
Jan F. Chadima 69dd72
+#endif
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 #if OPENSSL_VERSION_NUMBER >= 0x00907000L
Jan F. Chadima 69dd72
 # if defined(HAVE_EVP_SHA256)
Jan F. Chadima 69dd72
 # define evp_ssh_sha256 EVP_sha256
Petr Lautrbach 8a29de
@@ -382,6 +386,20 @@ choose_kex(Kex *k, char *client, char *s
Jan F. Chadima 69dd72
  		k->kex_type = KEX_ECDH_SHA2;
Jan F. Chadima 69dd72
 		k->evp_md = kex_ecdh_name_to_evpmd(k->name);
Jan F. Chadima 69dd72
 #endif
Jan F. Chadima 69dd72
+#ifdef GSSAPI
Jan F. Chadima 69dd72
+	} else if (strncmp(k->name, KEX_GSS_GEX_SHA1_ID,
Jan F. Chadima 69dd72
+	    sizeof(KEX_GSS_GEX_SHA1_ID) - 1) == 0) {
Jan F. Chadima 69dd72
+		k->kex_type = KEX_GSS_GEX_SHA1;
Jan F. Chadima 69dd72
+		k->evp_md = EVP_sha1();
Jan F. Chadima 69dd72
+	} else if (strncmp(k->name, KEX_GSS_GRP1_SHA1_ID,
Jan F. Chadima 69dd72
+	    sizeof(KEX_GSS_GRP1_SHA1_ID) - 1) == 0) {
Jan F. Chadima 69dd72
+		k->kex_type = KEX_GSS_GRP1_SHA1;
Jan F. Chadima 69dd72
+		k->evp_md = EVP_sha1();
Jan F. Chadima 69dd72
+	} else if (strncmp(k->name, KEX_GSS_GRP14_SHA1_ID,
Jan F. Chadima 69dd72
+	    sizeof(KEX_GSS_GRP14_SHA1_ID) - 1) == 0) {
Jan F. Chadima 69dd72
+		k->kex_type = KEX_GSS_GRP14_SHA1;
Jan F. Chadima 69dd72
+		k->evp_md = EVP_sha1();
Jan F. Chadima 69dd72
+#endif
Jan F. Chadima 69dd72
 	} else
Jan F. Chadima 69dd72
 		fatal("bad kex alg %s", k->name);
Jan F. Chadima 69dd72
 }
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/kexgssc.c.gsskex openssh-6.2p1/kexgssc.c
Petr Lautrbach 8a29de
--- openssh-6.2p1/kexgssc.c.gsskex	2013-03-27 13:19:11.143624259 +0100
Petr Lautrbach 8a29de
+++ openssh-6.2p1/kexgssc.c	2013-03-27 13:19:11.143624259 +0100
Jan F. Chadima 69dd72
@@ -0,0 +1,334 @@
Jan F. Chadima 69dd72
+/*
Jan F. Chadima 69dd72
+ * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
Jan F. Chadima 69dd72
+ *
Jan F. Chadima 69dd72
+ * Redistribution and use in source and binary forms, with or without
Jan F. Chadima 69dd72
+ * modification, are permitted provided that the following conditions
Jan F. Chadima 69dd72
+ * are met:
Jan F. Chadima 69dd72
+ * 1. Redistributions of source code must retain the above copyright
Jan F. Chadima 69dd72
+ *    notice, this list of conditions and the following disclaimer.
Jan F. Chadima 69dd72
+ * 2. Redistributions in binary form must reproduce the above copyright
Jan F. Chadima 69dd72
+ *    notice, this list of conditions and the following disclaimer in the
Jan F. Chadima 69dd72
+ *    documentation and/or other materials provided with the distribution.
Jan F. Chadima 69dd72
+ *
Jan F. Chadima 69dd72
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
Jan F. Chadima 69dd72
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
Jan F. Chadima 69dd72
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
Jan F. Chadima 69dd72
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
Jan F. Chadima 69dd72
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
Jan F. Chadima 69dd72
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
Jan F. Chadima 69dd72
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
Jan F. Chadima 69dd72
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Jan F. Chadima 69dd72
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
Jan F. Chadima 69dd72
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Jan F. Chadima 69dd72
+ */
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+#include "includes.h"
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+#ifdef GSSAPI
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+#include "includes.h"
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+#include <openssl/crypto.h>
Jan F. Chadima 69dd72
+#include <openssl/bn.h>
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+#include <string.h>
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+#include "xmalloc.h"
Jan F. Chadima 69dd72
+#include "buffer.h"
Jan F. Chadima 69dd72
+#include "ssh2.h"
Jan F. Chadima 69dd72
+#include "key.h"
Jan F. Chadima 69dd72
+#include "cipher.h"
Jan F. Chadima 69dd72
+#include "kex.h"
Jan F. Chadima 69dd72
+#include "log.h"
Jan F. Chadima 69dd72
+#include "packet.h"
Jan F. Chadima 69dd72
+#include "dh.h"
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+#include "ssh-gss.h"
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+void
Jan F. Chadima 69dd72
+kexgss_client(Kex *kex) {
Jan F. Chadima 69dd72
+	gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
Jan F. Chadima 69dd72
+	gss_buffer_desc recv_tok, gssbuf, msg_tok, *token_ptr;
Jan F. Chadima 69dd72
+	Gssctxt *ctxt;
Jan F. Chadima 69dd72
+	OM_uint32 maj_status, min_status, ret_flags;
Jan F. Chadima 69dd72
+	u_int klen, kout, slen = 0, hashlen, strlen;
Jan F. Chadima 69dd72
+	DH *dh; 
Jan F. Chadima 69dd72
+	BIGNUM *dh_server_pub = NULL;
Jan F. Chadima 69dd72
+	BIGNUM *shared_secret = NULL;
Jan F. Chadima 69dd72
+	BIGNUM *p = NULL;
Jan F. Chadima 69dd72
+	BIGNUM *g = NULL;	
Jan F. Chadima 69dd72
+	u_char *kbuf, *hash;
Jan F. Chadima 69dd72
+	u_char *serverhostkey = NULL;
Jan F. Chadima 69dd72
+	u_char *empty = "";
Jan F. Chadima 69dd72
+	char *msg;
Jan F. Chadima 69dd72
+	char *lang;
Jan F. Chadima 69dd72
+	int type = 0;
Jan F. Chadima 69dd72
+	int first = 1;
Jan F. Chadima 69dd72
+	int nbits = 0, min = DH_GRP_MIN, max = DH_GRP_MAX;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	/* Initialise our GSSAPI world */	
Jan F. Chadima 69dd72
+	ssh_gssapi_build_ctx(&ctxt);
Jan F. Chadima 69dd72
+	if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type) 
Jan F. Chadima 69dd72
+	    == GSS_C_NO_OID)
Jan F. Chadima 69dd72
+		fatal("Couldn't identify host exchange");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (ssh_gssapi_import_name(ctxt, kex->gss_host))
Jan F. Chadima 69dd72
+		fatal("Couldn't import hostname");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (kex->gss_client && 
Jan F. Chadima 69dd72
+	    ssh_gssapi_client_identity(ctxt, kex->gss_client))
Jan F. Chadima 69dd72
+		fatal("Couldn't acquire client credentials");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	switch (kex->kex_type) {
Jan F. Chadima 69dd72
+	case KEX_GSS_GRP1_SHA1:
Jan F. Chadima 69dd72
+		dh = dh_new_group1();
Jan F. Chadima 69dd72
+		break;
Jan F. Chadima 69dd72
+	case KEX_GSS_GRP14_SHA1:
Jan F. Chadima 69dd72
+		dh = dh_new_group14();
Jan F. Chadima 69dd72
+		break;
Jan F. Chadima 69dd72
+	case KEX_GSS_GEX_SHA1:
Jan F. Chadima 69dd72
+		debug("Doing group exchange\n");
Jan F. Chadima 69dd72
+		nbits = dh_estimate(kex->we_need * 8);
Jan F. Chadima 69dd72
+		packet_start(SSH2_MSG_KEXGSS_GROUPREQ);
Jan F. Chadima 69dd72
+		packet_put_int(min);
Jan F. Chadima 69dd72
+		packet_put_int(nbits);
Jan F. Chadima 69dd72
+		packet_put_int(max);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		packet_send();
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		packet_read_expect(SSH2_MSG_KEXGSS_GROUP);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		if ((p = BN_new()) == NULL)
Jan F. Chadima 69dd72
+			fatal("BN_new() failed");
Jan F. Chadima 69dd72
+		packet_get_bignum2(p);
Jan F. Chadima 69dd72
+		if ((g = BN_new()) == NULL)
Jan F. Chadima 69dd72
+			fatal("BN_new() failed");
Jan F. Chadima 69dd72
+		packet_get_bignum2(g);
Jan F. Chadima 69dd72
+		packet_check_eom();
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		if (BN_num_bits(p) < min || BN_num_bits(p) > max)
Jan F. Chadima 69dd72
+			fatal("GSSGRP_GEX group out of range: %d !< %d !< %d",
Jan F. Chadima 69dd72
+			    min, BN_num_bits(p), max);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		dh = dh_new_group(g, p);
Jan F. Chadima 69dd72
+		break;
Jan F. Chadima 69dd72
+	default:
Jan F. Chadima 69dd72
+		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
Jan F. Chadima 69dd72
+	}
Jan F. Chadima 69dd72
+	
Jan F. Chadima 69dd72
+	/* Step 1 - e is dh->pub_key */
Jan F. Chadima 69dd72
+	dh_gen_key(dh, kex->we_need * 8);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	/* This is f, we initialise it now to make life easier */
Jan F. Chadima 69dd72
+	dh_server_pub = BN_new();
Jan F. Chadima 69dd72
+	if (dh_server_pub == NULL)
Jan F. Chadima 69dd72
+		fatal("dh_server_pub == NULL");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	token_ptr = GSS_C_NO_BUFFER;
Jan F. Chadima 69dd72
+			 
Jan F. Chadima 69dd72
+	do {
Jan F. Chadima 69dd72
+		debug("Calling gss_init_sec_context");
Jan F. Chadima 69dd72
+		
Jan F. Chadima 69dd72
+		maj_status = ssh_gssapi_init_ctx(ctxt,
Jan F. Chadima 69dd72
+		    kex->gss_deleg_creds, token_ptr, &send_tok,
Jan F. Chadima 69dd72
+		    &ret_flags);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		if (GSS_ERROR(maj_status)) {
Jan F. Chadima 69dd72
+			if (send_tok.length != 0) {
Jan F. Chadima 69dd72
+				packet_start(SSH2_MSG_KEXGSS_CONTINUE);
Jan F. Chadima 69dd72
+				packet_put_string(send_tok.value,
Jan F. Chadima 69dd72
+				    send_tok.length);
Jan F. Chadima 69dd72
+			}
Jan F. Chadima 69dd72
+			fatal("gss_init_context failed");
Jan F. Chadima 69dd72
+		}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		/* If we've got an old receive buffer get rid of it */
Jan F. Chadima 69dd72
+		if (token_ptr != GSS_C_NO_BUFFER)
Jan F. Chadima 69dd72
+			xfree(recv_tok.value);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		if (maj_status == GSS_S_COMPLETE) {
Jan F. Chadima 69dd72
+			/* If mutual state flag is not true, kex fails */
Jan F. Chadima 69dd72
+			if (!(ret_flags & GSS_C_MUTUAL_FLAG))
Jan F. Chadima 69dd72
+				fatal("Mutual authentication failed");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+			/* If integ avail flag is not true kex fails */
Jan F. Chadima 69dd72
+			if (!(ret_flags & GSS_C_INTEG_FLAG))
Jan F. Chadima 69dd72
+				fatal("Integrity check failed");
Jan F. Chadima 69dd72
+		}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		/* 
Jan F. Chadima 69dd72
+		 * If we have data to send, then the last message that we
Jan F. Chadima 69dd72
+		 * received cannot have been a 'complete'. 
Jan F. Chadima 69dd72
+		 */
Jan F. Chadima 69dd72
+		if (send_tok.length != 0) {
Jan F. Chadima 69dd72
+			if (first) {
Jan F. Chadima 69dd72
+				packet_start(SSH2_MSG_KEXGSS_INIT);
Jan F. Chadima 69dd72
+				packet_put_string(send_tok.value,
Jan F. Chadima 69dd72
+				    send_tok.length);
Jan F. Chadima 69dd72
+				packet_put_bignum2(dh->pub_key);
Jan F. Chadima 69dd72
+				first = 0;
Jan F. Chadima 69dd72
+			} else {
Jan F. Chadima 69dd72
+				packet_start(SSH2_MSG_KEXGSS_CONTINUE);
Jan F. Chadima 69dd72
+				packet_put_string(send_tok.value,
Jan F. Chadima 69dd72
+				    send_tok.length);
Jan F. Chadima 69dd72
+			}
Jan F. Chadima 69dd72
+			packet_send();
Jan F. Chadima 69dd72
+			gss_release_buffer(&min_status, &send_tok);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+			/* If we've sent them data, they should reply */
Jan F. Chadima 69dd72
+			do {	
Jan F. Chadima 69dd72
+				type = packet_read();
Jan F. Chadima 69dd72
+				if (type == SSH2_MSG_KEXGSS_HOSTKEY) {
Jan F. Chadima 69dd72
+					debug("Received KEXGSS_HOSTKEY");
Jan F. Chadima 69dd72
+					if (serverhostkey)
Jan F. Chadima 69dd72
+						fatal("Server host key received more than once");
Jan F. Chadima 69dd72
+					serverhostkey = 
Jan F. Chadima 69dd72
+					    packet_get_string(&slen);
Jan F. Chadima 69dd72
+				}
Jan F. Chadima 69dd72
+			} while (type == SSH2_MSG_KEXGSS_HOSTKEY);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+			switch (type) {
Jan F. Chadima 69dd72
+			case SSH2_MSG_KEXGSS_CONTINUE:
Jan F. Chadima 69dd72
+				debug("Received GSSAPI_CONTINUE");
Jan F. Chadima 69dd72
+				if (maj_status == GSS_S_COMPLETE) 
Jan F. Chadima 69dd72
+					fatal("GSSAPI Continue received from server when complete");
Jan F. Chadima 69dd72
+				recv_tok.value = packet_get_string(&strlen);
Jan F. Chadima 69dd72
+				recv_tok.length = strlen; 
Jan F. Chadima 69dd72
+				break;
Jan F. Chadima 69dd72
+			case SSH2_MSG_KEXGSS_COMPLETE:
Jan F. Chadima 69dd72
+				debug("Received GSSAPI_COMPLETE");
Jan F. Chadima 69dd72
+				packet_get_bignum2(dh_server_pub);
Jan F. Chadima 69dd72
+				msg_tok.value =  packet_get_string(&strlen);
Jan F. Chadima 69dd72
+				msg_tok.length = strlen; 
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+				/* Is there a token included? */
Jan F. Chadima 69dd72
+				if (packet_get_char()) {
Jan F. Chadima 69dd72
+					recv_tok.value=
Jan F. Chadima 69dd72
+					    packet_get_string(&strlen);
Jan F. Chadima 69dd72
+					recv_tok.length = strlen;
Jan F. Chadima 69dd72
+					/* If we're already complete - protocol error */
Jan F. Chadima 69dd72
+					if (maj_status == GSS_S_COMPLETE)
Jan F. Chadima 69dd72
+						packet_disconnect("Protocol error: received token when complete");
Jan F. Chadima 69dd72
+					} else {
Jan F. Chadima 69dd72
+						/* No token included */
Jan F. Chadima 69dd72
+						if (maj_status != GSS_S_COMPLETE)
Jan F. Chadima 69dd72
+							packet_disconnect("Protocol error: did not receive final token");
Jan F. Chadima 69dd72
+				}
Jan F. Chadima 69dd72
+				break;
Jan F. Chadima 69dd72
+			case SSH2_MSG_KEXGSS_ERROR:
Jan F. Chadima 69dd72
+				debug("Received Error");
Jan F. Chadima 69dd72
+				maj_status = packet_get_int();
Jan F. Chadima 69dd72
+				min_status = packet_get_int();
Jan F. Chadima 69dd72
+				msg = packet_get_string(NULL);
Jan F. Chadima 69dd72
+				lang = packet_get_string(NULL);
Jan F. Chadima 69dd72
+				fatal("GSSAPI Error: \n%.400s",msg);
Jan F. Chadima 69dd72
+			default:
Jan F. Chadima 69dd72
+				packet_disconnect("Protocol error: didn't expect packet type %d",
Jan F. Chadima 69dd72
+		    		type);
Jan F. Chadima 69dd72
+			}
Jan F. Chadima 69dd72
+			token_ptr = &recv_tok;
Jan F. Chadima 69dd72
+		} else {
Jan F. Chadima 69dd72
+			/* No data, and not complete */
Jan F. Chadima 69dd72
+			if (maj_status != GSS_S_COMPLETE)
Jan F. Chadima 69dd72
+				fatal("Not complete, and no token output");
Jan F. Chadima 69dd72
+		}
Jan F. Chadima 69dd72
+	} while (maj_status & GSS_S_CONTINUE_NEEDED);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	/* 
Jan F. Chadima 69dd72
+	 * We _must_ have received a COMPLETE message in reply from the 
Jan F. Chadima 69dd72
+	 * server, which will have set dh_server_pub and msg_tok 
Jan F. Chadima 69dd72
+	 */
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (type != SSH2_MSG_KEXGSS_COMPLETE)
Jan F. Chadima 69dd72
+		fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	/* Check f in range [1, p-1] */
Jan F. Chadima 69dd72
+	if (!dh_pub_is_valid(dh, dh_server_pub))
Jan F. Chadima 69dd72
+		packet_disconnect("bad server public DH value");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	/* compute K=f^x mod p */
Jan F. Chadima 69dd72
+	klen = DH_size(dh);
Jan F. Chadima 69dd72
+	kbuf = xmalloc(klen);
Jan F. Chadima 69dd72
+	kout = DH_compute_key(kbuf, dh_server_pub, dh);
Jan F. Chadima 3b545b
+	if ((int)kout < 0)
Jan F. Chadima 69dd72
+		fatal("DH_compute_key: failed");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	shared_secret = BN_new();
Jan F. Chadima 69dd72
+	if (shared_secret == NULL)
Jan F. Chadima 69dd72
+		fatal("kexgss_client: BN_new failed");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (BN_bin2bn(kbuf, kout, shared_secret) == NULL)
Jan F. Chadima 69dd72
+		fatal("kexdh_client: BN_bin2bn failed");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	memset(kbuf, 0, klen);
Jan F. Chadima 69dd72
+	xfree(kbuf);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	switch (kex->kex_type) {
Jan F. Chadima 69dd72
+	case KEX_GSS_GRP1_SHA1:
Jan F. Chadima 69dd72
+	case KEX_GSS_GRP14_SHA1:
Jan F. Chadima 69dd72
+		kex_dh_hash( kex->client_version_string, 
Jan F. Chadima 69dd72
+		    kex->server_version_string,
Jan F. Chadima 69dd72
+		    buffer_ptr(&kex->my), buffer_len(&kex->my),
Jan F. Chadima 69dd72
+		    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
Jan F. Chadima 69dd72
+		    (serverhostkey ? serverhostkey : empty), slen,
Jan F. Chadima 69dd72
+		    dh->pub_key,	/* e */
Jan F. Chadima 69dd72
+		    dh_server_pub,	/* f */
Jan F. Chadima 69dd72
+		    shared_secret,	/* K */
Jan F. Chadima 69dd72
+		    &hash, &hashlen
Jan F. Chadima 69dd72
+		);
Jan F. Chadima 69dd72
+		break;
Jan F. Chadima 69dd72
+	case KEX_GSS_GEX_SHA1:
Jan F. Chadima 69dd72
+		kexgex_hash(
Jan F. Chadima 69dd72
+		    kex->evp_md,
Jan F. Chadima 69dd72
+		    kex->client_version_string,
Jan F. Chadima 69dd72
+		    kex->server_version_string,
Jan F. Chadima 69dd72
+		    buffer_ptr(&kex->my), buffer_len(&kex->my),
Jan F. Chadima 69dd72
+		    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
Jan F. Chadima 69dd72
+		    (serverhostkey ? serverhostkey : empty), slen,
Jan F. Chadima 69dd72
+ 		    min, nbits, max,
Jan F. Chadima 69dd72
+		    dh->p, dh->g,
Jan F. Chadima 69dd72
+		    dh->pub_key,
Jan F. Chadima 69dd72
+		    dh_server_pub,
Jan F. Chadima 69dd72
+		    shared_secret,
Jan F. Chadima 69dd72
+		    &hash, &hashlen
Jan F. Chadima 69dd72
+		);
Jan F. Chadima 69dd72
+		break;
Jan F. Chadima 69dd72
+	default:
Jan F. Chadima 69dd72
+		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
Jan F. Chadima 69dd72
+	}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	gssbuf.value = hash;
Jan F. Chadima 69dd72
+	gssbuf.length = hashlen;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	/* Verify that the hash matches the MIC we just got. */
Jan F. Chadima 69dd72
+	if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok)))
Jan F. Chadima 69dd72
+		packet_disconnect("Hash's MIC didn't verify");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	xfree(msg_tok.value);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	DH_free(dh);
Jan F. Chadima 69dd72
+	if (serverhostkey)
Jan F. Chadima 69dd72
+		xfree(serverhostkey);
Jan F. Chadima 69dd72
+	BN_clear_free(dh_server_pub);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	/* save session id */
Jan F. Chadima 69dd72
+	if (kex->session_id == NULL) {
Jan F. Chadima 69dd72
+		kex->session_id_len = hashlen;
Jan F. Chadima 69dd72
+		kex->session_id = xmalloc(kex->session_id_len);
Jan F. Chadima 69dd72
+		memcpy(kex->session_id, hash, kex->session_id_len);
Jan F. Chadima 69dd72
+	}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (kex->gss_deleg_creds)
Jan F. Chadima 69dd72
+		ssh_gssapi_credentials_updated(ctxt);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (gss_kex_context == NULL)
Jan F. Chadima 69dd72
+		gss_kex_context = ctxt;
Jan F. Chadima 69dd72
+	else
Jan F. Chadima 69dd72
+		ssh_gssapi_delete_ctx(&ctxt);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	kex_derive_keys(kex, hash, hashlen, shared_secret);
Jan F. Chadima 69dd72
+	BN_clear_free(shared_secret);
Jan F. Chadima 69dd72
+	kex_finish(kex);
Jan F. Chadima 69dd72
+}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+#endif /* GSSAPI */
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/kexgsss.c.gsskex openssh-6.2p1/kexgsss.c
Petr Lautrbach 8a29de
--- openssh-6.2p1/kexgsss.c.gsskex	2013-03-27 13:19:11.144624254 +0100
Petr Lautrbach 8a29de
+++ openssh-6.2p1/kexgsss.c	2013-03-27 13:19:11.144624254 +0100
Jan F. Chadima 69dd72
@@ -0,0 +1,288 @@
Jan F. Chadima 69dd72
+/*
Jan F. Chadima 69dd72
+ * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
Jan F. Chadima 69dd72
+ *
Jan F. Chadima 69dd72
+ * Redistribution and use in source and binary forms, with or without
Jan F. Chadima 69dd72
+ * modification, are permitted provided that the following conditions
Jan F. Chadima 69dd72
+ * are met:
Jan F. Chadima 69dd72
+ * 1. Redistributions of source code must retain the above copyright
Jan F. Chadima 69dd72
+ *    notice, this list of conditions and the following disclaimer.
Jan F. Chadima 69dd72
+ * 2. Redistributions in binary form must reproduce the above copyright
Jan F. Chadima 69dd72
+ *    notice, this list of conditions and the following disclaimer in the
Jan F. Chadima 69dd72
+ *    documentation and/or other materials provided with the distribution.
Jan F. Chadima 69dd72
+ *
Jan F. Chadima 69dd72
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
Jan F. Chadima 69dd72
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
Jan F. Chadima 69dd72
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
Jan F. Chadima 69dd72
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
Jan F. Chadima 69dd72
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
Jan F. Chadima 69dd72
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
Jan F. Chadima 69dd72
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
Jan F. Chadima 69dd72
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Jan F. Chadima 69dd72
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
Jan F. Chadima 69dd72
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Jan F. Chadima 69dd72
+ */
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+#include "includes.h"
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+#ifdef GSSAPI
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+#include <string.h>
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+#include <openssl/crypto.h>
Jan F. Chadima 69dd72
+#include <openssl/bn.h>
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+#include "xmalloc.h"
Jan F. Chadima 69dd72
+#include "buffer.h"
Jan F. Chadima 69dd72
+#include "ssh2.h"
Jan F. Chadima 69dd72
+#include "key.h"
Jan F. Chadima 69dd72
+#include "cipher.h"
Jan F. Chadima 69dd72
+#include "kex.h"
Jan F. Chadima 69dd72
+#include "log.h"
Jan F. Chadima 69dd72
+#include "packet.h"
Jan F. Chadima 69dd72
+#include "dh.h"
Jan F. Chadima 69dd72
+#include "ssh-gss.h"
Jan F. Chadima 69dd72
+#include "monitor_wrap.h"
Jan F. Chadima 69dd72
+#include "servconf.h"
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+extern ServerOptions options;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+void
Jan F. Chadima 69dd72
+kexgss_server(Kex *kex)
Jan F. Chadima 69dd72
+{
Jan F. Chadima 69dd72
+	OM_uint32 maj_status, min_status;
Jan F. Chadima 69dd72
+	
Jan F. Chadima 69dd72
+	/* 
Jan F. Chadima 69dd72
+	 * Some GSSAPI implementations use the input value of ret_flags (an
Jan F. Chadima 69dd72
+ 	 * output variable) as a means of triggering mechanism specific 
Jan F. Chadima 69dd72
+ 	 * features. Initializing it to zero avoids inadvertently 
Jan F. Chadima 69dd72
+ 	 * activating this non-standard behaviour.
Jan F. Chadima 69dd72
+	 */
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	OM_uint32 ret_flags = 0;
Jan F. Chadima 69dd72
+	gss_buffer_desc gssbuf, recv_tok, msg_tok;
Jan F. Chadima 69dd72
+	gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
Jan F. Chadima 69dd72
+	Gssctxt *ctxt = NULL;
Jan F. Chadima 69dd72
+	u_int slen, klen, kout, hashlen;
Jan F. Chadima 69dd72
+	u_char *kbuf, *hash;
Jan F. Chadima 69dd72
+	DH *dh;
Jan F. Chadima 69dd72
+	int min = -1, max = -1, nbits = -1;
Jan F. Chadima 69dd72
+	BIGNUM *shared_secret = NULL;
Jan F. Chadima 69dd72
+	BIGNUM *dh_client_pub = NULL;
Jan F. Chadima 69dd72
+	int type = 0;
Jan F. Chadima 69dd72
+	gss_OID oid;
Jan F. Chadima 69dd72
+	char *mechs;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	/* Initialise GSSAPI */
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	/* If we're rekeying, privsep means that some of the private structures
Jan F. Chadima 69dd72
+	 * in the GSSAPI code are no longer available. This kludges them back
Jan F. Chadima 69dd72
+	 * into life
Jan F. Chadima 69dd72
+	 */
Jan F. Chadima 69dd72
+	if (!ssh_gssapi_oid_table_ok()) 
Jan F. Chadima 69dd72
+		if ((mechs = ssh_gssapi_server_mechanisms()))
Jan F. Chadima 69dd72
+			xfree(mechs);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	debug2("%s: Identifying %s", __func__, kex->name);
Jan F. Chadima 69dd72
+	oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type);
Jan F. Chadima 69dd72
+	if (oid == GSS_C_NO_OID)
Jan F. Chadima 69dd72
+	   fatal("Unknown gssapi mechanism");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	debug2("%s: Acquiring credentials", __func__);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid))))
Jan F. Chadima 69dd72
+		fatal("Unable to acquire credentials for the server");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	switch (kex->kex_type) {
Jan F. Chadima 69dd72
+	case KEX_GSS_GRP1_SHA1:
Jan F. Chadima 69dd72
+		dh = dh_new_group1();
Jan F. Chadima 69dd72
+		break;
Jan F. Chadima 69dd72
+	case KEX_GSS_GRP14_SHA1:
Jan F. Chadima 69dd72
+		dh = dh_new_group14();
Jan F. Chadima 69dd72
+		break;
Jan F. Chadima 69dd72
+	case KEX_GSS_GEX_SHA1:
Jan F. Chadima 69dd72
+		debug("Doing group exchange");
Jan F. Chadima 69dd72
+		packet_read_expect(SSH2_MSG_KEXGSS_GROUPREQ);
Jan F. Chadima 69dd72
+		min = packet_get_int();
Jan F. Chadima 69dd72
+		nbits = packet_get_int();
Jan F. Chadima 69dd72
+		max = packet_get_int();
Jan F. Chadima 69dd72
+		min = MAX(DH_GRP_MIN, min);
Jan F. Chadima 69dd72
+		max = MIN(DH_GRP_MAX, max);
Jan F. Chadima 69dd72
+		packet_check_eom();
Jan F. Chadima 69dd72
+		if (max < min || nbits < min || max < nbits)
Jan F. Chadima 69dd72
+			fatal("GSS_GEX, bad parameters: %d !< %d !< %d",
Jan F. Chadima 69dd72
+			    min, nbits, max);
Jan F. Chadima 69dd72
+		dh = PRIVSEP(choose_dh(min, nbits, max));
Jan F. Chadima 69dd72
+		if (dh == NULL)
Jan F. Chadima 69dd72
+			packet_disconnect("Protocol error: no matching group found");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		packet_start(SSH2_MSG_KEXGSS_GROUP);
Jan F. Chadima 69dd72
+		packet_put_bignum2(dh->p);
Jan F. Chadima 69dd72
+		packet_put_bignum2(dh->g);
Jan F. Chadima 69dd72
+		packet_send();
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		packet_write_wait();
Jan F. Chadima 69dd72
+		break;
Jan F. Chadima 69dd72
+	default:
Jan F. Chadima 69dd72
+		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
Jan F. Chadima 69dd72
+	}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	dh_gen_key(dh, kex->we_need * 8);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	do {
Jan F. Chadima 69dd72
+		debug("Wait SSH2_MSG_GSSAPI_INIT");
Jan F. Chadima 69dd72
+		type = packet_read();
Jan F. Chadima 69dd72
+		switch(type) {
Jan F. Chadima 69dd72
+		case SSH2_MSG_KEXGSS_INIT:
Jan F. Chadima 69dd72
+			if (dh_client_pub != NULL) 
Jan F. Chadima 69dd72
+				fatal("Received KEXGSS_INIT after initialising");
Jan F. Chadima 69dd72
+			recv_tok.value = packet_get_string(&slen);
Jan F. Chadima 69dd72
+			recv_tok.length = slen; 
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+			if ((dh_client_pub = BN_new()) == NULL)
Jan F. Chadima 69dd72
+				fatal("dh_client_pub == NULL");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+			packet_get_bignum2(dh_client_pub);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+			/* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */
Jan F. Chadima 69dd72
+			break;
Jan F. Chadima 69dd72
+		case SSH2_MSG_KEXGSS_CONTINUE:
Jan F. Chadima 69dd72
+			recv_tok.value = packet_get_string(&slen);
Jan F. Chadima 69dd72
+			recv_tok.length = slen; 
Jan F. Chadima 69dd72
+			break;
Jan F. Chadima 69dd72
+		default:
Jan F. Chadima 69dd72
+			packet_disconnect(
Jan F. Chadima 69dd72
+			    "Protocol error: didn't expect packet type %d",
Jan F. Chadima 69dd72
+			    type);
Jan F. Chadima 69dd72
+		}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok, 
Jan F. Chadima 69dd72
+		    &send_tok, &ret_flags));
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		xfree(recv_tok.value);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		if (maj_status != GSS_S_COMPLETE && send_tok.length == 0)
Jan F. Chadima 69dd72
+			fatal("Zero length token output when incomplete");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		if (dh_client_pub == NULL)
Jan F. Chadima 69dd72
+			fatal("No client public key");
Jan F. Chadima 69dd72
+		
Jan F. Chadima 69dd72
+		if (maj_status & GSS_S_CONTINUE_NEEDED) {
Jan F. Chadima 69dd72
+			debug("Sending GSSAPI_CONTINUE");
Jan F. Chadima 69dd72
+			packet_start(SSH2_MSG_KEXGSS_CONTINUE);
Jan F. Chadima 69dd72
+			packet_put_string(send_tok.value, send_tok.length);
Jan F. Chadima 69dd72
+			packet_send();
Jan F. Chadima 69dd72
+			gss_release_buffer(&min_status, &send_tok);
Jan F. Chadima 69dd72
+		}
Jan F. Chadima 69dd72
+	} while (maj_status & GSS_S_CONTINUE_NEEDED);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (GSS_ERROR(maj_status)) {
Jan F. Chadima 69dd72
+		if (send_tok.length > 0) {
Jan F. Chadima 69dd72
+			packet_start(SSH2_MSG_KEXGSS_CONTINUE);
Jan F. Chadima 69dd72
+			packet_put_string(send_tok.value, send_tok.length);
Jan F. Chadima 69dd72
+			packet_send();
Jan F. Chadima 69dd72
+		}
Jan F. Chadima 69dd72
+		fatal("accept_ctx died");
Jan F. Chadima 69dd72
+	}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (!(ret_flags & GSS_C_MUTUAL_FLAG))
Jan F. Chadima 69dd72
+		fatal("Mutual Authentication flag wasn't set");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (!(ret_flags & GSS_C_INTEG_FLAG))
Jan F. Chadima 69dd72
+		fatal("Integrity flag wasn't set");
Jan F. Chadima 69dd72
+	
Jan F. Chadima 69dd72
+	if (!dh_pub_is_valid(dh, dh_client_pub))
Jan F. Chadima 69dd72
+		packet_disconnect("bad client public DH value");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	klen = DH_size(dh);
Jan F. Chadima 69dd72
+	kbuf = xmalloc(klen); 
Jan F. Chadima 69dd72
+	kout = DH_compute_key(kbuf, dh_client_pub, dh);
Jan F. Chadima 3b545b
+	if ((int)kout < 0)
Jan F. Chadima 69dd72
+		fatal("DH_compute_key: failed");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	shared_secret = BN_new();
Jan F. Chadima 69dd72
+	if (shared_secret == NULL)
Jan F. Chadima 69dd72
+		fatal("kexgss_server: BN_new failed");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (BN_bin2bn(kbuf, kout, shared_secret) == NULL)
Jan F. Chadima 69dd72
+		fatal("kexgss_server: BN_bin2bn failed");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	memset(kbuf, 0, klen);
Jan F. Chadima 69dd72
+	xfree(kbuf);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	switch (kex->kex_type) {
Jan F. Chadima 69dd72
+	case KEX_GSS_GRP1_SHA1:
Jan F. Chadima 69dd72
+	case KEX_GSS_GRP14_SHA1:
Jan F. Chadima 69dd72
+		kex_dh_hash(
Jan F. Chadima 69dd72
+		    kex->client_version_string, kex->server_version_string,
Jan F. Chadima 69dd72
+		    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
Jan F. Chadima 69dd72
+		    buffer_ptr(&kex->my), buffer_len(&kex->my),
Jan F. Chadima 69dd72
+		    NULL, 0, /* Change this if we start sending host keys */
Jan F. Chadima 69dd72
+		    dh_client_pub, dh->pub_key, shared_secret,
Jan F. Chadima 69dd72
+		    &hash, &hashlen
Jan F. Chadima 69dd72
+		);
Jan F. Chadima 69dd72
+		break;
Jan F. Chadima 69dd72
+	case KEX_GSS_GEX_SHA1:
Jan F. Chadima 69dd72
+		kexgex_hash(
Jan F. Chadima 69dd72
+		    kex->evp_md,
Jan F. Chadima 69dd72
+		    kex->client_version_string, kex->server_version_string,
Jan F. Chadima 69dd72
+		    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
Jan F. Chadima 69dd72
+		    buffer_ptr(&kex->my), buffer_len(&kex->my),
Jan F. Chadima 69dd72
+		    NULL, 0,
Jan F. Chadima 69dd72
+		    min, nbits, max,
Jan F. Chadima 69dd72
+		    dh->p, dh->g,
Jan F. Chadima 69dd72
+		    dh_client_pub,
Jan F. Chadima 69dd72
+		    dh->pub_key,
Jan F. Chadima 69dd72
+		    shared_secret,
Jan F. Chadima 69dd72
+		    &hash, &hashlen
Jan F. Chadima 69dd72
+		);
Jan F. Chadima 69dd72
+		break;
Jan F. Chadima 69dd72
+	default:
Jan F. Chadima 69dd72
+		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
Jan F. Chadima 69dd72
+	}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	BN_clear_free(dh_client_pub);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (kex->session_id == NULL) {
Jan F. Chadima 69dd72
+		kex->session_id_len = hashlen;
Jan F. Chadima 69dd72
+		kex->session_id = xmalloc(kex->session_id_len);
Jan F. Chadima 69dd72
+		memcpy(kex->session_id, hash, kex->session_id_len);
Jan F. Chadima 69dd72
+	}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	gssbuf.value = hash;
Jan F. Chadima 69dd72
+	gssbuf.length = hashlen;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt,&gssbuf,&msg_tok))))
Jan F. Chadima 69dd72
+		fatal("Couldn't get MIC");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	packet_start(SSH2_MSG_KEXGSS_COMPLETE);
Jan F. Chadima 69dd72
+	packet_put_bignum2(dh->pub_key);
Jan F. Chadima 69dd72
+	packet_put_string(msg_tok.value,msg_tok.length);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (send_tok.length != 0) {
Jan F. Chadima 69dd72
+		packet_put_char(1); /* true */
Jan F. Chadima 69dd72
+		packet_put_string(send_tok.value, send_tok.length);
Jan F. Chadima 69dd72
+	} else {
Jan F. Chadima 69dd72
+		packet_put_char(0); /* false */
Jan F. Chadima 69dd72
+	}
Jan F. Chadima 69dd72
+	packet_send();
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	gss_release_buffer(&min_status, &send_tok);
Jan F. Chadima 69dd72
+	gss_release_buffer(&min_status, &msg_tok);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (gss_kex_context == NULL)
Jan F. Chadima 69dd72
+		gss_kex_context = ctxt;
Jan F. Chadima 69dd72
+	else 
Jan F. Chadima 69dd72
+		ssh_gssapi_delete_ctx(&ctxt);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	DH_free(dh);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	kex_derive_keys(kex, hash, hashlen, shared_secret);
Jan F. Chadima 69dd72
+	BN_clear_free(shared_secret);
Jan F. Chadima 69dd72
+	kex_finish(kex);
Jan F. Chadima 69dd72
+
Petr Lautrbach d9e618
+	/* If this was a rekey, then save out any delegated credentials we
Petr Lautrbach d9e618
+	 * just exchanged.  */
Petr Lautrbach d9e618
+	if (options.gss_store_rekey)
Petr Lautrbach d9e618
+		ssh_gssapi_rekey_creds();
Petr Lautrbach d9e618
+}
Petr Lautrbach d9e618
+#endif /* GSSAPI */
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/kex.h.gsskex openssh-6.2p1/kex.h
Petr Lautrbach 8a29de
--- openssh-6.2p1/kex.h.gsskex	2013-03-27 13:19:11.039624686 +0100
Petr Lautrbach 8a29de
+++ openssh-6.2p1/kex.h	2013-03-27 13:19:11.144624254 +0100
Petr Lautrbach d9e618
@@ -73,6 +73,9 @@ enum kex_exchange {
Petr Lautrbach d9e618
 	KEX_DH_GEX_SHA1,
Petr Lautrbach d9e618
 	KEX_DH_GEX_SHA256,
Petr Lautrbach d9e618
 	KEX_ECDH_SHA2,
Petr Lautrbach d9e618
+	KEX_GSS_GRP1_SHA1,
Petr Lautrbach d9e618
+	KEX_GSS_GRP14_SHA1,
Petr Lautrbach d9e618
+	KEX_GSS_GEX_SHA1,
Petr Lautrbach d9e618
 	KEX_MAX
Petr Lautrbach d9e618
 };
Petr Lautrbach d9e618
 
Petr Lautrbach 8a29de
@@ -131,6 +134,12 @@ struct Kex {
Petr Lautrbach d9e618
 	sig_atomic_t done;
Petr Lautrbach d9e618
 	int	flags;
Petr Lautrbach d9e618
 	const EVP_MD *evp_md;
Petr Lautrbach d9e618
+#ifdef GSSAPI
Petr Lautrbach d9e618
+	int	gss_deleg_creds;
Petr Lautrbach d9e618
+	int	gss_trust_dns;
Petr Lautrbach d9e618
+	char    *gss_host;
Petr Lautrbach d9e618
+	char	*gss_client;
Petr Lautrbach d9e618
+#endif
Petr Lautrbach d9e618
 	char	*client_version_string;
Petr Lautrbach d9e618
 	char	*server_version_string;
Petr Lautrbach d9e618
 	int	(*verify_host_key)(Key *);
Petr Lautrbach 8a29de
@@ -158,6 +167,11 @@ void	 kexgex_server(Kex *);
Petr Lautrbach d9e618
 void	 kexecdh_client(Kex *);
Petr Lautrbach d9e618
 void	 kexecdh_server(Kex *);
Petr Lautrbach d9e618
 
Petr Lautrbach d9e618
+#ifdef GSSAPI
Petr Lautrbach d9e618
+void	kexgss_client(Kex *);
Petr Lautrbach d9e618
+void	kexgss_server(Kex *);
Petr Lautrbach d9e618
+#endif
Petr Lautrbach d9e618
+
Petr Lautrbach d9e618
 void	newkeys_destroy(Newkeys *newkeys);
Petr Lautrbach d9e618
 
Petr Lautrbach d9e618
 void
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/key.c.gsskex openssh-6.2p1/key.c
Petr Lautrbach 8a29de
--- openssh-6.2p1/key.c.gsskex	2013-03-27 13:19:11.102624427 +0100
Petr Lautrbach 8a29de
+++ openssh-6.2p1/key.c	2013-03-27 13:19:11.144624254 +0100
Petr Lautrbach 9fe1af
@@ -1011,6 +1011,8 @@ key_ssh_name_from_type_nid(int type, int
Jan F. Chadima 69dd72
 		}
Jan F. Chadima 69dd72
 		break;
Jan F. Chadima 69dd72
 #endif /* OPENSSL_HAS_ECC */
Jan F. Chadima 69dd72
+	case KEY_NULL:
Jan F. Chadima 69dd72
+		return "null";
Jan F. Chadima 69dd72
 	}
Jan F. Chadima 69dd72
 	return "ssh-unknown";
Jan F. Chadima 69dd72
 }
Petr Lautrbach 9fe1af
@@ -1316,6 +1318,8 @@ key_type_from_name(char *name)
Jan F. Chadima 69dd72
 	    strcmp(name, "ecdsa-sha2-nistp521-cert-v01@openssh.com") == 0) {
Jan F. Chadima 69dd72
 		return KEY_ECDSA_CERT;
Jan F. Chadima 69dd72
 #endif
Jan F. Chadima 69dd72
+	} else if (strcmp(name, "null") == 0) {
Jan F. Chadima 69dd72
+		return KEY_NULL;
Jan F. Chadima 69dd72
 	}
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 	debug2("key_type_from_name: unknown key type '%s'", name);
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/key.h.gsskex openssh-6.2p1/key.h
Petr Lautrbach 8a29de
--- openssh-6.2p1/key.h.gsskex	2013-03-27 13:19:11.046624657 +0100
Petr Lautrbach 8a29de
+++ openssh-6.2p1/key.h	2013-03-27 13:19:11.145624250 +0100
Jan F. Chadima 69dd72
@@ -44,6 +44,7 @@ enum types {
Jan F. Chadima 69dd72
 	KEY_ECDSA_CERT,
Jan F. Chadima 69dd72
 	KEY_RSA_CERT_V00,
Jan F. Chadima 69dd72
 	KEY_DSA_CERT_V00,
Jan F. Chadima 69dd72
+	KEY_NULL,
Jan F. Chadima 69dd72
 	KEY_UNSPEC
Jan F. Chadima 69dd72
 };
Jan F. Chadima 69dd72
 enum fp_type {
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/Makefile.in.gsskex openssh-6.2p1/Makefile.in
Petr Lautrbach 8a29de
--- openssh-6.2p1/Makefile.in.gsskex	2013-03-27 13:19:11.138624279 +0100
Petr Lautrbach 8a29de
+++ openssh-6.2p1/Makefile.in	2013-03-27 13:19:11.145624250 +0100
Petr Lautrbach 8a29de
@@ -77,6 +77,7 @@ LIBSSH_OBJS=authfd.o authfile.o bufaux.o
Petr Lautrbach d9e618
 	atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \
Petr Lautrbach d9e618
 	monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \
Petr Lautrbach d9e618
 	kexdh.o kexgex.o kexdhc.o kexgexc.o bufec.o kexecdh.o kexecdhc.o \
Petr Lautrbach d9e618
+	kexgssc.o \
Petr Lautrbach 8a29de
 	msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \
Petr Lautrbach 8a29de
 	jpake.o schnorr.o ssh-pkcs11.o krl.o auditstub.o
Petr Lautrbach d9e618
 
Petr Lautrbach 8a29de
@@ -93,7 +94,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw
Petr Lautrbach d9e618
 	auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-jpake.o \
Petr Lautrbach d9e618
 	monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o kexecdhs.o \
Petr Lautrbach d9e618
 	auth-krb5.o \
Petr Lautrbach d9e618
-	auth2-gss.o gss-serv.o gss-serv-krb5.o \
Petr Lautrbach d9e618
+	auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o\
Petr Lautrbach d9e618
 	loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
Petr Lautrbach d9e618
 	sftp-server.o sftp-common.o \
Petr Lautrbach d9e618
 	roaming_common.o roaming_serv.o \
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/monitor.c.gsskex openssh-6.2p1/monitor.c
Petr Lautrbach 8a29de
--- openssh-6.2p1/monitor.c.gsskex	2013-03-27 13:19:11.063624587 +0100
Petr Lautrbach 8a29de
+++ openssh-6.2p1/monitor.c	2013-03-27 13:19:11.145624250 +0100
Petr Lautrbach 51ca3b
@@ -186,6 +186,8 @@ int mm_answer_gss_setup_ctx(int, Buffer
Jan F. Chadima 69dd72
 int mm_answer_gss_accept_ctx(int, Buffer *);
Jan F. Chadima 69dd72
 int mm_answer_gss_userok(int, Buffer *);
Jan F. Chadima 69dd72
 int mm_answer_gss_checkmic(int, Buffer *);
Jan F. Chadima 69dd72
+int mm_answer_gss_sign(int, Buffer *);
Jan F. Chadima 69dd72
+int mm_answer_gss_updatecreds(int, Buffer *);
Jan F. Chadima 69dd72
 #endif
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 #ifdef SSH_AUDIT_EVENTS
Petr Lautrbach 51ca3b
@@ -270,6 +272,7 @@ struct mon_table mon_dispatch_proto20[]
Jan F. Chadima 69dd72
     {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx},
Jan F. Chadima 69dd72
     {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
Jan F. Chadima 69dd72
     {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic},
Jan F. Chadima 69dd72
+    {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign},
Jan F. Chadima 69dd72
 #endif
Jan F. Chadima 69dd72
 #ifdef JPAKE
Jan F. Chadima 69dd72
     {MONITOR_REQ_JPAKE_GET_PWDATA, MON_ONCE, mm_answer_jpake_get_pwdata},
Petr Lautrbach 51ca3b
@@ -282,6 +285,12 @@ struct mon_table mon_dispatch_proto20[]
Jan F. Chadima 69dd72
 };
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 struct mon_table mon_dispatch_postauth20[] = {
Jan F. Chadima 69dd72
+#ifdef GSSAPI
Jan F. Chadima 69dd72
+    {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx},
Jan F. Chadima 69dd72
+    {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx},
Jan F. Chadima 69dd72
+    {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign},
Jan F. Chadima 69dd72
+    {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds},
Jan F. Chadima 69dd72
+#endif
Jan F. Chadima 69dd72
     {MONITOR_REQ_MODULI, 0, mm_answer_moduli},
Jan F. Chadima 69dd72
     {MONITOR_REQ_SIGN, 0, mm_answer_sign},
Jan F. Chadima 69dd72
     {MONITOR_REQ_PTY, 0, mm_answer_pty},
Petr Lautrbach 5039c7
@@ -404,6 +413,10 @@ monitor_child_preauth(Authctxt *_authctx
Jan F. Chadima 69dd72
 		/* Permit requests for moduli and signatures */
Jan F. Chadima 69dd72
 		monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
Jan F. Chadima 69dd72
 		monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
Jan F. Chadima 69dd72
+#ifdef GSSAPI
Jan F. Chadima 69dd72
+		/* and for the GSSAPI key exchange */
Jan F. Chadima 69dd72
+		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
Jan F. Chadima 69dd72
+#endif
Jan F. Chadima 69dd72
 	} else {
Jan F. Chadima 69dd72
 		mon_dispatch = mon_dispatch_proto15;
Petr Lautrbach 5039c7
 
Petr Lautrbach 8a29de
@@ -519,6 +532,10 @@ monitor_child_postauth(struct monitor *p
Jan F. Chadima 69dd72
 		monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
Jan F. Chadima 69dd72
 		monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
Jan F. Chadima 69dd72
 		monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
Jan F. Chadima 69dd72
+#ifdef GSSAPI
Jan F. Chadima 69dd72
+		/* and for the GSSAPI key exchange */
Jan F. Chadima 69dd72
+		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
Jan F. Chadima 69dd72
+#endif		
Jan F. Chadima 69dd72
 	} else {
Jan F. Chadima 69dd72
 		mon_dispatch = mon_dispatch_postauth15;
Jan F. Chadima 69dd72
 		monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
Petr Lautrbach 8a29de
@@ -1950,6 +1967,13 @@ mm_get_kex(Buffer *m)
Jan F. Chadima 69dd72
 	kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
Jan F. Chadima 69dd72
 	kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
Jan F. Chadima 69dd72
 	kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
Jan F. Chadima 69dd72
+#ifdef GSSAPI
Jan F. Chadima 69dd72
+	if (options.gss_keyex) {
Jan F. Chadima 69dd72
+		kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
Jan F. Chadima 69dd72
+		kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
Jan F. Chadima 69dd72
+		kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
Jan F. Chadima 69dd72
+	}
Jan F. Chadima 69dd72
+#endif
Jan F. Chadima 69dd72
 	kex->server = 1;
Jan F. Chadima 69dd72
 	kex->hostkey_type = buffer_get_int(m);
Jan F. Chadima 69dd72
 	kex->kex_type = buffer_get_int(m);
Petr Lautrbach 8a29de
@@ -2173,6 +2197,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer
Jan F. Chadima 69dd72
 	OM_uint32 major;
Jan F. Chadima 69dd72
 	u_int len;
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
+	if (!options.gss_authentication && !options.gss_keyex)
Jan F. Chadima 69dd72
+		fatal("In GSSAPI monitor when GSSAPI is disabled");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 	goid.elements = buffer_get_string(m, &len;;
Jan F. Chadima 69dd72
 	goid.length = len;
Jan F. Chadima 69dd72
 
Petr Lautrbach 8a29de
@@ -2200,6 +2227,9 @@ mm_answer_gss_accept_ctx(int sock, Buffe
Jan F. Chadima 69dd72
 	OM_uint32 flags = 0; /* GSI needs this */
Jan F. Chadima 69dd72
 	u_int len;
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
+	if (!options.gss_authentication && !options.gss_keyex)
Jan F. Chadima 69dd72
+		fatal("In GSSAPI monitor when GSSAPI is disabled");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 	in.value = buffer_get_string(m, &len;;
Jan F. Chadima 69dd72
 	in.length = len;
Jan F. Chadima 69dd72
 	major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags);
Petr Lautrbach 8a29de
@@ -2217,6 +2247,7 @@ mm_answer_gss_accept_ctx(int sock, Buffe
Jan F. Chadima 69dd72
 		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
Jan F. Chadima 69dd72
 		monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
Jan F. Chadima 69dd72
 		monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
Jan F. Chadima 69dd72
+		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1);
Jan F. Chadima 69dd72
 	}
Jan F. Chadima 69dd72
 	return (0);
Jan F. Chadima 69dd72
 }
Petr Lautrbach 8a29de
@@ -2228,6 +2259,9 @@ mm_answer_gss_checkmic(int sock, Buffer
Jan F. Chadima 69dd72
 	OM_uint32 ret;
Jan F. Chadima 69dd72
 	u_int len;
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
+	if (!options.gss_authentication && !options.gss_keyex)
Jan F. Chadima 69dd72
+		fatal("In GSSAPI monitor when GSSAPI is disabled");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 	gssbuf.value = buffer_get_string(m, &len;;
Jan F. Chadima 69dd72
 	gssbuf.length = len;
Jan F. Chadima 69dd72
 	mic.value = buffer_get_string(m, &len;;
Petr Lautrbach 8a29de
@@ -2254,7 +2288,11 @@ mm_answer_gss_userok(int sock, Buffer *m
Jan F. Chadima 69dd72
 {
Jan F. Chadima 69dd72
 	int authenticated;
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
-	authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user);
Jan F. Chadima 69dd72
+	if (!options.gss_authentication && !options.gss_keyex)
Jan F. Chadima 69dd72
+		fatal("In GSSAPI monitor when GSSAPI is disabled");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	authenticated = authctxt->valid && 
Jan F. Chadima 69dd72
+	    ssh_gssapi_userok(authctxt->user, authctxt->pw);
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 	buffer_clear(m);
Jan F. Chadima 69dd72
 	buffer_put_int(m, authenticated);
Petr Lautrbach 8a29de
@@ -2267,6 +2305,74 @@ mm_answer_gss_userok(int sock, Buffer *m
Jan F. Chadima 69dd72
 	/* Monitor loop will terminate if authenticated */
Jan F. Chadima 69dd72
 	return (authenticated);
Jan F. Chadima 69dd72
 }
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+int 
Jan F. Chadima 69dd72
+mm_answer_gss_sign(int socket, Buffer *m)
Jan F. Chadima 69dd72
+{
Jan F. Chadima 69dd72
+	gss_buffer_desc data;
Jan F. Chadima 69dd72
+	gss_buffer_desc hash = GSS_C_EMPTY_BUFFER;
Jan F. Chadima 69dd72
+	OM_uint32 major, minor;
Jan F. Chadima 69dd72
+	u_int len;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (!options.gss_authentication && !options.gss_keyex)
Jan F. Chadima 69dd72
+		fatal("In GSSAPI monitor when GSSAPI is disabled");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	data.value = buffer_get_string(m, &len;;
Jan F. Chadima 69dd72
+	data.length = len;
Jan F. Chadima 69dd72
+	if (data.length != 20) 
Jan F. Chadima 69dd72
+		fatal("%s: data length incorrect: %d", __func__, 
Jan F. Chadima 69dd72
+		    (int) data.length);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	/* Save the session ID on the first time around */
Jan F. Chadima 69dd72
+	if (session_id2_len == 0) {
Jan F. Chadima 69dd72
+		session_id2_len = data.length;
Jan F. Chadima 69dd72
+		session_id2 = xmalloc(session_id2_len);
Jan F. Chadima 69dd72
+		memcpy(session_id2, data.value, session_id2_len);
Jan F. Chadima 69dd72
+	}
Jan F. Chadima 69dd72
+	major = ssh_gssapi_sign(gsscontext, &data, &hash);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	xfree(data.value);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	buffer_clear(m);
Jan F. Chadima 69dd72
+	buffer_put_int(m, major);
Jan F. Chadima 69dd72
+	buffer_put_string(m, hash.value, hash.length);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	mm_request_send(socket, MONITOR_ANS_GSSSIGN, m);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	gss_release_buffer(&minor, &hash);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	/* Turn on getpwnam permissions */
Jan F. Chadima 69dd72
+	monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
Jan F. Chadima 69dd72
+	
Jan F. Chadima 69dd72
+	/* And credential updating, for when rekeying */
Jan F. Chadima 69dd72
+	monitor_permit(mon_dispatch, MONITOR_REQ_GSSUPCREDS, 1);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	return (0);
Jan F. Chadima 69dd72
+}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+int
Jan F. Chadima 69dd72
+mm_answer_gss_updatecreds(int socket, Buffer *m) {
Jan F. Chadima 69dd72
+	ssh_gssapi_ccache store;
Jan F. Chadima 69dd72
+	int ok;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	store.filename = buffer_get_string(m, NULL);
Jan F. Chadima 69dd72
+	store.envvar   = buffer_get_string(m, NULL);
Jan F. Chadima 69dd72
+	store.envval   = buffer_get_string(m, NULL);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	ok = ssh_gssapi_update_creds(&store);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	xfree(store.filename);
Jan F. Chadima 69dd72
+	xfree(store.envvar);
Jan F. Chadima 69dd72
+	xfree(store.envval);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	buffer_clear(m);
Jan F. Chadima 69dd72
+	buffer_put_int(m, ok);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	return(0);
Jan F. Chadima 69dd72
+}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 #endif /* GSSAPI */
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 #ifdef JPAKE
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/monitor.h.gsskex openssh-6.2p1/monitor.h
Petr Lautrbach 8a29de
--- openssh-6.2p1/monitor.h.gsskex	2013-03-27 13:19:11.063624587 +0100
Petr Lautrbach 8a29de
+++ openssh-6.2p1/monitor.h	2013-03-27 13:19:11.146624246 +0100
Petr Lautrbach 8a29de
@@ -64,6 +64,8 @@ enum monitor_reqtype {
Petr Lautrbach 8a29de
 #ifdef WITH_SELINUX
Petr Lautrbach 8a29de
 	MONITOR_REQ_AUTHROLE = 80,
Petr Lautrbach 8a29de
 #endif
Petr Lautrbach 8a29de
+	MONITOR_REQ_GSSSIGN = 82, MONITOR_ANS_GSSSIGN = 83,
Petr Lautrbach 8a29de
+	MONITOR_REQ_GSSUPCREDS = 84, MONITOR_ANS_GSSUPCREDS = 85,
Petr Lautrbach 8a29de
 
Petr Lautrbach 8a29de
 	MONITOR_REQ_PAM_START = 100,
Petr Lautrbach 8a29de
 	MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103,
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/monitor_wrap.c.gsskex openssh-6.2p1/monitor_wrap.c
Petr Lautrbach 8a29de
--- openssh-6.2p1/monitor_wrap.c.gsskex	2013-03-27 13:19:11.064624583 +0100
Petr Lautrbach 8a29de
+++ openssh-6.2p1/monitor_wrap.c	2013-03-27 13:19:11.146624246 +0100
Petr Lautrbach 8a29de
@@ -1327,7 +1327,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss
Jan F. Chadima 69dd72
 }
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 int
Jan F. Chadima 69dd72
-mm_ssh_gssapi_userok(char *user)
Jan F. Chadima 69dd72
+mm_ssh_gssapi_userok(char *user, struct passwd *pw)
Jan F. Chadima 69dd72
 {
Jan F. Chadima 69dd72
 	Buffer m;
Jan F. Chadima 69dd72
 	int authenticated = 0;
Petr Lautrbach 8a29de
@@ -1344,6 +1344,51 @@ mm_ssh_gssapi_userok(char *user)
Jan F. Chadima 69dd72
 	debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not ");
Jan F. Chadima 69dd72
 	return (authenticated);
Jan F. Chadima 69dd72
 }
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+OM_uint32
Jan F. Chadima 69dd72
+mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash)
Jan F. Chadima 69dd72
+{
Jan F. Chadima 69dd72
+	Buffer m;
Jan F. Chadima 69dd72
+	OM_uint32 major;
Jan F. Chadima 69dd72
+	u_int len;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	buffer_init(&m);
Jan F. Chadima 69dd72
+	buffer_put_string(&m, data->value, data->length);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSIGN, &m);
Jan F. Chadima 69dd72
+	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSIGN, &m);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	major = buffer_get_int(&m);
Jan F. Chadima 69dd72
+	hash->value = buffer_get_string(&m, &len;;
Jan F. Chadima 69dd72
+	hash->length = len;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	buffer_free(&m);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	return(major);
Jan F. Chadima 69dd72
+}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+int
Jan F. Chadima 69dd72
+mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *store)
Jan F. Chadima 69dd72
+{
Jan F. Chadima 69dd72
+	Buffer m;
Jan F. Chadima 69dd72
+	int ok;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	buffer_init(&m);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	buffer_put_cstring(&m, store->filename ? store->filename : "");
Jan F. Chadima 69dd72
+	buffer_put_cstring(&m, store->envvar ? store->envvar : "");
Jan F. Chadima 69dd72
+	buffer_put_cstring(&m, store->envval ? store->envval : "");
Jan F. Chadima 69dd72
+	
Jan F. Chadima 69dd72
+	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUPCREDS, &m);
Jan F. Chadima 69dd72
+	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUPCREDS, &m);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	ok = buffer_get_int(&m);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	buffer_free(&m);
Jan F. Chadima 69dd72
+	
Jan F. Chadima 69dd72
+	return (ok);
Jan F. Chadima 69dd72
+}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 #endif /* GSSAPI */
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 #ifdef JPAKE
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/monitor_wrap.h.gsskex openssh-6.2p1/monitor_wrap.h
Petr Lautrbach 8a29de
--- openssh-6.2p1/monitor_wrap.h.gsskex	2013-03-27 13:19:11.064624583 +0100
Petr Lautrbach 8a29de
+++ openssh-6.2p1/monitor_wrap.h	2013-03-27 13:19:11.146624246 +0100
Petr Lautrbach d9e618
@@ -62,8 +62,10 @@ BIGNUM *mm_auth_rsa_generate_challenge(K
Jan F. Chadima 69dd72
 OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
Jan F. Chadima 69dd72
 OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *,
Jan F. Chadima 69dd72
    gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *);
Jan F. Chadima 69dd72
-int mm_ssh_gssapi_userok(char *user);
Jan F. Chadima 69dd72
+int mm_ssh_gssapi_userok(char *user, struct passwd *);
Jan F. Chadima 69dd72
 OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
Jan F. Chadima 69dd72
+OM_uint32 mm_ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t);
Jan F. Chadima 69dd72
+int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *);
Jan F. Chadima 69dd72
 #endif
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 #ifdef USE_PAM
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/readconf.c.gsskex openssh-6.2p1/readconf.c
Petr Lautrbach 8a29de
--- openssh-6.2p1/readconf.c.gsskex	2011-10-02 09:59:03.000000000 +0200
Petr Lautrbach 8a29de
+++ openssh-6.2p1/readconf.c	2013-03-27 13:19:11.147624242 +0100
Jan F. Chadima 69dd72
@@ -129,6 +129,8 @@ typedef enum {
Jan F. Chadima 69dd72
 	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
Jan F. Chadima 69dd72
 	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
Jan F. Chadima 69dd72
 	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
Jan F. Chadima 69dd72
+	oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey,
Jan F. Chadima 69dd72
+	oGssServerIdentity, 
Jan F. Chadima 69dd72
 	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
Jan F. Chadima 69dd72
 	oSendEnv, oControlPath, oControlMaster, oControlPersist,
Jan F. Chadima 69dd72
 	oHashKnownHosts,
Jan F. Chadima 69dd72
@@ -169,10 +171,19 @@ static struct {
Jan F. Chadima 69dd72
 	{ "afstokenpassing", oUnsupported },
Jan F. Chadima 69dd72
 #if defined(GSSAPI)
Jan F. Chadima 69dd72
 	{ "gssapiauthentication", oGssAuthentication },
Jan F. Chadima 69dd72
+	{ "gssapikeyexchange", oGssKeyEx },
Jan F. Chadima 69dd72
 	{ "gssapidelegatecredentials", oGssDelegateCreds },
Jan F. Chadima 69dd72
+	{ "gssapitrustdns", oGssTrustDns },
Jan F. Chadima 69dd72
+	{ "gssapiclientidentity", oGssClientIdentity },
Jan F. Chadima 69dd72
+	{ "gssapiserveridentity", oGssServerIdentity },
Jan F. Chadima 69dd72
+	{ "gssapirenewalforcesrekey", oGssRenewalRekey },
Jan F. Chadima 69dd72
 #else
Jan F. Chadima 69dd72
 	{ "gssapiauthentication", oUnsupported },
Jan F. Chadima 69dd72
+	{ "gssapikeyexchange", oUnsupported },
Jan F. Chadima 69dd72
 	{ "gssapidelegatecredentials", oUnsupported },
Jan F. Chadima 69dd72
+	{ "gssapitrustdns", oUnsupported },
Jan F. Chadima 69dd72
+	{ "gssapiclientidentity", oUnsupported },
Jan F. Chadima 69dd72
+	{ "gssapirenewalforcesrekey", oUnsupported },
Jan F. Chadima 69dd72
 #endif
Jan F. Chadima 69dd72
 	{ "fallbacktorsh", oDeprecated },
Jan F. Chadima 69dd72
 	{ "usersh", oDeprecated },
Petr Lautrbach aacd01
@@ -503,10 +514,30 @@ parse_flag:
Jan F. Chadima 69dd72
 		intptr = &options->gss_authentication;
Jan F. Chadima 69dd72
 		goto parse_flag;
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
+	case oGssKeyEx:
Jan F. Chadima 69dd72
+		intptr = &options->gss_keyex;
Jan F. Chadima 69dd72
+		goto parse_flag;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 	case oGssDelegateCreds:
Jan F. Chadima 69dd72
 		intptr = &options->gss_deleg_creds;
Jan F. Chadima 69dd72
 		goto parse_flag;
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
+	case oGssTrustDns:
Jan F. Chadima 69dd72
+		intptr = &options->gss_trust_dns;
Jan F. Chadima 69dd72
+		goto parse_flag;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	case oGssClientIdentity:
Jan F. Chadima 69dd72
+		charptr = &options->gss_client_identity;
Jan F. Chadima 69dd72
+		goto parse_string;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	case oGssServerIdentity:
Jan F. Chadima 69dd72
+		charptr = &options->gss_server_identity;
Jan F. Chadima 69dd72
+		goto parse_string;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	case oGssRenewalRekey:
Jan F. Chadima 69dd72
+		intptr = &options->gss_renewal_rekey;
Jan F. Chadima 69dd72
+		goto parse_flag;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 	case oBatchMode:
Jan F. Chadima 69dd72
 		intptr = &options->batch_mode;
Jan F. Chadima 69dd72
 		goto parse_flag;
Petr Lautrbach aacd01
@@ -1158,7 +1189,12 @@ initialize_options(Options * options)
Jan F. Chadima 69dd72
 	options->pubkey_authentication = -1;
Jan F. Chadima 69dd72
 	options->challenge_response_authentication = -1;
Jan F. Chadima 69dd72
 	options->gss_authentication = -1;
Jan F. Chadima 69dd72
+	options->gss_keyex = -1;
Jan F. Chadima 69dd72
 	options->gss_deleg_creds = -1;
Jan F. Chadima 69dd72
+	options->gss_trust_dns = -1;
Jan F. Chadima 69dd72
+	options->gss_renewal_rekey = -1;
Jan F. Chadima 69dd72
+	options->gss_client_identity = NULL;
Jan F. Chadima 69dd72
+	options->gss_server_identity = NULL;
Jan F. Chadima 69dd72
 	options->password_authentication = -1;
Jan F. Chadima 69dd72
 	options->kbd_interactive_authentication = -1;
Jan F. Chadima 69dd72
 	options->kbd_interactive_devices = NULL;
Petr Lautrbach aacd01
@@ -1258,8 +1294,14 @@ fill_default_options(Options * options)
Jan F. Chadima 69dd72
 		options->challenge_response_authentication = 1;
Jan F. Chadima 69dd72
 	if (options->gss_authentication == -1)
Jan F. Chadima 69dd72
 		options->gss_authentication = 0;
Jan F. Chadima 69dd72
+	if (options->gss_keyex == -1)
Jan F. Chadima 69dd72
+		options->gss_keyex = 0;
Jan F. Chadima 69dd72
 	if (options->gss_deleg_creds == -1)
Jan F. Chadima 69dd72
 		options->gss_deleg_creds = 0;
Jan F. Chadima 69dd72
+	if (options->gss_trust_dns == -1)
Jan F. Chadima 69dd72
+		options->gss_trust_dns = 0;
Jan F. Chadima 69dd72
+	if (options->gss_renewal_rekey == -1)
Jan F. Chadima 69dd72
+		options->gss_renewal_rekey = 0;
Jan F. Chadima 69dd72
 	if (options->password_authentication == -1)
Jan F. Chadima 69dd72
 		options->password_authentication = 1;
Jan F. Chadima 69dd72
 	if (options->kbd_interactive_authentication == -1)
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/readconf.h.gsskex openssh-6.2p1/readconf.h
Petr Lautrbach 8a29de
--- openssh-6.2p1/readconf.h.gsskex	2011-10-02 09:59:03.000000000 +0200
Petr Lautrbach 8a29de
+++ openssh-6.2p1/readconf.h	2013-03-27 13:19:11.147624242 +0100
Petr Lautrbach 51ca3b
@@ -48,7 +48,12 @@ typedef struct {
Jan F. Chadima 69dd72
 	int     challenge_response_authentication;
Jan F. Chadima 69dd72
 					/* Try S/Key or TIS, authentication. */
Jan F. Chadima 69dd72
 	int     gss_authentication;	/* Try GSS authentication */
Jan F. Chadima 69dd72
+	int     gss_keyex;		/* Try GSS key exchange */
Jan F. Chadima 69dd72
 	int     gss_deleg_creds;	/* Delegate GSS credentials */
Jan F. Chadima 69dd72
+	int	gss_trust_dns;		/* Trust DNS for GSS canonicalization */
Jan F. Chadima 69dd72
+	int	gss_renewal_rekey;	/* Credential renewal forces rekey */
Jan F. Chadima 69dd72
+	char    *gss_client_identity;   /* Principal to initiate GSSAPI with */
Jan F. Chadima 69dd72
+	char    *gss_server_identity;   /* GSSAPI target principal */
Jan F. Chadima 69dd72
 	int     password_authentication;	/* Try password
Jan F. Chadima 69dd72
 						 * authentication. */
Jan F. Chadima 69dd72
 	int     kbd_interactive_authentication; /* Try keyboard-interactive auth. */
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/servconf.c.gsskex openssh-6.2p1/servconf.c
Petr Lautrbach 8a29de
--- openssh-6.2p1/servconf.c.gsskex	2013-03-27 13:19:11.128624320 +0100
Petr Lautrbach 8a29de
+++ openssh-6.2p1/servconf.c	2013-03-27 13:19:11.147624242 +0100
Petr Lautrbach 9fe1af
@@ -102,7 +102,10 @@ initialize_server_options(ServerOptions
Jan F. Chadima 69dd72
 	options->kerberos_ticket_cleanup = -1;
Jan F. Chadima 69dd72
 	options->kerberos_get_afs_token = -1;
Jan F. Chadima 69dd72
 	options->gss_authentication=-1;
Jan F. Chadima 69dd72
+	options->gss_keyex = -1;
Jan F. Chadima 69dd72
 	options->gss_cleanup_creds = -1;
Jan F. Chadima 69dd72
+	options->gss_strict_acceptor = -1;
Jan F. Chadima 69dd72
+	options->gss_store_rekey = -1;
Jan F. Chadima 69dd72
 	options->password_authentication = -1;
Jan F. Chadima 69dd72
 	options->kbd_interactive_authentication = -1;
Jan F. Chadima 69dd72
 	options->challenge_response_authentication = -1;
Petr Lautrbach 5039c7
@@ -234,8 +237,14 @@ fill_default_server_options(ServerOption
Jan F. Chadima 69dd72
 		options->kerberos_get_afs_token = 0;
Jan F. Chadima 69dd72
 	if (options->gss_authentication == -1)
Jan F. Chadima 69dd72
 		options->gss_authentication = 0;
Jan F. Chadima 69dd72
+	if (options->gss_keyex == -1)
Jan F. Chadima 69dd72
+		options->gss_keyex = 0;
Jan F. Chadima 69dd72
 	if (options->gss_cleanup_creds == -1)
Jan F. Chadima 69dd72
 		options->gss_cleanup_creds = 1;
Jan F. Chadima 69dd72
+	if (options->gss_strict_acceptor == -1)
Jan F. Chadima 69dd72
+		options->gss_strict_acceptor = 1;
Jan F. Chadima 69dd72
+	if (options->gss_store_rekey == -1)
Jan F. Chadima 69dd72
+		options->gss_store_rekey = 0;
Jan F. Chadima 69dd72
 	if (options->password_authentication == -1)
Jan F. Chadima 69dd72
 		options->password_authentication = 1;
Jan F. Chadima 69dd72
 	if (options->kbd_interactive_authentication == -1)
Petr Lautrbach 5039c7
@@ -331,7 +340,9 @@ typedef enum {
Petr Lautrbach d9e618
 	sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication,
Petr Lautrbach d9e618
 	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
Petr Lautrbach d9e618
 	sClientAliveCountMax, sAuthorizedKeysFile,
Jan F. Chadima 69dd72
-	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
Jan F. Chadima 69dd72
+	sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
Jan F. Chadima 69dd72
+	sGssKeyEx, sGssStoreRekey,
Jan F. Chadima 69dd72
+	sAcceptEnv, sPermitTunnel,
Jan F. Chadima 69dd72
 	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
Jan F. Chadima 69dd72
 	sUsePrivilegeSeparation, sAllowAgentForwarding,
Petr Lautrbach 5039c7
 	sZeroKnowledgePasswordAuthentication, sHostCertificate,
Petr Lautrbach 5039c7
@@ -397,10 +408,20 @@ static struct {
Jan F. Chadima 69dd72
 #ifdef GSSAPI
Jan F. Chadima 69dd72
 	{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
Jan F. Chadima 69dd72
 	{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
Jan F. Chadima 69dd72
+	{ "gssapicleanupcreds", sGssCleanupCreds, SSHCFG_GLOBAL },
Jan F. Chadima 69dd72
+	{ "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
Jan F. Chadima 69dd72
+	{ "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
Jan F. Chadima 69dd72
+	{ "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL },
Jan F. Chadima 69dd72
 #else
Jan F. Chadima 69dd72
 	{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
Jan F. Chadima 69dd72
 	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
Jan F. Chadima 69dd72
+	{ "gssapicleanupcreds", sUnsupported, SSHCFG_GLOBAL },
Jan F. Chadima 69dd72
+	{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
Jan F. Chadima 69dd72
+	{ "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
Jan F. Chadima 69dd72
+	{ "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL },
Jan F. Chadima 69dd72
 #endif
Jan F. Chadima 69dd72
+	{ "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL },
Jan F. Chadima 69dd72
+	{ "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL },
Jan F. Chadima 69dd72
 	{ "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
Jan F. Chadima 69dd72
 	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
Jan F. Chadima 69dd72
 	{ "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
Petr Lautrbach 8a29de
@@ -1054,10 +1075,22 @@ process_server_config_line(ServerOptions
Jan F. Chadima 69dd72
 		intptr = &options->gss_authentication;
Jan F. Chadima 69dd72
 		goto parse_flag;
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
+	case sGssKeyEx:
Jan F. Chadima 69dd72
+		intptr = &options->gss_keyex;
Jan F. Chadima 69dd72
+		goto parse_flag;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 	case sGssCleanupCreds:
Jan F. Chadima 69dd72
 		intptr = &options->gss_cleanup_creds;
Jan F. Chadima 69dd72
 		goto parse_flag;
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
+	case sGssStrictAcceptor:
Jan F. Chadima 69dd72
+		intptr = &options->gss_strict_acceptor;
Jan F. Chadima 69dd72
+		goto parse_flag;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	case sGssStoreRekey:
Jan F. Chadima 69dd72
+		intptr = &options->gss_store_rekey;
Jan F. Chadima 69dd72
+		goto parse_flag;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 	case sPasswordAuthentication:
Jan F. Chadima 69dd72
 		intptr = &options->password_authentication;
Jan F. Chadima 69dd72
 		goto parse_flag;
Petr Lautrbach 8a29de
@@ -1938,6 +1971,9 @@ dump_config(ServerOptions *o)
Petr Lautrbach d9e618
 #ifdef GSSAPI
Jan F. Chadima 69dd72
 	dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
Jan F. Chadima 69dd72
 	dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
Jan F. Chadima 69dd72
+	dump_cfg_fmtint(sGssKeyEx, o->gss_keyex);
Jan F. Chadima 69dd72
+	dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor);
Jan F. Chadima 69dd72
+	dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey);
Jan F. Chadima 69dd72
 #endif
Jan F. Chadima 69dd72
 #ifdef JPAKE
Jan F. Chadima 69dd72
 	dump_cfg_fmtint(sZeroKnowledgePasswordAuthentication,
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/servconf.h.gsskex openssh-6.2p1/servconf.h
Petr Lautrbach 8a29de
--- openssh-6.2p1/servconf.h.gsskex	2013-03-27 13:19:11.128624320 +0100
Petr Lautrbach 8a29de
+++ openssh-6.2p1/servconf.h	2013-03-27 13:19:11.147624242 +0100
Petr Lautrbach 8a29de
@@ -110,7 +110,10 @@ typedef struct {
Jan F. Chadima 69dd72
 	int     kerberos_get_afs_token;		/* If true, try to get AFS token if
Jan F. Chadima 69dd72
 						 * authenticated with Kerberos. */
Jan F. Chadima 69dd72
 	int     gss_authentication;	/* If true, permit GSSAPI authentication */
Jan F. Chadima 69dd72
+	int     gss_keyex;		/* If true, permit GSSAPI key exchange */
Jan F. Chadima 69dd72
 	int     gss_cleanup_creds;	/* If true, destroy cred cache on logout */
Jan F. Chadima 69dd72
+	int 	gss_strict_acceptor;	/* If true, restrict the GSSAPI acceptor name */
Jan F. Chadima 69dd72
+	int 	gss_store_rekey;
Jan F. Chadima 69dd72
 	int     password_authentication;	/* If true, permit password
Jan F. Chadima 69dd72
 						 * authentication. */
Jan F. Chadima 69dd72
 	int     kbd_interactive_authentication;	/* If true, permit */
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/ssh_config.5.gsskex openssh-6.2p1/ssh_config.5
Petr Lautrbach 8a29de
--- openssh-6.2p1/ssh_config.5.gsskex	2013-01-09 06:12:19.000000000 +0100
Petr Lautrbach 8a29de
+++ openssh-6.2p1/ssh_config.5	2013-03-27 13:19:11.148624238 +0100
Petr Lautrbach 8a29de
@@ -530,11 +530,43 @@ Specifies whether user authentication ba
Jan F. Chadima 69dd72
 The default is
Jan F. Chadima 69dd72
 .Dq no .
Jan F. Chadima 69dd72
 Note that this option applies to protocol version 2 only.
Jan F. Chadima 69dd72
+.It Cm GSSAPIKeyExchange
Jan F. Chadima 69dd72
+Specifies whether key exchange based on GSSAPI may be used. When using
Jan F. Chadima 69dd72
+GSSAPI key exchange the server need not have a host key.
Jan F. Chadima 69dd72
+The default is
Jan F. Chadima 69dd72
+.Dq no .
Jan F. Chadima 69dd72
+Note that this option applies to protocol version 2 only.
Jan F. Chadima 69dd72
+.It Cm GSSAPIClientIdentity
Jan F. Chadima 69dd72
+If set, specifies the GSSAPI client identity that ssh should use when 
Jan F. Chadima 69dd72
+connecting to the server. The default is unset, which means that the default 
Jan F. Chadima 69dd72
+identity will be used.
Jan F. Chadima 69dd72
+.It Cm GSSAPIServerIdentity
Jan F. Chadima 69dd72
+If set, specifies the GSSAPI server identity that ssh should expect when 
Jan F. Chadima 69dd72
+connecting to the server. The default is unset, which means that the
Jan F. Chadima 69dd72
+expected GSSAPI server identity will be determined from the target
Jan F. Chadima 69dd72
+hostname.
Jan F. Chadima 69dd72
 .It Cm GSSAPIDelegateCredentials
Jan F. Chadima 69dd72
 Forward (delegate) credentials to the server.
Jan F. Chadima 69dd72
 The default is
Jan F. Chadima 69dd72
 .Dq no .
Jan F. Chadima 69dd72
-Note that this option applies to protocol version 2 only.
Jan F. Chadima 69dd72
+Note that this option applies to protocol version 2 connections using GSSAPI.
Jan F. Chadima 69dd72
+.It Cm GSSAPIRenewalForcesRekey
Jan F. Chadima 69dd72
+If set to 
Jan F. Chadima 69dd72
+.Dq yes
Jan F. Chadima 69dd72
+then renewal of the client's GSSAPI credentials will force the rekeying of the
Jan F. Chadima 69dd72
+ssh connection. With a compatible server, this can delegate the renewed 
Jan F. Chadima 69dd72
+credentials to a session on the server.
Jan F. Chadima 69dd72
+The default is
Jan F. Chadima 69dd72
+.Dq no .
Jan F. Chadima 69dd72
+.It Cm GSSAPITrustDns
Jan F. Chadima 69dd72
+Set to 
Jan F. Chadima 69dd72
+.Dq yes to indicate that the DNS is trusted to securely canonicalize
Jan F. Chadima 69dd72
+the name of the host being connected to. If 
Jan F. Chadima 69dd72
+.Dq no, the hostname entered on the
Jan F. Chadima 69dd72
+command line will be passed untouched to the GSSAPI library.
Jan F. Chadima 69dd72
+The default is
Jan F. Chadima 69dd72
+.Dq no .
Jan F. Chadima 69dd72
+This option only applies to protocol version 2 connections using GSSAPI.
Jan F. Chadima 69dd72
 .It Cm HashKnownHosts
Jan F. Chadima 69dd72
 Indicates that
Jan F. Chadima 69dd72
 .Xr ssh 1
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/ssh_config.gsskex openssh-6.2p1/ssh_config
Petr Lautrbach 8a29de
--- openssh-6.2p1/ssh_config.gsskex	2013-03-27 13:19:11.120624353 +0100
Petr Lautrbach 8a29de
+++ openssh-6.2p1/ssh_config	2013-03-27 13:19:11.148624238 +0100
Petr Lautrbach 5039c7
@@ -26,6 +26,8 @@
Petr Lautrbach 5039c7
 #   HostbasedAuthentication no
Petr Lautrbach 5039c7
 #   GSSAPIAuthentication no
Petr Lautrbach 5039c7
 #   GSSAPIDelegateCredentials no
Petr Lautrbach 5039c7
+#   GSSAPIKeyExchange no
Petr Lautrbach 5039c7
+#   GSSAPITrustDNS no
Petr Lautrbach 5039c7
 #   BatchMode no
Petr Lautrbach 5039c7
 #   CheckHostIP yes
Petr Lautrbach 5039c7
 #   AddressFamily any
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/sshconnect2.c.gsskex openssh-6.2p1/sshconnect2.c
Petr Lautrbach 8a29de
--- openssh-6.2p1/sshconnect2.c.gsskex	2013-03-27 13:19:11.104624419 +0100
Petr Lautrbach 8a29de
+++ openssh-6.2p1/sshconnect2.c	2013-03-27 13:19:11.149624234 +0100
Jan F. Chadima 69dd72
@@ -162,9 +162,34 @@ ssh_kex2(char *host, struct sockaddr *ho
Jan F. Chadima 69dd72
 {
Jan F. Chadima 69dd72
 	Kex *kex;
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
+#ifdef GSSAPI
Jan F. Chadima 69dd72
+	char *orig = NULL, *gss = NULL;
Jan F. Chadima 69dd72
+	char *gss_host = NULL;
Jan F. Chadima 69dd72
+#endif
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 	xxx_host = host;
Jan F. Chadima 69dd72
 	xxx_hostaddr = hostaddr;
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
+#ifdef GSSAPI
Jan F. Chadima 69dd72
+	if (options.gss_keyex) {
Jan F. Chadima 69dd72
+		/* Add the GSSAPI mechanisms currently supported on this 
Jan F. Chadima 69dd72
+		 * client to the key exchange algorithm proposal */
Jan F. Chadima 69dd72
+		orig = myproposal[PROPOSAL_KEX_ALGS];
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		if (options.gss_trust_dns)
Jan F. Chadima 69dd72
+			gss_host = (char *)get_canonical_hostname(1);
Jan F. Chadima 69dd72
+		else
Jan F. Chadima 69dd72
+			gss_host = host;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		gss = ssh_gssapi_client_mechanisms(gss_host, options.gss_client_identity);
Jan F. Chadima 69dd72
+		if (gss) {
Jan F. Chadima 69dd72
+			debug("Offering GSSAPI proposal: %s", gss);
Jan F. Chadima 69dd72
+			xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
Jan F. Chadima 69dd72
+			    "%s,%s", gss, orig);
Jan F. Chadima 69dd72
+		}
Jan F. Chadima 69dd72
+	}
Jan F. Chadima 69dd72
+#endif
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 	if (options.ciphers == (char *)-1) {
Jan F. Chadima 69dd72
 		logit("No valid ciphers for protocol version 2 given, using defaults.");
Jan F. Chadima 69dd72
 		options.ciphers = NULL;
Jan F. Chadima 69dd72
@@ -207,6 +232,17 @@ ssh_kex2(char *host, struct sockaddr *ho
Jan F. Chadima 69dd72
 	if (options.kex_algorithms != NULL)
Jan F. Chadima 69dd72
 		myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms;
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
+#ifdef GSSAPI
Jan F. Chadima 69dd72
+	/* If we've got GSSAPI algorithms, then we also support the
Jan F. Chadima 69dd72
+	 * 'null' hostkey, as a last resort */
Jan F. Chadima 69dd72
+	if (options.gss_keyex && gss) {
Jan F. Chadima 69dd72
+		orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
Jan F. Chadima 69dd72
+		xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], 
Jan F. Chadima 69dd72
+		    "%s,null", orig);
Jan F. Chadima 69dd72
+		xfree(gss);
Jan F. Chadima 69dd72
+	}
Jan F. Chadima 69dd72
+#endif
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 	if (options.rekey_limit)
Jan F. Chadima 69dd72
 		packet_set_rekey_limit((u_int32_t)options.rekey_limit);
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
@@ -217,10 +253,30 @@ ssh_kex2(char *host, struct sockaddr *ho
Jan F. Chadima 69dd72
 	kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
Jan F. Chadima 69dd72
 	kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
Jan F. Chadima 69dd72
 	kex->kex[KEX_ECDH_SHA2] = kexecdh_client;
Jan F. Chadima 69dd72
+#ifdef GSSAPI
Jan F. Chadima 69dd72
+	if (options.gss_keyex) {
Jan F. Chadima 69dd72
+		kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client;
Jan F. Chadima 69dd72
+		kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_client;
Jan F. Chadima 69dd72
+		kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client;
Jan F. Chadima 69dd72
+	}
Jan F. Chadima 69dd72
+#endif
Jan F. Chadima 69dd72
 	kex->client_version_string=client_version_string;
Jan F. Chadima 69dd72
 	kex->server_version_string=server_version_string;
Jan F. Chadima 69dd72
 	kex->verify_host_key=&verify_host_key_callback;
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
+#ifdef GSSAPI
Jan F. Chadima 69dd72
+	if (options.gss_keyex) {
Jan F. Chadima 69dd72
+		kex->gss_deleg_creds = options.gss_deleg_creds;
Jan F. Chadima 69dd72
+		kex->gss_trust_dns = options.gss_trust_dns;
Jan F. Chadima 69dd72
+		kex->gss_client = options.gss_client_identity;
Jan F. Chadima 69dd72
+		if (options.gss_server_identity) {
Jan F. Chadima 69dd72
+			kex->gss_host = options.gss_server_identity;
Jan F. Chadima 69dd72
+		} else {
Jan F. Chadima 69dd72
+			kex->gss_host = gss_host;
Jan F. Chadima 69dd72
+        }
Jan F. Chadima 69dd72
+	}
Jan F. Chadima 69dd72
+#endif
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 	xxx_kex = kex;
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 	dispatch_run(DISPATCH_BLOCK, &kex->done, kex);
Petr Lautrbach 8a29de
@@ -316,6 +372,7 @@ void	input_gssapi_token(int type, u_int3
Jan F. Chadima 69dd72
 void	input_gssapi_hash(int type, u_int32_t, void *);
Jan F. Chadima 69dd72
 void	input_gssapi_error(int, u_int32_t, void *);
Jan F. Chadima 69dd72
 void	input_gssapi_errtok(int, u_int32_t, void *);
Jan F. Chadima 69dd72
+int	userauth_gsskeyex(Authctxt *authctxt);
Jan F. Chadima 69dd72
 #endif
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 void	userauth(Authctxt *, char *);
Petr Lautrbach 8a29de
@@ -331,6 +388,11 @@ static char *authmethods_get(void);
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 Authmethod authmethods[] = {
Jan F. Chadima 69dd72
 #ifdef GSSAPI
Jan F. Chadima 69dd72
+	{"gssapi-keyex",
Jan F. Chadima 69dd72
+		userauth_gsskeyex,
Jan F. Chadima 69dd72
+		NULL,
Jan F. Chadima 69dd72
+		&options.gss_authentication,
Jan F. Chadima 69dd72
+		NULL},
Jan F. Chadima 69dd72
 	{"gssapi-with-mic",
Jan F. Chadima 69dd72
 		userauth_gssapi,
Jan F. Chadima 69dd72
 		NULL,
Petr Lautrbach 8a29de
@@ -638,19 +700,31 @@ userauth_gssapi(Authctxt *authctxt)
Jan F. Chadima 69dd72
 	static u_int mech = 0;
Jan F. Chadima 69dd72
 	OM_uint32 min;
Jan F. Chadima 69dd72
 	int ok = 0;
Jan F. Chadima 69dd72
+	const char *gss_host;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (options.gss_server_identity)
Jan F. Chadima 69dd72
+		gss_host = options.gss_server_identity;
Jan F. Chadima 69dd72
+	else if (options.gss_trust_dns)
Jan F. Chadima 69dd72
+		gss_host = get_canonical_hostname(1);
Jan F. Chadima 69dd72
+	else
Jan F. Chadima 69dd72
+		gss_host = authctxt->host;
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 	/* Try one GSSAPI method at a time, rather than sending them all at
Jan F. Chadima 69dd72
 	 * once. */
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 	if (gss_supported == NULL)
Jan F. Chadima 69dd72
-		gss_indicate_mechs(&min, &gss_supported);
Jan F. Chadima 69dd72
+		if (GSS_ERROR(gss_indicate_mechs(&min, &gss_supported))) {
Jan F. Chadima 69dd72
+			gss_supported = NULL;
Jan F. Chadima 69dd72
+			return 0;
Jan F. Chadima 69dd72
+		}
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 	/* Check to see if the mechanism is usable before we offer it */
Jan F. Chadima 69dd72
 	while (mech < gss_supported->count && !ok) {
Jan F. Chadima 69dd72
 		/* My DER encoding requires length<128 */
Jan F. Chadima 69dd72
 		if (gss_supported->elements[mech].length < 128 &&
Jan F. Chadima 69dd72
 		    ssh_gssapi_check_mechanism(&gssctxt, 
Jan F. Chadima 69dd72
-		    &gss_supported->elements[mech], authctxt->host)) {
Jan F. Chadima 69dd72
+		    &gss_supported->elements[mech], gss_host, 
Jan F. Chadima 69dd72
+                    options.gss_client_identity)) {
Jan F. Chadima 69dd72
 			ok = 1; /* Mechanism works */
Jan F. Chadima 69dd72
 		} else {
Jan F. Chadima 69dd72
 			mech++;
Petr Lautrbach 8a29de
@@ -747,8 +821,8 @@ input_gssapi_response(int type, u_int32_
Jan F. Chadima 69dd72
 {
Jan F. Chadima 69dd72
 	Authctxt *authctxt = ctxt;
Jan F. Chadima 69dd72
 	Gssctxt *gssctxt;
Jan F. Chadima 69dd72
-	int oidlen;
Jan F. Chadima 69dd72
-	char *oidv;
Jan F. Chadima 69dd72
+	u_int oidlen;
Jan F. Chadima 69dd72
+	u_char *oidv;
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 	if (authctxt == NULL)
Jan F. Chadima 69dd72
 		fatal("input_gssapi_response: no authentication context");
Petr Lautrbach 8a29de
@@ -858,6 +932,48 @@ input_gssapi_error(int type, u_int32_t p
Jan F. Chadima 69dd72
 	xfree(msg);
Jan F. Chadima 69dd72
 	xfree(lang);
Jan F. Chadima 69dd72
 }
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+int
Jan F. Chadima 69dd72
+userauth_gsskeyex(Authctxt *authctxt)
Jan F. Chadima 69dd72
+{
Jan F. Chadima 69dd72
+	Buffer b;
Jan F. Chadima 69dd72
+	gss_buffer_desc gssbuf;
Jan F. Chadima 69dd72
+	gss_buffer_desc mic = GSS_C_EMPTY_BUFFER;
Jan F. Chadima 69dd72
+	OM_uint32 ms;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	static int attempt = 0;
Jan F. Chadima 69dd72
+	if (attempt++ >= 1)
Jan F. Chadima 69dd72
+		return (0);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (gss_kex_context == NULL) {
Jan F. Chadima 69dd72
+		debug("No valid Key exchange context"); 
Jan F. Chadima 69dd72
+		return (0);
Jan F. Chadima 69dd72
+	}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	ssh_gssapi_buildmic(&b, authctxt->server_user, authctxt->service,
Jan F. Chadima 69dd72
+	    "gssapi-keyex");
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	gssbuf.value = buffer_ptr(&b);
Jan F. Chadima 69dd72
+	gssbuf.length = buffer_len(&b);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) {
Jan F. Chadima 69dd72
+		buffer_free(&b);
Jan F. Chadima 69dd72
+		return (0);
Jan F. Chadima 69dd72
+	}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	packet_start(SSH2_MSG_USERAUTH_REQUEST);
Jan F. Chadima 69dd72
+	packet_put_cstring(authctxt->server_user);
Jan F. Chadima 69dd72
+	packet_put_cstring(authctxt->service);
Jan F. Chadima 69dd72
+	packet_put_cstring(authctxt->method->name);
Jan F. Chadima 69dd72
+	packet_put_string(mic.value, mic.length);
Jan F. Chadima 69dd72
+	packet_send();
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	buffer_free(&b);
Jan F. Chadima 69dd72
+	gss_release_buffer(&ms, &mic);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	return (1);
Jan F. Chadima 69dd72
+}
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 #endif /* GSSAPI */
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 int
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/sshd.c.gsskex openssh-6.2p1/sshd.c
Petr Lautrbach 8a29de
--- openssh-6.2p1/sshd.c.gsskex	2013-03-27 13:19:11.133624300 +0100
Petr Lautrbach 8a29de
+++ openssh-6.2p1/sshd.c	2013-03-27 13:19:11.149624234 +0100
Jan F. Chadima 69dd72
@@ -124,6 +124,10 @@
Jan F. Chadima 69dd72
 #include "ssh-sandbox.h"
Jan F. Chadima 69dd72
 #include "version.h"
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
+#ifdef USE_SECURITY_SESSION_API
Jan F. Chadima 69dd72
+#include <Security/AuthSession.h>
Jan F. Chadima 69dd72
+#endif
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 #ifdef LIBWRAP
Jan F. Chadima 69dd72
 #include <tcpd.h>
Jan F. Chadima 69dd72
 #include <syslog.h>
Petr Lautrbach 8a29de
@@ -1733,10 +1737,13 @@ main(int ac, char **av)
Jan F. Chadima 69dd72
 		logit("Disabling protocol version 1. Could not load host key");
Jan F. Chadima 69dd72
 		options.protocol &= ~SSH_PROTO_1;
Jan F. Chadima 69dd72
 	}
Jan F. Chadima 69dd72
+#ifndef GSSAPI
Jan F. Chadima 69dd72
+	/* The GSSAPI key exchange can run without a host key */
Jan F. Chadima 69dd72
 	if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) {
Jan F. Chadima 69dd72
 		logit("Disabling protocol version 2. Could not load host key");
Jan F. Chadima 69dd72
 		options.protocol &= ~SSH_PROTO_2;
Jan F. Chadima 69dd72
 	}
Jan F. Chadima 69dd72
+#endif
Jan F. Chadima 69dd72
 	if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) {
Jan F. Chadima 69dd72
 		logit("sshd: no hostkeys available -- exiting.");
Jan F. Chadima 69dd72
 		exit(1);
Petr Lautrbach 8a29de
@@ -2068,6 +2075,60 @@ main(int ac, char **av)
Jan F. Chadima 69dd72
 	/* Log the connection. */
Jan F. Chadima 69dd72
 	verbose("Connection from %.500s port %d", remote_ip, remote_port);
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
+#ifdef USE_SECURITY_SESSION_API
Jan F. Chadima 69dd72
+	/*
Jan F. Chadima 69dd72
+	 * Create a new security session for use by the new user login if
Jan F. Chadima 69dd72
+	 * the current session is the root session or we are not launched
Jan F. Chadima 69dd72
+	 * by inetd (eg: debugging mode or server mode).  We do not
Jan F. Chadima 69dd72
+	 * necessarily need to create a session if we are launched from
Jan F. Chadima 69dd72
+	 * inetd because Panther xinetd will create a session for us.
Jan F. Chadima 69dd72
+	 *
Jan F. Chadima 69dd72
+	 * The only case where this logic will fail is if there is an
Jan F. Chadima 69dd72
+	 * inetd running in a non-root session which is not creating
Jan F. Chadima 69dd72
+	 * new sessions for us.  Then all the users will end up in the
Jan F. Chadima 69dd72
+	 * same session (bad).
Jan F. Chadima 69dd72
+	 *
Jan F. Chadima 69dd72
+	 * When the client exits, the session will be destroyed for us
Jan F. Chadima 69dd72
+	 * automatically.
Jan F. Chadima 69dd72
+	 *
Jan F. Chadima 69dd72
+	 * We must create the session before any credentials are stored
Jan F. Chadima 69dd72
+	 * (including AFS pags, which happens a few lines below).
Jan F. Chadima 69dd72
+	 */
Jan F. Chadima 69dd72
+	{
Jan F. Chadima 69dd72
+		OSStatus err = 0;
Jan F. Chadima 69dd72
+		SecuritySessionId sid = 0;
Jan F. Chadima 69dd72
+		SessionAttributeBits sattrs = 0;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		err = SessionGetInfo(callerSecuritySession, &sid, &sattrs);
Jan F. Chadima 69dd72
+		if (err)
Jan F. Chadima 69dd72
+			error("SessionGetInfo() failed with error %.8X",
Jan F. Chadima 69dd72
+			    (unsigned) err);
Jan F. Chadima 69dd72
+		else
Jan F. Chadima 69dd72
+			debug("Current Session ID is %.8X / Session Attributes are %.8X",
Jan F. Chadima 69dd72
+			    (unsigned) sid, (unsigned) sattrs);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+		if (inetd_flag && !(sattrs & sessionIsRoot))
Jan F. Chadima 69dd72
+			debug("Running in inetd mode in a non-root session... "
Jan F. Chadima 69dd72
+			    "assuming inetd created the session for us.");
Jan F. Chadima 69dd72
+		else {
Jan F. Chadima 69dd72
+			debug("Creating new security session...");
Jan F. Chadima 69dd72
+			err = SessionCreate(0, sessionHasTTY | sessionIsRemote);
Jan F. Chadima 69dd72
+			if (err)
Jan F. Chadima 69dd72
+				error("SessionCreate() failed with error %.8X",
Jan F. Chadima 69dd72
+				    (unsigned) err);
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+			err = SessionGetInfo(callerSecuritySession, &sid, 
Jan F. Chadima 69dd72
+			    &sattrs);
Jan F. Chadima 69dd72
+			if (err)
Jan F. Chadima 69dd72
+				error("SessionGetInfo() failed with error %.8X",
Jan F. Chadima 69dd72
+				    (unsigned) err);
Jan F. Chadima 69dd72
+			else
Jan F. Chadima 69dd72
+				debug("New Session ID is %.8X / Session Attributes are %.8X",
Jan F. Chadima 69dd72
+				    (unsigned) sid, (unsigned) sattrs);
Jan F. Chadima 69dd72
+		}
Jan F. Chadima 69dd72
+	}
Jan F. Chadima 69dd72
+#endif
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 	/*
Jan F. Chadima 69dd72
 	 * We don't want to listen forever unless the other side
Jan F. Chadima 69dd72
 	 * successfully authenticates itself.  So we set up an alarm which is
Petr Lautrbach aacd01
@@ -2466,6 +2526,48 @@ do_ssh2_kex(void)
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
 	myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types();
Jan F. Chadima 69dd72
 
Jan F. Chadima 69dd72
+#ifdef GSSAPI
Jan F. Chadima 69dd72
+	{
Jan F. Chadima 69dd72
+	char *orig;
Jan F. Chadima 69dd72
+	char *gss = NULL;
Jan F. Chadima 69dd72
+	char *newstr = NULL;
Jan F. Chadima 69dd72
+	orig = myproposal[PROPOSAL_KEX_ALGS];
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	/* 
Jan F. Chadima 69dd72
+	 * If we don't have a host key, then there's no point advertising
Jan F. Chadima 69dd72
+	 * the other key exchange algorithms
Jan F. Chadima 69dd72
+	 */
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0)
Jan F. Chadima 69dd72
+		orig = NULL;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (options.gss_keyex)
Jan F. Chadima 69dd72
+		gss = ssh_gssapi_server_mechanisms();
Jan F. Chadima 69dd72
+	else
Jan F. Chadima 69dd72
+		gss = NULL;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (gss && orig)
Jan F. Chadima 69dd72
+		xasprintf(&newstr, "%s,%s", gss, orig);
Jan F. Chadima 69dd72
+	else if (gss)
Jan F. Chadima 69dd72
+		newstr = gss;
Jan F. Chadima 69dd72
+	else if (orig)
Jan F. Chadima 69dd72
+		newstr = orig;
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	/* 
Jan F. Chadima 69dd72
+	 * If we've got GSSAPI mechanisms, then we've got the 'null' host
Jan F. Chadima 69dd72
+	 * key alg, but we can't tell people about it unless its the only
Jan F. Chadima 69dd72
+  	 * host key algorithm we support
Jan F. Chadima 69dd72
+	 */
Jan F. Chadima 69dd72
+	if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0)
Jan F. Chadima 69dd72
+		myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null";
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
+	if (newstr)
Jan F. Chadima 69dd72
+		myproposal[PROPOSAL_KEX_ALGS] = newstr;
Jan F. Chadima 69dd72
+	else
Jan F. Chadima 69dd72
+		fatal("No supported key exchange algorithms");
Jan F. Chadima 69dd72
+	}
Jan F. Chadima 69dd72
+#endif
Jan F. Chadima 69dd72
+
Jan F. Chadima 69dd72
 	/* start key exchange */
Jan F. Chadima 69dd72
 	kex = kex_setup(myproposal);
Jan F. Chadima 69dd72
 	kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
Petr Lautrbach aacd01
@@ -2473,6 +2575,13 @@ do_ssh2_kex(void)
Jan F. Chadima 69dd72
 	kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
Jan F. Chadima 69dd72
 	kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
Jan F. Chadima 69dd72
 	kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
Jan F. Chadima 69dd72
+#ifdef GSSAPI
Jan F. Chadima 69dd72
+	if (options.gss_keyex) {
Jan F. Chadima 69dd72
+		kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
Jan F. Chadima 69dd72
+		kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
Jan F. Chadima 69dd72
+		kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
Jan F. Chadima 69dd72
+	}
Jan F. Chadima 69dd72
+#endif
Jan F. Chadima 69dd72
 	kex->server = 1;
Jan F. Chadima 69dd72
 	kex->client_version_string=client_version_string;
Jan F. Chadima 69dd72
 	kex->server_version_string=server_version_string;
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/sshd_config.5.gsskex openssh-6.2p1/sshd_config.5
Petr Lautrbach 8a29de
--- openssh-6.2p1/sshd_config.5.gsskex	2013-03-27 13:19:11.129624316 +0100
Petr Lautrbach 8a29de
+++ openssh-6.2p1/sshd_config.5	2013-03-27 13:19:11.150624230 +0100
Petr Lautrbach 8a29de
@@ -481,12 +481,40 @@ Specifies whether user authentication ba
Jan F. Chadima 69dd72
 The default is
Jan F. Chadima 69dd72
 .Dq no .
Jan F. Chadima 69dd72
 Note that this option applies to protocol version 2 only.
Jan F. Chadima 69dd72
+.It Cm GSSAPIKeyExchange
Jan F. Chadima 69dd72
+Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange
Jan F. Chadima 69dd72
+doesn't rely on ssh keys to verify host identity.
Jan F. Chadima 69dd72
+The default is
Jan F. Chadima 69dd72
+.Dq no .
Jan F. Chadima 69dd72
+Note that this option applies to protocol version 2 only.
Jan F. Chadima 69dd72
 .It Cm GSSAPICleanupCredentials
Jan F. Chadima 69dd72
 Specifies whether to automatically destroy the user's credentials cache
Jan F. Chadima 69dd72
 on logout.
Jan F. Chadima 69dd72
 The default is
Jan F. Chadima 69dd72
 .Dq yes .
Jan F. Chadima 69dd72
 Note that this option applies to protocol version 2 only.
Jan F. Chadima 69dd72
+.It Cm GSSAPIStrictAcceptorCheck
Jan F. Chadima 69dd72
+Determines whether to be strict about the identity of the GSSAPI acceptor 
Jan F. Chadima 69dd72
+a client authenticates against. If
Jan F. Chadima 69dd72
+.Dq yes
Jan F. Chadima 69dd72
+then the client must authenticate against the
Jan F. Chadima 69dd72
+.Pa host
Jan F. Chadima 69dd72
+service on the current hostname. If 
Jan F. Chadima 69dd72
+.Dq no
Jan F. Chadima 69dd72
+then the client may authenticate against any service key stored in the 
Jan F. Chadima 69dd72
+machine's default store. This facility is provided to assist with operation 
Jan F. Chadima 69dd72
+on multi homed machines. 
Jan F. Chadima 69dd72
+The default is
Jan F. Chadima 69dd72
+.Dq yes .
Jan F. Chadima 69dd72
+Note that this option applies only to protocol version 2 GSSAPI connections,
Jan F. Chadima 69dd72
+and setting it to 
Jan F. Chadima 69dd72
+.Dq no
Jan F. Chadima 69dd72
+may only work with recent Kerberos GSSAPI libraries.
Jan F. Chadima 69dd72
+.It Cm GSSAPIStoreCredentialsOnRekey
Jan F. Chadima 69dd72
+Controls whether the user's GSSAPI credentials should be updated following a 
Jan F. Chadima 69dd72
+successful connection rekeying. This option can be used to accepted renewed 
Jan F. Chadima 69dd72
+or updated credentials from a compatible client. The default is
Jan F. Chadima 69dd72
+.Dq no .
Jan F. Chadima 69dd72
 .It Cm HostbasedAuthentication
Jan F. Chadima 69dd72
 Specifies whether rhosts or /etc/hosts.equiv authentication together
Jan F. Chadima 69dd72
 with successful public key client host authentication is allowed
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/sshd_config.gsskex openssh-6.2p1/sshd_config
Petr Lautrbach 8a29de
--- openssh-6.2p1/sshd_config.gsskex	2013-03-27 13:19:11.133624300 +0100
Petr Lautrbach 8a29de
+++ openssh-6.2p1/sshd_config	2013-03-27 13:19:11.150624230 +0100
Petr Lautrbach 5039c7
@@ -89,6 +89,8 @@ ChallengeResponseAuthentication no
Petr Lautrbach 5039c7
 GSSAPIAuthentication yes
Petr Lautrbach 5039c7
 #GSSAPICleanupCredentials yes
Petr Lautrbach 5039c7
 GSSAPICleanupCredentials yes
Petr Lautrbach 5039c7
+#GSSAPIStrictAcceptorCheck yes
Petr Lautrbach 5039c7
+#GSSAPIKeyExchange no
Petr Lautrbach 5039c7
 
Petr Lautrbach 5039c7
 # Set this to 'yes' to enable PAM authentication, account processing, 
Petr Lautrbach 5039c7
 # and session processing. If this is enabled, PAM authentication will 
Petr Lautrbach 8a29de
diff -up openssh-6.2p1/ssh-gss.h.gsskex openssh-6.2p1/ssh-gss.h
Petr Lautrbach 8a29de
--- openssh-6.2p1/ssh-gss.h.gsskex	2013-02-25 01:24:44.000000000 +0100
Petr Lautrbach 8a29de
+++ openssh-6.2p1/ssh-gss.h	2013-03-27 13:19:11.150624230 +0100
Petr Lautrbach d9e618
@@ -1,6 +1,6 @@
Petr Lautrbach d9e618
 /* $OpenBSD: ssh-gss.h,v 1.10 2007/06/12 08:20:00 djm Exp $ */
Petr Lautrbach d9e618
 /*
Petr Lautrbach d9e618
- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
Petr Lautrbach d9e618
+ * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
Petr Lautrbach d9e618
  *
Petr Lautrbach d9e618
  * Redistribution and use in source and binary forms, with or without
Petr Lautrbach d9e618
  * modification, are permitted provided that the following conditions
Petr Lautrbach 8a29de
@@ -61,10 +61,22 @@
Jan F. Chadima 69dd72
 
Petr Lautrbach d9e618
 #define SSH_GSS_OIDTYPE 0x06
Petr Lautrbach d9e618
 
Petr Lautrbach d9e618
+#define SSH2_MSG_KEXGSS_INIT                            30
Petr Lautrbach d9e618
+#define SSH2_MSG_KEXGSS_CONTINUE                        31
Petr Lautrbach d9e618
+#define SSH2_MSG_KEXGSS_COMPLETE                        32
Petr Lautrbach d9e618
+#define SSH2_MSG_KEXGSS_HOSTKEY                         33
Petr Lautrbach d9e618
+#define SSH2_MSG_KEXGSS_ERROR                           34
Petr Lautrbach d9e618
+#define SSH2_MSG_KEXGSS_GROUPREQ			40
Petr Lautrbach d9e618
+#define SSH2_MSG_KEXGSS_GROUP				41
Petr Lautrbach d9e618
+#define KEX_GSS_GRP1_SHA1_ID				"gss-group1-sha1-"
Petr Lautrbach d9e618
+#define KEX_GSS_GRP14_SHA1_ID				"gss-group14-sha1-"
Petr Lautrbach d9e618
+#define KEX_GSS_GEX_SHA1_ID				"gss-gex-sha1-"
Petr Lautrbach d9e618
+
Petr Lautrbach d9e618
 typedef struct {
Petr Lautrbach d9e618
 	char *filename;
Petr Lautrbach d9e618
 	char *envvar;
Petr Lautrbach d9e618
 	char *envval;
Petr Lautrbach d9e618
+	struct passwd *owner;
Petr Lautrbach d9e618
 	void *data;
Petr Lautrbach d9e618
 } ssh_gssapi_ccache;
Petr Lautrbach d9e618
 
Petr Lautrbach 8a29de
@@ -72,8 +84,11 @@ typedef struct {
Petr Lautrbach d9e618
 	gss_buffer_desc displayname;
Petr Lautrbach d9e618
 	gss_buffer_desc exportedname;
Petr Lautrbach d9e618
 	gss_cred_id_t creds;
Petr Lautrbach d9e618
+	gss_name_t name;
Petr Lautrbach d9e618
 	struct ssh_gssapi_mech_struct *mech;
Petr Lautrbach d9e618
 	ssh_gssapi_ccache store;
Petr Lautrbach d9e618
+	int used;
Petr Lautrbach d9e618
+	int updated;
Petr Lautrbach d9e618
 } ssh_gssapi_client;
Petr Lautrbach d9e618
 
Petr Lautrbach d9e618
 typedef struct ssh_gssapi_mech_struct {
Petr Lautrbach 8a29de
@@ -84,6 +99,7 @@ typedef struct ssh_gssapi_mech_struct {
Petr Lautrbach d9e618
 	int (*userok) (ssh_gssapi_client *, char *);
Petr Lautrbach d9e618
 	int (*localname) (ssh_gssapi_client *, char **);
Petr Lautrbach d9e618
 	void (*storecreds) (ssh_gssapi_client *);
Petr Lautrbach d9e618
+	int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *);
Petr Lautrbach d9e618
 } ssh_gssapi_mech;
Petr Lautrbach d9e618
 
Petr Lautrbach d9e618
 typedef struct {
Petr Lautrbach 8a29de
@@ -94,10 +110,11 @@ typedef struct {
Petr Lautrbach d9e618
 	gss_OID		oid; /* client */
Petr Lautrbach d9e618
 	gss_cred_id_t	creds; /* server */
Petr Lautrbach d9e618
 	gss_name_t	client; /* server */
Petr Lautrbach d9e618
-	gss_cred_id_t	client_creds; /* server */
Petr Lautrbach d9e618
+	gss_cred_id_t	client_creds; /* both */
Petr Lautrbach d9e618
 } Gssctxt;
Petr Lautrbach d9e618
 
Petr Lautrbach d9e618
 extern ssh_gssapi_mech *supported_mechs[];
Petr Lautrbach d9e618
+extern Gssctxt *gss_kex_context;
Petr Lautrbach d9e618
 
Petr Lautrbach d9e618
 int  ssh_gssapi_check_oid(Gssctxt *, void *, size_t);
Petr Lautrbach d9e618
 void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t);
Petr Lautrbach 8a29de
@@ -117,16 +134,30 @@ void ssh_gssapi_build_ctx(Gssctxt **);
Petr Lautrbach d9e618
 void ssh_gssapi_delete_ctx(Gssctxt **);
Petr Lautrbach d9e618
 OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t);
Petr Lautrbach d9e618
 void ssh_gssapi_buildmic(Buffer *, const char *, const char *, const char *);
Petr Lautrbach d9e618
-int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *);
Petr Lautrbach d9e618
+int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *, const char *);
Petr Lautrbach d9e618
+OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *);
Petr Lautrbach d9e618
+int ssh_gssapi_credentials_updated(Gssctxt *);
Petr Lautrbach d9e618
 
Petr Lautrbach d9e618
 /* In the server */
Petr Lautrbach d9e618
+typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, 
Petr Lautrbach d9e618
+    const char *);
Petr Lautrbach d9e618
+char *ssh_gssapi_client_mechanisms(const char *, const char *);
Petr Lautrbach d9e618
+char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, const char *,
Petr Lautrbach d9e618
+    const char *);
Petr Lautrbach d9e618
+gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int);
Petr Lautrbach d9e618
+int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, 
Petr Lautrbach d9e618
+    const char *);
Petr Lautrbach d9e618
 OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
Petr Lautrbach d9e618
-int ssh_gssapi_userok(char *name);
Petr Lautrbach d9e618
+int ssh_gssapi_userok(char *name, struct passwd *);
Petr Lautrbach d9e618
 OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
Petr Lautrbach d9e618
 void ssh_gssapi_do_child(char ***, u_int *);
Petr Lautrbach d9e618
 void ssh_gssapi_cleanup_creds(void);
Petr Lautrbach d9e618
 void ssh_gssapi_storecreds(void);
Petr Lautrbach d9e618
 
Petr Lautrbach d9e618
+char *ssh_gssapi_server_mechanisms(void);
Petr Lautrbach d9e618
+int ssh_gssapi_oid_table_ok();
Petr Lautrbach d9e618
+
Petr Lautrbach d9e618
+int ssh_gssapi_update_creds(ssh_gssapi_ccache *store);
Petr Lautrbach d9e618
 #endif /* GSSAPI */
Petr Lautrbach d9e618
 
Petr Lautrbach d9e618
 #endif /* _SSH_GSS_H */