OpenSSH problem on Solaris 8
Jacques A. Vidrine
n at nectar.cc
Wed May 22 14:45:46 EDT 2002
On Wed, May 22, 2002 at 10:28:03AM -0500, Steve Langasek wrote:
> I would love it if you could send these patches to me (or to the list),
> because it would save me the trouble of writing them. I have a two-node
> high availability cluster here that I'd like to use kerberized ssh on,
> and it bugs me to no end that starting services on one of the nodes (and
> bringing up the shared IP address) causes ssh to smell funny on the node's
> real IP. I'm always happy to accept a patch that'll save me the time to
> implement it myself. :)
Sure, attached. I'm afraid there are other fixes and such also.
What you're looking for has to do with
ssh_gssapi_get_server_name()
options.gss_server_name
and associated stuff.
Cheers,
--
Jacques A. Vidrine <n at nectar.cc> http://www.nectar.cc/
NTT/Verio SME . FreeBSD UNIX . Heimdal Kerberos
jvidrine at verio.net . nectar at FreeBSD.org . nectar at kth.se
-------------- next part --------------
Index: buffer.c
===================================================================
RCS file: /home/cvs/ssh/buffer.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.4.1
diff -u -r1.1.1.1 -r1.1.1.1.4.1
--- buffer.c 20 Feb 2002 14:43:30 -0000 1.1.1.1
+++ buffer.c 20 Feb 2002 15:34:09 -0000 1.1.1.1.4.1
@@ -106,6 +106,19 @@
return buffer->end - buffer->offset;
}
+/* Gets the byte at the beginning of the buffer without consuming it. */
+
+int
+buffer_peek(Buffer *buffer)
+{
+ char *p;
+
+ if (buffer->end - buffer->offset < 1)
+ fatal("buffer_peek: buffer exhausted");
+ p = (char *)(buffer->buf + buffer->offset);
+ return (u_char) *p;
+}
+
/* Gets data from the beginning of the buffer. */
void
Index: buffer.h
===================================================================
RCS file: /home/cvs/ssh/buffer.h,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.4.1
diff -u -r1.1.1.1 -r1.1.1.1.4.1
--- buffer.h 20 Feb 2002 14:43:30 -0000 1.1.1.1
+++ buffer.h 20 Feb 2002 15:34:09 -0000 1.1.1.1.4.1
@@ -33,6 +33,7 @@
void buffer_append(Buffer *, const char *, u_int);
void buffer_append_space(Buffer *, char **, u_int);
+int buffer_peek(Buffer *);
void buffer_get(Buffer *, char *, u_int);
void buffer_consume(Buffer *, u_int);
Index: channels.c
===================================================================
RCS file: /home/cvs/ssh/channels.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.4.1
diff -u -r1.1.1.1 -r1.1.1.1.4.1
--- channels.c 20 Feb 2002 14:43:30 -0000 1.1.1.1
+++ channels.c 8 Mar 2002 04:06:42 -0000 1.1.1.1.4.1
@@ -145,7 +145,7 @@
{
Channel *c;
- if (id < 0 || id > channels_alloc) {
+ if (id < 0 || id >= channels_alloc) {
log("channel_lookup: %d: bad id", id);
return NULL;
}
Index: gss-genr.c
===================================================================
RCS file: /home/cvs/ssh/gss-genr.c,v
retrieving revision 1.1.2.1
retrieving revision 1.1.4.3
diff -u -r1.1.2.1 -r1.1.4.3
--- gss-genr.c 20 Feb 2002 14:47:22 -0000 1.1.2.1
+++ gss-genr.c 20 Feb 2002 20:24:01 -0000 1.1.4.3
@@ -31,6 +31,7 @@
#include "buffer.h"
#include "bufaux.h"
#include "packet.h"
+#include "canohost.h"
#include "compat.h"
#include <openssl/evp.h>
#include "cipher.h"
@@ -93,7 +94,7 @@
*/
char *
-ssh_gssapi_mechanisms(int server,char *host) {
+ssh_gssapi_mechanisms(const char *gss_server_name, char *host) {
gss_OID_set supported;
OM_uint32 maj_status, min_status;
Buffer buf;
@@ -118,8 +119,8 @@
if (present) {
ssh_gssapi_build_ctx(&ctx);
ssh_gssapi_set_oid(&ctx,&supported_mechs[i].oid);
- if (server) {
- if (ssh_gssapi_acquire_cred(&ctx)) {
+ if (gss_server_name != NULL) {
+ if (ssh_gssapi_acquire_cred(&ctx, gss_server_name)) {
ssh_gssapi_delete_ctx(&ctx);
continue;
}
@@ -237,14 +238,26 @@
return 0;
}
+void
+ssh_gssapi_free_errors(struct ssh_gssapi_errors *errors)
+{
+ int i;
+
+ for (i = 0; i < errors->count; i++)
+ free(errors->msg[i]);
+}
/* All this effort to report an error ... */
void
-ssh_gssapi_error(OM_uint32 major_status,OM_uint32 minor_status) {
+ssh_gssapi_get_errors(OM_uint32 major_status, OM_uint32 minor_status,
+ struct ssh_gssapi_errors *errors)
+{
+#define SSH_GSSAPI_ERRORS_MAX(errors) (sizeof((errors).msg) / sizeof((errors).msg[0]))
OM_uint32 lmaj, lmin;
gss_buffer_desc msg;
OM_uint32 ctx;
+ memset(errors, 0, sizeof(*errors));
ctx = 0;
/* The GSSAPI error */
do {
@@ -253,7 +266,17 @@
GSS_C_NULL_OID,
&ctx, &msg);
if (lmaj == GSS_S_COMPLETE) {
- debug((char *)msg.value);
+ if (errors->count == SSH_GSSAPI_ERRORS_MAX(*errors)) {
+ debug("ssh_gssapi_errors: maximum error count reached (%d)",
+ SSH_GSSAPI_ERRORS_MAX(*errors));
+ return;
+ }
+ errors->msg[errors->count] = strdup((char *)msg.value);
+ if (errors->msg[errors->count] == NULL) {
+ debug("ssh_gssapi_errors: memory allocation failure");
+ return;
+ }
+ errors->count++;
(void) gss_release_buffer(&lmin, &msg);
}
} while (ctx!=0);
@@ -265,10 +288,58 @@
GSS_C_NULL_OID,
&ctx, &msg);
if (lmaj == GSS_S_COMPLETE) {
- debug((char *)msg.value);
+ if (errors->count == SSH_GSSAPI_ERRORS_MAX(*errors)) {
+ debug("ssh_gssapi_errors: maximum error count reached (%d)",
+ SSH_GSSAPI_ERRORS_MAX(*errors));
+ return;
+ }
+ errors->msg[errors->count] = strdup((char *)msg.value);
+ if (errors->msg[errors->count] == NULL) {
+ debug("ssh_gssapi_errors: memory allocation failure");
+ return;
+ }
+ errors->count++;
(void) gss_release_buffer(&lmin, &msg);
}
} while (ctx!=0);
+#undef SSH_GSSAPI_ERRORS_MAX
+}
+
+void
+ssh_gssapi_error(OM_uint32 major_status,OM_uint32 minor_status)
+{
+ struct ssh_gssapi_errors errors;
+ int i;
+
+ ssh_gssapi_get_errors(major_status, minor_status, &errors);
+ for (i = 0; i < errors.count; i++)
+ debug(errors.msg[i]);
+ ssh_gssapi_free_errors(&errors);
+}
+
+void
+ssh_gssapi_flatten_errors(struct ssh_gssapi_errors *errors, char *buf, size_t buflen)
+{
+ char *p;
+ int i, n;
+
+ if (errors->count < 1) {
+ debug("ssh_gssapi_flatten_errors: no errors");
+ return;
+ } else {
+ n = snprintf(buf, buflen, "%s", errors->msg[0]);
+ if (n >= buflen)
+ return;
+ buflen -= n;
+ buf += n;
+ }
+ for (i = 1; i < errors->count; i++) {
+ n = snprintf(buf, buflen, "/ %s", errors->msg[i]);
+ if (n >= buflen)
+ return;
+ buflen -= n;
+ buf += n;
+ }
}
/* Initialise our GSSAPI context. We use this opaque structure to contain all
@@ -354,13 +425,13 @@
* oid
* credentials (from ssh_gssapi_acquire_cred)
*/
-OM_uint32 ssh_gssapi_accept_ctx(Gssctxt *ctx,gss_buffer_desc *recv_tok,
+OM_uint32 ssh_gssapi_accept_ctx(OM_uint32 *min_status, Gssctxt *ctx, gss_buffer_desc *recv_tok,
gss_buffer_desc *send_tok, OM_uint32 *flags)
{
- OM_uint32 maj_status, min_status;
+ OM_uint32 maj_status;
gss_OID mech;
- maj_status=gss_accept_sec_context(&min_status,
+ maj_status=gss_accept_sec_context(min_status,
&ctx->context,
ctx->creds,
recv_tok,
@@ -372,7 +443,7 @@
NULL,
&ctx->client_creds);
if (GSS_ERROR(maj_status)) {
- ssh_gssapi_error(maj_status,min_status);
+ ssh_gssapi_error(maj_status, *min_status);
}
if (ctx->client_creds) {
@@ -431,11 +502,38 @@
return(maj_status);
}
+static int
+ssh_gssapi_get_server_name(const char *gss_server_name, char *buf, size_t buflen)
+{
+ char *p;
+ int fd;
+
+ if (gss_server_name == NULL)
+ fatal("ssh_gssapi_import_server_name: gss_server_name == NULL");
+ if (strcmp(gss_server_name, GSS_SERVER_NAME_HOSTNAME) == 0) {
+ if (gethostname(buf, buflen) != 0) {
+ debug("ssh_gssapi_import_server_name: gethostname failed");
+ return(-1);
+ }
+ } else if (strcmp(gss_server_name, GSS_SERVER_NAME_SOCKET) == 0) {
+ fd = packet_get_connection_in();
+ if ((p = get_local_name(fd)) == NULL) {
+ debug("ssh_gssapi_import_server_name: get_local_name failed");
+ return(-1);
+ }
+ strlcpy(buf, p, buflen);
+ free(p);
+ } else
+ strlcpy(buf, gss_server_name, buflen);
+ debug("Server GSSAPI name: %s", buf);
+ return 0;
+}
+
/* Acquire credentials for a server running on the current host.
* Requires that the context structure contains a valid OID
*/
OM_uint32
-ssh_gssapi_acquire_cred(Gssctxt *ctx) {
+ssh_gssapi_acquire_cred(Gssctxt *ctx, const char *gss_server_name) {
OM_uint32 maj_status, min_status;
char lname[MAXHOSTNAMELEN];
gss_OID_set oidset;
@@ -443,13 +541,10 @@
gss_create_empty_oid_set(&min_status,&oidset);
gss_add_oid_set_member(&min_status,ctx->oid,&oidset);
- if (gethostname(lname, MAXHOSTNAMELEN)) {
- return(-1);
- }
-
- if ((maj_status=ssh_gssapi_import_name(ctx,lname))) {
+ if (ssh_gssapi_get_server_name(gss_server_name, lname, sizeof(lname)) != 0)
+ return(-1);
+ if ((maj_status=ssh_gssapi_import_name(ctx, lname)))
return(maj_status);
- }
if ((maj_status=gss_acquire_cred(&min_status,
ctx->name,
0,
Index: gss-serv.c
===================================================================
RCS file: /home/cvs/ssh/gss-serv.c,v
retrieving revision 1.1.2.1
retrieving revision 1.1.4.2
diff -u -r1.1.2.1 -r1.1.4.2
--- gss-serv.c 20 Feb 2002 14:47:23 -0000 1.1.2.1
+++ gss-serv.c 20 Feb 2002 19:46:02 -0000 1.1.4.2
@@ -137,8 +137,6 @@
char ccname[35];
static char name[40];
int tmpfd;
- OM_uint32 maj_status,min_status;
-
if (gssapi_client_creds==NULL) {
debug("No credentials stored");
@@ -488,7 +486,7 @@
ssh_gssapi_build_ctx(ctxt);
ssh_gssapi_set_oid(ctxt,&oid);
- if (ssh_gssapi_acquire_cred(ctxt))
+ if (ssh_gssapi_acquire_cred(ctxt, options.gss_server_name))
return 0;
/* Send SSH_MSG_USERAUTH_GSSAPI_RESPONSE */
@@ -521,7 +519,7 @@
recv_tok.value=packet_get_string(&recv_tok.length);
- maj_status=ssh_gssapi_accept_ctx(gssctxt, &recv_tok, &send_tok, NULL);
+ maj_status=ssh_gssapi_accept_ctx(&min_status, gssctxt, &recv_tok, &send_tok, NULL);
packet_done();
if (GSS_ERROR(maj_status)) {
diff -u -r1.1.1.1.2.1 -r1.1.1.1.4.1
Index: kex.h
===================================================================
RCS file: /home/cvs/ssh/kex.h,v
retrieving revision 1.1.1.1.2.1
retrieving revision 1.1.1.1.4.3
diff -u -r1.1.1.1.2.1 -r1.1.1.1.4.3
--- kex.h 20 Feb 2002 14:47:23 -0000 1.1.1.1.2.1
+++ kex.h 20 Feb 2002 19:46:02 -0000 1.1.1.1.4.3
@@ -96,7 +96,12 @@
struct KexOptions {
int gss_deleg_creds;
+ int gss_backwards_compat;
+ const char *gss_server_name;
};
+
+#define GSS_SERVER_NAME_SOCKET "*SOCKET*"
+#define GSS_SERVER_NAME_HOSTNAME "*HOSTNAME*"
struct Kex {
u_char *session_id;
Index: kexgss.c
===================================================================
RCS file: /home/cvs/ssh/kexgss.c,v
retrieving revision 1.1.2.1
retrieving revision 1.1.4.5
diff -u -r1.1.2.1 -r1.1.4.5
--- kexgss.c 20 Feb 2002 14:47:23 -0000 1.1.2.1
+++ kexgss.c 20 Feb 2002 20:24:01 -0000 1.1.4.5
@@ -50,7 +50,8 @@
u_char *serverhostkeyblob, int sbloblen,
BIGNUM *client_dh_pub,
BIGNUM *server_dh_pub,
- BIGNUM *shared_secret)
+ BIGNUM *shared_secret,
+ int gss_backwards_compat)
{
Buffer b;
static u_char digest[EVP_MAX_MD_SIZE];
@@ -69,7 +70,8 @@
buffer_put_char(&b, SSH2_MSG_KEXINIT);
buffer_append(&b, skexinit, skexinitlen);
- buffer_put_string(&b, serverhostkeyblob, sbloblen);
+ if (!gss_backwards_compat)
+ buffer_put_string(&b, serverhostkeyblob, sbloblen);
buffer_put_bignum2(&b, client_dh_pub);
buffer_put_bignum2(&b, server_dh_pub);
buffer_put_bignum2(&b, shared_secret);
@@ -103,6 +105,7 @@
unsigned char *kbuf;
unsigned char *hash;
unsigned char *serverhostkey;
+ const char *host;
int type = 0;
int first = 1;
int slen = 0;
@@ -112,9 +115,10 @@
if (ssh_gssapi_id_kex(&ctxt,kex->name)) {
fatal("Couldn't identify host exchange");
}
- if (ssh_gssapi_import_name(&ctxt,kex->host)) {
- fatal("Couldn't import hostname ");
- }
+ host = kex->options.gss_server_name ? kex->options.gss_server_name : kex->host;
+ debug("Server GSSAPI name: %s", host);
+ if (ssh_gssapi_import_name(&ctxt, host))
+ fatal("Couldn't import server name");
/* This code should match that in ssh_dh1_client */
@@ -163,12 +167,19 @@
if (send_tok.length !=0) {
if (first) {
packet_start(SSH2_MSG_KEXGSS_INIT);
+ if (kex->options.gss_backwards_compat)
+ packet_put_char(first);
packet_put_string(send_tok.value,
send_tok.length);
packet_put_bignum2(dh->pub_key);
first=0;
} else {
- packet_start(SSH2_MSG_KEXGSS_CONTINUE);
+ if (!kex->options.gss_backwards_compat) {
+ packet_start(SSH2_MSG_KEXGSS_CONTINUE);
+ } else {
+ packet_start(SSH2_MSG_KEXGSS_INIT);
+ packet_put_char(first);
+ }
packet_put_string(send_tok.value,
send_tok.length);
}
@@ -247,7 +258,8 @@
serverhostkey, slen, /* server host key */
dh->pub_key, /* e */
dh_server_pub, /* f */
- shared_secret /* K */
+ shared_secret, /* K */
+ kex->options.gss_backwards_compat
);
gssbuf.value=hash;
@@ -284,7 +296,7 @@
kexgss_server(Kex *kex)
{
- OM_uint32 maj_status, min_status;
+ OM_uint32 maj_status, min_status, discard;
/* Some GSSAPI implementations use the input value of ret_flags (an
* output variable) as a means of triggering mechanism specific
@@ -303,13 +315,14 @@
BIGNUM *shared_secret = 0;
BIGNUM *dh_client_pub = 0;
int type =0;
+ int first = 1;
/* Initialise GSSAPI */
ssh_gssapi_build_ctx(&ctxt);
if (ssh_gssapi_id_kex(&ctxt,kex->name))
fatal("Unknown gssapi mechanism");
- if (ssh_gssapi_acquire_cred(&ctxt))
+ if (ssh_gssapi_acquire_cred(&ctxt, kex->options.gss_server_name))
fatal("Unable to acquire credentials for the server");
/* Initialise some bignums */
@@ -318,14 +331,23 @@
fatal("dh_client_pub == NULL");
do {
- debug("Wait SSH2_MSG_GSSAPI_INIT");
+ debug("Wait SSH2_MSG_KEXGSS_INIT");
type = packet_read(&plen);
switch(type) {
case SSH2_MSG_KEXGSS_INIT:
if (dlen!=0)
fatal("Received KEXGSS_INIT after initialising");
+ if (!kex->options.gss_backwards_compat && packet_peek() != 0) {
+ debug("Enabling GssapiBackwardsCompatibility");
+ kex->options.gss_backwards_compat = 1;
+ }
+ if (kex->options.gss_backwards_compat)
+ first = packet_get_char();
recv_tok.value=packet_get_string(&recv_tok.length);
- packet_get_bignum2(dh_client_pub, &dlen);
+ if (!kex->options.gss_backwards_compat || first) {
+ packet_get_bignum2(dh_client_pub, &dlen);
+ first = 0;
+ }
/* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */
break;
case SSH2_MSG_KEXGSS_CONTINUE:
@@ -337,10 +359,10 @@
packet_disconnect("Protocol error: didn't expect packet type %d",
type);
}
- maj_status=ssh_gssapi_accept_ctx(&ctxt,&recv_tok, &send_tok,
+ maj_status=ssh_gssapi_accept_ctx(&min_status, &ctxt,&recv_tok, &send_tok,
&ret_flags);
- gss_release_buffer(&min_status,&recv_tok);
+ gss_release_buffer(&discard,&recv_tok);
if (maj_status & GSS_S_CONTINUE_NEEDED) {
debug("Sending GSSAPI_CONTINUE");
@@ -352,8 +374,15 @@
}
} while (maj_status & GSS_S_CONTINUE_NEEDED);
- if (GSS_ERROR(maj_status))
- fatal("gss_accept_context died");
+ if (GSS_ERROR(maj_status)) {
+ char errbuf[1024]; /* XXX packet_disconnect handles 1024 bytes max */
+ struct ssh_gssapi_errors errors;
+
+ ssh_gssapi_get_errors(maj_status, min_status, &errors);
+ ssh_gssapi_flatten_errors(&errors, errbuf, sizeof(errbuf));
+ ssh_gssapi_free_errors(&errors);
+ packet_disconnect(errbuf);
+ }
debug("gss_complete");
if (!(ret_flags & GSS_C_MUTUAL_FLAG))
@@ -386,7 +415,8 @@
NULL, 0, /* Change this if we start sending host keys */
dh_client_pub,
dh->pub_key,
- shared_secret
+ shared_secret,
+ kex->options.gss_backwards_compat
);
BN_free(dh_client_pub);
Index: packet.c
===================================================================
RCS file: /home/cvs/ssh/packet.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.4.1
diff -u -r1.1.1.1 -r1.1.1.1.4.1
--- packet.c 20 Feb 2002 14:43:31 -0000 1.1.1.1
+++ packet.c 20 Feb 2002 15:34:10 -0000 1.1.1.1.4.1
@@ -961,6 +961,13 @@
buffer_append(&input, buf, len);
}
+/* Returns the next character from the packet without consuming it. */
+u_int
+packet_peek()
+{
+ return buffer_peek(&incoming_packet);
+}
+
/* Returns a character from the packet. */
u_int
Index: packet.h
===================================================================
RCS file: /home/cvs/ssh/packet.h,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.4.1
diff -u -r1.1.1.1 -r1.1.1.1.4.1
--- packet.h 20 Feb 2002 14:43:31 -0000 1.1.1.1
+++ packet.h 20 Feb 2002 15:34:10 -0000 1.1.1.1.4.1
@@ -45,6 +45,8 @@
int packet_read_poll(int *packet_len_ptr);
void packet_process_incoming(const char *buf, u_int len);
+u_int packet_peek(void);
+
u_int packet_get_char(void);
u_int packet_get_int(void);
void packet_get_bignum(BIGNUM * value, int *length_ptr);
Index: readconf.c
===================================================================
RCS file: /home/cvs/ssh/readconf.c,v
retrieving revision 1.1.1.1.2.1
retrieving revision 1.1.1.1.4.3
diff -u -r1.1.1.1.2.1 -r1.1.1.1.4.3
--- readconf.c 20 Feb 2002 14:47:24 -0000 1.1.1.1.2.1
+++ readconf.c 20 Feb 2002 20:24:02 -0000 1.1.1.1.4.3
@@ -100,7 +100,7 @@
oKerberosAuthentication,
#endif
#ifdef GSSAPI
- oGssAuthentication, oGssDelegateCreds,
+ oGssAuthentication, oGssDelegateCreds, oGssBackwardsCompat, oGssServerName,
#ifdef GSI
oGssGlobusDelegateLimitedCreds,
#endif /* GSI */
@@ -153,6 +153,8 @@
#ifdef GSSAPI
{ "gssapiauthentication", oGssAuthentication },
{ "gssapidelegatecredentials", oGssDelegateCreds },
+ { "gssapibackwardscompatibility", oGssBackwardsCompat },
+ { "gssapiservername", oGssServerName },
#ifdef GSI
/* For backwards compatability with old 1.2.27 client code */
{ "forwardgssapiglobusproxy", oGssDelegateCreds }, /* alias */
@@ -387,6 +389,18 @@
intptr = &options->gss_deleg_creds;
goto parse_flag;
+ case oGssBackwardsCompat:
+ intptr = &options->gss_backwards_compat;
+ goto parse_flag;
+
+ case oGssServerName:
+ charptr = &options->gss_server_name;
+ arg = strdelim(&s);
+ if (!arg || *arg == '\0')
+ fatal("%.200s line %d: Missing argument.", filename, linenum);
+ if (*activep && *charptr == NULL)
+ *charptr = xstrdup(arg);
+ break;
#ifdef GSI
case oGssGlobusDelegateLimitedCreds:
intptr = &options->gss_globus_deleg_limited_proxy;
@@ -786,6 +800,8 @@
#ifdef GSSAPI
options->gss_authentication = -1;
options->gss_deleg_creds = -1;
+ options->gss_backwards_compat = -1;
+ options->gss_server_name = NULL;
#ifdef GSI
options->gss_globus_deleg_limited_proxy = -1;
#endif /* GSI */
@@ -876,6 +892,8 @@
options->gss_authentication = 1;
if (options->gss_deleg_creds == -1)
options->gss_deleg_creds = 1;
+ if (options->gss_backwards_compat == -1)
+ options->gss_backwards_compat = 0;
#ifdef GSI
if (options->gss_globus_deleg_limited_proxy == -1)
options->gss_globus_deleg_limited_proxy = 0;
Index: readconf.h
===================================================================
RCS file: /home/cvs/ssh/readconf.h,v
retrieving revision 1.1.1.1.2.1
retrieving revision 1.1.1.1.4.3
diff -u -r1.1.1.1.2.1 -r1.1.1.1.4.3
--- readconf.h 20 Feb 2002 14:47:24 -0000 1.1.1.1.2.1
+++ readconf.h 20 Feb 2002 20:24:03 -0000 1.1.1.1.4.3
@@ -51,6 +51,8 @@
#ifdef GSSAPI
int gss_authentication;
int gss_deleg_creds;
+ int gss_backwards_compat;
+ const char *gss_server_name;
#ifdef GSI
int gss_globus_deleg_limited_proxy;
#endif /* GSI */
Index: servconf.c
===================================================================
RCS file: /home/cvs/ssh/servconf.c,v
retrieving revision 1.1.1.1.2.1
retrieving revision 1.1.1.1.4.4
diff -u -r1.1.1.1.2.1 -r1.1.1.1.4.4
--- servconf.c 20 Feb 2002 14:47:24 -0000 1.1.1.1.2.1
+++ servconf.c 20 Feb 2002 20:24:03 -0000 1.1.1.1.4.4
@@ -16,13 +16,7 @@
#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
+extern const char *krb5_defkeyname;
#endif
#ifdef AFS
#include <kafs.h>
@@ -88,6 +82,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;
@@ -129,6 +124,10 @@
void
fill_default_server_options(ServerOptions *options)
{
+ int krb4_keyfile, krb5_keyfile;
+
+ krb4_keyfile = krb5_keyfile = 0;
+
/* Portable-specific options */
if (options->pam_authentication_via_kbd_int == -1)
options->pam_authentication_via_kbd_int = 0;
@@ -193,6 +192,12 @@
options->rsa_authentication = 1;
if (options->pubkey_authentication == -1)
options->pubkey_authentication = 1;
+#ifdef KRB4
+ krb4_keyfile = (access(KEYFILE, R_OK) == 0);
+#endif
+#ifdef KRB5
+ krb5_keyfile = (access(krb5_defkeyname, R_OK) == 0);
+#endif
#ifdef GSSAPI
if (options->gss_authentication == -1)
options->gss_authentication = 1;
@@ -202,10 +207,12 @@
options->gss_use_session_ccache = 1;
if (options->gss_cleanup_creds == -1)
options->gss_cleanup_creds = 1;
+ if (options->gss_server_name == NULL)
+ options->gss_server_name = xstrdup(GSS_SERVER_NAME_SOCKET);
#endif
#if defined(KRB4) || defined(KRB5)
if (options->kerberos_authentication == -1)
- options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
+ options->kerberos_authentication = krb4_keyfile||krb5_keyfile;
if (options->kerberos_or_local_passwd == -1)
options->kerberos_or_local_passwd = 1;
if (options->kerberos_ticket_cleanup == -1)
@@ -267,6 +274,7 @@
sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
#ifdef GSSAPI
sGssAuthentication, sGssKeyEx, sGssUseSessionCredCache, sGssCleanupCreds,
+ sGssServerName,
#endif
#if defined(KRB4) || defined(KRB5)
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
@@ -323,6 +331,7 @@
{ "gssusesessionccache", sGssUseSessionCredCache },
{ "gssapiusesessioncredcache", sGssUseSessionCredCache },
{ "gssapicleanupcreds", sGssCleanupCreds },
+ { "gssapiservername", sGssServerName },
#endif
#if defined(KRB4) || defined(KRB5)
{ "kerberosauthentication", sKerberosAuthentication },
@@ -662,6 +671,15 @@
case sGssCleanupCreds:
intptr = &options->gss_cleanup_creds;
goto parse_flag;
+ case sGssServerName:
+ charptr = &options->gss_server_name;
+ arg = strdelim(&cp);
+ if (!arg || *arg == '\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:
Index: servconf.h
===================================================================
RCS file: /home/cvs/ssh/servconf.h,v
retrieving revision 1.1.1.1.2.1
retrieving revision 1.1.1.1.4.4
diff -u -r1.1.1.1.2.1 -r1.1.1.1.4.4
--- servconf.h 20 Feb 2002 14:47:24 -0000 1.1.1.1.2.1
+++ servconf.h 20 Feb 2002 20:24:03 -0000 1.1.1.1.4.4
@@ -72,12 +72,13 @@
int hostbased_uses_name_from_packet_only; /* experimental */
int rsa_authentication; /* If true, permit RSA authentication. */
int pubkey_authentication; /* If true, permit ssh2 pubkey authentication. */
- #ifdef GSSAPI
+#ifdef GSSAPI
int gss_authentication;
int gss_keyex;
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 */
+ const char *gss_server_name;
#endif
#if defined(KRB4) || defined(KRB5)
int kerberos_authentication; /* If true, permit Kerberos
Index: ssh-gss.h
===================================================================
RCS file: /home/cvs/ssh/ssh-gss.h,v
retrieving revision 1.1.2.1
retrieving revision 1.1.4.2
diff -u -r1.1.2.1 -r1.1.4.2
--- ssh-gss.h 20 Feb 2002 14:47:25 -0000 1.1.2.1
+++ ssh-gss.h 20 Feb 2002 19:46:04 -0000 1.1.4.2
@@ -80,12 +80,17 @@
gss_cred_id_t client_creds; /* server */
} Gssctxt;
+struct ssh_gssapi_errors {
+ int count;
+ char *msg[16];
+};
+
extern ssh_gssapi_mech supported_mechs[];
extern gss_buffer_desc gssapi_client_name;
extern gss_cred_id_t gssapi_client_creds;
extern enum ssh_gss_id gssapi_client_type;
-char *ssh_gssapi_mechanisms(int server, char *host);
+char *ssh_gssapi_mechanisms(const char *gss_server_name, char *host);
int ssh_gssapi_id_kex(Gssctxt *ctx, char *name);
void ssh_gssapi_set_oid_data(Gssctxt *ctx, void *data, size_t len);
void ssh_gssapi_set_oid(Gssctxt *ctx, gss_OID oid);
@@ -93,11 +98,12 @@
enum ssh_gss_id ssh_gssapi_get_ctype(Gssctxt *ctxt);
OM_uint32 ssh_gssapi_import_name(Gssctxt *ctx, char *host);
-OM_uint32 ssh_gssapi_acquire_cred(Gssctxt *ctx);
+OM_uint32 ssh_gssapi_acquire_cred(Gssctxt *ctx, const char *gss_server_name);
OM_uint32 ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds,
gss_buffer_desc *recv_tok,
gss_buffer_desc *send_tok, OM_uint32 *flags);
-OM_uint32 ssh_gssapi_accept_ctx(Gssctxt *ctx,
+OM_uint32 ssh_gssapi_accept_ctx(OM_uint32 *min_status,
+ Gssctxt *ctx,
gss_buffer_desc *recv_tok,
gss_buffer_desc *send_tok,
OM_uint32 *flags);
@@ -105,6 +111,10 @@
enum ssh_gss_id *type,
gss_buffer_desc *name,
gss_cred_id_t *creds);
+void ssh_gssapi_get_errors(OM_uint32 major_status,OM_uint32 minor_status,
+ struct ssh_gssapi_errors *errors);
+void ssh_gssapi_free_errors(struct ssh_gssapi_errors *errors);
+void ssh_gssapi_flatten_errors(struct ssh_gssapi_errors *errors, char *buf, size_t buflen);
void ssh_gssapi_error(OM_uint32 major_status,OM_uint32 minor_status);
void ssh_gssapi_build_ctx(Gssctxt *ctx);
void ssh_gssapi_delete_ctx(Gssctxt *ctx);
Index: ssh.c
===================================================================
RCS file: /home/cvs/ssh/ssh.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.4.1
diff -u -r1.1.1.1 -r1.1.1.1.4.1
--- ssh.c 20 Feb 2002 14:43:33 -0000 1.1.1.1
+++ ssh.c 20 Feb 2002 20:24:04 -0000 1.1.1.1.4.1
@@ -312,7 +312,7 @@
again:
while ((opt = getopt(ac, av,
- "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:NPR:TVX")) != -1) {
+ "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:G:I:L:NPR:TVX")) != -1) {
switch (opt) {
case '1':
options.protocol = SSH_PROTO_1;
@@ -522,6 +522,9 @@
break;
case 'F':
config = optarg;
+ break;
+ case 'G':
+ options.gss_server_name = xstrdup(optarg);
break;
default:
usage();
Index: sshconnect2.c
===================================================================
RCS file: /home/cvs/ssh/sshconnect2.c,v
retrieving revision 1.1.1.1.2.1
retrieving revision 1.1.1.1.4.5
diff -u -r1.1.1.1.2.1 -r1.1.1.1.4.5
--- sshconnect2.c 20 Feb 2002 14:47:25 -0000 1.1.1.1.2.1
+++ sshconnect2.c 21 Feb 2002 03:15:32 -0000 1.1.1.1.4.5
@@ -97,10 +97,12 @@
* code to decide whether each one should be included or not.
*/
{
- char *orig, *gss;
+ char *orig, *gss, *gss_host;
int len;
orig = myproposal[PROPOSAL_KEX_ALGS];
- gss = ssh_gssapi_mechanisms(0,host);
+ gss_host = options.gss_server_name ? options.gss_server_name :
+ host;
+ gss = ssh_gssapi_mechanisms(NULL, gss_host);
if (gss) {
len = strlen(orig)+strlen(gss)+2;
myproposal[PROPOSAL_KEX_ALGS]=xmalloc(len);
@@ -151,6 +153,8 @@
#ifdef GSSAPI
kex->options.gss_deleg_creds=options.gss_deleg_creds;
+ kex->options.gss_backwards_compat=options.gss_backwards_compat;
+ kex->options.gss_server_name=options.gss_server_name;
#endif
xxx_kex = kex;
@@ -493,6 +497,7 @@
{
int i;
Gssctxt *gssctxt;
+ const char *host;
static int tries=0;
/* For now, we only make one attempt at this. We could try offering
@@ -506,7 +511,9 @@
* trapped before sending any packets.
*/
ssh_gssapi_build_ctx(gssctxt);
- if (ssh_gssapi_import_name(gssctxt,authctxt->host)) {
+ host = options.gss_server_name ? options.gss_server_name : authctxt->host;
+ debug("Server GSSAPI name: %s", host);
+ if (ssh_gssapi_import_name(gssctxt, host)) {
return(0);
}
authctxt->methoddata=(void *)gssctxt;
Index: sshd.c
===================================================================
RCS file: /home/cvs/ssh/sshd.c,v
retrieving revision 1.1.1.1.2.1
retrieving revision 1.1.1.1.4.2
diff -u -r1.1.1.1.2.1 -r1.1.1.1.4.2
--- sshd.c 20 Feb 2002 14:47:25 -0000 1.1.1.1.2.1
+++ sshd.c 20 Feb 2002 19:46:04 -0000 1.1.1.1.4.2
@@ -1483,7 +1483,7 @@
orig= NULL;
if (options.gss_keyex)
- gss = ssh_gssapi_mechanisms(1,NULL);
+ gss = ssh_gssapi_mechanisms(options.gss_server_name, NULL);
else
gss = NULL;
@@ -1515,6 +1515,10 @@
kex->client_version_string=client_version_string;
kex->server_version_string=server_version_string;
kex->load_host_key=&get_hostkey_by_type;
+
+#ifdef GSSAPI
+ kex->options.gss_server_name=options.gss_server_name;
+#endif
xxx_kex = kex;
More information about the Kerberos
mailing list