vishalmishra434 / rpms / openssh

Forked from rpms/openssh a month ago
Clone
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/auth2.c.gsskex openssh-5.6p1/auth2.c
Jan F. Chadima 1b8a26
--- openssh-5.6p1/auth2.c.gsskex	2010-08-23 12:51:56.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/auth2.c	2010-08-23 12:51:58.000000000 +0200
Jan F. Chadima 3fdf10
@@ -69,6 +69,7 @@ extern Authmethod method_passwd;
Jan F. Chadima 3fdf10
 extern Authmethod method_kbdint;
Jan F. Chadima 3fdf10
 extern Authmethod method_hostbased;
Jan F. Chadima 3fdf10
 #ifdef GSSAPI
Jan F. Chadima 3fdf10
+extern Authmethod method_gsskeyex;
Jan F. Chadima 3fdf10
 extern Authmethod method_gssapi;
Jan F. Chadima 3fdf10
 #endif
Jan F. Chadima 3fdf10
 #ifdef JPAKE
Jan F. Chadima 3fdf10
@@ -79,6 +80,7 @@ Authmethod *authmethods[] = {
Jan F. Chadima 3fdf10
 	&method_none,
Jan F. Chadima 3fdf10
 	&method_pubkey,
Jan F. Chadima 3fdf10
 #ifdef GSSAPI
Jan F. Chadima 3fdf10
+	&method_gsskeyex,
Jan F. Chadima 3fdf10
 	&method_gssapi,
Jan F. Chadima 3fdf10
 #endif
Jan F. Chadima 3fdf10
 #ifdef JPAKE
Jan F. Chadima 3fdf10
@@ -289,6 +291,7 @@ input_userauth_request(int type, u_int32
Jan F. Chadima 3fdf10
 #endif
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 	authctxt->postponed = 0;
Jan F. Chadima 3fdf10
+	authctxt->server_caused_failure = 0;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 	/* try to authenticate user */
Jan F. Chadima 3fdf10
 	m = authmethod_lookup(method);
Jan F. Chadima 3fdf10
@@ -361,7 +364,8 @@ userauth_finish(Authctxt *authctxt, int 
Jan F. Chadima 3fdf10
 	} else {
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 		/* Allow initial try of "none" auth without failure penalty */
Jan F. Chadima 3fdf10
-		if (authctxt->attempt > 1 || strcmp(method, "none") != 0)
Jan F. Chadima 3fdf10
+		if (!authctxt->server_caused_failure &&
Jan F. Chadima 3fdf10
+		    (authctxt->attempt > 1 || strcmp(method, "none") != 0))
Jan F. Chadima 3fdf10
 			authctxt->failures++;
Jan F. Chadima 3fdf10
 		if (authctxt->failures >= options.max_authtries) {
Jan F. Chadima 3fdf10
 #ifdef SSH_AUDIT_EVENTS
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/auth2-gss.c.gsskex openssh-5.6p1/auth2-gss.c
Jan F. Chadima 1b8a26
--- openssh-5.6p1/auth2-gss.c.gsskex	2010-08-23 12:51:56.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/auth2-gss.c	2010-08-23 12:51:58.000000000 +0200
Jan F. Chadima 3fdf10
@@ -1,7 +1,7 @@
Jan F. Chadima 3fdf10
 /* $OpenBSD: auth2-gss.c,v 1.16 2007/10/29 00:52:45 dtucker Exp $ */
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 /*
Jan F. Chadima 3fdf10
- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
Jan F. Chadima 3fdf10
+ * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved.
Jan F. Chadima 3fdf10
  *
Jan F. Chadima 3fdf10
  * Redistribution and use in source and binary forms, with or without
Jan F. Chadima 3fdf10
  * modification, are permitted provided that the following conditions
Jan F. Chadima 3fdf10
@@ -52,6 +52,40 @@ static void input_gssapi_mic(int type, u
Jan F. Chadima 3fdf10
 static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt);
Jan F. Chadima 3fdf10
 static void input_gssapi_errtok(int, u_int32_t, void *);
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+/* 
Jan F. Chadima 3fdf10
+ * The 'gssapi_keyex' userauth mechanism.
Jan F. Chadima 3fdf10
+ */
Jan F. Chadima 3fdf10
+static int
Jan F. Chadima 3fdf10
+userauth_gsskeyex(Authctxt *authctxt)
Jan F. Chadima 3fdf10
+{
Jan F. Chadima 3fdf10
+	int authenticated = 0;
Jan F. Chadima 3fdf10
+	Buffer b;
Jan F. Chadima 3fdf10
+	gss_buffer_desc mic, gssbuf;
Jan F. Chadima 3fdf10
+	u_int len;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	mic.value = packet_get_string(&len;;
Jan F. Chadima 3fdf10
+	mic.length = len;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	packet_check_eom();
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service,
Jan F. Chadima 3fdf10
+	    "gssapi-keyex");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	gssbuf.value = buffer_ptr(&b);
Jan F. Chadima 3fdf10
+	gssbuf.length = buffer_len(&b);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	/* gss_kex_context is NULL with privsep, so we can't check it here */
Jan F. Chadima 3fdf10
+	if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, 
Jan F. Chadima 3fdf10
+	    &gssbuf, &mic))))
Jan F. Chadima 3fdf10
+		authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user,
Jan F. Chadima 3fdf10
+		    authctxt->pw));
Jan F. Chadima 3fdf10
+	
Jan F. Chadima 3fdf10
+	buffer_free(&b);
Jan F. Chadima 3fdf10
+	xfree(mic.value);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	return (authenticated);
Jan F. Chadima 3fdf10
+}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 /*
Jan F. Chadima 3fdf10
  * We only support those mechanisms that we know about (ie ones that we know
Jan F. Chadima 3fdf10
  * how to check local user kuserok and the like)
Jan F. Chadima 3fdf10
@@ -102,6 +136,7 @@ userauth_gssapi(Authctxt *authctxt)
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 	if (!present) {
Jan F. Chadima 3fdf10
 		xfree(doid);
Jan F. Chadima 3fdf10
+		authctxt->server_caused_failure = 1;
Jan F. Chadima 3fdf10
 		return (0);
Jan F. Chadima 3fdf10
 	}
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
@@ -109,6 +144,7 @@ userauth_gssapi(Authctxt *authctxt)
Jan F. Chadima 3fdf10
 		if (ctxt != NULL)
Jan F. Chadima 3fdf10
 			ssh_gssapi_delete_ctx(&ctxt);
Jan F. Chadima 3fdf10
 		xfree(doid);
Jan F. Chadima 3fdf10
+		authctxt->server_caused_failure = 1;
Jan F. Chadima 3fdf10
 		return (0);
Jan F. Chadima 3fdf10
 	}
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
@@ -242,7 +278,8 @@ input_gssapi_exchange_complete(int type,
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 	packet_check_eom();
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
-	authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
Jan F. Chadima 3fdf10
+	authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user,
Jan F. Chadima 3fdf10
+	    authctxt->pw));
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 	authctxt->postponed = 0;
Jan F. Chadima 3fdf10
 	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
Jan F. Chadima 3fdf10
@@ -284,7 +321,8 @@ input_gssapi_mic(int type, u_int32_t ple
Jan F. Chadima 3fdf10
 	gssbuf.length = buffer_len(&b);
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 	if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic))))
Jan F. Chadima 3fdf10
-		authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
Jan F. Chadima 3fdf10
+		authenticated = 
Jan F. Chadima 3fdf10
+		    PRIVSEP(ssh_gssapi_userok(authctxt->user, authctxt->pw));
Jan F. Chadima 3fdf10
 	else
Jan F. Chadima 3fdf10
 		logit("GSSAPI MIC check failed");
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
@@ -301,6 +339,12 @@ input_gssapi_mic(int type, u_int32_t ple
Jan F. Chadima 3fdf10
 	userauth_finish(authctxt, authenticated, "gssapi-with-mic");
Jan F. Chadima 3fdf10
 }
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+Authmethod method_gsskeyex = {
Jan F. Chadima 3fdf10
+	"gssapi-keyex",
Jan F. Chadima 3fdf10
+	userauth_gsskeyex,
Jan F. Chadima 3fdf10
+	&options.gss_authentication
Jan F. Chadima 3fdf10
+};
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 Authmethod method_gssapi = {
Jan F. Chadima 3fdf10
 	"gssapi-with-mic",
Jan F. Chadima 3fdf10
 	userauth_gssapi,
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/auth.h.gsskex openssh-5.6p1/auth.h
Jan F. Chadima 1b8a26
--- openssh-5.6p1/auth.h.gsskex	2010-08-23 12:51:56.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/auth.h	2010-08-23 12:51:58.000000000 +0200
Jan F. Chadima 3fdf10
@@ -53,6 +53,7 @@ struct Authctxt {
Jan F. Chadima 3fdf10
 	int		 valid;		/* user exists and is allowed to login */
Jan F. Chadima 3fdf10
 	int		 attempt;
Jan F. Chadima 3fdf10
 	int		 failures;
Jan F. Chadima 3fdf10
+	int		 server_caused_failure; 
Jan F. Chadima 3fdf10
 	int		 force_pwchange;
Jan F. Chadima 3fdf10
 	char		*user;		/* username sent by the client */
Jan F. Chadima 3fdf10
 	char		*service;
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/auth-krb5.c.gsskex openssh-5.6p1/auth-krb5.c
Jan F. Chadima 1b8a26
--- openssh-5.6p1/auth-krb5.c.gsskex	2009-12-21 00:49:22.000000000 +0100
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/auth-krb5.c	2010-08-23 12:51:58.000000000 +0200
Jan F. Chadima 3fdf10
@@ -170,8 +170,13 @@ auth_krb5_password(Authctxt *authctxt, c
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 	len = strlen(authctxt->krb5_ticket_file) + 6;
Jan F. Chadima 3fdf10
 	authctxt->krb5_ccname = xmalloc(len);
Jan F. Chadima 3fdf10
+#ifdef USE_CCAPI
Jan F. Chadima 3fdf10
+	snprintf(authctxt->krb5_ccname, len, "API:%s",
Jan F. Chadima 3fdf10
+	    authctxt->krb5_ticket_file);
Jan F. Chadima 3fdf10
+#else
Jan F. Chadima 3fdf10
 	snprintf(authctxt->krb5_ccname, len, "FILE:%s",
Jan F. Chadima 3fdf10
 	    authctxt->krb5_ticket_file);
Jan F. Chadima 3fdf10
+#endif
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 #ifdef USE_PAM
Jan F. Chadima 3fdf10
 	if (options.use_pam)
Jan F. Chadima 3fdf10
@@ -226,15 +231,22 @@ krb5_cleanup_proc(Authctxt *authctxt)
Jan F. Chadima 3fdf10
 #ifndef HEIMDAL
Jan F. Chadima 3fdf10
 krb5_error_code
Jan F. Chadima 3fdf10
 ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) {
Jan F. Chadima 3fdf10
-	int tmpfd, ret;
Jan F. Chadima 3fdf10
+	int ret;
Jan F. Chadima 3fdf10
 	char ccname[40];
Jan F. Chadima 3fdf10
 	mode_t old_umask;
Jan F. Chadima 3fdf10
+#ifdef USE_CCAPI
Jan F. Chadima 3fdf10
+	char cctemplate[] = "API:krb5cc_%d";
Jan F. Chadima 3fdf10
+#else
Jan F. Chadima 3fdf10
+	char cctemplate[] = "FILE:/tmp/krb5cc_%d_XXXXXXXXXX";
Jan F. Chadima 3fdf10
+	int tmpfd;
Jan F. Chadima 3fdf10
+#endif
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 	ret = snprintf(ccname, sizeof(ccname),
Jan F. Chadima 3fdf10
-	    "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid());
Jan F. Chadima 3fdf10
+	    cctemplate, geteuid());
Jan F. Chadima 3fdf10
 	if (ret < 0 || (size_t)ret >= sizeof(ccname))
Jan F. Chadima 3fdf10
 		return ENOMEM;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+#ifndef USE_CCAPI
Jan F. Chadima 3fdf10
 	old_umask = umask(0177);
Jan F. Chadima 3fdf10
 	tmpfd = mkstemp(ccname + strlen("FILE:"));
Jan F. Chadima 3fdf10
 	umask(old_umask);
Jan F. Chadima 3fdf10
@@ -249,6 +261,7 @@ ssh_krb5_cc_gen(krb5_context ctx, krb5_c
Jan F. Chadima 3fdf10
 		return errno;
Jan F. Chadima 3fdf10
 	}
Jan F. Chadima 3fdf10
 	close(tmpfd);
Jan F. Chadima 3fdf10
+#endif
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 	return (krb5_cc_resolve(ctx, ccname, ccache));
Jan F. Chadima 3fdf10
 }
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/ChangeLog.gssapi.gsskex openssh-5.6p1/ChangeLog.gssapi
Jan F. Chadima 1b8a26
--- openssh-5.6p1/ChangeLog.gssapi.gsskex	2010-08-23 12:51:58.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/ChangeLog.gssapi	2010-08-23 12:51:58.000000000 +0200
Jan F. Chadima 3fdf10
@@ -0,0 +1,95 @@
Jan F. Chadima 3fdf10
+20090615
Jan F. Chadima 3fdf10
+  - [ gss-genr.c gss-serv.c kexgssc.c kexgsss.c monitor.c sshconnect2.c
Jan F. Chadima 3fdf10
+      sshd.c ]
Jan F. Chadima 3fdf10
+    Fix issues identified by Greg Hudson following a code review
Jan F. Chadima 3fdf10
+	Check return value of gss_indicate_mechs
Jan F. Chadima 3fdf10
+	Protect GSSAPI calls in monitor, so they can only be used if enabled
Jan F. Chadima 3fdf10
+	Check return values of bignum functions in key exchange
Jan F. Chadima 3fdf10
+	Use BN_clear_free to clear other side's DH value
Jan F. Chadima 3fdf10
+	Make ssh_gssapi_id_kex more robust
Jan F. Chadima 3fdf10
+	Only configure kex table pointers if GSSAPI is enabled
Jan F. Chadima 3fdf10
+	Don't leak mechanism list, or gss mechanism list
Jan F. Chadima 3fdf10
+	Cast data.length before printing
Jan F. Chadima 3fdf10
+	If serverkey isn't provided, use an empty string, rather than NULL
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+20090201
Jan F. Chadima 3fdf10
+  - [ gss-genr.c gss-serv.c kex.h kexgssc.c readconf.c readconf.h ssh-gss.h
Jan F. Chadima 3fdf10
+      ssh_config.5 sshconnet2.c ]
Jan F. Chadima 3fdf10
+    Add support for the GSSAPIClientIdentity option, which allows the user
Jan F. Chadima 3fdf10
+    to specify which GSSAPI identity to use to contact a given server
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+20080404
Jan F. Chadima 3fdf10
+  - [ gss-serv.c ]
Jan F. Chadima 3fdf10
+    Add code to actually implement GSSAPIStrictAcceptCheck, which had somehow
Jan F. Chadima 3fdf10
+    been omitted from a previous version of this patch. Reported by Borislav
Jan F. Chadima 3fdf10
+    Stoichkov
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+20070317
Jan F. Chadima 3fdf10
+  - [ gss-serv-krb5.c ]
Jan F. Chadima 3fdf10
+    Remove C99ism, where new_ccname was being declared in the middle of a 
Jan F. Chadima 3fdf10
+    function
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+20061220
Jan F. Chadima 3fdf10
+  - [ servconf.c ]
Jan F. Chadima 3fdf10
+    Make default for GSSAPIStrictAcceptorCheck be Yes, to match previous, and 
Jan F. Chadima 3fdf10
+    documented, behaviour. Reported by Dan Watson.
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+20060910
Jan F. Chadima 3fdf10
+  - [ gss-genr.c kexgssc.c kexgsss.c kex.h monitor.c sshconnect2.c sshd.c
Jan F. Chadima 3fdf10
+      ssh-gss.h ]
Jan F. Chadima 3fdf10
+    add support for gss-group14-sha1 key exchange mechanisms
Jan F. Chadima 3fdf10
+  - [ gss-serv.c servconf.c servconf.h sshd_config sshd_config.5 ]
Jan F. Chadima 3fdf10
+    Add GSSAPIStrictAcceptorCheck option to allow the disabling of
Jan F. Chadima 3fdf10
+    acceptor principal checking on multi-homed machines.
Jan F. Chadima 3fdf10
+    <Bugzilla #928>
Jan F. Chadima 3fdf10
+  - [ sshd_config ssh_config ]
Jan F. Chadima 3fdf10
+    Add settings for GSSAPIKeyExchange and GSSAPITrustDNS to the sample
Jan F. Chadima 3fdf10
+    configuration files
Jan F. Chadima 3fdf10
+  - [ kexgss.c kegsss.c sshconnect2.c sshd.c ]
Jan F. Chadima 3fdf10
+    Code cleanup. Replace strlen/xmalloc/snprintf sequences with xasprintf()
Jan F. Chadima 3fdf10
+    Limit length of error messages displayed by client
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+20060909
Jan F. Chadima 3fdf10
+  - [ gss-genr.c gss-serv.c ]
Jan F. Chadima 3fdf10
+    move ssh_gssapi_acquire_cred() and ssh_gssapi_server_ctx to be server
Jan F. Chadima 3fdf10
+    only, where they belong 
Jan F. Chadima 3fdf10
+    <Bugzilla #1225>
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+20060829
Jan F. Chadima 3fdf10
+  - [ gss-serv-krb5.c ]
Jan F. Chadima 3fdf10
+    Fix CCAPI credentials cache name when creating KRB5CCNAME environment 
Jan F. Chadima 3fdf10
+    variable
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+20060828
Jan F. Chadima 3fdf10
+  - [ gss-genr.c ]
Jan F. Chadima 3fdf10
+    Avoid Heimdal context freeing problem
Jan F. Chadima 3fdf10
+    <Fixed upstream 20060829>
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+20060818
Jan F. Chadima 3fdf10
+  - [ gss-genr.c ssh-gss.h sshconnect2.c ]
Jan F. Chadima 3fdf10
+    Make sure that SPENGO is disabled 
Jan F. Chadima 3fdf10
+    <Bugzilla #1218 - Fixed upstream 20060818>
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+20060421
Jan F. Chadima 3fdf10
+  - [ gssgenr.c, sshconnect2.c ]
Jan F. Chadima 3fdf10
+    a few type changes (signed versus unsigned, int versus size_t) to
Jan F. Chadima 3fdf10
+    fix compiler errors/warnings 
Jan F. Chadima 3fdf10
+    (from jbasney AT ncsa.uiuc.edu)
Jan F. Chadima 3fdf10
+  - [ kexgssc.c, sshconnect2.c ]
Jan F. Chadima 3fdf10
+    fix uninitialized variable warnings
Jan F. Chadima 3fdf10
+    (from jbasney AT ncsa.uiuc.edu)
Jan F. Chadima 3fdf10
+  - [ gssgenr.c ]
Jan F. Chadima 3fdf10
+    pass oid to gss_display_status (helpful when using GSSAPI mechglue)
Jan F. Chadima 3fdf10
+    (from jbasney AT ncsa.uiuc.edu)
Jan F. Chadima 3fdf10
+    <Bugzilla #1220 >
Jan F. Chadima 3fdf10
+  - [ gss-serv-krb5.c ]
Jan F. Chadima 3fdf10
+    #ifdef HAVE_GSSAPI_KRB5 should be #ifdef HAVE_GSSAPI_KRB5_H
Jan F. Chadima 3fdf10
+    (from jbasney AT ncsa.uiuc.edu)
Jan F. Chadima 3fdf10
+    <Fixed upstream 20060304>
Jan F. Chadima 3fdf10
+  - [ readconf.c, readconf.h, ssh_config.5, sshconnect2.c 
Jan F. Chadima 3fdf10
+    add client-side GssapiKeyExchange option
Jan F. Chadima 3fdf10
+    (from jbasney AT ncsa.uiuc.edu)
Jan F. Chadima 3fdf10
+  - [ sshconnect2.c ]
Jan F. Chadima 3fdf10
+    add support for GssapiTrustDns option for gssapi-with-mic
Jan F. Chadima 3fdf10
+    (from jbasney AT ncsa.uiuc.edu)
Jan F. Chadima 3fdf10
+    <gssapi-with-mic support is Bugzilla #1008>
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/clientloop.c.gsskex openssh-5.6p1/clientloop.c
Jan F. Chadima 1b8a26
--- openssh-5.6p1/clientloop.c.gsskex	2010-08-03 08:04:46.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/clientloop.c	2010-08-23 12:51:58.000000000 +0200
Jan F. Chadima 3fdf10
@@ -111,6 +111,10 @@
Jan F. Chadima 3fdf10
 #include "msg.h"
Jan F. Chadima 3fdf10
 #include "roaming.h"
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+#ifdef GSSAPI
Jan F. Chadima 3fdf10
+#include "ssh-gss.h"
Jan F. Chadima 3fdf10
+#endif
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 /* import options */
Jan F. Chadima 3fdf10
 extern Options options;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 1b8a26
@@ -1483,6 +1487,13 @@ client_loop(int have_pty, int escape_cha
Jan F. Chadima 3fdf10
 		/* Do channel operations unless rekeying in progress. */
Jan F. Chadima 3fdf10
 		if (!rekeying) {
Jan F. Chadima 3fdf10
 			channel_after_select(readset, writeset);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+			if (options.gss_renewal_rekey &&
Jan F. Chadima 3fdf10
+			    ssh_gssapi_credentials_updated(GSS_C_NO_CONTEXT)) {
Jan F. Chadima 3fdf10
+				debug("credentials updated - forcing rekey");
Jan F. Chadima 3fdf10
+				need_rekeying = 1;
Jan F. Chadima 3fdf10
+			}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 			if (need_rekeying || packet_need_rekeying()) {
Jan F. Chadima 3fdf10
 				debug("need rekeying");
Jan F. Chadima 3fdf10
 				xxx_kex->done = 0;
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/configure.ac.gsskex openssh-5.6p1/configure.ac
Jan F. Chadima 1b8a26
--- openssh-5.6p1/configure.ac.gsskex	2010-08-23 12:51:57.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/configure.ac	2010-08-23 12:51:58.000000000 +0200
Jan F. Chadima 3fdf10
@@ -477,6 +477,30 @@ main() { if (NSVersionOfRunTimeLibrary("
Jan F. Chadima 3fdf10
 	    [Use tunnel device compatibility to OpenBSD])
Jan F. Chadima 3fdf10
 	AC_DEFINE(SSH_TUN_PREPEND_AF, 1,
Jan F. Chadima 3fdf10
 	    [Prepend the address family to IP tunnel traffic])
Jan F. Chadima 3fdf10
+	AC_MSG_CHECKING(if we have the Security Authorization Session API)
Jan F. Chadima 3fdf10
+	AC_TRY_COMPILE([#include <Security/AuthSession.h>],
Jan F. Chadima 3fdf10
+		[SessionCreate(0, 0);],
Jan F. Chadima 3fdf10
+		[ac_cv_use_security_session_api="yes"
Jan F. Chadima 3fdf10
+		 AC_DEFINE(USE_SECURITY_SESSION_API, 1, 
Jan F. Chadima 3fdf10
+			[platform has the Security Authorization Session API])
Jan F. Chadima 3fdf10
+		 LIBS="$LIBS -framework Security"
Jan F. Chadima 3fdf10
+		 AC_MSG_RESULT(yes)],
Jan F. Chadima 3fdf10
+		[ac_cv_use_security_session_api="no"
Jan F. Chadima 3fdf10
+		 AC_MSG_RESULT(no)])
Jan F. Chadima 3fdf10
+	AC_MSG_CHECKING(if we have an in-memory credentials cache)
Jan F. Chadima 3fdf10
+	AC_TRY_COMPILE(
Jan F. Chadima 3fdf10
+		[#include <Kerberos/Kerberos.h>],
Jan F. Chadima 3fdf10
+		[cc_context_t c;
Jan F. Chadima 3fdf10
+		 (void) cc_initialize (&c, 0, NULL, NULL);],
Jan F. Chadima 3fdf10
+		[AC_DEFINE(USE_CCAPI, 1, 
Jan F. Chadima 3fdf10
+			[platform uses an in-memory credentials cache])
Jan F. Chadima 3fdf10
+		 LIBS="$LIBS -framework Security"
Jan F. Chadima 3fdf10
+		 AC_MSG_RESULT(yes)
Jan F. Chadima 3fdf10
+		 if test "x$ac_cv_use_security_session_api" = "xno"; then
Jan F. Chadima 3fdf10
+			AC_MSG_ERROR(*** Need a security framework to use the credentials cache API ***)
Jan F. Chadima 3fdf10
+		fi],
Jan F. Chadima 3fdf10
+		[AC_MSG_RESULT(no)]
Jan F. Chadima 3fdf10
+	)
Jan F. Chadima 3fdf10
 	m4_pattern_allow(AU_IPv)
Jan F. Chadima 3fdf10
 	AC_CHECK_DECL(AU_IPv4, [], 
Jan F. Chadima 3fdf10
 	    AC_DEFINE(AU_IPv4, 0, [System only supports IPv4 audit records])
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/gss-genr.c.gsskex openssh-5.6p1/gss-genr.c
Jan F. Chadima 1b8a26
--- openssh-5.6p1/gss-genr.c.gsskex	2009-06-22 08:11:07.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/gss-genr.c	2010-08-23 12:51:58.000000000 +0200
Jan F. Chadima 3fdf10
@@ -39,12 +39,167 @@
Jan F. Chadima 3fdf10
 #include "buffer.h"
Jan F. Chadima 3fdf10
 #include "log.h"
Jan F. Chadima 3fdf10
 #include "ssh2.h"
Jan F. Chadima 3fdf10
+#include "cipher.h"
Jan F. Chadima 3fdf10
+#include "key.h"
Jan F. Chadima 3fdf10
+#include "kex.h"
Jan F. Chadima 3fdf10
+#include <openssl/evp.h>
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 #include "ssh-gss.h"
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 extern u_char *session_id2;
Jan F. Chadima 3fdf10
 extern u_int session_id2_len;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+typedef struct {
Jan F. Chadima 3fdf10
+	char *encoded;
Jan F. Chadima 3fdf10
+	gss_OID oid;
Jan F. Chadima 3fdf10
+} ssh_gss_kex_mapping;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+/*
Jan F. Chadima 3fdf10
+ * XXX - It would be nice to find a more elegant way of handling the
Jan F. Chadima 3fdf10
+ * XXX   passing of the key exchange context to the userauth routines
Jan F. Chadima 3fdf10
+ */
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+Gssctxt *gss_kex_context = NULL;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+static ssh_gss_kex_mapping *gss_enc2oid = NULL;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+int 
Jan F. Chadima 3fdf10
+ssh_gssapi_oid_table_ok() {
Jan F. Chadima 3fdf10
+	return (gss_enc2oid != NULL);
Jan F. Chadima 3fdf10
+}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+/*
Jan F. Chadima 3fdf10
+ * Return a list of the gss-group1-sha1 mechanisms supported by this program
Jan F. Chadima 3fdf10
+ *
Jan F. Chadima 3fdf10
+ * We test mechanisms to ensure that we can use them, to avoid starting
Jan F. Chadima 3fdf10
+ * a key exchange with a bad mechanism
Jan F. Chadima 3fdf10
+ */
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+char *
Jan F. Chadima 3fdf10
+ssh_gssapi_client_mechanisms(const char *host, const char *client) {
Jan F. Chadima 3fdf10
+	gss_OID_set gss_supported;
Jan F. Chadima 3fdf10
+	OM_uint32 min_status;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (GSS_ERROR(gss_indicate_mechs(&min_status, &gss_supported)))
Jan F. Chadima 3fdf10
+		return NULL;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	return(ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism,
Jan F. Chadima 3fdf10
+	    host, client));
Jan F. Chadima 3fdf10
+}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+char *
Jan F. Chadima 3fdf10
+ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check,
Jan F. Chadima 3fdf10
+    const char *host, const char *client) {
Jan F. Chadima 3fdf10
+	Buffer buf;
Jan F. Chadima 3fdf10
+	size_t i;
Jan F. Chadima 3fdf10
+	int oidpos, enclen;
Jan F. Chadima 3fdf10
+	char *mechs, *encoded;
Jan F. Chadima 3fdf10
+	u_char digest[EVP_MAX_MD_SIZE];
Jan F. Chadima 3fdf10
+	char deroid[2];
Jan F. Chadima 3fdf10
+	const EVP_MD *evp_md = EVP_md5();
Jan F. Chadima 3fdf10
+	EVP_MD_CTX md;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (gss_enc2oid != NULL) {
Jan F. Chadima 3fdf10
+		for (i = 0; gss_enc2oid[i].encoded != NULL; i++)
Jan F. Chadima 3fdf10
+			xfree(gss_enc2oid[i].encoded);
Jan F. Chadima 3fdf10
+		xfree(gss_enc2oid);
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	gss_enc2oid = xmalloc(sizeof(ssh_gss_kex_mapping) *
Jan F. Chadima 3fdf10
+	    (gss_supported->count + 1));
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	buffer_init(&buf;;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	oidpos = 0;
Jan F. Chadima 3fdf10
+	for (i = 0; i < gss_supported->count; i++) {
Jan F. Chadima 3fdf10
+		if (gss_supported->elements[i].length < 128 &&
Jan F. Chadima 3fdf10
+		    (*check)(NULL, &(gss_supported->elements[i]), host, client)) {
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+			deroid[0] = SSH_GSS_OIDTYPE;
Jan F. Chadima 3fdf10
+			deroid[1] = gss_supported->elements[i].length;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+			EVP_DigestInit(&md, evp_md);
Jan F. Chadima 3fdf10
+			EVP_DigestUpdate(&md, deroid, 2);
Jan F. Chadima 3fdf10
+			EVP_DigestUpdate(&md,
Jan F. Chadima 3fdf10
+			    gss_supported->elements[i].elements,
Jan F. Chadima 3fdf10
+			    gss_supported->elements[i].length);
Jan F. Chadima 3fdf10
+			EVP_DigestFinal(&md, digest, NULL);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+			encoded = xmalloc(EVP_MD_size(evp_md) * 2);
Jan F. Chadima 3fdf10
+			enclen = __b64_ntop(digest, EVP_MD_size(evp_md),
Jan F. Chadima 3fdf10
+			    encoded, EVP_MD_size(evp_md) * 2);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+			if (oidpos != 0)
Jan F. Chadima 3fdf10
+				buffer_put_char(&buf, ',');
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+			buffer_append(&buf, KEX_GSS_GEX_SHA1_ID,
Jan F. Chadima 3fdf10
+			    sizeof(KEX_GSS_GEX_SHA1_ID) - 1);
Jan F. Chadima 3fdf10
+			buffer_append(&buf, encoded, enclen);
Jan F. Chadima 3fdf10
+			buffer_put_char(&buf, ',');
Jan F. Chadima 3fdf10
+			buffer_append(&buf, KEX_GSS_GRP1_SHA1_ID, 
Jan F. Chadima 3fdf10
+			    sizeof(KEX_GSS_GRP1_SHA1_ID) - 1);
Jan F. Chadima 3fdf10
+			buffer_append(&buf, encoded, enclen);
Jan F. Chadima 3fdf10
+			buffer_put_char(&buf, ',');
Jan F. Chadima 3fdf10
+			buffer_append(&buf, KEX_GSS_GRP14_SHA1_ID,
Jan F. Chadima 3fdf10
+			    sizeof(KEX_GSS_GRP14_SHA1_ID) - 1);
Jan F. Chadima 3fdf10
+			buffer_append(&buf, encoded, enclen);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+			gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]);
Jan F. Chadima 3fdf10
+			gss_enc2oid[oidpos].encoded = encoded;
Jan F. Chadima 3fdf10
+			oidpos++;
Jan F. Chadima 3fdf10
+		}
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+	gss_enc2oid[oidpos].oid = NULL;
Jan F. Chadima 3fdf10
+	gss_enc2oid[oidpos].encoded = NULL;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	buffer_put_char(&buf, '\0');
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	mechs = xmalloc(buffer_len(&buf));
Jan F. Chadima 3fdf10
+	buffer_get(&buf, mechs, buffer_len(&buf));
Jan F. Chadima 3fdf10
+	buffer_free(&buf;;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (strlen(mechs) == 0) {
Jan F. Chadima 3fdf10
+		xfree(mechs);
Jan F. Chadima 3fdf10
+		mechs = NULL;
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+	
Jan F. Chadima 3fdf10
+	return (mechs);
Jan F. Chadima 3fdf10
+}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+gss_OID
Jan F. Chadima 3fdf10
+ssh_gssapi_id_kex(Gssctxt *ctx, char *name, int kex_type) {
Jan F. Chadima 3fdf10
+	int i = 0;
Jan F. Chadima 3fdf10
+	
Jan F. Chadima 3fdf10
+	switch (kex_type) {
Jan F. Chadima 3fdf10
+	case KEX_GSS_GRP1_SHA1:
Jan F. Chadima 3fdf10
+		if (strlen(name) < sizeof(KEX_GSS_GRP1_SHA1_ID))
Jan F. Chadima 3fdf10
+			return GSS_C_NO_OID;
Jan F. Chadima 3fdf10
+		name += sizeof(KEX_GSS_GRP1_SHA1_ID) - 1;
Jan F. Chadima 3fdf10
+		break;
Jan F. Chadima 3fdf10
+	case KEX_GSS_GRP14_SHA1:
Jan F. Chadima 3fdf10
+		if (strlen(name) < sizeof(KEX_GSS_GRP14_SHA1_ID))
Jan F. Chadima 3fdf10
+			return GSS_C_NO_OID;
Jan F. Chadima 3fdf10
+		name += sizeof(KEX_GSS_GRP14_SHA1_ID) - 1;
Jan F. Chadima 3fdf10
+		break;
Jan F. Chadima 3fdf10
+	case KEX_GSS_GEX_SHA1:
Jan F. Chadima 3fdf10
+		if (strlen(name) < sizeof(KEX_GSS_GEX_SHA1_ID))
Jan F. Chadima 3fdf10
+			return GSS_C_NO_OID;
Jan F. Chadima 3fdf10
+		name += sizeof(KEX_GSS_GEX_SHA1_ID) - 1;
Jan F. Chadima 3fdf10
+		break;
Jan F. Chadima 3fdf10
+	default:
Jan F. Chadima 3fdf10
+		return GSS_C_NO_OID;
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	while (gss_enc2oid[i].encoded != NULL &&
Jan F. Chadima 3fdf10
+	    strcmp(name, gss_enc2oid[i].encoded) != 0)
Jan F. Chadima 3fdf10
+		i++;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (gss_enc2oid[i].oid != NULL && ctx != NULL)
Jan F. Chadima 3fdf10
+		ssh_gssapi_set_oid(ctx, gss_enc2oid[i].oid);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	return gss_enc2oid[i].oid;
Jan F. Chadima 3fdf10
+}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 /* Check that the OID in a data stream matches that in the context */
Jan F. Chadima 3fdf10
 int
Jan F. Chadima 3fdf10
 ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len)
Jan F. Chadima 3fdf10
@@ -197,7 +352,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int de
Jan F. Chadima 3fdf10
 	}
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 	ctx->major = gss_init_sec_context(&ctx->minor,
Jan F. Chadima 3fdf10
-	    GSS_C_NO_CREDENTIAL, &ctx->context, ctx->name, ctx->oid,
Jan F. Chadima 3fdf10
+	    ctx->client_creds, &ctx->context, ctx->name, ctx->oid,
Jan F. Chadima 3fdf10
 	    GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag,
Jan F. Chadima 3fdf10
 	    0, NULL, recv_tok, NULL, send_tok, flags, NULL);
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
@@ -227,8 +382,42 @@ ssh_gssapi_import_name(Gssctxt *ctx, con
Jan F. Chadima 3fdf10
 }
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 OM_uint32
Jan F. Chadima 3fdf10
+ssh_gssapi_client_identity(Gssctxt *ctx, const char *name)
Jan F. Chadima 3fdf10
+{
Jan F. Chadima 3fdf10
+	gss_buffer_desc gssbuf;
Jan F. Chadima 3fdf10
+	gss_name_t gssname;
Jan F. Chadima 3fdf10
+	OM_uint32 status;
Jan F. Chadima 3fdf10
+	gss_OID_set oidset;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	gssbuf.value = (void *) name;
Jan F. Chadima 3fdf10
+	gssbuf.length = strlen(gssbuf.value);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	gss_create_empty_oid_set(&status, &oidset);
Jan F. Chadima 3fdf10
+	gss_add_oid_set_member(&status, ctx->oid, &oidset);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	ctx->major = gss_import_name(&ctx->minor, &gssbuf,
Jan F. Chadima 3fdf10
+	    GSS_C_NT_USER_NAME, &gssname);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (!ctx->major)
Jan F. Chadima 3fdf10
+		ctx->major = gss_acquire_cred(&ctx->minor, 
Jan F. Chadima 3fdf10
+		    gssname, 0, oidset, GSS_C_INITIATE, 
Jan F. Chadima 3fdf10
+		    &ctx->client_creds, NULL, NULL);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	gss_release_name(&status, &gssname);
Jan F. Chadima 3fdf10
+	gss_release_oid_set(&status, &oidset);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (ctx->major)
Jan F. Chadima 3fdf10
+		ssh_gssapi_error(ctx);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	return(ctx->major);
Jan F. Chadima 3fdf10
+}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+OM_uint32
Jan F. Chadima 3fdf10
 ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash)
Jan F. Chadima 3fdf10
 {
Jan F. Chadima 3fdf10
+	if (ctx == NULL) 
Jan F. Chadima 3fdf10
+		return -1;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 	if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context,
Jan F. Chadima 3fdf10
 	    GSS_C_QOP_DEFAULT, buffer, hash)))
Jan F. Chadima 3fdf10
 		ssh_gssapi_error(ctx);
Jan F. Chadima 3fdf10
@@ -236,6 +425,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer
Jan F. Chadima 3fdf10
 	return (ctx->major);
Jan F. Chadima 3fdf10
 }
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+/* Priviledged when used by server */
Jan F. Chadima 3fdf10
+OM_uint32
Jan F. Chadima 3fdf10
+ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
Jan F. Chadima 3fdf10
+{
Jan F. Chadima 3fdf10
+	if (ctx == NULL)
Jan F. Chadima 3fdf10
+		return -1;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	ctx->major = gss_verify_mic(&ctx->minor, ctx->context,
Jan F. Chadima 3fdf10
+	    gssbuf, gssmic, NULL);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	return (ctx->major);
Jan F. Chadima 3fdf10
+}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 void
Jan F. Chadima 3fdf10
 ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service,
Jan F. Chadima 3fdf10
     const char *context)
Jan F. Chadima 3fdf10
@@ -249,11 +451,16 @@ ssh_gssapi_buildmic(Buffer *b, const cha
Jan F. Chadima 3fdf10
 }
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 int
Jan F. Chadima 3fdf10
-ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host)
Jan F. Chadima 3fdf10
+ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host, 
Jan F. Chadima 3fdf10
+    const char *client)
Jan F. Chadima 3fdf10
 {
Jan F. Chadima 3fdf10
 	gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
Jan F. Chadima 3fdf10
 	OM_uint32 major, minor;
Jan F. Chadima 3fdf10
 	gss_OID_desc spnego_oid = {6, (void *)"\x2B\x06\x01\x05\x05\x02"};
Jan F. Chadima 3fdf10
+	Gssctxt *intctx = NULL;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (ctx == NULL)
Jan F. Chadima 3fdf10
+		ctx = &intct;;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 	/* RFC 4462 says we MUST NOT do SPNEGO */
Jan F. Chadima 3fdf10
 	if (oid->length == spnego_oid.length && 
Jan F. Chadima 3fdf10
@@ -263,6 +470,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx
Jan F. Chadima 3fdf10
 	ssh_gssapi_build_ctx(ctx);
Jan F. Chadima 3fdf10
 	ssh_gssapi_set_oid(*ctx, oid);
Jan F. Chadima 3fdf10
 	major = ssh_gssapi_import_name(*ctx, host);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (!GSS_ERROR(major) && client)
Jan F. Chadima 3fdf10
+		major = ssh_gssapi_client_identity(*ctx, client);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 	if (!GSS_ERROR(major)) {
Jan F. Chadima 3fdf10
 		major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, 
Jan F. Chadima 3fdf10
 		    NULL);
Jan F. Chadima 3fdf10
@@ -272,10 +483,67 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx
Jan F. Chadima 3fdf10
 			    GSS_C_NO_BUFFER);
Jan F. Chadima 3fdf10
 	}
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
-	if (GSS_ERROR(major)) 
Jan F. Chadima 3fdf10
+	if (GSS_ERROR(major) || intctx != NULL) 
Jan F. Chadima 3fdf10
 		ssh_gssapi_delete_ctx(ctx);
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 	return (!GSS_ERROR(major));
Jan F. Chadima 3fdf10
 }
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+int
Jan F. Chadima 3fdf10
+ssh_gssapi_credentials_updated(Gssctxt *ctxt) {
Jan F. Chadima 3fdf10
+	static gss_name_t saved_name = GSS_C_NO_NAME;
Jan F. Chadima 3fdf10
+	static OM_uint32 saved_lifetime = 0;
Jan F. Chadima 3fdf10
+	static gss_OID saved_mech = GSS_C_NO_OID;
Jan F. Chadima 3fdf10
+	static gss_name_t name;
Jan F. Chadima 3fdf10
+	static OM_uint32 last_call = 0;
Jan F. Chadima 3fdf10
+	OM_uint32 lifetime, now, major, minor;
Jan F. Chadima 3fdf10
+	int equal;
Jan F. Chadima 3fdf10
+	gss_cred_usage_t usage = GSS_C_INITIATE;
Jan F. Chadima 3fdf10
+	
Jan F. Chadima 3fdf10
+	now = time(NULL);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (ctxt) {
Jan F. Chadima 3fdf10
+		debug("Rekey has happened - updating saved versions");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		if (saved_name != GSS_C_NO_NAME)
Jan F. Chadima 3fdf10
+			gss_release_name(&minor, &saved_name);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		major = gss_inquire_cred(&minor, GSS_C_NO_CREDENTIAL,
Jan F. Chadima 3fdf10
+		    &saved_name, &saved_lifetime, NULL, NULL);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		if (!GSS_ERROR(major)) {
Jan F. Chadima 3fdf10
+			saved_mech = ctxt->oid;
Jan F. Chadima 3fdf10
+		        saved_lifetime+= now;
Jan F. Chadima 3fdf10
+		} else {
Jan F. Chadima 3fdf10
+			/* Handle the error */
Jan F. Chadima 3fdf10
+		}
Jan F. Chadima 3fdf10
+		return 0;
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (now - last_call < 10)
Jan F. Chadima 3fdf10
+		return 0;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	last_call = now;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (saved_mech == GSS_C_NO_OID)
Jan F. Chadima 3fdf10
+		return 0;
Jan F. Chadima 3fdf10
+	
Jan F. Chadima 3fdf10
+	major = gss_inquire_cred(&minor, GSS_C_NO_CREDENTIAL, 
Jan F. Chadima 3fdf10
+	    &name, &lifetime, NULL, NULL);
Jan F. Chadima 3fdf10
+	if (major == GSS_S_CREDENTIALS_EXPIRED)
Jan F. Chadima 3fdf10
+		return 0;
Jan F. Chadima 3fdf10
+	else if (GSS_ERROR(major))
Jan F. Chadima 3fdf10
+		return 0;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	major = gss_compare_name(&minor, saved_name, name, &equal);
Jan F. Chadima 3fdf10
+	gss_release_name(&minor, &name);
Jan F. Chadima 3fdf10
+	if (GSS_ERROR(major))
Jan F. Chadima 3fdf10
+		return 0;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (equal && (saved_lifetime < lifetime + now - 10))
Jan F. Chadima 3fdf10
+		return 1;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	return 0;
Jan F. Chadima 3fdf10
+}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 #endif /* GSSAPI */
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/gss-serv.c.gsskex openssh-5.6p1/gss-serv.c
Jan F. Chadima 1b8a26
--- openssh-5.6p1/gss-serv.c.gsskex	2008-05-19 07:05:07.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/gss-serv.c	2010-08-23 12:51:58.000000000 +0200
Jan F. Chadima 3fdf10
@@ -1,7 +1,7 @@
Jan F. Chadima 3fdf10
 /* $OpenBSD: gss-serv.c,v 1.22 2008/05/08 12:02:23 djm Exp $ */
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 /*
Jan F. Chadima 3fdf10
- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
Jan F. Chadima 3fdf10
+ * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
Jan F. Chadima 3fdf10
  *
Jan F. Chadima 3fdf10
  * Redistribution and use in source and binary forms, with or without
Jan F. Chadima 3fdf10
  * modification, are permitted provided that the following conditions
Jan F. Chadima 3fdf10
@@ -45,15 +45,20 @@
Jan F. Chadima 3fdf10
 #include "channels.h"
Jan F. Chadima 3fdf10
 #include "session.h"
Jan F. Chadima 3fdf10
 #include "misc.h"
Jan F. Chadima 3fdf10
+#include "servconf.h"
Jan F. Chadima 3fdf10
+#include "uidswap.h"
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 #include "ssh-gss.h"
Jan F. Chadima 3fdf10
+#include "monitor_wrap.h"
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+extern ServerOptions options;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 static ssh_gssapi_client gssapi_client =
Jan F. Chadima 3fdf10
     { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER,
Jan F. Chadima 3fdf10
-    GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL}};
Jan F. Chadima 3fdf10
+    GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME,  NULL, {NULL, NULL, NULL}, 0, 0};
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 ssh_gssapi_mech gssapi_null_mech =
Jan F. Chadima 3fdf10
-    { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL};
Jan F. Chadima 3fdf10
+    { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL, NULL};
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 #ifdef KRB5
Jan F. Chadima 3fdf10
 extern ssh_gssapi_mech gssapi_kerberos_mech;
Jan F. Chadima 3fdf10
@@ -81,25 +86,32 @@ ssh_gssapi_acquire_cred(Gssctxt *ctx)
Jan F. Chadima 3fdf10
 	char lname[MAXHOSTNAMELEN];
Jan F. Chadima 3fdf10
 	gss_OID_set oidset;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
-	gss_create_empty_oid_set(&status, &oidset);
Jan F. Chadima 3fdf10
-	gss_add_oid_set_member(&status, ctx->oid, &oidset);
Jan F. Chadima 3fdf10
+	if (options.gss_strict_acceptor) {
Jan F. Chadima 3fdf10
+		gss_create_empty_oid_set(&status, &oidset);
Jan F. Chadima 3fdf10
+		gss_add_oid_set_member(&status, ctx->oid, &oidset);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		if (gethostname(lname, MAXHOSTNAMELEN)) {
Jan F. Chadima 3fdf10
+			gss_release_oid_set(&status, &oidset);
Jan F. Chadima 3fdf10
+			return (-1);
Jan F. Chadima 3fdf10
+		}
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
-	if (gethostname(lname, MAXHOSTNAMELEN)) {
Jan F. Chadima 3fdf10
-		gss_release_oid_set(&status, &oidset);
Jan F. Chadima 3fdf10
-		return (-1);
Jan F. Chadima 3fdf10
-	}
Jan F. Chadima 3fdf10
+		if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) {
Jan F. Chadima 3fdf10
+			gss_release_oid_set(&status, &oidset);
Jan F. Chadima 3fdf10
+			return (ctx->major);
Jan F. Chadima 3fdf10
+		}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		if ((ctx->major = gss_acquire_cred(&ctx->minor,
Jan F. Chadima 3fdf10
+		    ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, 
Jan F. Chadima 3fdf10
+		    NULL, NULL)))
Jan F. Chadima 3fdf10
+			ssh_gssapi_error(ctx);
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
-	if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) {
Jan F. Chadima 3fdf10
 		gss_release_oid_set(&status, &oidset);
Jan F. Chadima 3fdf10
 		return (ctx->major);
Jan F. Chadima 3fdf10
+	} else {
Jan F. Chadima 3fdf10
+		ctx->name = GSS_C_NO_NAME;
Jan F. Chadima 3fdf10
+		ctx->creds = GSS_C_NO_CREDENTIAL;
Jan F. Chadima 3fdf10
 	}
Jan F. Chadima 3fdf10
-
Jan F. Chadima 3fdf10
-	if ((ctx->major = gss_acquire_cred(&ctx->minor,
Jan F. Chadima 3fdf10
-	    ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL)))
Jan F. Chadima 3fdf10
-		ssh_gssapi_error(ctx);
Jan F. Chadima 3fdf10
-
Jan F. Chadima 3fdf10
-	gss_release_oid_set(&status, &oidset);
Jan F. Chadima 3fdf10
-	return (ctx->major);
Jan F. Chadima 3fdf10
+	return GSS_S_COMPLETE;
Jan F. Chadima 3fdf10
 }
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 /* Privileged */
Jan F. Chadima 3fdf10
@@ -114,6 +126,29 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss
Jan F. Chadima 3fdf10
 }
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 /* Unprivileged */
Jan F. Chadima 3fdf10
+char *
Jan F. Chadima 3fdf10
+ssh_gssapi_server_mechanisms() {
Jan F. Chadima 3fdf10
+	gss_OID_set	supported;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	ssh_gssapi_supported_oids(&supported);
Jan F. Chadima 3fdf10
+	return (ssh_gssapi_kex_mechs(supported, &ssh_gssapi_server_check_mech,
Jan F. Chadima 3fdf10
+	    NULL, NULL));
Jan F. Chadima 3fdf10
+}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+/* Unprivileged */
Jan F. Chadima 3fdf10
+int
Jan F. Chadima 3fdf10
+ssh_gssapi_server_check_mech(Gssctxt **dum, gss_OID oid, const char *data,
Jan F. Chadima 3fdf10
+    const char *dummy) {
Jan F. Chadima 3fdf10
+	Gssctxt *ctx = NULL;
Jan F. Chadima 3fdf10
+	int res;
Jan F. Chadima 3fdf10
+ 
Jan F. Chadima 3fdf10
+	res = !GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx, oid)));
Jan F. Chadima 3fdf10
+	ssh_gssapi_delete_ctx(&ctx;;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	return (res);
Jan F. Chadima 3fdf10
+}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+/* Unprivileged */
Jan F. Chadima 3fdf10
 void
Jan F. Chadima 3fdf10
 ssh_gssapi_supported_oids(gss_OID_set *oidset)
Jan F. Chadima 3fdf10
 {
Jan F. Chadima 3fdf10
@@ -123,7 +158,9 @@ ssh_gssapi_supported_oids(gss_OID_set *o
Jan F. Chadima 3fdf10
 	gss_OID_set supported;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 	gss_create_empty_oid_set(&min_status, oidset);
Jan F. Chadima 3fdf10
-	gss_indicate_mechs(&min_status, &supported);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (GSS_ERROR(gss_indicate_mechs(&min_status, &supported)))
Jan F. Chadima 3fdf10
+		return;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 	while (supported_mechs[i]->name != NULL) {
Jan F. Chadima 3fdf10
 		if (GSS_ERROR(gss_test_oid_set_member(&min_status,
Jan F. Chadima 3fdf10
@@ -247,8 +284,48 @@ OM_uint32
Jan F. Chadima 3fdf10
 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
Jan F. Chadima 3fdf10
 {
Jan F. Chadima 3fdf10
 	int i = 0;
Jan F. Chadima 3fdf10
+	int equal = 0;
Jan F. Chadima 3fdf10
+	gss_name_t new_name = GSS_C_NO_NAME;
Jan F. Chadima 3fdf10
+	gss_buffer_desc ename = GSS_C_EMPTY_BUFFER;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (options.gss_store_rekey && client->used && ctx->client_creds) {
Jan F. Chadima 3fdf10
+		if (client->mech->oid.length != ctx->oid->length ||
Jan F. Chadima 3fdf10
+		    (memcmp(client->mech->oid.elements,
Jan F. Chadima 3fdf10
+		     ctx->oid->elements, ctx->oid->length) !=0)) {
Jan F. Chadima 3fdf10
+			debug("Rekeyed credentials have different mechanism");
Jan F. Chadima 3fdf10
+			return GSS_S_COMPLETE;
Jan F. Chadima 3fdf10
+		}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		if ((ctx->major = gss_inquire_cred_by_mech(&ctx->minor, 
Jan F. Chadima 3fdf10
+		    ctx->client_creds, ctx->oid, &new_name, 
Jan F. Chadima 3fdf10
+		    NULL, NULL, NULL))) {
Jan F. Chadima 3fdf10
+			ssh_gssapi_error(ctx);
Jan F. Chadima 3fdf10
+			return (ctx->major);
Jan F. Chadima 3fdf10
+		}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		ctx->major = gss_compare_name(&ctx->minor, client->name, 
Jan F. Chadima 3fdf10
+		    new_name, &equal);
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
-	gss_buffer_desc ename;
Jan F. Chadima 3fdf10
+		if (GSS_ERROR(ctx->major)) {
Jan F. Chadima 3fdf10
+			ssh_gssapi_error(ctx);
Jan F. Chadima 3fdf10
+			return (ctx->major);
Jan F. Chadima 3fdf10
+		}
Jan F. Chadima 3fdf10
+ 
Jan F. Chadima 3fdf10
+		if (!equal) {
Jan F. Chadima 3fdf10
+			debug("Rekeyed credentials have different name");
Jan F. Chadima 3fdf10
+			return GSS_S_COMPLETE;
Jan F. Chadima 3fdf10
+		}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		debug("Marking rekeyed credentials for export");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		gss_release_name(&ctx->minor, &client->name);
Jan F. Chadima 3fdf10
+		gss_release_cred(&ctx->minor, &client->creds);
Jan F. Chadima 3fdf10
+		client->name = new_name;
Jan F. Chadima 3fdf10
+		client->creds = ctx->client_creds;
Jan F. Chadima 3fdf10
+        	ctx->client_creds = GSS_C_NO_CREDENTIAL;
Jan F. Chadima 3fdf10
+		client->updated = 1;
Jan F. Chadima 3fdf10
+		return GSS_S_COMPLETE;
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 	client->mech = NULL;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
@@ -263,6 +340,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g
Jan F. Chadima 3fdf10
 	if (client->mech == NULL)
Jan F. Chadima 3fdf10
 		return GSS_S_FAILURE;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+	if (ctx->client_creds &&
Jan F. Chadima 3fdf10
+	    (ctx->major = gss_inquire_cred_by_mech(&ctx->minor,
Jan F. Chadima 3fdf10
+	     ctx->client_creds, ctx->oid, &client->name, NULL, NULL, NULL))) {
Jan F. Chadima 3fdf10
+		ssh_gssapi_error(ctx);
Jan F. Chadima 3fdf10
+		return (ctx->major);
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 	if ((ctx->major = gss_display_name(&ctx->minor, ctx->client,
Jan F. Chadima 3fdf10
 	    &client->displayname, NULL))) {
Jan F. Chadima 3fdf10
 		ssh_gssapi_error(ctx);
Jan F. Chadima 3fdf10
@@ -280,6 +364,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g
Jan F. Chadima 3fdf10
 		return (ctx->major);
Jan F. Chadima 3fdf10
 	}
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+	gss_release_buffer(&ctx->minor, &ename);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 	/* We can't copy this structure, so we just move the pointer to it */
Jan F. Chadima 3fdf10
 	client->creds = ctx->client_creds;
Jan F. Chadima 3fdf10
 	ctx->client_creds = GSS_C_NO_CREDENTIAL;
Jan F. Chadima 3fdf10
@@ -327,7 +413,7 @@ ssh_gssapi_do_child(char ***envp, u_int 
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 /* Privileged */
Jan F. Chadima 3fdf10
 int
Jan F. Chadima 3fdf10
-ssh_gssapi_userok(char *user)
Jan F. Chadima 3fdf10
+ssh_gssapi_userok(char *user, struct passwd *pw)
Jan F. Chadima 3fdf10
 {
Jan F. Chadima 3fdf10
 	OM_uint32 lmin;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
@@ -337,9 +423,11 @@ ssh_gssapi_userok(char *user)
Jan F. Chadima 3fdf10
 		return 0;
Jan F. Chadima 3fdf10
 	}
Jan F. Chadima 3fdf10
 	if (gssapi_client.mech && gssapi_client.mech->userok)
Jan F. Chadima 3fdf10
-		if ((*gssapi_client.mech->userok)(&gssapi_client, user))
Jan F. Chadima 3fdf10
+		if ((*gssapi_client.mech->userok)(&gssapi_client, user)) {
Jan F. Chadima 3fdf10
+			gssapi_client.used = 1;
Jan F. Chadima 3fdf10
+			gssapi_client.store.owner = pw;
Jan F. Chadima 3fdf10
 			return 1;
Jan F. Chadima 3fdf10
-		else {
Jan F. Chadima 3fdf10
+		} else {
Jan F. Chadima 3fdf10
 			/* Destroy delegated credentials if userok fails */
Jan F. Chadima 3fdf10
 			gss_release_buffer(&lmin, &gssapi_client.displayname);
Jan F. Chadima 3fdf10
 			gss_release_buffer(&lmin, &gssapi_client.exportedname);
Jan F. Chadima 3fdf10
@@ -352,14 +440,90 @@ ssh_gssapi_userok(char *user)
Jan F. Chadima 3fdf10
 	return (0);
Jan F. Chadima 3fdf10
 }
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
-/* Privileged */
Jan F. Chadima 3fdf10
-OM_uint32
Jan F. Chadima 3fdf10
-ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
Jan F. Chadima 3fdf10
+/* These bits are only used for rekeying. The unpriviledged child is running 
Jan F. Chadima 3fdf10
+ * as the user, the monitor is root.
Jan F. Chadima 3fdf10
+ *
Jan F. Chadima 3fdf10
+ * In the child, we want to :
Jan F. Chadima 3fdf10
+ *    *) Ask the monitor to store our credentials into the store we specify
Jan F. Chadima 3fdf10
+ *    *) If it succeeds, maybe do a PAM update
Jan F. Chadima 3fdf10
+ */
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+/* Stuff for PAM */
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+#ifdef USE_PAM
Jan F. Chadima 3fdf10
+static int ssh_gssapi_simple_conv(int n, const struct pam_message **msg, 
Jan F. Chadima 3fdf10
+    struct pam_response **resp, void *data)
Jan F. Chadima 3fdf10
 {
Jan F. Chadima 3fdf10
-	ctx->major = gss_verify_mic(&ctx->minor, ctx->context,
Jan F. Chadima 3fdf10
-	    gssbuf, gssmic, NULL);
Jan F. Chadima 3fdf10
+	return (PAM_CONV_ERR);
Jan F. Chadima 3fdf10
+}
Jan F. Chadima 3fdf10
+#endif
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
-	return (ctx->major);
Jan F. Chadima 3fdf10
+void
Jan F. Chadima 3fdf10
+ssh_gssapi_rekey_creds() {
Jan F. Chadima 3fdf10
+	int ok;
Jan F. Chadima 3fdf10
+	int ret;
Jan F. Chadima 3fdf10
+#ifdef USE_PAM
Jan F. Chadima 3fdf10
+	pam_handle_t *pamh = NULL;
Jan F. Chadima 3fdf10
+	struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL};
Jan F. Chadima 3fdf10
+	char *envstr;
Jan F. Chadima 3fdf10
+#endif
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (gssapi_client.store.filename == NULL && 
Jan F. Chadima 3fdf10
+	    gssapi_client.store.envval == NULL &&
Jan F. Chadima 3fdf10
+	    gssapi_client.store.envvar == NULL)
Jan F. Chadima 3fdf10
+		return;
Jan F. Chadima 3fdf10
+ 
Jan F. Chadima 3fdf10
+	ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store));
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (!ok)
Jan F. Chadima 3fdf10
+		return;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	debug("Rekeyed credentials stored successfully");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	/* Actually managing to play with the ssh pam stack from here will
Jan F. Chadima 3fdf10
+	 * be next to impossible. In any case, we may want different options
Jan F. Chadima 3fdf10
+	 * for rekeying. So, use our own :)
Jan F. Chadima 3fdf10
+	 */
Jan F. Chadima 3fdf10
+#ifdef USE_PAM	
Jan F. Chadima 3fdf10
+	if (!use_privsep) {
Jan F. Chadima 3fdf10
+		debug("Not even going to try and do PAM with privsep disabled");
Jan F. Chadima 3fdf10
+		return;
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	ret = pam_start("sshd-rekey", gssapi_client.store.owner->pw_name,
Jan F. Chadima 3fdf10
+ 	    &pamconv, &pamh);
Jan F. Chadima 3fdf10
+	if (ret)
Jan F. Chadima 3fdf10
+		return;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, 
Jan F. Chadima 3fdf10
+	    gssapi_client.store.envval);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	ret = pam_putenv(pamh, envstr);
Jan F. Chadima 3fdf10
+	if (!ret)
Jan F. Chadima 3fdf10
+		pam_setcred(pamh, PAM_REINITIALIZE_CRED);
Jan F. Chadima 3fdf10
+	pam_end(pamh, PAM_SUCCESS);
Jan F. Chadima 3fdf10
+#endif
Jan F. Chadima 3fdf10
+}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+int 
Jan F. Chadima 3fdf10
+ssh_gssapi_update_creds(ssh_gssapi_ccache *store) {
Jan F. Chadima 3fdf10
+	int ok = 0;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	/* Check we've got credentials to store */
Jan F. Chadima 3fdf10
+	if (!gssapi_client.updated)
Jan F. Chadima 3fdf10
+		return 0;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	gssapi_client.updated = 0;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	temporarily_use_uid(gssapi_client.store.owner);
Jan F. Chadima 3fdf10
+	if (gssapi_client.mech && gssapi_client.mech->updatecreds)
Jan F. Chadima 3fdf10
+		ok = (*gssapi_client.mech->updatecreds)(store, &gssapi_client);
Jan F. Chadima 3fdf10
+	else
Jan F. Chadima 3fdf10
+		debug("No update function for this mechanism");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	restore_uid();
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	return ok;
Jan F. Chadima 3fdf10
 }
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 #endif
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/gss-serv-krb5.c.gsskex openssh-5.6p1/gss-serv-krb5.c
Jan F. Chadima 1b8a26
--- openssh-5.6p1/gss-serv-krb5.c.gsskex	2006-09-01 07:38:36.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/gss-serv-krb5.c	2010-08-23 12:51:58.000000000 +0200
Jan F. Chadima 3fdf10
@@ -1,7 +1,7 @@
Jan F. Chadima 3fdf10
 /* $OpenBSD: gss-serv-krb5.c,v 1.7 2006/08/03 03:34:42 deraadt Exp $ */
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 /*
Jan F. Chadima 3fdf10
- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
Jan F. Chadima 3fdf10
+ * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved.
Jan F. Chadima 3fdf10
  *
Jan F. Chadima 3fdf10
  * Redistribution and use in source and binary forms, with or without
Jan F. Chadima 3fdf10
  * modification, are permitted provided that the following conditions
Jan F. Chadima 3fdf10
@@ -120,6 +120,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
Jan F. Chadima 3fdf10
 	krb5_principal princ;
Jan F. Chadima 3fdf10
 	OM_uint32 maj_status, min_status;
Jan F. Chadima 3fdf10
 	int len;
Jan F. Chadima 3fdf10
+	const char *new_ccname;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 	if (client->creds == NULL) {
Jan F. Chadima 3fdf10
 		debug("No credentials stored");
Jan F. Chadima 3fdf10
@@ -168,11 +169,16 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
Jan F. Chadima 3fdf10
 		return;
Jan F. Chadima 3fdf10
 	}
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
-	client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache));
Jan F. Chadima 3fdf10
+	new_ccname = krb5_cc_get_name(krb_context, ccache);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 	client->store.envvar = "KRB5CCNAME";
Jan F. Chadima 3fdf10
-	len = strlen(client->store.filename) + 6;
Jan F. Chadima 3fdf10
-	client->store.envval = xmalloc(len);
Jan F. Chadima 3fdf10
-	snprintf(client->store.envval, len, "FILE:%s", client->store.filename);
Jan F. Chadima 3fdf10
+#ifdef USE_CCAPI
Jan F. Chadima 3fdf10
+	xasprintf(&client->store.envval, "API:%s", new_ccname);
Jan F. Chadima 3fdf10
+	client->store.filename = NULL;
Jan F. Chadima 3fdf10
+#else
Jan F. Chadima 3fdf10
+	xasprintf(&client->store.envval, "FILE:%s", new_ccname);
Jan F. Chadima 3fdf10
+	client->store.filename = xstrdup(new_ccname);
Jan F. Chadima 3fdf10
+#endif
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 #ifdef USE_PAM
Jan F. Chadima 3fdf10
 	if (options.use_pam)
Jan F. Chadima 3fdf10
@@ -184,6 +190,71 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
Jan F. Chadima 3fdf10
 	return;
Jan F. Chadima 3fdf10
 }
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+int
Jan F. Chadima 3fdf10
+ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, 
Jan F. Chadima 3fdf10
+    ssh_gssapi_client *client)
Jan F. Chadima 3fdf10
+{
Jan F. Chadima 3fdf10
+	krb5_ccache ccache = NULL;
Jan F. Chadima 3fdf10
+	krb5_principal principal = NULL;
Jan F. Chadima 3fdf10
+	char *name = NULL;
Jan F. Chadima 3fdf10
+	krb5_error_code problem;
Jan F. Chadima 3fdf10
+	OM_uint32 maj_status, min_status;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+   	if ((problem = krb5_cc_resolve(krb_context, store->envval, &ccache))) {
Jan F. Chadima 3fdf10
+                logit("krb5_cc_resolve(): %.100s",
Jan F. Chadima 3fdf10
+                    krb5_get_err_text(krb_context, problem));
Jan F. Chadima 3fdf10
+                return 0;
Jan F. Chadima 3fdf10
+       	}
Jan F. Chadima 3fdf10
+	
Jan F. Chadima 3fdf10
+	/* Find out who the principal in this cache is */
Jan F. Chadima 3fdf10
+	if ((problem = krb5_cc_get_principal(krb_context, ccache, 
Jan F. Chadima 3fdf10
+	    &principal))) {
Jan F. Chadima 3fdf10
+		logit("krb5_cc_get_principal(): %.100s",
Jan F. Chadima 3fdf10
+		    krb5_get_err_text(krb_context, problem));
Jan F. Chadima 3fdf10
+		krb5_cc_close(krb_context, ccache);
Jan F. Chadima 3fdf10
+		return 0;
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if ((problem = krb5_unparse_name(krb_context, principal, &name))) {
Jan F. Chadima 3fdf10
+		logit("krb5_unparse_name(): %.100s",
Jan F. Chadima 3fdf10
+		    krb5_get_err_text(krb_context, problem));
Jan F. Chadima 3fdf10
+		krb5_free_principal(krb_context, principal);
Jan F. Chadima 3fdf10
+		krb5_cc_close(krb_context, ccache);
Jan F. Chadima 3fdf10
+		return 0;
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (strcmp(name,client->exportedname.value)!=0) {
Jan F. Chadima 3fdf10
+		debug("Name in local credentials cache differs. Not storing");
Jan F. Chadima 3fdf10
+		krb5_free_principal(krb_context, principal);
Jan F. Chadima 3fdf10
+		krb5_cc_close(krb_context, ccache);
Jan F. Chadima 3fdf10
+		krb5_free_unparsed_name(krb_context, name);
Jan F. Chadima 3fdf10
+		return 0;
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+	krb5_free_unparsed_name(krb_context, name);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	/* Name matches, so lets get on with it! */
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if ((problem = krb5_cc_initialize(krb_context, ccache, principal))) {
Jan F. Chadima 3fdf10
+		logit("krb5_cc_initialize(): %.100s",
Jan F. Chadima 3fdf10
+		    krb5_get_err_text(krb_context, problem));
Jan F. Chadima 3fdf10
+		krb5_free_principal(krb_context, principal);
Jan F. Chadima 3fdf10
+		krb5_cc_close(krb_context, ccache);
Jan F. Chadima 3fdf10
+		return 0;
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	krb5_free_principal(krb_context, principal);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if ((maj_status = gss_krb5_copy_ccache(&min_status, client->creds,
Jan F. Chadima 3fdf10
+	    ccache))) {
Jan F. Chadima 3fdf10
+		logit("gss_krb5_copy_ccache() failed. Sorry!");
Jan F. Chadima 3fdf10
+		krb5_cc_close(krb_context, ccache);
Jan F. Chadima 3fdf10
+		return 0;
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	return 1;
Jan F. Chadima 3fdf10
+}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 ssh_gssapi_mech gssapi_kerberos_mech = {
Jan F. Chadima 3fdf10
 	"toWM5Slw5Ew8Mqkay+al2g==",
Jan F. Chadima 3fdf10
 	"Kerberos",
Jan F. Chadima 3fdf10
@@ -191,7 +262,8 @@ ssh_gssapi_mech gssapi_kerberos_mech = {
Jan F. Chadima 3fdf10
 	NULL,
Jan F. Chadima 3fdf10
 	&ssh_gssapi_krb5_userok,
Jan F. Chadima 3fdf10
 	NULL,
Jan F. Chadima 3fdf10
-	&ssh_gssapi_krb5_storecreds
Jan F. Chadima 3fdf10
+	&ssh_gssapi_krb5_storecreds,
Jan F. Chadima 3fdf10
+	&ssh_gssapi_krb5_updatecreds
Jan F. Chadima 3fdf10
 };
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 #endif /* KRB5 */
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/kex.c.gsskex openssh-5.6p1/kex.c
Jan F. Chadima 1b8a26
--- openssh-5.6p1/kex.c.gsskex	2010-01-08 06:50:41.000000000 +0100
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/kex.c	2010-08-23 12:51:58.000000000 +0200
Jan F. Chadima 3fdf10
@@ -50,6 +50,10 @@
Jan F. Chadima 3fdf10
 #include "monitor.h"
Jan F. Chadima 3fdf10
 #include "roaming.h"
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+#ifdef GSSAPI
Jan F. Chadima 3fdf10
+#include "ssh-gss.h"
Jan F. Chadima 3fdf10
+#endif
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 #if OPENSSL_VERSION_NUMBER >= 0x00907000L
Jan F. Chadima 3fdf10
 # if defined(HAVE_EVP_SHA256)
Jan F. Chadima 3fdf10
 # define evp_ssh_sha256 EVP_sha256
Jan F. Chadima 3fdf10
@@ -326,6 +330,20 @@ choose_kex(Kex *k, char *client, char *s
Jan F. Chadima 3fdf10
 		k->kex_type = KEX_DH_GEX_SHA256;
Jan F. Chadima 3fdf10
 		k->evp_md = evp_ssh_sha256();
Jan F. Chadima 3fdf10
 #endif
Jan F. Chadima 3fdf10
+#ifdef GSSAPI
Jan F. Chadima 3fdf10
+	} else if (strncmp(k->name, KEX_GSS_GEX_SHA1_ID,
Jan F. Chadima 3fdf10
+	    sizeof(KEX_GSS_GEX_SHA1_ID) - 1) == 0) {
Jan F. Chadima 3fdf10
+		k->kex_type = KEX_GSS_GEX_SHA1;
Jan F. Chadima 3fdf10
+		k->evp_md = EVP_sha1();
Jan F. Chadima 3fdf10
+	} else if (strncmp(k->name, KEX_GSS_GRP1_SHA1_ID,
Jan F. Chadima 3fdf10
+	    sizeof(KEX_GSS_GRP1_SHA1_ID) - 1) == 0) {
Jan F. Chadima 3fdf10
+		k->kex_type = KEX_GSS_GRP1_SHA1;
Jan F. Chadima 3fdf10
+		k->evp_md = EVP_sha1();
Jan F. Chadima 3fdf10
+	} else if (strncmp(k->name, KEX_GSS_GRP14_SHA1_ID,
Jan F. Chadima 3fdf10
+	    sizeof(KEX_GSS_GRP14_SHA1_ID) - 1) == 0) {
Jan F. Chadima 3fdf10
+		k->kex_type = KEX_GSS_GRP14_SHA1;
Jan F. Chadima 3fdf10
+		k->evp_md = EVP_sha1();
Jan F. Chadima 3fdf10
+#endif
Jan F. Chadima 3fdf10
 	} else
Jan F. Chadima 3fdf10
 		fatal("bad kex alg %s", k->name);
Jan F. Chadima 3fdf10
 }
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/kexgssc.c.gsskex openssh-5.6p1/kexgssc.c
Jan F. Chadima 1b8a26
--- openssh-5.6p1/kexgssc.c.gsskex	2010-08-23 12:51:58.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/kexgssc.c	2010-08-23 12:51:58.000000000 +0200
Jan F. Chadima 3fdf10
@@ -0,0 +1,334 @@
Jan F. Chadima 3fdf10
+/*
Jan F. Chadima 3fdf10
+ * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
Jan F. Chadima 3fdf10
+ *
Jan F. Chadima 3fdf10
+ * Redistribution and use in source and binary forms, with or without
Jan F. Chadima 3fdf10
+ * modification, are permitted provided that the following conditions
Jan F. Chadima 3fdf10
+ * are met:
Jan F. Chadima 3fdf10
+ * 1. Redistributions of source code must retain the above copyright
Jan F. Chadima 3fdf10
+ *    notice, this list of conditions and the following disclaimer.
Jan F. Chadima 3fdf10
+ * 2. Redistributions in binary form must reproduce the above copyright
Jan F. Chadima 3fdf10
+ *    notice, this list of conditions and the following disclaimer in the
Jan F. Chadima 3fdf10
+ *    documentation and/or other materials provided with the distribution.
Jan F. Chadima 3fdf10
+ *
Jan F. Chadima 3fdf10
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
Jan F. Chadima 3fdf10
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
Jan F. Chadima 3fdf10
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
Jan F. Chadima 3fdf10
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
Jan F. Chadima 3fdf10
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
Jan F. Chadima 3fdf10
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
Jan F. Chadima 3fdf10
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
Jan F. Chadima 3fdf10
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Jan F. Chadima 3fdf10
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
Jan F. Chadima 3fdf10
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Jan F. Chadima 3fdf10
+ */
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+#include "includes.h"
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+#ifdef GSSAPI
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+#include "includes.h"
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+#include <openssl/crypto.h>
Jan F. Chadima 3fdf10
+#include <openssl/bn.h>
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+#include <string.h>
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+#include "xmalloc.h"
Jan F. Chadima 3fdf10
+#include "buffer.h"
Jan F. Chadima 3fdf10
+#include "ssh2.h"
Jan F. Chadima 3fdf10
+#include "key.h"
Jan F. Chadima 3fdf10
+#include "cipher.h"
Jan F. Chadima 3fdf10
+#include "kex.h"
Jan F. Chadima 3fdf10
+#include "log.h"
Jan F. Chadima 3fdf10
+#include "packet.h"
Jan F. Chadima 3fdf10
+#include "dh.h"
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+#include "ssh-gss.h"
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+void
Jan F. Chadima 3fdf10
+kexgss_client(Kex *kex) {
Jan F. Chadima 3fdf10
+	gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
Jan F. Chadima 3fdf10
+	gss_buffer_desc recv_tok, gssbuf, msg_tok, *token_ptr;
Jan F. Chadima 3fdf10
+	Gssctxt *ctxt;
Jan F. Chadima 3fdf10
+	OM_uint32 maj_status, min_status, ret_flags;
Jan F. Chadima 3fdf10
+	u_int klen, kout, slen = 0, hashlen, strlen;
Jan F. Chadima 3fdf10
+	DH *dh; 
Jan F. Chadima 3fdf10
+	BIGNUM *dh_server_pub = NULL;
Jan F. Chadima 3fdf10
+	BIGNUM *shared_secret = NULL;
Jan F. Chadima 3fdf10
+	BIGNUM *p = NULL;
Jan F. Chadima 3fdf10
+	BIGNUM *g = NULL;	
Jan F. Chadima 3fdf10
+	u_char *kbuf, *hash;
Jan F. Chadima 3fdf10
+	u_char *serverhostkey = NULL;
Jan F. Chadima 3fdf10
+	u_char *empty = "";
Jan F. Chadima 3fdf10
+	char *msg;
Jan F. Chadima 3fdf10
+	char *lang;
Jan F. Chadima 3fdf10
+	int type = 0;
Jan F. Chadima 3fdf10
+	int first = 1;
Jan F. Chadima 3fdf10
+	int nbits = 0, min = DH_GRP_MIN, max = DH_GRP_MAX;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	/* Initialise our GSSAPI world */	
Jan F. Chadima 3fdf10
+	ssh_gssapi_build_ctx(&ctxt);
Jan F. Chadima 3fdf10
+	if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type) 
Jan F. Chadima 3fdf10
+	    == GSS_C_NO_OID)
Jan F. Chadima 3fdf10
+		fatal("Couldn't identify host exchange");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (ssh_gssapi_import_name(ctxt, kex->gss_host))
Jan F. Chadima 3fdf10
+		fatal("Couldn't import hostname");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (kex->gss_client && 
Jan F. Chadima 3fdf10
+	    ssh_gssapi_client_identity(ctxt, kex->gss_client))
Jan F. Chadima 3fdf10
+		fatal("Couldn't acquire client credentials");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	switch (kex->kex_type) {
Jan F. Chadima 3fdf10
+	case KEX_GSS_GRP1_SHA1:
Jan F. Chadima 3fdf10
+		dh = dh_new_group1();
Jan F. Chadima 3fdf10
+		break;
Jan F. Chadima 3fdf10
+	case KEX_GSS_GRP14_SHA1:
Jan F. Chadima 3fdf10
+		dh = dh_new_group14();
Jan F. Chadima 3fdf10
+		break;
Jan F. Chadima 3fdf10
+	case KEX_GSS_GEX_SHA1:
Jan F. Chadima 3fdf10
+		debug("Doing group exchange\n");
Jan F. Chadima 3fdf10
+		nbits = dh_estimate(kex->we_need * 8);
Jan F. Chadima 3fdf10
+		packet_start(SSH2_MSG_KEXGSS_GROUPREQ);
Jan F. Chadima 3fdf10
+		packet_put_int(min);
Jan F. Chadima 3fdf10
+		packet_put_int(nbits);
Jan F. Chadima 3fdf10
+		packet_put_int(max);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		packet_send();
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		packet_read_expect(SSH2_MSG_KEXGSS_GROUP);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		if ((p = BN_new()) == NULL)
Jan F. Chadima 3fdf10
+			fatal("BN_new() failed");
Jan F. Chadima 3fdf10
+		packet_get_bignum2(p);
Jan F. Chadima 3fdf10
+		if ((g = BN_new()) == NULL)
Jan F. Chadima 3fdf10
+			fatal("BN_new() failed");
Jan F. Chadima 3fdf10
+		packet_get_bignum2(g);
Jan F. Chadima 3fdf10
+		packet_check_eom();
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		if (BN_num_bits(p) < min || BN_num_bits(p) > max)
Jan F. Chadima 3fdf10
+			fatal("GSSGRP_GEX group out of range: %d !< %d !< %d",
Jan F. Chadima 3fdf10
+			    min, BN_num_bits(p), max);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		dh = dh_new_group(g, p);
Jan F. Chadima 3fdf10
+		break;
Jan F. Chadima 3fdf10
+	default:
Jan F. Chadima 3fdf10
+		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+	
Jan F. Chadima 3fdf10
+	/* Step 1 - e is dh->pub_key */
Jan F. Chadima 3fdf10
+	dh_gen_key(dh, kex->we_need * 8);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	/* This is f, we initialise it now to make life easier */
Jan F. Chadima 3fdf10
+	dh_server_pub = BN_new();
Jan F. Chadima 3fdf10
+	if (dh_server_pub == NULL)
Jan F. Chadima 3fdf10
+		fatal("dh_server_pub == NULL");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	token_ptr = GSS_C_NO_BUFFER;
Jan F. Chadima 3fdf10
+			 
Jan F. Chadima 3fdf10
+	do {
Jan F. Chadima 3fdf10
+		debug("Calling gss_init_sec_context");
Jan F. Chadima 3fdf10
+		
Jan F. Chadima 3fdf10
+		maj_status = ssh_gssapi_init_ctx(ctxt,
Jan F. Chadima 3fdf10
+		    kex->gss_deleg_creds, token_ptr, &send_tok,
Jan F. Chadima 3fdf10
+		    &ret_flags);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		if (GSS_ERROR(maj_status)) {
Jan F. Chadima 3fdf10
+			if (send_tok.length != 0) {
Jan F. Chadima 3fdf10
+				packet_start(SSH2_MSG_KEXGSS_CONTINUE);
Jan F. Chadima 3fdf10
+				packet_put_string(send_tok.value,
Jan F. Chadima 3fdf10
+				    send_tok.length);
Jan F. Chadima 3fdf10
+			}
Jan F. Chadima 3fdf10
+			fatal("gss_init_context failed");
Jan F. Chadima 3fdf10
+		}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		/* If we've got an old receive buffer get rid of it */
Jan F. Chadima 3fdf10
+		if (token_ptr != GSS_C_NO_BUFFER)
Jan F. Chadima 3fdf10
+			xfree(recv_tok.value);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		if (maj_status == GSS_S_COMPLETE) {
Jan F. Chadima 3fdf10
+			/* If mutual state flag is not true, kex fails */
Jan F. Chadima 3fdf10
+			if (!(ret_flags & GSS_C_MUTUAL_FLAG))
Jan F. Chadima 3fdf10
+				fatal("Mutual authentication failed");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+			/* If integ avail flag is not true kex fails */
Jan F. Chadima 3fdf10
+			if (!(ret_flags & GSS_C_INTEG_FLAG))
Jan F. Chadima 3fdf10
+				fatal("Integrity check failed");
Jan F. Chadima 3fdf10
+		}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		/* 
Jan F. Chadima 3fdf10
+		 * If we have data to send, then the last message that we
Jan F. Chadima 3fdf10
+		 * received cannot have been a 'complete'. 
Jan F. Chadima 3fdf10
+		 */
Jan F. Chadima 3fdf10
+		if (send_tok.length != 0) {
Jan F. Chadima 3fdf10
+			if (first) {
Jan F. Chadima 3fdf10
+				packet_start(SSH2_MSG_KEXGSS_INIT);
Jan F. Chadima 3fdf10
+				packet_put_string(send_tok.value,
Jan F. Chadima 3fdf10
+				    send_tok.length);
Jan F. Chadima 3fdf10
+				packet_put_bignum2(dh->pub_key);
Jan F. Chadima 3fdf10
+				first = 0;
Jan F. Chadima 3fdf10
+			} else {
Jan F. Chadima 3fdf10
+				packet_start(SSH2_MSG_KEXGSS_CONTINUE);
Jan F. Chadima 3fdf10
+				packet_put_string(send_tok.value,
Jan F. Chadima 3fdf10
+				    send_tok.length);
Jan F. Chadima 3fdf10
+			}
Jan F. Chadima 3fdf10
+			packet_send();
Jan F. Chadima 3fdf10
+			gss_release_buffer(&min_status, &send_tok);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+			/* If we've sent them data, they should reply */
Jan F. Chadima 3fdf10
+			do {	
Jan F. Chadima 3fdf10
+				type = packet_read();
Jan F. Chadima 3fdf10
+				if (type == SSH2_MSG_KEXGSS_HOSTKEY) {
Jan F. Chadima 3fdf10
+					debug("Received KEXGSS_HOSTKEY");
Jan F. Chadima 3fdf10
+					if (serverhostkey)
Jan F. Chadima 3fdf10
+						fatal("Server host key received more than once");
Jan F. Chadima 3fdf10
+					serverhostkey = 
Jan F. Chadima 3fdf10
+					    packet_get_string(&slen);
Jan F. Chadima 3fdf10
+				}
Jan F. Chadima 3fdf10
+			} while (type == SSH2_MSG_KEXGSS_HOSTKEY);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+			switch (type) {
Jan F. Chadima 3fdf10
+			case SSH2_MSG_KEXGSS_CONTINUE:
Jan F. Chadima 3fdf10
+				debug("Received GSSAPI_CONTINUE");
Jan F. Chadima 3fdf10
+				if (maj_status == GSS_S_COMPLETE) 
Jan F. Chadima 3fdf10
+					fatal("GSSAPI Continue received from server when complete");
Jan F. Chadima 3fdf10
+				recv_tok.value = packet_get_string(&strlen);
Jan F. Chadima 3fdf10
+				recv_tok.length = strlen; 
Jan F. Chadima 3fdf10
+				break;
Jan F. Chadima 3fdf10
+			case SSH2_MSG_KEXGSS_COMPLETE:
Jan F. Chadima 3fdf10
+				debug("Received GSSAPI_COMPLETE");
Jan F. Chadima 3fdf10
+				packet_get_bignum2(dh_server_pub);
Jan F. Chadima 3fdf10
+				msg_tok.value =  packet_get_string(&strlen);
Jan F. Chadima 3fdf10
+				msg_tok.length = strlen; 
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+				/* Is there a token included? */
Jan F. Chadima 3fdf10
+				if (packet_get_char()) {
Jan F. Chadima 3fdf10
+					recv_tok.value=
Jan F. Chadima 3fdf10
+					    packet_get_string(&strlen);
Jan F. Chadima 3fdf10
+					recv_tok.length = strlen;
Jan F. Chadima 3fdf10
+					/* If we're already complete - protocol error */
Jan F. Chadima 3fdf10
+					if (maj_status == GSS_S_COMPLETE)
Jan F. Chadima 3fdf10
+						packet_disconnect("Protocol error: received token when complete");
Jan F. Chadima 3fdf10
+					} else {
Jan F. Chadima 3fdf10
+						/* No token included */
Jan F. Chadima 3fdf10
+						if (maj_status != GSS_S_COMPLETE)
Jan F. Chadima 3fdf10
+							packet_disconnect("Protocol error: did not receive final token");
Jan F. Chadima 3fdf10
+				}
Jan F. Chadima 3fdf10
+				break;
Jan F. Chadima 3fdf10
+			case SSH2_MSG_KEXGSS_ERROR:
Jan F. Chadima 3fdf10
+				debug("Received Error");
Jan F. Chadima 3fdf10
+				maj_status = packet_get_int();
Jan F. Chadima 3fdf10
+				min_status = packet_get_int();
Jan F. Chadima 3fdf10
+				msg = packet_get_string(NULL);
Jan F. Chadima 3fdf10
+				lang = packet_get_string(NULL);
Jan F. Chadima 3fdf10
+				fatal("GSSAPI Error: \n%.400s",msg);
Jan F. Chadima 3fdf10
+			default:
Jan F. Chadima 3fdf10
+				packet_disconnect("Protocol error: didn't expect packet type %d",
Jan F. Chadima 3fdf10
+		    		type);
Jan F. Chadima 3fdf10
+			}
Jan F. Chadima 3fdf10
+			token_ptr = &recv_tok;
Jan F. Chadima 3fdf10
+		} else {
Jan F. Chadima 3fdf10
+			/* No data, and not complete */
Jan F. Chadima 3fdf10
+			if (maj_status != GSS_S_COMPLETE)
Jan F. Chadima 3fdf10
+				fatal("Not complete, and no token output");
Jan F. Chadima 3fdf10
+		}
Jan F. Chadima 3fdf10
+	} while (maj_status & GSS_S_CONTINUE_NEEDED);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	/* 
Jan F. Chadima 3fdf10
+	 * We _must_ have received a COMPLETE message in reply from the 
Jan F. Chadima 3fdf10
+	 * server, which will have set dh_server_pub and msg_tok 
Jan F. Chadima 3fdf10
+	 */
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (type != SSH2_MSG_KEXGSS_COMPLETE)
Jan F. Chadima 3fdf10
+		fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	/* Check f in range [1, p-1] */
Jan F. Chadima 3fdf10
+	if (!dh_pub_is_valid(dh, dh_server_pub))
Jan F. Chadima 3fdf10
+		packet_disconnect("bad server public DH value");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	/* compute K=f^x mod p */
Jan F. Chadima 3fdf10
+	klen = DH_size(dh);
Jan F. Chadima 3fdf10
+	kbuf = xmalloc(klen);
Jan F. Chadima 3fdf10
+	kout = DH_compute_key(kbuf, dh_server_pub, dh);
Jan F. Chadima 3fdf10
+	if (kout < 0)
Jan F. Chadima 3fdf10
+		fatal("DH_compute_key: failed");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	shared_secret = BN_new();
Jan F. Chadima 3fdf10
+	if (shared_secret == NULL)
Jan F. Chadima 3fdf10
+		fatal("kexgss_client: BN_new failed");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (BN_bin2bn(kbuf, kout, shared_secret) == NULL)
Jan F. Chadima 3fdf10
+		fatal("kexdh_client: BN_bin2bn failed");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	memset(kbuf, 0, klen);
Jan F. Chadima 3fdf10
+	xfree(kbuf);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	switch (kex->kex_type) {
Jan F. Chadima 3fdf10
+	case KEX_GSS_GRP1_SHA1:
Jan F. Chadima 3fdf10
+	case KEX_GSS_GRP14_SHA1:
Jan F. Chadima 3fdf10
+		kex_dh_hash( kex->client_version_string, 
Jan F. Chadima 3fdf10
+		    kex->server_version_string,
Jan F. Chadima 3fdf10
+		    buffer_ptr(&kex->my), buffer_len(&kex->my),
Jan F. Chadima 3fdf10
+		    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
Jan F. Chadima 3fdf10
+		    (serverhostkey ? serverhostkey : empty), slen,
Jan F. Chadima 3fdf10
+		    dh->pub_key,	/* e */
Jan F. Chadima 3fdf10
+		    dh_server_pub,	/* f */
Jan F. Chadima 3fdf10
+		    shared_secret,	/* K */
Jan F. Chadima 3fdf10
+		    &hash, &hashlen
Jan F. Chadima 3fdf10
+		);
Jan F. Chadima 3fdf10
+		break;
Jan F. Chadima 3fdf10
+	case KEX_GSS_GEX_SHA1:
Jan F. Chadima 3fdf10
+		kexgex_hash(
Jan F. Chadima 3fdf10
+		    kex->evp_md,
Jan F. Chadima 3fdf10
+		    kex->client_version_string,
Jan F. Chadima 3fdf10
+		    kex->server_version_string,
Jan F. Chadima 3fdf10
+		    buffer_ptr(&kex->my), buffer_len(&kex->my),
Jan F. Chadima 3fdf10
+		    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
Jan F. Chadima 3fdf10
+		    (serverhostkey ? serverhostkey : empty), slen,
Jan F. Chadima 3fdf10
+ 		    min, nbits, max,
Jan F. Chadima 3fdf10
+		    dh->p, dh->g,
Jan F. Chadima 3fdf10
+		    dh->pub_key,
Jan F. Chadima 3fdf10
+		    dh_server_pub,
Jan F. Chadima 3fdf10
+		    shared_secret,
Jan F. Chadima 3fdf10
+		    &hash, &hashlen
Jan F. Chadima 3fdf10
+		);
Jan F. Chadima 3fdf10
+		break;
Jan F. Chadima 3fdf10
+	default:
Jan F. Chadima 3fdf10
+		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	gssbuf.value = hash;
Jan F. Chadima 3fdf10
+	gssbuf.length = hashlen;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	/* Verify that the hash matches the MIC we just got. */
Jan F. Chadima 3fdf10
+	if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok)))
Jan F. Chadima 3fdf10
+		packet_disconnect("Hash's MIC didn't verify");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	xfree(msg_tok.value);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	DH_free(dh);
Jan F. Chadima 3fdf10
+	if (serverhostkey)
Jan F. Chadima 3fdf10
+		xfree(serverhostkey);
Jan F. Chadima 3fdf10
+	BN_clear_free(dh_server_pub);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	/* save session id */
Jan F. Chadima 3fdf10
+	if (kex->session_id == NULL) {
Jan F. Chadima 3fdf10
+		kex->session_id_len = hashlen;
Jan F. Chadima 3fdf10
+		kex->session_id = xmalloc(kex->session_id_len);
Jan F. Chadima 3fdf10
+		memcpy(kex->session_id, hash, kex->session_id_len);
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (kex->gss_deleg_creds)
Jan F. Chadima 3fdf10
+		ssh_gssapi_credentials_updated(ctxt);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (gss_kex_context == NULL)
Jan F. Chadima 3fdf10
+		gss_kex_context = ctxt;
Jan F. Chadima 3fdf10
+	else
Jan F. Chadima 3fdf10
+		ssh_gssapi_delete_ctx(&ctxt);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	kex_derive_keys(kex, hash, hashlen, shared_secret);
Jan F. Chadima 3fdf10
+	BN_clear_free(shared_secret);
Jan F. Chadima 3fdf10
+	kex_finish(kex);
Jan F. Chadima 3fdf10
+}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+#endif /* GSSAPI */
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/kexgsss.c.gsskex openssh-5.6p1/kexgsss.c
Jan F. Chadima 1b8a26
--- openssh-5.6p1/kexgsss.c.gsskex	2010-08-23 12:51:58.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/kexgsss.c	2010-08-23 12:51:58.000000000 +0200
Jan F. Chadima 3fdf10
@@ -0,0 +1,288 @@
Jan F. Chadima 3fdf10
+/*
Jan F. Chadima 3fdf10
+ * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
Jan F. Chadima 3fdf10
+ *
Jan F. Chadima 3fdf10
+ * Redistribution and use in source and binary forms, with or without
Jan F. Chadima 3fdf10
+ * modification, are permitted provided that the following conditions
Jan F. Chadima 3fdf10
+ * are met:
Jan F. Chadima 3fdf10
+ * 1. Redistributions of source code must retain the above copyright
Jan F. Chadima 3fdf10
+ *    notice, this list of conditions and the following disclaimer.
Jan F. Chadima 3fdf10
+ * 2. Redistributions in binary form must reproduce the above copyright
Jan F. Chadima 3fdf10
+ *    notice, this list of conditions and the following disclaimer in the
Jan F. Chadima 3fdf10
+ *    documentation and/or other materials provided with the distribution.
Jan F. Chadima 3fdf10
+ *
Jan F. Chadima 3fdf10
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
Jan F. Chadima 3fdf10
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
Jan F. Chadima 3fdf10
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
Jan F. Chadima 3fdf10
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
Jan F. Chadima 3fdf10
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
Jan F. Chadima 3fdf10
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
Jan F. Chadima 3fdf10
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
Jan F. Chadima 3fdf10
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Jan F. Chadima 3fdf10
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
Jan F. Chadima 3fdf10
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Jan F. Chadima 3fdf10
+ */
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+#include "includes.h"
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+#ifdef GSSAPI
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+#include <string.h>
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+#include <openssl/crypto.h>
Jan F. Chadima 3fdf10
+#include <openssl/bn.h>
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+#include "xmalloc.h"
Jan F. Chadima 3fdf10
+#include "buffer.h"
Jan F. Chadima 3fdf10
+#include "ssh2.h"
Jan F. Chadima 3fdf10
+#include "key.h"
Jan F. Chadima 3fdf10
+#include "cipher.h"
Jan F. Chadima 3fdf10
+#include "kex.h"
Jan F. Chadima 3fdf10
+#include "log.h"
Jan F. Chadima 3fdf10
+#include "packet.h"
Jan F. Chadima 3fdf10
+#include "dh.h"
Jan F. Chadima 3fdf10
+#include "ssh-gss.h"
Jan F. Chadima 3fdf10
+#include "monitor_wrap.h"
Jan F. Chadima 3fdf10
+#include "servconf.h"
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+extern ServerOptions options;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+void
Jan F. Chadima 3fdf10
+kexgss_server(Kex *kex)
Jan F. Chadima 3fdf10
+{
Jan F. Chadima 3fdf10
+	OM_uint32 maj_status, min_status;
Jan F. Chadima 3fdf10
+	
Jan F. Chadima 3fdf10
+	/* 
Jan F. Chadima 3fdf10
+	 * Some GSSAPI implementations use the input value of ret_flags (an
Jan F. Chadima 3fdf10
+ 	 * output variable) as a means of triggering mechanism specific 
Jan F. Chadima 3fdf10
+ 	 * features. Initializing it to zero avoids inadvertently 
Jan F. Chadima 3fdf10
+ 	 * activating this non-standard behaviour.
Jan F. Chadima 3fdf10
+	 */
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	OM_uint32 ret_flags = 0;
Jan F. Chadima 3fdf10
+	gss_buffer_desc gssbuf, recv_tok, msg_tok;
Jan F. Chadima 3fdf10
+	gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
Jan F. Chadima 3fdf10
+	Gssctxt *ctxt = NULL;
Jan F. Chadima 3fdf10
+	u_int slen, klen, kout, hashlen;
Jan F. Chadima 3fdf10
+	u_char *kbuf, *hash;
Jan F. Chadima 3fdf10
+	DH *dh;
Jan F. Chadima 3fdf10
+	int min = -1, max = -1, nbits = -1;
Jan F. Chadima 3fdf10
+	BIGNUM *shared_secret = NULL;
Jan F. Chadima 3fdf10
+	BIGNUM *dh_client_pub = NULL;
Jan F. Chadima 3fdf10
+	int type = 0;
Jan F. Chadima 3fdf10
+	gss_OID oid;
Jan F. Chadima 3fdf10
+	char *mechs;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	/* Initialise GSSAPI */
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	/* If we're rekeying, privsep means that some of the private structures
Jan F. Chadima 3fdf10
+	 * in the GSSAPI code are no longer available. This kludges them back
Jan F. Chadima 3fdf10
+	 * into life
Jan F. Chadima 3fdf10
+	 */
Jan F. Chadima 3fdf10
+	if (!ssh_gssapi_oid_table_ok()) 
Jan F. Chadima 3fdf10
+		if ((mechs = ssh_gssapi_server_mechanisms()))
Jan F. Chadima 3fdf10
+			xfree(mechs);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	debug2("%s: Identifying %s", __func__, kex->name);
Jan F. Chadima 3fdf10
+	oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type);
Jan F. Chadima 3fdf10
+	if (oid == GSS_C_NO_OID)
Jan F. Chadima 3fdf10
+	   fatal("Unknown gssapi mechanism");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	debug2("%s: Acquiring credentials", __func__);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid))))
Jan F. Chadima 3fdf10
+		fatal("Unable to acquire credentials for the server");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	switch (kex->kex_type) {
Jan F. Chadima 3fdf10
+	case KEX_GSS_GRP1_SHA1:
Jan F. Chadima 3fdf10
+		dh = dh_new_group1();
Jan F. Chadima 3fdf10
+		break;
Jan F. Chadima 3fdf10
+	case KEX_GSS_GRP14_SHA1:
Jan F. Chadima 3fdf10
+		dh = dh_new_group14();
Jan F. Chadima 3fdf10
+		break;
Jan F. Chadima 3fdf10
+	case KEX_GSS_GEX_SHA1:
Jan F. Chadima 3fdf10
+		debug("Doing group exchange");
Jan F. Chadima 3fdf10
+		packet_read_expect(SSH2_MSG_KEXGSS_GROUPREQ);
Jan F. Chadima 3fdf10
+		min = packet_get_int();
Jan F. Chadima 3fdf10
+		nbits = packet_get_int();
Jan F. Chadima 3fdf10
+		max = packet_get_int();
Jan F. Chadima 3fdf10
+		min = MAX(DH_GRP_MIN, min);
Jan F. Chadima 3fdf10
+		max = MIN(DH_GRP_MAX, max);
Jan F. Chadima 3fdf10
+		packet_check_eom();
Jan F. Chadima 3fdf10
+		if (max < min || nbits < min || max < nbits)
Jan F. Chadima 3fdf10
+			fatal("GSS_GEX, bad parameters: %d !< %d !< %d",
Jan F. Chadima 3fdf10
+			    min, nbits, max);
Jan F. Chadima 3fdf10
+		dh = PRIVSEP(choose_dh(min, nbits, max));
Jan F. Chadima 3fdf10
+		if (dh == NULL)
Jan F. Chadima 3fdf10
+			packet_disconnect("Protocol error: no matching group found");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		packet_start(SSH2_MSG_KEXGSS_GROUP);
Jan F. Chadima 3fdf10
+		packet_put_bignum2(dh->p);
Jan F. Chadima 3fdf10
+		packet_put_bignum2(dh->g);
Jan F. Chadima 3fdf10
+		packet_send();
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		packet_write_wait();
Jan F. Chadima 3fdf10
+		break;
Jan F. Chadima 3fdf10
+	default:
Jan F. Chadima 3fdf10
+		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	dh_gen_key(dh, kex->we_need * 8);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	do {
Jan F. Chadima 3fdf10
+		debug("Wait SSH2_MSG_GSSAPI_INIT");
Jan F. Chadima 3fdf10
+		type = packet_read();
Jan F. Chadima 3fdf10
+		switch(type) {
Jan F. Chadima 3fdf10
+		case SSH2_MSG_KEXGSS_INIT:
Jan F. Chadima 3fdf10
+			if (dh_client_pub != NULL) 
Jan F. Chadima 3fdf10
+				fatal("Received KEXGSS_INIT after initialising");
Jan F. Chadima 3fdf10
+			recv_tok.value = packet_get_string(&slen);
Jan F. Chadima 3fdf10
+			recv_tok.length = slen; 
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+			if ((dh_client_pub = BN_new()) == NULL)
Jan F. Chadima 3fdf10
+				fatal("dh_client_pub == NULL");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+			packet_get_bignum2(dh_client_pub);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+			/* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */
Jan F. Chadima 3fdf10
+			break;
Jan F. Chadima 3fdf10
+		case SSH2_MSG_KEXGSS_CONTINUE:
Jan F. Chadima 3fdf10
+			recv_tok.value = packet_get_string(&slen);
Jan F. Chadima 3fdf10
+			recv_tok.length = slen; 
Jan F. Chadima 3fdf10
+			break;
Jan F. Chadima 3fdf10
+		default:
Jan F. Chadima 3fdf10
+			packet_disconnect(
Jan F. Chadima 3fdf10
+			    "Protocol error: didn't expect packet type %d",
Jan F. Chadima 3fdf10
+			    type);
Jan F. Chadima 3fdf10
+		}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok, 
Jan F. Chadima 3fdf10
+		    &send_tok, &ret_flags));
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		xfree(recv_tok.value);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		if (maj_status != GSS_S_COMPLETE && send_tok.length == 0)
Jan F. Chadima 3fdf10
+			fatal("Zero length token output when incomplete");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		if (dh_client_pub == NULL)
Jan F. Chadima 3fdf10
+			fatal("No client public key");
Jan F. Chadima 3fdf10
+		
Jan F. Chadima 3fdf10
+		if (maj_status & GSS_S_CONTINUE_NEEDED) {
Jan F. Chadima 3fdf10
+			debug("Sending GSSAPI_CONTINUE");
Jan F. Chadima 3fdf10
+			packet_start(SSH2_MSG_KEXGSS_CONTINUE);
Jan F. Chadima 3fdf10
+			packet_put_string(send_tok.value, send_tok.length);
Jan F. Chadima 3fdf10
+			packet_send();
Jan F. Chadima 3fdf10
+			gss_release_buffer(&min_status, &send_tok);
Jan F. Chadima 3fdf10
+		}
Jan F. Chadima 3fdf10
+	} while (maj_status & GSS_S_CONTINUE_NEEDED);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (GSS_ERROR(maj_status)) {
Jan F. Chadima 3fdf10
+		if (send_tok.length > 0) {
Jan F. Chadima 3fdf10
+			packet_start(SSH2_MSG_KEXGSS_CONTINUE);
Jan F. Chadima 3fdf10
+			packet_put_string(send_tok.value, send_tok.length);
Jan F. Chadima 3fdf10
+			packet_send();
Jan F. Chadima 3fdf10
+		}
Jan F. Chadima 3fdf10
+		fatal("accept_ctx died");
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (!(ret_flags & GSS_C_MUTUAL_FLAG))
Jan F. Chadima 3fdf10
+		fatal("Mutual Authentication flag wasn't set");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (!(ret_flags & GSS_C_INTEG_FLAG))
Jan F. Chadima 3fdf10
+		fatal("Integrity flag wasn't set");
Jan F. Chadima 3fdf10
+	
Jan F. Chadima 3fdf10
+	if (!dh_pub_is_valid(dh, dh_client_pub))
Jan F. Chadima 3fdf10
+		packet_disconnect("bad client public DH value");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	klen = DH_size(dh);
Jan F. Chadima 3fdf10
+	kbuf = xmalloc(klen); 
Jan F. Chadima 3fdf10
+	kout = DH_compute_key(kbuf, dh_client_pub, dh);
Jan F. Chadima 3fdf10
+	if (kout < 0)
Jan F. Chadima 3fdf10
+		fatal("DH_compute_key: failed");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	shared_secret = BN_new();
Jan F. Chadima 3fdf10
+	if (shared_secret == NULL)
Jan F. Chadima 3fdf10
+		fatal("kexgss_server: BN_new failed");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (BN_bin2bn(kbuf, kout, shared_secret) == NULL)
Jan F. Chadima 3fdf10
+		fatal("kexgss_server: BN_bin2bn failed");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	memset(kbuf, 0, klen);
Jan F. Chadima 3fdf10
+	xfree(kbuf);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	switch (kex->kex_type) {
Jan F. Chadima 3fdf10
+	case KEX_GSS_GRP1_SHA1:
Jan F. Chadima 3fdf10
+	case KEX_GSS_GRP14_SHA1:
Jan F. Chadima 3fdf10
+		kex_dh_hash(
Jan F. Chadima 3fdf10
+		    kex->client_version_string, kex->server_version_string,
Jan F. Chadima 3fdf10
+		    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
Jan F. Chadima 3fdf10
+		    buffer_ptr(&kex->my), buffer_len(&kex->my),
Jan F. Chadima 3fdf10
+		    NULL, 0, /* Change this if we start sending host keys */
Jan F. Chadima 3fdf10
+		    dh_client_pub, dh->pub_key, shared_secret,
Jan F. Chadima 3fdf10
+		    &hash, &hashlen
Jan F. Chadima 3fdf10
+		);
Jan F. Chadima 3fdf10
+		break;
Jan F. Chadima 3fdf10
+	case KEX_GSS_GEX_SHA1:
Jan F. Chadima 3fdf10
+		kexgex_hash(
Jan F. Chadima 3fdf10
+		    kex->evp_md,
Jan F. Chadima 3fdf10
+		    kex->client_version_string, kex->server_version_string,
Jan F. Chadima 3fdf10
+		    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
Jan F. Chadima 3fdf10
+		    buffer_ptr(&kex->my), buffer_len(&kex->my),
Jan F. Chadima 3fdf10
+		    NULL, 0,
Jan F. Chadima 3fdf10
+		    min, nbits, max,
Jan F. Chadima 3fdf10
+		    dh->p, dh->g,
Jan F. Chadima 3fdf10
+		    dh_client_pub,
Jan F. Chadima 3fdf10
+		    dh->pub_key,
Jan F. Chadima 3fdf10
+		    shared_secret,
Jan F. Chadima 3fdf10
+		    &hash, &hashlen
Jan F. Chadima 3fdf10
+		);
Jan F. Chadima 3fdf10
+		break;
Jan F. Chadima 3fdf10
+	default:
Jan F. Chadima 3fdf10
+		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	BN_clear_free(dh_client_pub);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (kex->session_id == NULL) {
Jan F. Chadima 3fdf10
+		kex->session_id_len = hashlen;
Jan F. Chadima 3fdf10
+		kex->session_id = xmalloc(kex->session_id_len);
Jan F. Chadima 3fdf10
+		memcpy(kex->session_id, hash, kex->session_id_len);
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	gssbuf.value = hash;
Jan F. Chadima 3fdf10
+	gssbuf.length = hashlen;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt,&gssbuf,&msg_tok))))
Jan F. Chadima 3fdf10
+		fatal("Couldn't get MIC");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	packet_start(SSH2_MSG_KEXGSS_COMPLETE);
Jan F. Chadima 3fdf10
+	packet_put_bignum2(dh->pub_key);
Jan F. Chadima 3fdf10
+	packet_put_string(msg_tok.value,msg_tok.length);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (send_tok.length != 0) {
Jan F. Chadima 3fdf10
+		packet_put_char(1); /* true */
Jan F. Chadima 3fdf10
+		packet_put_string(send_tok.value, send_tok.length);
Jan F. Chadima 3fdf10
+	} else {
Jan F. Chadima 3fdf10
+		packet_put_char(0); /* false */
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+	packet_send();
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	gss_release_buffer(&min_status, &send_tok);
Jan F. Chadima 3fdf10
+	gss_release_buffer(&min_status, &msg_tok);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (gss_kex_context == NULL)
Jan F. Chadima 3fdf10
+		gss_kex_context = ctxt;
Jan F. Chadima 3fdf10
+	else 
Jan F. Chadima 3fdf10
+		ssh_gssapi_delete_ctx(&ctxt);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	DH_free(dh);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	kex_derive_keys(kex, hash, hashlen, shared_secret);
Jan F. Chadima 3fdf10
+	BN_clear_free(shared_secret);
Jan F. Chadima 3fdf10
+	kex_finish(kex);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	/* If this was a rekey, then save out any delegated credentials we
Jan F. Chadima 3fdf10
+	 * just exchanged.  */
Jan F. Chadima 3fdf10
+	if (options.gss_store_rekey)
Jan F. Chadima 3fdf10
+		ssh_gssapi_rekey_creds();
Jan F. Chadima 3fdf10
+}
Jan F. Chadima 3fdf10
+#endif /* GSSAPI */
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/kex.h.gsskex openssh-5.6p1/kex.h
Jan F. Chadima 1b8a26
--- openssh-5.6p1/kex.h.gsskex	2010-02-26 21:55:05.000000000 +0100
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/kex.h	2010-08-23 12:51:58.000000000 +0200
Jan F. Chadima 3fdf10
@@ -67,6 +67,9 @@ enum kex_exchange {
Jan F. Chadima 3fdf10
 	KEX_DH_GRP14_SHA1,
Jan F. Chadima 3fdf10
 	KEX_DH_GEX_SHA1,
Jan F. Chadima 3fdf10
 	KEX_DH_GEX_SHA256,
Jan F. Chadima 3fdf10
+	KEX_GSS_GRP1_SHA1,
Jan F. Chadima 3fdf10
+	KEX_GSS_GRP14_SHA1,
Jan F. Chadima 3fdf10
+	KEX_GSS_GEX_SHA1,
Jan F. Chadima 3fdf10
 	KEX_MAX
Jan F. Chadima 3fdf10
 };
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
@@ -123,6 +126,12 @@ struct Kex {
Jan F. Chadima 3fdf10
 	sig_atomic_t done;
Jan F. Chadima 3fdf10
 	int	flags;
Jan F. Chadima 3fdf10
 	const EVP_MD *evp_md;
Jan F. Chadima 3fdf10
+#ifdef GSSAPI
Jan F. Chadima 3fdf10
+	int	gss_deleg_creds;
Jan F. Chadima 3fdf10
+	int	gss_trust_dns;
Jan F. Chadima 3fdf10
+	char    *gss_host;
Jan F. Chadima 3fdf10
+	char	*gss_client;
Jan F. Chadima 3fdf10
+#endif
Jan F. Chadima 3fdf10
 	char	*client_version_string;
Jan F. Chadima 3fdf10
 	char	*server_version_string;
Jan F. Chadima 3fdf10
 	int	(*verify_host_key)(Key *);
Jan F. Chadima 3fdf10
@@ -146,6 +155,11 @@ void	 kexdh_server(Kex *);
Jan F. Chadima 3fdf10
 void	 kexgex_client(Kex *);
Jan F. Chadima 3fdf10
 void	 kexgex_server(Kex *);
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+#ifdef GSSAPI
Jan F. Chadima 3fdf10
+void	kexgss_client(Kex *);
Jan F. Chadima 3fdf10
+void	kexgss_server(Kex *);
Jan F. Chadima 3fdf10
+#endif
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 void
Jan F. Chadima 3fdf10
 kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int,
Jan F. Chadima 3fdf10
     BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *);
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/key.c.gsskex openssh-5.6p1/key.c
Jan F. Chadima 1b8a26
--- openssh-5.6p1/key.c.gsskex	2010-07-16 05:58:37.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/key.c	2010-08-23 12:56:03.000000000 +0200
Jan F. Chadima 1b8a26
@@ -1020,6 +1020,8 @@ key_type_from_name(char *name)
Jan F. Chadima 3fdf10
 		return KEY_RSA_CERT;
Jan F. Chadima 1b8a26
 	} else if (strcmp(name, "ssh-dss-cert-v01@openssh.com") == 0) {
Jan F. Chadima 3fdf10
 		return KEY_DSA_CERT;
Jan F. Chadima 3fdf10
+	} else if (strcmp(name, "null") == 0) {
Jan F. Chadima 3fdf10
+		return KEY_NULL;
Jan F. Chadima 3fdf10
 	}
Jan F. Chadima 3fdf10
 	debug2("key_type_from_name: unknown key type '%s'", name);
Jan F. Chadima 3fdf10
 	return KEY_UNSPEC;
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/key.h.gsskex openssh-5.6p1/key.h
Jan F. Chadima 1b8a26
--- openssh-5.6p1/key.h.gsskex	2010-04-16 07:56:22.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/key.h	2010-08-23 12:56:32.000000000 +0200
Jan F. Chadima 1b8a26
@@ -39,6 +39,7 @@ enum types {
Jan F. Chadima 3fdf10
 	KEY_DSA_CERT,
Jan F. Chadima 1b8a26
 	KEY_RSA_CERT_V00,
Jan F. Chadima 1b8a26
 	KEY_DSA_CERT_V00,
Jan F. Chadima 3fdf10
+	KEY_NULL,
Jan F. Chadima 3fdf10
 	KEY_UNSPEC
Jan F. Chadima 3fdf10
 };
Jan F. Chadima 3fdf10
 enum fp_type {
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/Makefile.in.gsskex openssh-5.6p1/Makefile.in
Jan F. Chadima 1b8a26
--- openssh-5.6p1/Makefile.in.gsskex	2010-08-23 12:51:58.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/Makefile.in	2010-08-23 12:51:58.000000000 +0200
Jan F. Chadima 86b2d1
@@ -76,11 +76,11 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o b
Jan F. Chadima 3fdf10
 	monitor_fdpass.o rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o \
Jan F. Chadima 3fdf10
 	kexgex.o kexdhc.o kexgexc.o msg.o progressmeter.o dns.o \
Jan F. Chadima 3fdf10
 	entropy.o gss-genr.o umac.o jpake.o schnorr.o \
Jan F. Chadima 3fdf10
-	ssh-pkcs11.o
Jan F. Chadima 3fdf10
+	ssh-pkcs11.o kexgssc.o
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
Jan F. Chadima 3fdf10
 	sshconnect.o sshconnect1.o sshconnect2.o mux.o \
Jan F. Chadima 3fdf10
-	roaming_common.o roaming_client.o
Jan F. Chadima 3fdf10
+	roaming_common.o roaming_client.o kexgssc.o
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
Jan F. Chadima 3fdf10
 	sshpty.o sshlogin.o servconf.o serverloop.o \
Jan F. Chadima 86b2d1
@@ -93,7 +93,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw
Jan F. Chadima 3fdf10
 	auth2-gss.o gss-serv.o gss-serv-krb5.o \
Jan F. Chadima 3fdf10
 	loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
Jan F. Chadima 3fdf10
 	audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o \
Jan F. Chadima 3fdf10
-	roaming_common.o roaming_serv.o
Jan F. Chadima 3fdf10
+	roaming_common.o roaming_serv.o kexgsss.o
Jan F. Chadima 3fdf10
 
Jan F. Chadima 86b2d1
 MANPAGES	= moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out ssh-pkcs11-helper.8.out ssh-ldap-helper.8.out sshd_config.5.out ssh_config.5.out ssh-ldap.conf.5.out
Jan F. Chadima 86b2d1
 MANPAGES_IN	= moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 ssh-pkcs11-helper.8 ssh-ldap-helper.8 sshd_config.5 ssh_config.5 ssh-ldap.conf.5
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/monitor.c.gsskex openssh-5.6p1/monitor.c
Jan F. Chadima 1b8a26
--- openssh-5.6p1/monitor.c.gsskex	2010-08-23 12:51:56.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/monitor.c	2010-08-23 12:51:58.000000000 +0200
Jan F. Chadima 3fdf10
@@ -175,6 +175,8 @@ int mm_answer_gss_setup_ctx(int, Buffer 
Jan F. Chadima 3fdf10
 int mm_answer_gss_accept_ctx(int, Buffer *);
Jan F. Chadima 3fdf10
 int mm_answer_gss_userok(int, Buffer *);
Jan F. Chadima 3fdf10
 int mm_answer_gss_checkmic(int, Buffer *);
Jan F. Chadima 3fdf10
+int mm_answer_gss_sign(int, Buffer *);
Jan F. Chadima 3fdf10
+int mm_answer_gss_updatecreds(int, Buffer *);
Jan F. Chadima 3fdf10
 #endif
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 #ifdef SSH_AUDIT_EVENTS
Jan F. Chadima 3fdf10
@@ -247,6 +249,7 @@ struct mon_table mon_dispatch_proto20[] 
Jan F. Chadima 3fdf10
     {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx},
Jan F. Chadima 3fdf10
     {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
Jan F. Chadima 3fdf10
     {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic},
Jan F. Chadima 3fdf10
+    {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign},
Jan F. Chadima 3fdf10
 #endif
Jan F. Chadima 3fdf10
 #ifdef JPAKE
Jan F. Chadima 3fdf10
     {MONITOR_REQ_JPAKE_GET_PWDATA, MON_ONCE, mm_answer_jpake_get_pwdata},
Jan F. Chadima 3fdf10
@@ -259,6 +262,12 @@ struct mon_table mon_dispatch_proto20[] 
Jan F. Chadima 3fdf10
 };
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 struct mon_table mon_dispatch_postauth20[] = {
Jan F. Chadima 3fdf10
+#ifdef GSSAPI
Jan F. Chadima 3fdf10
+    {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx},
Jan F. Chadima 3fdf10
+    {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx},
Jan F. Chadima 3fdf10
+    {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign},
Jan F. Chadima 3fdf10
+    {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds},
Jan F. Chadima 3fdf10
+#endif
Jan F. Chadima 3fdf10
     {MONITOR_REQ_MODULI, 0, mm_answer_moduli},
Jan F. Chadima 3fdf10
     {MONITOR_REQ_SIGN, 0, mm_answer_sign},
Jan F. Chadima 3fdf10
     {MONITOR_REQ_PTY, 0, mm_answer_pty},
Jan F. Chadima 3fdf10
@@ -363,6 +372,10 @@ monitor_child_preauth(Authctxt *_authctx
Jan F. Chadima 3fdf10
 		/* Permit requests for moduli and signatures */
Jan F. Chadima 3fdf10
 		monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
Jan F. Chadima 3fdf10
 		monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
Jan F. Chadima 3fdf10
+#ifdef GSSAPI
Jan F. Chadima 3fdf10
+		/* and for the GSSAPI key exchange */
Jan F. Chadima 3fdf10
+		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
Jan F. Chadima 3fdf10
+#endif
Jan F. Chadima 3fdf10
 	} else {
Jan F. Chadima 3fdf10
 		mon_dispatch = mon_dispatch_proto15;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
@@ -449,6 +462,10 @@ monitor_child_postauth(struct monitor *p
Jan F. Chadima 3fdf10
 		monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
Jan F. Chadima 3fdf10
 		monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
Jan F. Chadima 3fdf10
 		monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
Jan F. Chadima 3fdf10
+#ifdef GSSAPI
Jan F. Chadima 3fdf10
+		/* and for the GSSAPI key exchange */
Jan F. Chadima 3fdf10
+		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
Jan F. Chadima 3fdf10
+#endif		
Jan F. Chadima 3fdf10
 	} else {
Jan F. Chadima 3fdf10
 		mon_dispatch = mon_dispatch_postauth15;
Jan F. Chadima 3fdf10
 		monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
Jan F. Chadima 86b2d1
@@ -1723,6 +1740,13 @@ mm_get_kex(Buffer *m)
Jan F. Chadima 3fdf10
 	kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
Jan F. Chadima 3fdf10
 	kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
Jan F. Chadima 3fdf10
 	kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
Jan F. Chadima 3fdf10
+#ifdef GSSAPI
Jan F. Chadima 3fdf10
+	if (options.gss_keyex) {
Jan F. Chadima 3fdf10
+		kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
Jan F. Chadima 3fdf10
+		kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
Jan F. Chadima 3fdf10
+		kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+#endif
Jan F. Chadima 3fdf10
 	kex->server = 1;
Jan F. Chadima 3fdf10
 	kex->hostkey_type = buffer_get_int(m);
Jan F. Chadima 3fdf10
 	kex->kex_type = buffer_get_int(m);
Jan F. Chadima 86b2d1
@@ -1929,6 +1953,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer
Jan F. Chadima 3fdf10
 	OM_uint32 major;
Jan F. Chadima 3fdf10
 	u_int len;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+	if (!options.gss_authentication && !options.gss_keyex)
Jan F. Chadima 3fdf10
+		fatal("In GSSAPI monitor when GSSAPI is disabled");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 	goid.elements = buffer_get_string(m, &len;;
Jan F. Chadima 3fdf10
 	goid.length = len;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 86b2d1
@@ -1956,6 +1983,9 @@ mm_answer_gss_accept_ctx(int sock, Buffe
Jan F. Chadima 3fdf10
 	OM_uint32 flags = 0; /* GSI needs this */
Jan F. Chadima 3fdf10
 	u_int len;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+	if (!options.gss_authentication && !options.gss_keyex)
Jan F. Chadima 3fdf10
+		fatal("In GSSAPI monitor when GSSAPI is disabled");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 	in.value = buffer_get_string(m, &len;;
Jan F. Chadima 3fdf10
 	in.length = len;
Jan F. Chadima 3fdf10
 	major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags);
Jan F. Chadima 86b2d1
@@ -1973,6 +2003,7 @@ mm_answer_gss_accept_ctx(int sock, Buffe
Jan F. Chadima 3fdf10
 		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
Jan F. Chadima 3fdf10
 		monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
Jan F. Chadima 3fdf10
 		monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
Jan F. Chadima 3fdf10
+		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1);
Jan F. Chadima 3fdf10
 	}
Jan F. Chadima 3fdf10
 	return (0);
Jan F. Chadima 3fdf10
 }
Jan F. Chadima 86b2d1
@@ -1984,6 +2015,9 @@ mm_answer_gss_checkmic(int sock, Buffer 
Jan F. Chadima 3fdf10
 	OM_uint32 ret;
Jan F. Chadima 3fdf10
 	u_int len;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+	if (!options.gss_authentication && !options.gss_keyex)
Jan F. Chadima 3fdf10
+		fatal("In GSSAPI monitor when GSSAPI is disabled");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 	gssbuf.value = buffer_get_string(m, &len;;
Jan F. Chadima 3fdf10
 	gssbuf.length = len;
Jan F. Chadima 3fdf10
 	mic.value = buffer_get_string(m, &len;;
Jan F. Chadima 86b2d1
@@ -2010,7 +2044,11 @@ mm_answer_gss_userok(int sock, Buffer *m
Jan F. Chadima 3fdf10
 {
Jan F. Chadima 3fdf10
 	int authenticated;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
-	authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user);
Jan F. Chadima 3fdf10
+	if (!options.gss_authentication && !options.gss_keyex)
Jan F. Chadima 3fdf10
+		fatal("In GSSAPI monitor when GSSAPI is disabled");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	authenticated = authctxt->valid && 
Jan F. Chadima 3fdf10
+	    ssh_gssapi_userok(authctxt->user, authctxt->pw);
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 	buffer_clear(m);
Jan F. Chadima 3fdf10
 	buffer_put_int(m, authenticated);
Jan F. Chadima 86b2d1
@@ -2023,6 +2061,74 @@ mm_answer_gss_userok(int sock, Buffer *m
Jan F. Chadima 3fdf10
 	/* Monitor loop will terminate if authenticated */
Jan F. Chadima 3fdf10
 	return (authenticated);
Jan F. Chadima 3fdf10
 }
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+int 
Jan F. Chadima 3fdf10
+mm_answer_gss_sign(int socket, Buffer *m)
Jan F. Chadima 3fdf10
+{
Jan F. Chadima 3fdf10
+	gss_buffer_desc data;
Jan F. Chadima 3fdf10
+	gss_buffer_desc hash = GSS_C_EMPTY_BUFFER;
Jan F. Chadima 3fdf10
+	OM_uint32 major, minor;
Jan F. Chadima 3fdf10
+	u_int len;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (!options.gss_authentication && !options.gss_keyex)
Jan F. Chadima 3fdf10
+		fatal("In GSSAPI monitor when GSSAPI is disabled");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	data.value = buffer_get_string(m, &len;;
Jan F. Chadima 3fdf10
+	data.length = len;
Jan F. Chadima 3fdf10
+	if (data.length != 20) 
Jan F. Chadima 3fdf10
+		fatal("%s: data length incorrect: %d", __func__, 
Jan F. Chadima 3fdf10
+		    (int) data.length);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	/* Save the session ID on the first time around */
Jan F. Chadima 3fdf10
+	if (session_id2_len == 0) {
Jan F. Chadima 3fdf10
+		session_id2_len = data.length;
Jan F. Chadima 3fdf10
+		session_id2 = xmalloc(session_id2_len);
Jan F. Chadima 3fdf10
+		memcpy(session_id2, data.value, session_id2_len);
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+	major = ssh_gssapi_sign(gsscontext, &data, &hash);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	xfree(data.value);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	buffer_clear(m);
Jan F. Chadima 3fdf10
+	buffer_put_int(m, major);
Jan F. Chadima 3fdf10
+	buffer_put_string(m, hash.value, hash.length);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	mm_request_send(socket, MONITOR_ANS_GSSSIGN, m);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	gss_release_buffer(&minor, &hash);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	/* Turn on getpwnam permissions */
Jan F. Chadima 3fdf10
+	monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
Jan F. Chadima 3fdf10
+	
Jan F. Chadima 3fdf10
+	/* And credential updating, for when rekeying */
Jan F. Chadima 3fdf10
+	monitor_permit(mon_dispatch, MONITOR_REQ_GSSUPCREDS, 1);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	return (0);
Jan F. Chadima 3fdf10
+}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+int
Jan F. Chadima 3fdf10
+mm_answer_gss_updatecreds(int socket, Buffer *m) {
Jan F. Chadima 3fdf10
+	ssh_gssapi_ccache store;
Jan F. Chadima 3fdf10
+	int ok;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	store.filename = buffer_get_string(m, NULL);
Jan F. Chadima 3fdf10
+	store.envvar   = buffer_get_string(m, NULL);
Jan F. Chadima 3fdf10
+	store.envval   = buffer_get_string(m, NULL);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	ok = ssh_gssapi_update_creds(&store);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	xfree(store.filename);
Jan F. Chadima 3fdf10
+	xfree(store.envvar);
Jan F. Chadima 3fdf10
+	xfree(store.envval);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	buffer_clear(m);
Jan F. Chadima 3fdf10
+	buffer_put_int(m, ok);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	return(0);
Jan F. Chadima 3fdf10
+}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 #endif /* GSSAPI */
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 #ifdef JPAKE
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/monitor.h.gsskex openssh-5.6p1/monitor.h
Jan F. Chadima 1b8a26
--- openssh-5.6p1/monitor.h.gsskex	2010-08-23 12:51:56.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/monitor.h	2010-08-23 12:51:58.000000000 +0200
Jan F. Chadima 3fdf10
@@ -56,6 +56,8 @@ enum monitor_reqtype {
Jan F. Chadima 3fdf10
 	MONITOR_REQ_GSSSTEP, MONITOR_ANS_GSSSTEP,
Jan F. Chadima 3fdf10
 	MONITOR_REQ_GSSUSEROK, MONITOR_ANS_GSSUSEROK,
Jan F. Chadima 3fdf10
 	MONITOR_REQ_GSSCHECKMIC, MONITOR_ANS_GSSCHECKMIC,
Jan F. Chadima 3fdf10
+	MONITOR_REQ_GSSSIGN, MONITOR_ANS_GSSSIGN,
Jan F. Chadima 3fdf10
+	MONITOR_REQ_GSSUPCREDS, MONITOR_ANS_GSSUPCREDS,
Jan F. Chadima 3fdf10
 	MONITOR_REQ_PAM_START,
Jan F. Chadima 3fdf10
 	MONITOR_REQ_PAM_ACCOUNT, MONITOR_ANS_PAM_ACCOUNT,
Jan F. Chadima 3fdf10
 	MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX,
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/monitor_wrap.c.gsskex openssh-5.6p1/monitor_wrap.c
Jan F. Chadima 1b8a26
--- openssh-5.6p1/monitor_wrap.c.gsskex	2010-08-23 12:51:56.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/monitor_wrap.c	2010-08-23 12:51:58.000000000 +0200
Jan F. Chadima 86b2d1
@@ -1250,7 +1250,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss
Jan F. Chadima 3fdf10
 }
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 int
Jan F. Chadima 3fdf10
-mm_ssh_gssapi_userok(char *user)
Jan F. Chadima 3fdf10
+mm_ssh_gssapi_userok(char *user, struct passwd *pw)
Jan F. Chadima 3fdf10
 {
Jan F. Chadima 3fdf10
 	Buffer m;
Jan F. Chadima 3fdf10
 	int authenticated = 0;
Jan F. Chadima 86b2d1
@@ -1267,6 +1267,51 @@ mm_ssh_gssapi_userok(char *user)
Jan F. Chadima 3fdf10
 	debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not ");
Jan F. Chadima 3fdf10
 	return (authenticated);
Jan F. Chadima 3fdf10
 }
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+OM_uint32
Jan F. Chadima 3fdf10
+mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash)
Jan F. Chadima 3fdf10
+{
Jan F. Chadima 3fdf10
+	Buffer m;
Jan F. Chadima 3fdf10
+	OM_uint32 major;
Jan F. Chadima 3fdf10
+	u_int len;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	buffer_init(&m);
Jan F. Chadima 3fdf10
+	buffer_put_string(&m, data->value, data->length);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSIGN, &m);
Jan F. Chadima 3fdf10
+	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSIGN, &m);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	major = buffer_get_int(&m);
Jan F. Chadima 3fdf10
+	hash->value = buffer_get_string(&m, &len;;
Jan F. Chadima 3fdf10
+	hash->length = len;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	buffer_free(&m);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	return(major);
Jan F. Chadima 3fdf10
+}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+int
Jan F. Chadima 3fdf10
+mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *store)
Jan F. Chadima 3fdf10
+{
Jan F. Chadima 3fdf10
+	Buffer m;
Jan F. Chadima 3fdf10
+	int ok;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	buffer_init(&m);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	buffer_put_cstring(&m, store->filename ? store->filename : "");
Jan F. Chadima 3fdf10
+	buffer_put_cstring(&m, store->envvar ? store->envvar : "");
Jan F. Chadima 3fdf10
+	buffer_put_cstring(&m, store->envval ? store->envval : "");
Jan F. Chadima 3fdf10
+	
Jan F. Chadima 3fdf10
+	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUPCREDS, &m);
Jan F. Chadima 3fdf10
+	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUPCREDS, &m);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	ok = buffer_get_int(&m);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	buffer_free(&m);
Jan F. Chadima 3fdf10
+	
Jan F. Chadima 3fdf10
+	return (ok);
Jan F. Chadima 3fdf10
+}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 #endif /* GSSAPI */
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 #ifdef JPAKE
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/monitor_wrap.h.gsskex openssh-5.6p1/monitor_wrap.h
Jan F. Chadima 1b8a26
--- openssh-5.6p1/monitor_wrap.h.gsskex	2010-08-23 12:51:56.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/monitor_wrap.h	2010-08-23 12:51:58.000000000 +0200
Jan F. Chadima 3fdf10
@@ -60,8 +60,10 @@ BIGNUM *mm_auth_rsa_generate_challenge(K
Jan F. Chadima 3fdf10
 OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
Jan F. Chadima 3fdf10
 OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *,
Jan F. Chadima 3fdf10
    gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *);
Jan F. Chadima 3fdf10
-int mm_ssh_gssapi_userok(char *user);
Jan F. Chadima 3fdf10
+int mm_ssh_gssapi_userok(char *user, struct passwd *);
Jan F. Chadima 3fdf10
 OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
Jan F. Chadima 3fdf10
+OM_uint32 mm_ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t);
Jan F. Chadima 3fdf10
+int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *);
Jan F. Chadima 3fdf10
 #endif
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 #ifdef USE_PAM
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/readconf.c.gsskex openssh-5.6p1/readconf.c
Jan F. Chadima 1b8a26
--- openssh-5.6p1/readconf.c.gsskex	2010-08-03 08:04:46.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/readconf.c	2010-08-23 12:57:26.000000000 +0200
Jan F. Chadima 3fdf10
@@ -127,6 +127,7 @@ typedef enum {
Jan F. Chadima 3fdf10
 	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
Jan F. Chadima 3fdf10
 	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
Jan F. Chadima 3fdf10
 	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
Jan F. Chadima 3fdf10
+	oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey,
Jan F. Chadima 3fdf10
 	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
Jan F. Chadima 1b8a26
 	oSendEnv, oControlPath, oControlMaster, oControlPersist,
Jan F. Chadima 1b8a26
 	oHashKnownHosts,
Jan F. Chadima 1b8a26
@@ -166,10 +167,18 @@ static struct {
Jan F. Chadima 3fdf10
 	{ "afstokenpassing", oUnsupported },
Jan F. Chadima 3fdf10
 #if defined(GSSAPI)
Jan F. Chadima 3fdf10
 	{ "gssapiauthentication", oGssAuthentication },
Jan F. Chadima 3fdf10
+	{ "gssapikeyexchange", oGssKeyEx },
Jan F. Chadima 3fdf10
 	{ "gssapidelegatecredentials", oGssDelegateCreds },
Jan F. Chadima 3fdf10
+	{ "gssapitrustdns", oGssTrustDns },
Jan F. Chadima 3fdf10
+	{ "gssapiclientidentity", oGssClientIdentity },
Jan F. Chadima 3fdf10
+	{ "gssapirenewalforcesrekey", oGssRenewalRekey },
Jan F. Chadima 3fdf10
 #else
Jan F. Chadima 3fdf10
 	{ "gssapiauthentication", oUnsupported },
Jan F. Chadima 3fdf10
+	{ "gssapikeyexchange", oUnsupported },
Jan F. Chadima 3fdf10
 	{ "gssapidelegatecredentials", oUnsupported },
Jan F. Chadima 3fdf10
+	{ "gssapitrustdns", oUnsupported },
Jan F. Chadima 3fdf10
+	{ "gssapiclientidentity", oUnsupported },
Jan F. Chadima 3fdf10
+	{ "gssapirenewalforcesrekey", oUnsupported },
Jan F. Chadima 3fdf10
 #endif
Jan F. Chadima 3fdf10
 	{ "fallbacktorsh", oDeprecated },
Jan F. Chadima 3fdf10
 	{ "usersh", oDeprecated },
Jan F. Chadima 1b8a26
@@ -474,10 +483,26 @@ parse_flag:
Jan F. Chadima 3fdf10
 		intptr = &options->gss_authentication;
Jan F. Chadima 3fdf10
 		goto parse_flag;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+	case oGssKeyEx:
Jan F. Chadima 3fdf10
+		intptr = &options->gss_keyex;
Jan F. Chadima 3fdf10
+		goto parse_flag;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 	case oGssDelegateCreds:
Jan F. Chadima 3fdf10
 		intptr = &options->gss_deleg_creds;
Jan F. Chadima 3fdf10
 		goto parse_flag;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+	case oGssTrustDns:
Jan F. Chadima 3fdf10
+		intptr = &options->gss_trust_dns;
Jan F. Chadima 3fdf10
+		goto parse_flag;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	case oGssClientIdentity:
Jan F. Chadima 3fdf10
+		charptr = &options->gss_client_identity;
Jan F. Chadima 3fdf10
+		goto parse_string;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	case oGssRenewalRekey:
Jan F. Chadima 3fdf10
+		intptr = &options->gss_renewal_rekey;
Jan F. Chadima 3fdf10
+		goto parse_flag;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 	case oBatchMode:
Jan F. Chadima 3fdf10
 		intptr = &options->batch_mode;
Jan F. Chadima 3fdf10
 		goto parse_flag;
Jan F. Chadima 1b8a26
@@ -1058,7 +1083,11 @@ initialize_options(Options * options)
Jan F. Chadima 3fdf10
 	options->pubkey_authentication = -1;
Jan F. Chadima 3fdf10
 	options->challenge_response_authentication = -1;
Jan F. Chadima 3fdf10
 	options->gss_authentication = -1;
Jan F. Chadima 3fdf10
+	options->gss_keyex = -1;
Jan F. Chadima 3fdf10
 	options->gss_deleg_creds = -1;
Jan F. Chadima 3fdf10
+	options->gss_trust_dns = -1;
Jan F. Chadima 3fdf10
+	options->gss_renewal_rekey = -1;
Jan F. Chadima 3fdf10
+	options->gss_client_identity = NULL;
Jan F. Chadima 3fdf10
 	options->password_authentication = -1;
Jan F. Chadima 3fdf10
 	options->kbd_interactive_authentication = -1;
Jan F. Chadima 3fdf10
 	options->kbd_interactive_devices = NULL;
Jan F. Chadima 1b8a26
@@ -1156,8 +1185,14 @@ fill_default_options(Options * options)
Jan F. Chadima 3fdf10
 		options->challenge_response_authentication = 1;
Jan F. Chadima 3fdf10
 	if (options->gss_authentication == -1)
Jan F. Chadima 3fdf10
 		options->gss_authentication = 0;
Jan F. Chadima 3fdf10
+	if (options->gss_keyex == -1)
Jan F. Chadima 3fdf10
+		options->gss_keyex = 0;
Jan F. Chadima 3fdf10
 	if (options->gss_deleg_creds == -1)
Jan F. Chadima 3fdf10
 		options->gss_deleg_creds = 0;
Jan F. Chadima 3fdf10
+	if (options->gss_trust_dns == -1)
Jan F. Chadima 3fdf10
+		options->gss_trust_dns = 0;
Jan F. Chadima 3fdf10
+	if (options->gss_renewal_rekey == -1)
Jan F. Chadima 3fdf10
+		options->gss_renewal_rekey = 0;
Jan F. Chadima 3fdf10
 	if (options->password_authentication == -1)
Jan F. Chadima 3fdf10
 		options->password_authentication = 1;
Jan F. Chadima 3fdf10
 	if (options->kbd_interactive_authentication == -1)
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/readconf.h.gsskex openssh-5.6p1/readconf.h
Jan F. Chadima 1b8a26
--- openssh-5.6p1/readconf.h.gsskex	2010-08-03 08:04:46.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/readconf.h	2010-08-23 12:51:59.000000000 +0200
Jan F. Chadima 1b8a26
@@ -46,7 +46,11 @@ typedef struct {
Jan F. Chadima 3fdf10
 	int     challenge_response_authentication;
Jan F. Chadima 3fdf10
 					/* Try S/Key or TIS, authentication. */
Jan F. Chadima 3fdf10
 	int     gss_authentication;	/* Try GSS authentication */
Jan F. Chadima 3fdf10
+	int     gss_keyex;		/* Try GSS key exchange */
Jan F. Chadima 3fdf10
 	int     gss_deleg_creds;	/* Delegate GSS credentials */
Jan F. Chadima 3fdf10
+	int	gss_trust_dns;		/* Trust DNS for GSS canonicalization */
Jan F. Chadima 3fdf10
+	int	gss_renewal_rekey;	/* Credential renewal forces rekey */
Jan F. Chadima 3fdf10
+	char    *gss_client_identity;   /* Principal to initiate GSSAPI with */
Jan F. Chadima 3fdf10
 	int     password_authentication;	/* Try password
Jan F. Chadima 3fdf10
 						 * authentication. */
Jan F. Chadima 3fdf10
 	int     kbd_interactive_authentication; /* Try keyboard-interactive auth. */
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/servconf.c.gsskex openssh-5.6p1/servconf.c
Jan F. Chadima 1b8a26
--- openssh-5.6p1/servconf.c.gsskex	2010-08-23 12:51:56.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/servconf.c	2010-08-23 12:51:59.000000000 +0200
Jan F. Chadima 3fdf10
@@ -93,7 +93,10 @@ initialize_server_options(ServerOptions 
Jan F. Chadima 3fdf10
 	options->kerberos_ticket_cleanup = -1;
Jan F. Chadima 3fdf10
 	options->kerberos_get_afs_token = -1;
Jan F. Chadima 3fdf10
 	options->gss_authentication=-1;
Jan F. Chadima 3fdf10
+	options->gss_keyex = -1;
Jan F. Chadima 3fdf10
 	options->gss_cleanup_creds = -1;
Jan F. Chadima 3fdf10
+	options->gss_strict_acceptor = -1;
Jan F. Chadima 3fdf10
+	options->gss_store_rekey = -1;
Jan F. Chadima 3fdf10
 	options->password_authentication = -1;
Jan F. Chadima 3fdf10
 	options->kbd_interactive_authentication = -1;
Jan F. Chadima 3fdf10
 	options->challenge_response_authentication = -1;
Jan F. Chadima 1b8a26
@@ -218,8 +221,14 @@ fill_default_server_options(ServerOption
Jan F. Chadima 3fdf10
 		options->kerberos_get_afs_token = 0;
Jan F. Chadima 3fdf10
 	if (options->gss_authentication == -1)
Jan F. Chadima 3fdf10
 		options->gss_authentication = 0;
Jan F. Chadima 3fdf10
+	if (options->gss_keyex == -1)
Jan F. Chadima 3fdf10
+		options->gss_keyex = 0;
Jan F. Chadima 3fdf10
 	if (options->gss_cleanup_creds == -1)
Jan F. Chadima 3fdf10
 		options->gss_cleanup_creds = 1;
Jan F. Chadima 3fdf10
+	if (options->gss_strict_acceptor == -1)
Jan F. Chadima 3fdf10
+		options->gss_strict_acceptor = 1;
Jan F. Chadima 3fdf10
+	if (options->gss_store_rekey == -1)
Jan F. Chadima 3fdf10
+		options->gss_store_rekey = 0;
Jan F. Chadima 3fdf10
 	if (options->password_authentication == -1)
Jan F. Chadima 3fdf10
 		options->password_authentication = 1;
Jan F. Chadima 3fdf10
 	if (options->kbd_interactive_authentication == -1)
Jan F. Chadima 1b8a26
@@ -313,7 +322,9 @@ typedef enum {
Jan F. Chadima 3fdf10
 	sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication,
Jan F. Chadima 3fdf10
 	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
Jan F. Chadima 3fdf10
 	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
Jan F. Chadima 3fdf10
-	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
Jan F. Chadima 3fdf10
+	sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
Jan F. Chadima 3fdf10
+	sGssKeyEx, sGssStoreRekey,
Jan F. Chadima 3fdf10
+	sAcceptEnv, sPermitTunnel,
Jan F. Chadima 3fdf10
 	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
Jan F. Chadima 3fdf10
 	sUsePrivilegeSeparation, sAllowAgentForwarding,
Jan F. Chadima 3fdf10
 	sZeroKnowledgePasswordAuthentication, sHostCertificate,
Jan F. Chadima 1b8a26
@@ -377,9 +388,15 @@ static struct {
Jan F. Chadima 3fdf10
 #ifdef GSSAPI
Jan F. Chadima 3fdf10
 	{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
Jan F. Chadima 3fdf10
 	{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
Jan F. Chadima 3fdf10
+	{ "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
Jan F. Chadima 3fdf10
+	{ "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
Jan F. Chadima 3fdf10
+	{ "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL },
Jan F. Chadima 3fdf10
 #else
Jan F. Chadima 3fdf10
 	{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
Jan F. Chadima 3fdf10
 	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
Jan F. Chadima 3fdf10
+	{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
Jan F. Chadima 3fdf10
+	{ "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
Jan F. Chadima 3fdf10
+	{ "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL },
Jan F. Chadima 3fdf10
 #endif
Jan F. Chadima 3fdf10
 	{ "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
Jan F. Chadima 3fdf10
 	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
Jan F. Chadima 1b8a26
@@ -941,10 +958,22 @@ process_server_config_line(ServerOptions
Jan F. Chadima 3fdf10
 		intptr = &options->gss_authentication;
Jan F. Chadima 3fdf10
 		goto parse_flag;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+	case sGssKeyEx:
Jan F. Chadima 3fdf10
+		intptr = &options->gss_keyex;
Jan F. Chadima 3fdf10
+		goto parse_flag;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 	case sGssCleanupCreds:
Jan F. Chadima 3fdf10
 		intptr = &options->gss_cleanup_creds;
Jan F. Chadima 3fdf10
 		goto parse_flag;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+	case sGssStrictAcceptor:
Jan F. Chadima 3fdf10
+		intptr = &options->gss_strict_acceptor;
Jan F. Chadima 3fdf10
+		goto parse_flag;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	case sGssStoreRekey:
Jan F. Chadima 3fdf10
+		intptr = &options->gss_store_rekey;
Jan F. Chadima 3fdf10
+		goto parse_flag;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 	case sPasswordAuthentication:
Jan F. Chadima 3fdf10
 		intptr = &options->password_authentication;
Jan F. Chadima 3fdf10
 		goto parse_flag;
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/servconf.h.gsskex openssh-5.6p1/servconf.h
Jan F. Chadima 1b8a26
--- openssh-5.6p1/servconf.h.gsskex	2010-08-23 12:51:56.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/servconf.h	2010-08-23 12:51:59.000000000 +0200
Jan F. Chadima 3fdf10
@@ -94,7 +94,10 @@ typedef struct {
Jan F. Chadima 3fdf10
 	int     kerberos_get_afs_token;		/* If true, try to get AFS token if
Jan F. Chadima 3fdf10
 						 * authenticated with Kerberos. */
Jan F. Chadima 3fdf10
 	int     gss_authentication;	/* If true, permit GSSAPI authentication */
Jan F. Chadima 3fdf10
+	int     gss_keyex;		/* If true, permit GSSAPI key exchange */
Jan F. Chadima 3fdf10
 	int     gss_cleanup_creds;	/* If true, destroy cred cache on logout */
Jan F. Chadima 3fdf10
+	int 	gss_strict_acceptor;	/* If true, restrict the GSSAPI acceptor name */
Jan F. Chadima 3fdf10
+	int 	gss_store_rekey;
Jan F. Chadima 3fdf10
 	int     password_authentication;	/* If true, permit password
Jan F. Chadima 3fdf10
 						 * authentication. */
Jan F. Chadima 3fdf10
 	int     kbd_interactive_authentication;	/* If true, permit */
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/ssh_config.5.gsskex openssh-5.6p1/ssh_config.5
Jan F. Chadima 1b8a26
--- openssh-5.6p1/ssh_config.5.gsskex	2010-08-05 05:03:13.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/ssh_config.5	2010-08-23 12:51:59.000000000 +0200
Jan F. Chadima 1b8a26
@@ -509,11 +509,38 @@ Specifies whether user authentication ba
Jan F. Chadima 3fdf10
 The default is
Jan F. Chadima 3fdf10
 .Dq no .
Jan F. Chadima 3fdf10
 Note that this option applies to protocol version 2 only.
Jan F. Chadima 3fdf10
+.It Cm GSSAPIKeyExchange
Jan F. Chadima 3fdf10
+Specifies whether key exchange based on GSSAPI may be used. When using
Jan F. Chadima 3fdf10
+GSSAPI key exchange the server need not have a host key.
Jan F. Chadima 3fdf10
+The default is
Jan F. Chadima 3fdf10
+.Dq no .
Jan F. Chadima 3fdf10
+Note that this option applies to protocol version 2 only.
Jan F. Chadima 3fdf10
+.It Cm GSSAPIClientIdentity
Jan F. Chadima 3fdf10
+If set, specifies the GSSAPI client identity that ssh should use when 
Jan F. Chadima 3fdf10
+connecting to the server. The default is unset, which means that the default 
Jan F. Chadima 3fdf10
+identity will be used.
Jan F. Chadima 3fdf10
 .It Cm GSSAPIDelegateCredentials
Jan F. Chadima 3fdf10
 Forward (delegate) credentials to the server.
Jan F. Chadima 3fdf10
 The default is
Jan F. Chadima 3fdf10
 .Dq no .
Jan F. Chadima 3fdf10
-Note that this option applies to protocol version 2 only.
Jan F. Chadima 3fdf10
+Note that this option applies to protocol version 2 connections using GSSAPI.
Jan F. Chadima 3fdf10
+.It Cm GSSAPIRenewalForcesRekey
Jan F. Chadima 3fdf10
+If set to 
Jan F. Chadima 3fdf10
+.Dq yes
Jan F. Chadima 3fdf10
+then renewal of the client's GSSAPI credentials will force the rekeying of the
Jan F. Chadima 3fdf10
+ssh connection. With a compatible server, this can delegate the renewed 
Jan F. Chadima 3fdf10
+credentials to a session on the server.
Jan F. Chadima 3fdf10
+The default is
Jan F. Chadima 3fdf10
+.Dq no .
Jan F. Chadima 3fdf10
+.It Cm GSSAPITrustDns
Jan F. Chadima 3fdf10
+Set to 
Jan F. Chadima 3fdf10
+.Dq yes to indicate that the DNS is trusted to securely canonicalize
Jan F. Chadima 3fdf10
+the name of the host being connected to. If 
Jan F. Chadima 3fdf10
+.Dq no, the hostname entered on the
Jan F. Chadima 3fdf10
+command line will be passed untouched to the GSSAPI library.
Jan F. Chadima 3fdf10
+The default is
Jan F. Chadima 3fdf10
+.Dq no .
Jan F. Chadima 3fdf10
+This option only applies to protocol version 2 connections using GSSAPI.
Jan F. Chadima 3fdf10
 .It Cm HashKnownHosts
Jan F. Chadima 3fdf10
 Indicates that
Jan F. Chadima 3fdf10
 .Xr ssh 1
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/ssh_config.gsskex openssh-5.6p1/ssh_config
Jan F. Chadima 1b8a26
--- openssh-5.6p1/ssh_config.gsskex	2010-08-23 12:51:55.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/ssh_config	2010-08-23 12:51:59.000000000 +0200
Jan F. Chadima 3fdf10
@@ -26,6 +26,8 @@
Jan F. Chadima 3fdf10
 #   HostbasedAuthentication no
Jan F. Chadima 3fdf10
 #   GSSAPIAuthentication no
Jan F. Chadima 3fdf10
 #   GSSAPIDelegateCredentials no
Jan F. Chadima 3fdf10
+#   GSSAPIKeyExchange no
Jan F. Chadima 3fdf10
+#   GSSAPITrustDNS no
Jan F. Chadima 3fdf10
 #   BatchMode no
Jan F. Chadima 3fdf10
 #   CheckHostIP yes
Jan F. Chadima 3fdf10
 #   AddressFamily any
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/sshconnect2.c.gsskex openssh-5.6p1/sshconnect2.c
Jan F. Chadima 1b8a26
--- openssh-5.6p1/sshconnect2.c.gsskex	2010-08-23 12:51:58.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/sshconnect2.c	2010-08-23 12:51:59.000000000 +0200
Jan F. Chadima 3fdf10
@@ -108,9 +108,34 @@ ssh_kex2(char *host, struct sockaddr *ho
Jan F. Chadima 3fdf10
 {
Jan F. Chadima 3fdf10
 	Kex *kex;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+#ifdef GSSAPI
Jan F. Chadima 3fdf10
+	char *orig = NULL, *gss = NULL;
Jan F. Chadima 3fdf10
+	char *gss_host = NULL;
Jan F. Chadima 3fdf10
+#endif
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 	xxx_host = host;
Jan F. Chadima 3fdf10
 	xxx_hostaddr = hostaddr;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+#ifdef GSSAPI
Jan F. Chadima 3fdf10
+	if (options.gss_keyex) {
Jan F. Chadima 3fdf10
+		/* Add the GSSAPI mechanisms currently supported on this 
Jan F. Chadima 3fdf10
+		 * client to the key exchange algorithm proposal */
Jan F. Chadima 3fdf10
+		orig = myproposal[PROPOSAL_KEX_ALGS];
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		if (options.gss_trust_dns)
Jan F. Chadima 3fdf10
+			gss_host = (char *)get_canonical_hostname(1);
Jan F. Chadima 3fdf10
+		else
Jan F. Chadima 3fdf10
+			gss_host = host;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		gss = ssh_gssapi_client_mechanisms(gss_host, options.gss_client_identity);
Jan F. Chadima 3fdf10
+		if (gss) {
Jan F. Chadima 3fdf10
+			debug("Offering GSSAPI proposal: %s", gss);
Jan F. Chadima 3fdf10
+			xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
Jan F. Chadima 3fdf10
+			    "%s,%s", gss, orig);
Jan F. Chadima 3fdf10
+		}
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+#endif
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 	if (options.ciphers == (char *)-1) {
Jan F. Chadima 3fdf10
 		logit("No valid ciphers for protocol version 2 given, using defaults.");
Jan F. Chadima 3fdf10
 		options.ciphers = NULL;
Jan F. Chadima 3fdf10
@@ -146,6 +171,17 @@ ssh_kex2(char *host, struct sockaddr *ho
Jan F. Chadima 3fdf10
 		myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
Jan F. Chadima 3fdf10
 		    options.hostkeyalgorithms;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+#ifdef GSSAPI
Jan F. Chadima 3fdf10
+	/* If we've got GSSAPI algorithms, then we also support the
Jan F. Chadima 3fdf10
+	 * 'null' hostkey, as a last resort */
Jan F. Chadima 3fdf10
+	if (options.gss_keyex && gss) {
Jan F. Chadima 3fdf10
+		orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
Jan F. Chadima 3fdf10
+		xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], 
Jan F. Chadima 3fdf10
+		    "%s,null", orig);
Jan F. Chadima 3fdf10
+		xfree(gss);
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+#endif
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 	if (options.rekey_limit)
Jan F. Chadima 3fdf10
 		packet_set_rekey_limit((u_int32_t)options.rekey_limit);
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
@@ -155,10 +191,26 @@ ssh_kex2(char *host, struct sockaddr *ho
Jan F. Chadima 3fdf10
 	kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
Jan F. Chadima 3fdf10
 	kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
Jan F. Chadima 3fdf10
 	kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
Jan F. Chadima 3fdf10
+#ifdef GSSAPI
Jan F. Chadima 3fdf10
+	if (options.gss_keyex) {
Jan F. Chadima 3fdf10
+		kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client;
Jan F. Chadima 3fdf10
+		kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_client;
Jan F. Chadima 3fdf10
+		kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client;
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+#endif
Jan F. Chadima 3fdf10
 	kex->client_version_string=client_version_string;
Jan F. Chadima 3fdf10
 	kex->server_version_string=server_version_string;
Jan F. Chadima 3fdf10
 	kex->verify_host_key=&verify_host_key_callback;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+#ifdef GSSAPI
Jan F. Chadima 3fdf10
+	if (options.gss_keyex) {
Jan F. Chadima 3fdf10
+		kex->gss_deleg_creds = options.gss_deleg_creds;
Jan F. Chadima 3fdf10
+		kex->gss_trust_dns = options.gss_trust_dns;
Jan F. Chadima 3fdf10
+		kex->gss_client = options.gss_client_identity;
Jan F. Chadima 3fdf10
+		kex->gss_host = gss_host;
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+#endif
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 	xxx_kex = kex;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 	dispatch_run(DISPATCH_BLOCK, &kex->done, kex);
Jan F. Chadima 3fdf10
@@ -253,6 +305,7 @@ void	input_gssapi_token(int type, u_int3
Jan F. Chadima 3fdf10
 void	input_gssapi_hash(int type, u_int32_t, void *);
Jan F. Chadima 3fdf10
 void	input_gssapi_error(int, u_int32_t, void *);
Jan F. Chadima 3fdf10
 void	input_gssapi_errtok(int, u_int32_t, void *);
Jan F. Chadima 3fdf10
+int	userauth_gsskeyex(Authctxt *authctxt);
Jan F. Chadima 3fdf10
 #endif
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 void	userauth(Authctxt *, char *);
Jan F. Chadima 3fdf10
@@ -268,6 +321,10 @@ static char *authmethods_get(void);
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 Authmethod authmethods[] = {
Jan F. Chadima 3fdf10
 #ifdef GSSAPI
Jan F. Chadima 3fdf10
+	{"gssapi-keyex",
Jan F. Chadima 3fdf10
+		userauth_gsskeyex,
Jan F. Chadima 3fdf10
+		&options.gss_authentication,
Jan F. Chadima 3fdf10
+		NULL},
Jan F. Chadima 3fdf10
 	{"gssapi-with-mic",
Jan F. Chadima 3fdf10
 		userauth_gssapi,
Jan F. Chadima 3fdf10
 		NULL,
Jan F. Chadima 3fdf10
@@ -576,23 +633,35 @@ userauth_gssapi(Authctxt *authctxt)
Jan F. Chadima 3fdf10
 	int ok = 0;
Jan F. Chadima 3fdf10
 	char* remotehost = NULL;
Jan F. Chadima 3fdf10
 	const char* canonicalhost = get_canonical_hostname(1);
Jan F. Chadima 3fdf10
+	const char *gss_host;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 	if ( strcmp( canonicalhost, "UNKNOWN" )  == 0 )
Jan F. Chadima 3fdf10
 		remotehost = authctxt->host;
Jan F. Chadima 3fdf10
 	else
Jan F. Chadima 3fdf10
 		remotehost = canonicalhost;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+	if (options.gss_trust_dns)
Jan F. Chadima 3fdf10
+//		gss_host = get_canonical_hostname(1);
Jan F. Chadima 3fdf10
+		gss_host = remotehost;
Jan F. Chadima 3fdf10
+	else
Jan F. Chadima 3fdf10
+		gss_host = authctxt->host;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 	/* Try one GSSAPI method at a time, rather than sending them all at
Jan F. Chadima 3fdf10
 	 * once. */
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 	if (gss_supported == NULL)
Jan F. Chadima 3fdf10
-		gss_indicate_mechs(&min, &gss_supported);
Jan F. Chadima 3fdf10
+		if (GSS_ERROR(gss_indicate_mechs(&min, &gss_supported))) {
Jan F. Chadima 3fdf10
+			gss_supported = NULL;
Jan F. Chadima 3fdf10
+			return 0;
Jan F. Chadima 3fdf10
+		}
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 	/* Check to see if the mechanism is usable before we offer it */
Jan F. Chadima 3fdf10
 	while (mech < gss_supported->count && !ok) {
Jan F. Chadima 3fdf10
 		/* My DER encoding requires length<128 */
Jan F. Chadima 3fdf10
 		if (gss_supported->elements[mech].length < 128 &&
Jan F. Chadima 3fdf10
 		    ssh_gssapi_check_mechanism(&gssctxt, 
Jan F. Chadima 3fdf10
-		    &gss_supported->elements[mech], remotehost)) {
Jan F. Chadima 3fdf10
+		    &gss_supported->elements[mech], gss_host, 
Jan F. Chadima 3fdf10
+		    options.gss_client_identity)) {
Jan F. Chadima 3fdf10
 			ok = 1; /* Mechanism works */
Jan F. Chadima 3fdf10
 		} else {
Jan F. Chadima 3fdf10
 			mech++;
Jan F. Chadima 3fdf10
@@ -689,8 +758,8 @@ input_gssapi_response(int type, u_int32_
Jan F. Chadima 3fdf10
 {
Jan F. Chadima 3fdf10
 	Authctxt *authctxt = ctxt;
Jan F. Chadima 3fdf10
 	Gssctxt *gssctxt;
Jan F. Chadima 3fdf10
-	int oidlen;
Jan F. Chadima 3fdf10
-	char *oidv;
Jan F. Chadima 3fdf10
+	u_int oidlen;
Jan F. Chadima 3fdf10
+	u_char *oidv;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 	if (authctxt == NULL)
Jan F. Chadima 3fdf10
 		fatal("input_gssapi_response: no authentication context");
Jan F. Chadima 3fdf10
@@ -800,6 +869,48 @@ input_gssapi_error(int type, u_int32_t p
Jan F. Chadima 3fdf10
 	xfree(msg);
Jan F. Chadima 3fdf10
 	xfree(lang);
Jan F. Chadima 3fdf10
 }
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+int
Jan F. Chadima 3fdf10
+userauth_gsskeyex(Authctxt *authctxt)
Jan F. Chadima 3fdf10
+{
Jan F. Chadima 3fdf10
+	Buffer b;
Jan F. Chadima 3fdf10
+	gss_buffer_desc gssbuf;
Jan F. Chadima 3fdf10
+	gss_buffer_desc mic = GSS_C_EMPTY_BUFFER;
Jan F. Chadima 3fdf10
+	OM_uint32 ms;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	static int attempt = 0;
Jan F. Chadima 3fdf10
+	if (attempt++ >= 1)
Jan F. Chadima 3fdf10
+		return (0);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (gss_kex_context == NULL) {
Jan F. Chadima 3fdf10
+		debug("No valid Key exchange context"); 
Jan F. Chadima 3fdf10
+		return (0);
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	ssh_gssapi_buildmic(&b, authctxt->server_user, authctxt->service,
Jan F. Chadima 3fdf10
+	    "gssapi-keyex");
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	gssbuf.value = buffer_ptr(&b);
Jan F. Chadima 3fdf10
+	gssbuf.length = buffer_len(&b);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) {
Jan F. Chadima 3fdf10
+		buffer_free(&b);
Jan F. Chadima 3fdf10
+		return (0);
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	packet_start(SSH2_MSG_USERAUTH_REQUEST);
Jan F. Chadima 3fdf10
+	packet_put_cstring(authctxt->server_user);
Jan F. Chadima 3fdf10
+	packet_put_cstring(authctxt->service);
Jan F. Chadima 3fdf10
+	packet_put_cstring(authctxt->method->name);
Jan F. Chadima 3fdf10
+	packet_put_string(mic.value, mic.length);
Jan F. Chadima 3fdf10
+	packet_send();
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	buffer_free(&b);
Jan F. Chadima 3fdf10
+	gss_release_buffer(&ms, &mic);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	return (1);
Jan F. Chadima 3fdf10
+}
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 #endif /* GSSAPI */
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 int
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/sshd.c.gsskex openssh-5.6p1/sshd.c
Jan F. Chadima 1b8a26
--- openssh-5.6p1/sshd.c.gsskex	2010-08-23 12:51:58.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/sshd.c	2010-08-23 12:51:59.000000000 +0200
Jan F. Chadima 3fdf10
@@ -129,6 +129,10 @@ int allow_severity;
Jan F. Chadima 3fdf10
 int deny_severity;
Jan F. Chadima 3fdf10
 #endif /* LIBWRAP */
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+#ifdef USE_SECURITY_SESSION_API
Jan F. Chadima 3fdf10
+#include <Security/AuthSession.h>
Jan F. Chadima 3fdf10
+#endif
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 #ifndef O_NOCTTY
Jan F. Chadima 3fdf10
 #define O_NOCTTY	0
Jan F. Chadima 3fdf10
 #endif
Jan F. Chadima 1b8a26
@@ -1601,10 +1605,13 @@ main(int ac, char **av)
Jan F. Chadima 3fdf10
 		logit("Disabling protocol version 1. Could not load host key");
Jan F. Chadima 3fdf10
 		options.protocol &= ~SSH_PROTO_1;
Jan F. Chadima 3fdf10
 	}
Jan F. Chadima 3fdf10
+#ifndef GSSAPI
Jan F. Chadima 3fdf10
+	/* The GSSAPI key exchange can run without a host key */
Jan F. Chadima 3fdf10
 	if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) {
Jan F. Chadima 3fdf10
 		logit("Disabling protocol version 2. Could not load host key");
Jan F. Chadima 3fdf10
 		options.protocol &= ~SSH_PROTO_2;
Jan F. Chadima 3fdf10
 	}
Jan F. Chadima 3fdf10
+#endif
Jan F. Chadima 3fdf10
 	if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) {
Jan F. Chadima 3fdf10
 		logit("sshd: no hostkeys available -- exiting.");
Jan F. Chadima 3fdf10
 		exit(1);
Jan F. Chadima 1b8a26
@@ -1937,6 +1944,60 @@ main(int ac, char **av)
Jan F. Chadima 3fdf10
 	/* Log the connection. */
Jan F. Chadima 3fdf10
 	verbose("Connection from %.500s port %d", remote_ip, remote_port);
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+#ifdef USE_SECURITY_SESSION_API
Jan F. Chadima 3fdf10
+	/*
Jan F. Chadima 3fdf10
+	 * Create a new security session for use by the new user login if
Jan F. Chadima 3fdf10
+	 * the current session is the root session or we are not launched
Jan F. Chadima 3fdf10
+	 * by inetd (eg: debugging mode or server mode).  We do not
Jan F. Chadima 3fdf10
+	 * necessarily need to create a session if we are launched from
Jan F. Chadima 3fdf10
+	 * inetd because Panther xinetd will create a session for us.
Jan F. Chadima 3fdf10
+	 *
Jan F. Chadima 3fdf10
+	 * The only case where this logic will fail is if there is an
Jan F. Chadima 3fdf10
+	 * inetd running in a non-root session which is not creating
Jan F. Chadima 3fdf10
+	 * new sessions for us.  Then all the users will end up in the
Jan F. Chadima 3fdf10
+	 * same session (bad).
Jan F. Chadima 3fdf10
+	 *
Jan F. Chadima 3fdf10
+	 * When the client exits, the session will be destroyed for us
Jan F. Chadima 3fdf10
+	 * automatically.
Jan F. Chadima 3fdf10
+	 *
Jan F. Chadima 3fdf10
+	 * We must create the session before any credentials are stored
Jan F. Chadima 3fdf10
+	 * (including AFS pags, which happens a few lines below).
Jan F. Chadima 3fdf10
+	 */
Jan F. Chadima 3fdf10
+	{
Jan F. Chadima 3fdf10
+		OSStatus err = 0;
Jan F. Chadima 3fdf10
+		SecuritySessionId sid = 0;
Jan F. Chadima 3fdf10
+		SessionAttributeBits sattrs = 0;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		err = SessionGetInfo(callerSecuritySession, &sid, &sattrs);
Jan F. Chadima 3fdf10
+		if (err)
Jan F. Chadima 3fdf10
+			error("SessionGetInfo() failed with error %.8X",
Jan F. Chadima 3fdf10
+			    (unsigned) err);
Jan F. Chadima 3fdf10
+		else
Jan F. Chadima 3fdf10
+			debug("Current Session ID is %.8X / Session Attributes are %.8X",
Jan F. Chadima 3fdf10
+			    (unsigned) sid, (unsigned) sattrs);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+		if (inetd_flag && !(sattrs & sessionIsRoot))
Jan F. Chadima 3fdf10
+			debug("Running in inetd mode in a non-root session... "
Jan F. Chadima 3fdf10
+			    "assuming inetd created the session for us.");
Jan F. Chadima 3fdf10
+		else {
Jan F. Chadima 3fdf10
+			debug("Creating new security session...");
Jan F. Chadima 3fdf10
+			err = SessionCreate(0, sessionHasTTY | sessionIsRemote);
Jan F. Chadima 3fdf10
+			if (err)
Jan F. Chadima 3fdf10
+				error("SessionCreate() failed with error %.8X",
Jan F. Chadima 3fdf10
+				    (unsigned) err);
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+			err = SessionGetInfo(callerSecuritySession, &sid, 
Jan F. Chadima 3fdf10
+			    &sattrs);
Jan F. Chadima 3fdf10
+			if (err)
Jan F. Chadima 3fdf10
+				error("SessionGetInfo() failed with error %.8X",
Jan F. Chadima 3fdf10
+				    (unsigned) err);
Jan F. Chadima 3fdf10
+			else
Jan F. Chadima 3fdf10
+				debug("New Session ID is %.8X / Session Attributes are %.8X",
Jan F. Chadima 3fdf10
+				    (unsigned) sid, (unsigned) sattrs);
Jan F. Chadima 3fdf10
+		}
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+#endif
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 	/*
Jan F. Chadima 3fdf10
 	 * We don't want to listen forever unless the other side
Jan F. Chadima 3fdf10
 	 * successfully authenticates itself.  So we set up an alarm which is
Jan F. Chadima 1b8a26
@@ -2324,12 +2385,61 @@ do_ssh2_kex(void)
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 	myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types();
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+#ifdef GSSAPI
Jan F. Chadima 3fdf10
+	{
Jan F. Chadima 3fdf10
+	char *orig;
Jan F. Chadima 3fdf10
+	char *gss = NULL;
Jan F. Chadima 3fdf10
+	char *newstr = NULL;
Jan F. Chadima 3fdf10
+	orig = myproposal[PROPOSAL_KEX_ALGS];
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	/* 
Jan F. Chadima 3fdf10
+	 * If we don't have a host key, then there's no point advertising
Jan F. Chadima 3fdf10
+	 * the other key exchange algorithms
Jan F. Chadima 3fdf10
+	 */
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0)
Jan F. Chadima 3fdf10
+		orig = NULL;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (options.gss_keyex)
Jan F. Chadima 3fdf10
+		gss = ssh_gssapi_server_mechanisms();
Jan F. Chadima 3fdf10
+	else
Jan F. Chadima 3fdf10
+		gss = NULL;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (gss && orig)
Jan F. Chadima 3fdf10
+		xasprintf(&newstr, "%s,%s", gss, orig);
Jan F. Chadima 3fdf10
+	else if (gss)
Jan F. Chadima 3fdf10
+		newstr = gss;
Jan F. Chadima 3fdf10
+	else if (orig)
Jan F. Chadima 3fdf10
+		newstr = orig;
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	/* 
Jan F. Chadima 3fdf10
+	 * If we've got GSSAPI mechanisms, then we've got the 'null' host
Jan F. Chadima 3fdf10
+	 * key alg, but we can't tell people about it unless its the only
Jan F. Chadima 3fdf10
+  	 * host key algorithm we support
Jan F. Chadima 3fdf10
+	 */
Jan F. Chadima 3fdf10
+	if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0)
Jan F. Chadima 3fdf10
+		myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null";
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+	if (newstr)
Jan F. Chadima 3fdf10
+		myproposal[PROPOSAL_KEX_ALGS] = newstr;
Jan F. Chadima 3fdf10
+	else
Jan F. Chadima 3fdf10
+		fatal("No supported key exchange algorithms");
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+#endif
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 	/* start key exchange */
Jan F. Chadima 3fdf10
 	kex = kex_setup(myproposal);
Jan F. Chadima 3fdf10
 	kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
Jan F. Chadima 3fdf10
 	kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
Jan F. Chadima 3fdf10
 	kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
Jan F. Chadima 3fdf10
 	kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
Jan F. Chadima 3fdf10
+#ifdef GSSAPI
Jan F. Chadima 3fdf10
+	if (options.gss_keyex) {
Jan F. Chadima 3fdf10
+		kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
Jan F. Chadima 3fdf10
+		kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
Jan F. Chadima 3fdf10
+		kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
Jan F. Chadima 3fdf10
+	}
Jan F. Chadima 3fdf10
+#endif
Jan F. Chadima 3fdf10
 	kex->server = 1;
Jan F. Chadima 3fdf10
 	kex->client_version_string=client_version_string;
Jan F. Chadima 3fdf10
 	kex->server_version_string=server_version_string;
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/sshd_config.5.gsskex openssh-5.6p1/sshd_config.5
Jan F. Chadima 1b8a26
--- openssh-5.6p1/sshd_config.5.gsskex	2010-08-23 12:51:56.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/sshd_config.5	2010-08-23 12:51:59.000000000 +0200
Jan F. Chadima 1b8a26
@@ -424,12 +424,40 @@ Specifies whether user authentication ba
Jan F. Chadima 3fdf10
 The default is
Jan F. Chadima 3fdf10
 .Dq no .
Jan F. Chadima 3fdf10
 Note that this option applies to protocol version 2 only.
Jan F. Chadima 3fdf10
+.It Cm GSSAPIKeyExchange
Jan F. Chadima 3fdf10
+Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange
Jan F. Chadima 3fdf10
+doesn't rely on ssh keys to verify host identity.
Jan F. Chadima 3fdf10
+The default is
Jan F. Chadima 3fdf10
+.Dq no .
Jan F. Chadima 3fdf10
+Note that this option applies to protocol version 2 only.
Jan F. Chadima 3fdf10
 .It Cm GSSAPICleanupCredentials
Jan F. Chadima 3fdf10
 Specifies whether to automatically destroy the user's credentials cache
Jan F. Chadima 3fdf10
 on logout.
Jan F. Chadima 3fdf10
 The default is
Jan F. Chadima 3fdf10
 .Dq yes .
Jan F. Chadima 3fdf10
 Note that this option applies to protocol version 2 only.
Jan F. Chadima 3fdf10
+.It Cm GSSAPIStrictAcceptorCheck
Jan F. Chadima 3fdf10
+Determines whether to be strict about the identity of the GSSAPI acceptor 
Jan F. Chadima 3fdf10
+a client authenticates against. If
Jan F. Chadima 3fdf10
+.Dq yes
Jan F. Chadima 3fdf10
+then the client must authenticate against the
Jan F. Chadima 3fdf10
+.Pa host
Jan F. Chadima 3fdf10
+service on the current hostname. If 
Jan F. Chadima 3fdf10
+.Dq no
Jan F. Chadima 3fdf10
+then the client may authenticate against any service key stored in the 
Jan F. Chadima 3fdf10
+machine's default store. This facility is provided to assist with operation 
Jan F. Chadima 3fdf10
+on multi homed machines. 
Jan F. Chadima 3fdf10
+The default is
Jan F. Chadima 3fdf10
+.Dq yes .
Jan F. Chadima 3fdf10
+Note that this option applies only to protocol version 2 GSSAPI connections,
Jan F. Chadima 3fdf10
+and setting it to 
Jan F. Chadima 3fdf10
+.Dq no
Jan F. Chadima 3fdf10
+may only work with recent Kerberos GSSAPI libraries.
Jan F. Chadima 3fdf10
+.It Cm GSSAPIStoreCredentialsOnRekey
Jan F. Chadima 3fdf10
+Controls whether the user's GSSAPI credentials should be updated following a 
Jan F. Chadima 3fdf10
+successful connection rekeying. This option can be used to accepted renewed 
Jan F. Chadima 3fdf10
+or updated credentials from a compatible client. The default is
Jan F. Chadima 3fdf10
+.Dq no .
Jan F. Chadima 3fdf10
 .It Cm HostbasedAuthentication
Jan F. Chadima 3fdf10
 Specifies whether rhosts or /etc/hosts.equiv authentication together
Jan F. Chadima 3fdf10
 with successful public key client host authentication is allowed
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/sshd_config.gsskex openssh-5.6p1/sshd_config
Jan F. Chadima 1b8a26
--- openssh-5.6p1/sshd_config.gsskex	2010-08-23 12:51:56.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/sshd_config	2010-08-23 12:51:59.000000000 +0200
Jan F. Chadima 3fdf10
@@ -78,6 +78,8 @@ ChallengeResponseAuthentication no
Jan F. Chadima 3fdf10
 GSSAPIAuthentication yes
Jan F. Chadima 3fdf10
 #GSSAPICleanupCredentials yes
Jan F. Chadima 3fdf10
 GSSAPICleanupCredentials yes
Jan F. Chadima 3fdf10
+#GSSAPIStrictAcceptorCheck yes
Jan F. Chadima 3fdf10
+#GSSAPIKeyExchange no
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 # Set this to 'yes' to enable PAM authentication, account processing, 
Jan F. Chadima 3fdf10
 # and session processing. If this is enabled, PAM authentication will 
Jan F. Chadima 1b8a26
diff -up openssh-5.6p1/ssh-gss.h.gsskex openssh-5.6p1/ssh-gss.h
Jan F. Chadima 1b8a26
--- openssh-5.6p1/ssh-gss.h.gsskex	2007-06-12 15:40:39.000000000 +0200
Jan F. Chadima 1b8a26
+++ openssh-5.6p1/ssh-gss.h	2010-08-23 12:51:59.000000000 +0200
Jan F. Chadima 3fdf10
@@ -1,6 +1,6 @@
Jan F. Chadima 3fdf10
 /* $OpenBSD: ssh-gss.h,v 1.10 2007/06/12 08:20:00 djm Exp $ */
Jan F. Chadima 3fdf10
 /*
Jan F. Chadima 3fdf10
- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
Jan F. Chadima 3fdf10
+ * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
Jan F. Chadima 3fdf10
  *
Jan F. Chadima 3fdf10
  * Redistribution and use in source and binary forms, with or without
Jan F. Chadima 3fdf10
  * modification, are permitted provided that the following conditions
Jan F. Chadima 3fdf10
@@ -60,10 +60,22 @@
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 #define SSH_GSS_OIDTYPE 0x06
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+#define SSH2_MSG_KEXGSS_INIT                            30
Jan F. Chadima 3fdf10
+#define SSH2_MSG_KEXGSS_CONTINUE                        31
Jan F. Chadima 3fdf10
+#define SSH2_MSG_KEXGSS_COMPLETE                        32
Jan F. Chadima 3fdf10
+#define SSH2_MSG_KEXGSS_HOSTKEY                         33
Jan F. Chadima 3fdf10
+#define SSH2_MSG_KEXGSS_ERROR                           34
Jan F. Chadima 3fdf10
+#define SSH2_MSG_KEXGSS_GROUPREQ			40
Jan F. Chadima 3fdf10
+#define SSH2_MSG_KEXGSS_GROUP				41
Jan F. Chadima 3fdf10
+#define KEX_GSS_GRP1_SHA1_ID				"gss-group1-sha1-"
Jan F. Chadima 3fdf10
+#define KEX_GSS_GRP14_SHA1_ID				"gss-group14-sha1-"
Jan F. Chadima 3fdf10
+#define KEX_GSS_GEX_SHA1_ID				"gss-gex-sha1-"
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
 typedef struct {
Jan F. Chadima 3fdf10
 	char *filename;
Jan F. Chadima 3fdf10
 	char *envvar;
Jan F. Chadima 3fdf10
 	char *envval;
Jan F. Chadima 3fdf10
+	struct passwd *owner;
Jan F. Chadima 3fdf10
 	void *data;
Jan F. Chadima 3fdf10
 } ssh_gssapi_ccache;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
@@ -71,8 +83,11 @@ typedef struct {
Jan F. Chadima 3fdf10
 	gss_buffer_desc displayname;
Jan F. Chadima 3fdf10
 	gss_buffer_desc exportedname;
Jan F. Chadima 3fdf10
 	gss_cred_id_t creds;
Jan F. Chadima 3fdf10
+	gss_name_t name;
Jan F. Chadima 3fdf10
 	struct ssh_gssapi_mech_struct *mech;
Jan F. Chadima 3fdf10
 	ssh_gssapi_ccache store;
Jan F. Chadima 3fdf10
+	int used;
Jan F. Chadima 3fdf10
+	int updated;
Jan F. Chadima 3fdf10
 } ssh_gssapi_client;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 typedef struct ssh_gssapi_mech_struct {
Jan F. Chadima 3fdf10
@@ -83,6 +98,7 @@ typedef struct ssh_gssapi_mech_struct {
Jan F. Chadima 3fdf10
 	int (*userok) (ssh_gssapi_client *, char *);
Jan F. Chadima 3fdf10
 	int (*localname) (ssh_gssapi_client *, char **);
Jan F. Chadima 3fdf10
 	void (*storecreds) (ssh_gssapi_client *);
Jan F. Chadima 3fdf10
+	int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *);
Jan F. Chadima 3fdf10
 } ssh_gssapi_mech;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 typedef struct {
Jan F. Chadima 3fdf10
@@ -93,10 +109,11 @@ typedef struct {
Jan F. Chadima 3fdf10
 	gss_OID		oid; /* client */
Jan F. Chadima 3fdf10
 	gss_cred_id_t	creds; /* server */
Jan F. Chadima 3fdf10
 	gss_name_t	client; /* server */
Jan F. Chadima 3fdf10
-	gss_cred_id_t	client_creds; /* server */
Jan F. Chadima 3fdf10
+	gss_cred_id_t	client_creds; /* both */
Jan F. Chadima 3fdf10
 } Gssctxt;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 extern ssh_gssapi_mech *supported_mechs[];
Jan F. Chadima 3fdf10
+extern Gssctxt *gss_kex_context;
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 int  ssh_gssapi_check_oid(Gssctxt *, void *, size_t);
Jan F. Chadima 3fdf10
 void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t);
Jan F. Chadima 3fdf10
@@ -116,16 +133,30 @@ void ssh_gssapi_build_ctx(Gssctxt **);
Jan F. Chadima 3fdf10
 void ssh_gssapi_delete_ctx(Gssctxt **);
Jan F. Chadima 3fdf10
 OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t);
Jan F. Chadima 3fdf10
 void ssh_gssapi_buildmic(Buffer *, const char *, const char *, const char *);
Jan F. Chadima 3fdf10
-int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *);
Jan F. Chadima 3fdf10
+int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *, const char *);
Jan F. Chadima 3fdf10
+OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *);
Jan F. Chadima 3fdf10
+int ssh_gssapi_credentials_updated(Gssctxt *);
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 /* In the server */
Jan F. Chadima 3fdf10
+typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, 
Jan F. Chadima 3fdf10
+    const char *);
Jan F. Chadima 3fdf10
+char *ssh_gssapi_client_mechanisms(const char *, const char *);
Jan F. Chadima 3fdf10
+char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, const char *,
Jan F. Chadima 3fdf10
+    const char *);
Jan F. Chadima 3fdf10
+gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int);
Jan F. Chadima 3fdf10
+int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, 
Jan F. Chadima 3fdf10
+    const char *);
Jan F. Chadima 3fdf10
 OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
Jan F. Chadima 3fdf10
-int ssh_gssapi_userok(char *name);
Jan F. Chadima 3fdf10
+int ssh_gssapi_userok(char *name, struct passwd *);
Jan F. Chadima 3fdf10
 OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
Jan F. Chadima 3fdf10
 void ssh_gssapi_do_child(char ***, u_int *);
Jan F. Chadima 3fdf10
 void ssh_gssapi_cleanup_creds(void);
Jan F. Chadima 3fdf10
 void ssh_gssapi_storecreds(void);
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
+char *ssh_gssapi_server_mechanisms(void);
Jan F. Chadima 3fdf10
+int ssh_gssapi_oid_table_ok();
Jan F. Chadima 3fdf10
+
Jan F. Chadima 3fdf10
+int ssh_gssapi_update_creds(ssh_gssapi_ccache *store);
Jan F. Chadima 3fdf10
 #endif /* GSSAPI */
Jan F. Chadima 3fdf10
 
Jan F. Chadima 3fdf10
 #endif /* _SSH_GSS_H */