Patch for Simons openssh gssapi patch for multihomed systems

Jacques A. Vidrine nectar at celabo.org
Wed Sep 24 21:51:08 EDT 2003


On Wed, Sep 24, 2003 at 03:23:20PM -0400, Sam Hartman wrote:
> >>>>> "Jacques" == Jacques A Vidrine <nectar at celabo.org> writes:
> 
>     Jacques> On Tue, Sep 23, 2003 at 07:31:49PM +0100, Markus Moeller wrote:
>     >> Here is a patch on top of Simons gssapi patch for openssh 3.6.1p2 to
>     >> support multihomed systems.
> 
>     Jacques> A simpler approach is to pass GSS_C_NO_NAME to gss_acquire_cred.  This
>     Jacques> will allow any name present in the keytab.
> 
> Yes, and I'd like to see that as a configurable option.  That would
> even be a reasonable default if you gss_display_name the name and make
> sure it starts with host.

Hmm, that's sounds like what I have locally.  I added a
`GssServerName' option for the server and client (the latter is really
handy through NATs and TCP circuit relays).

   not set         -- use GSS_C_NO_NAME
   use_gethostname -- behaves as Simon's original patch
   use_getsockname -- behaves as Markus's patch
   other           -- uses the given name exactly

Below are the patches which implement this.  I've been using similar
for years now.  WARNING:  I manually edited out other, unrelated,
local modifications.

Cheers,
-- 
Jacques Vidrine   . NTT/Verio SME      . FreeBSD UNIX       . Heimdal
nectar at celabo.org . jvidrine at verio.net . nectar at freebsd.org . nectar at kth.se


--- sshconnect2.c	(.../gssapi/3.6.1p2)	(revision 61)
+++ sshconnect2.c	(.../release/hippo.1)	(revision 61)
@@ -93,7 +93,8 @@
 	/* Add the GSSAPI mechanisms currently supported on this client to
 	 * the key exchange algorithm proposal */
 	orig = myproposal[PROPOSAL_KEX_ALGS];
-	gss = ssh_gssapi_client_mechanisms(get_canonical_hostname(1));	
+	gss = ssh_gssapi_client_mechanisms(options.gss_server_name != NULL ?
+	    options.gss_server_name : get_canonical_hostname(1));	
 	if (gss) {
 	   len = strlen(orig)+strlen(gss)+2;
 	   myproposal[PROPOSAL_KEX_ALGS]=xmalloc(len);
@@ -150,6 +151,7 @@
 	kex->verify_host_key=&verify_host_key_callback;
 #ifdef GSSAPI
 	kex->options.gss_deleg_creds=options.gss_deleg_creds;
+	kex->options.gss_server_name=options.gss_server_name;
 #endif
 	xxx_kex = kex;
 
--- ssh-gss.h	(.../gssapi/3.6.1p2)	(revision 61)
+++ ssh-gss.h	(.../release/hippo.1)	(revision 61)
@@ -106,7 +106,7 @@
 ssh_gssapi_mech *ssh_gssapi_get_ctype(Gssctxt *ctxt);
 
 OM_uint32 ssh_gssapi_import_name(Gssctxt *ctx, const char *host);
-OM_uint32 ssh_gssapi_acquire_cred(Gssctxt *ctx);
+OM_uint32 ssh_gssapi_acquire_cred(Gssctxt *ctx, const char *host);
 OM_uint32 ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds,
 			      gss_buffer_desc *recv_tok, 
 			      gss_buffer_desc *send_tok, OM_uint32 *flags);
@@ -122,7 +122,7 @@
 char *ssh_gssapi_last_error(Gssctxt *ctxt, OM_uint32 *maj, OM_uint32 *min);
 void ssh_gssapi_build_ctx(Gssctxt **ctx);
 void ssh_gssapi_delete_ctx(Gssctxt **ctx);
-OM_uint32 ssh_gssapi_server_ctx(Gssctxt **ctx,gss_OID oid);
+OM_uint32 ssh_gssapi_server_ctx(Gssctxt **ctx,gss_OID oid, const char *host);
 
 int ssh_gssapi_check_mechanism(gss_OID oid, char *host);
 
--- gss-genr.c	(.../gssapi/3.6.1p2)	(revision 61)
+++ gss-genr.c	(.../release/hippo.1)	(revision 61)
@@ -38,6 +38,7 @@
 #include "log.h"
 #include "compat.h"
 #include "monitor_wrap.h"
+#include "canohost.h"
 
 #include <netdb.h>
 
@@ -376,6 +377,7 @@
 		return(-1);
         }
         snprintf(gssbuf.value,gssbuf.length,"host@%s",host);
+	debug("GSSAPI gss_import_name: %.*s", gssbuf.length, gssbuf.value);
         if ((ctx->major=gss_import_name(&ctx->minor,
                                    	&gssbuf,
                                         GSS_C_NT_HOSTBASED_SERVICE,
@@ -393,20 +395,46 @@
  
 /* Returns a GSSAPI error code */
 OM_uint32
-ssh_gssapi_acquire_cred(Gssctxt *ctx) {
+ssh_gssapi_acquire_cred(Gssctxt *ctx, const char *host) {
+	/* Special names for the GssapiServerName option. */
+	static char use_getsockname[] = "use_getsockname";
+	static char use_gethostname[] = "use_gethostname";
+
 	OM_uint32 status;
-	char lname[MAXHOSTNAMELEN];
+	char lname[MAXHOSTNAMELEN], *desired_name, *storage;
 	gss_OID_set oidset;
+	int fd;
 	
 	gss_create_empty_oid_set(&status,&oidset);
 	gss_add_oid_set_member(&status,ctx->oid,&oidset);
 	
-        if (gethostname(lname, MAXHOSTNAMELEN)) {
-                return(-1);
-        }
+	storage = NULL;
+	if (host == NULL)
+		desired_name = NULL;
+	else if (strcmp(host, use_gethostname) == 0) {
+        	if (gethostname(lname, sizeof(lname)) != 0)
+			fatal("What?  We don't have a hostname?  Ridiculous!");
+		else
+			desired_name = lname;
+	} else if (strcmp(host, use_getsockname) == 0) {
+		fd = packet_get_connection_in();
+		desired_name = get_local_name(fd);
+		if (desired_name == NULL)
+			debug("Could not determine local socket name");
+		else
+			storage = desired_name;
+	} else 
+		desired_name = host;
 
-	if (GSS_ERROR(ssh_gssapi_import_name(ctx,lname))) {
-		return(ctx->major);
+	if (desired_name == NULL) 
+		ctx->name = GSS_C_NO_NAME;
+	else {
+		status = ssh_gssapi_import_name(ctx, desired_name);
+		if (storage != NULL)
+			free(storage);
+		if (GSS_ERROR(status)) {
+			return(ctx->major);
+		}
 	}
 	
 	if ((ctx->major=gss_acquire_cred(&ctx->minor,
@@ -436,11 +470,11 @@
 }
 
 OM_uint32
-ssh_gssapi_server_ctx(Gssctxt **ctx,gss_OID oid) {
+ssh_gssapi_server_ctx(Gssctxt **ctx,gss_OID oid, const char *host) {
 	if (*ctx) ssh_gssapi_delete_ctx(ctx);
 	ssh_gssapi_build_ctx(ctx);
 	ssh_gssapi_set_oid(*ctx,oid);
-	return(ssh_gssapi_acquire_cred(*ctx));
+	return(ssh_gssapi_acquire_cred(*ctx,host));
 }
 
 int
--- kexgssc.c	(.../gssapi/3.6.1p2)	(revision 61)
+++ kexgssc.c	(.../release/hippo.1)	(revision 61)
@@ -66,7 +66,8 @@
 		fatal("Couldn't identify host exchange");
 	}
 
-	if (ssh_gssapi_import_name(ctxt,get_canonical_hostname(1))) {
+	if (ssh_gssapi_import_name(ctxt,kex->options.gss_server_name != NULL ?
+	    kex->options.gss_server_name : get_canonical_hostname(1))) {
 		fatal("Couldn't import hostname ");
 	}
 	
--- gss-serv.c	(.../gssapi/3.6.1p2)	(revision 61)
+++ gss-serv.c	(.../release/hippo.1)	(revision 61)
@@ -122,7 +122,8 @@
 
 		if (present) {
 		    if (!GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx,
-					    &supported_mechs[i]->oid)))) {
+					    &supported_mechs[i]->oid,
+					    options.gss_server_name)))) {
 			/* Append gss_group1_sha1_x to our list */
 			if (first++!=0)
 				buffer_put_char(&buf,',');
--- servconf.c	(.../gssapi/3.6.1p2)	(revision 61)
+++ servconf.c	(.../release/hippo.1)	(revision 61)
@@ -15,15 +15,6 @@
 #if defined(KRB4)
 #include <krb.h>
 #endif
-#if defined(KRB5)
-#ifdef HEIMDAL
-#include <krb.h>
-#else
-/* Bodge - but then, so is using the kerberos IV KEYFILE to get a Kerberos V
- * keytab */
-#define KEYFILE "/etc/krb5.keytab"
-#endif
-#endif
 #ifdef AFS
 #include <kafs.h>
 #endif
@@ -39,6 +30,7 @@
 #include "cipher.h"
 #include "kex.h"
 #include "mac.h"
+#include "ssh-gss.h"
 
 static void add_listen_addr(ServerOptions *, char *, u_short);
 static void add_one_listen_addr(ServerOptions *, char *, u_short);
@@ -91,6 +83,7 @@
 	options->gss_keyex=-1;
 	options->gss_use_session_ccache = -1;
 	options->gss_cleanup_creds = -1;
+	options->gss_server_name = NULL;
 #endif
 #if defined(KRB4) || defined(KRB5)
 	options->kerberos_authentication = -1;
@@ -298,6 +291,7 @@
 	sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
 #ifdef GSSAPI
 	sGssAuthentication, sGssKeyEx, sGssUseSessionCredCache, sGssCleanupCreds,
+	sGssServerName,
 #endif
 #if defined(KRB4) || defined(KRB5)
 	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
@@ -355,6 +349,7 @@
 	{ "gssusesessionccache", sGssUseSessionCredCache },
 	{ "gssapiusesessioncredcache", sGssUseSessionCredCache },
 	{ "gssapicleanupcreds", sGssCleanupCreds },
+	{ "gssapiservername", sGssServerName },
 #endif
 #if defined(KRB4) || defined(KRB5)
 	{ "kerberosauthentication", sKerberosAuthentication },
@@ -684,6 +679,16 @@
 	case sGssCleanupCreds:
 		intptr = &options->gss_cleanup_creds;
 		goto parse_flag;
+	case sGssServerName:
+		charptr = &options->gss_server_name;
+		arg = strdelim(&cp);
+		if (arg == NULL || arg[0] == '\0')
+			fatal("%s line %d: missing server name.", filename,
+			    linenum);
+		if (*charptr != NULL)
+			free(*charptr);
+		*charptr = xstrdup(arg);
+		break;
 #endif
 #if defined(KRB4) || defined(KRB5)
 	case sKerberosAuthentication:
--- kexgsss.c	(.../gssapi/3.6.1p2)	(revision 61)
+++ kexgsss.c	(.../release/hippo.1)	(revision 61)
@@ -39,7 +39,10 @@
 #include "ssh2.h"
 #include "ssh-gss.h"
 #include "monitor_wrap.h"
+#include "servconf.h"
 
+extern ServerOptions options;
+
 static void kex_gss_send_error(Gssctxt *ctxt);
 
 void
@@ -75,7 +78,8 @@
 	
 	debug2("%s: Acquiring credentials",__func__);
 	
-	if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt,oid)))) {
+	if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt,oid,
+	    options.gss_server_name)))) {
 		kex_gss_send_error(ctxt);
         	fatal("Unable to acquire credentials for the server");
         }
--- servconf.h	(.../gssapi/3.6.1p2)	(revision 61)
+++ servconf.h	(.../release/hippo.1)	(revision 61)
@@ -79,6 +79,7 @@
 	int     gss_use_session_ccache;        /* If true, delegated credentials are
 	                                        * stored in a session specific cache */
 	int 	gss_cleanup_creds;	       /* If true, destroy cred cache on logout */
+	char	*gss_server_name;	/* Server name to use for GSSAPI */
 #endif	
 #if defined(KRB4) || defined(KRB5)
 	int     kerberos_authentication;	/* If true, permit Kerberos
--- auth2-gss.c	(.../gssapi/3.6.1p2)	(revision 61)
+++ auth2-gss.c	(.../release/hippo.1)	(revision 61)
@@ -108,7 +108,8 @@
                 return(0);
         }
                 
-	if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt,&oid)))) {
+	if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt,&oid,
+	    options.gss_server_name)))) {
 		ssh_gssapi_userauth_error(ctxt);
 		return(0);
 	}
--- monitor.c	(.../gssapi/3.6.1p2)	(revision 61)
+++ monitor.c	(.../release/hippo.1)	(revision 61)
@@ -1706,11 +1813,15 @@
         gss_OID_desc oid;
         OM_uint32 major;
 	u_int len;
+	char *host;
 
         oid.elements=buffer_get_string(m,&len);
 	oid.length=len;
-                
-        major=ssh_gssapi_server_ctx(&gsscontext,&oid);
+	if (buffer_get_char(m))
+		host = buffer_get_string(m,&len);
+	else
+		host = NULL;
+        major=ssh_gssapi_server_ctx(&gsscontext,&oid,host);
 
         xfree(oid.elements);
 
--- monitor_wrap.c	(.../gssapi/3.6.1p2)	(revision 61)
+++ monitor_wrap.c	(.../release/hippo.1)	(revision 61)
@@ -1025,7 +1109,7 @@
 #endif
 #ifdef GSSAPI
 OM_uint32
-mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) {
+mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid, const char *host) {
         Buffer m;
         OM_uint32 major;
                 
@@ -1034,6 +1118,11 @@
 
         buffer_init(&m);
         buffer_put_string(&m,oid->elements,oid->length);
+	if (host != NULL) {
+		buffer_put_char(&m, 1);
+		buffer_put_string(&m,host,strlen(host)+1);
+	} else
+		buffer_put_char(&m, 0);
 
         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, &m);
         mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, &m);
--- readconf.c	(.../gssapi/3.6.1p2)	(revision 61)
+++ readconf.c	(.../release/hippo.1)	(revision 61)
@@ -98,7 +98,7 @@
 	oKerberosAuthentication,
 #endif
 #ifdef GSSAPI
-	oGssAuthentication, oGssDelegateCreds,
+	oGssAuthentication, oGssDelegateCreds, oGssServerName,
 #ifdef GSI
 	oGssGlobusDelegateLimitedCreds,
 #endif /* GSI */
@@ -153,6 +153,7 @@
 #ifdef GSSAPI
 	{ "gssapiauthentication", oGssAuthentication },
 	{ "gssapidelegatecredentials", oGssDelegateCreds },
+	{ "gssapiservername", oGssServerName },
 #ifdef GSI
 	/* For backwards compatability with old 1.2.27 client code */
 	{ "forwardgssapiglobusproxy", oGssDelegateCreds }, /* alias */
@@ -389,6 +390,16 @@
 	case oGssDelegateCreds:
 		intptr = &options->gss_deleg_creds;
 		goto parse_flag;
+
+	case oGssServerName:
+		charptr = &options->gss_server_name;
+		arg = strdelim(&s);
+		if (arg == NULL || arg[0] == '\0')
+			fatal("%.200s line %d: Missing argument.", filename,
+			    linenum);
+		if (*activep && *charptr == NULL)
+			*charptr = xstrdup(arg);
+		break;
  
 #ifdef GSI
 	case oGssGlobusDelegateLimitedCreds:
@@ -783,6 +794,7 @@
 #ifdef GSSAPI
         options->gss_authentication = -1;
         options->gss_deleg_creds = -1;
+	options->gss_server_name = NULL;
 #ifdef GSI
         options->gss_globus_deleg_limited_proxy = -1;
 #endif /* GSI */
--- monitor_wrap.h	(.../gssapi/3.6.1p2)	(revision 61)
+++ monitor_wrap.h	(.../release/hippo.1)	(revision 61)
@@ -57,11 +57,12 @@
 
 #ifdef USE_PAM
 void mm_start_pam(char *);
 #endif
 
 #ifdef GSSAPI
 #include "ssh-gss.h"
-OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **ctxt, gss_OID oid);
+OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **ctxt, gss_OID oid,
+				   const char *host);
 OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *ctxt, gss_buffer_desc *recv,
 				   gss_buffer_desc *send, OM_uint32 *flags);
 OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctxt, gss_buffer_desc *buffer,
--- readconf.h	(.../gssapi/3.6.1p2)	(revision 61)
+++ readconf.h	(.../release/hippo.1)	(revision 61)
@@ -51,6 +51,7 @@
 #ifdef GSSAPI
 	int 	gss_authentication;
 	int	gss_deleg_creds;
+	const char *gss_server_name;
 #ifdef GSI
 	int	gss_globus_deleg_limited_proxy;
 #endif /* GSI */
--- kex.h	(.../gssapi/3.6.1p2)	(revision 61)
+++ kex.h	(.../release/hippo.1)	(revision 61)
@@ -99,6 +99,7 @@
 
 struct KexOptions {
 	int	gss_deleg_creds;
+	char	*gss_server_name;
 };
 
 struct Kex {


More information about the Kerberos mailing list