View | Details | Raw Unified | Return to bug 1242 | Differences between
and this patch

Collapse All | Expand All

(-)Makefile.in.orig (-2 / +3 lines)
Lines 71-77 Link Here
71
	atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \
71
	atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \
72
	monitor_fdpass.o rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o \
72
	monitor_fdpass.o rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o \
73
	kexgex.o kexdhc.o kexgexc.o scard.o msg.o progressmeter.o dns.o \
73
	kexgex.o kexdhc.o kexgexc.o scard.o msg.o progressmeter.o dns.o \
74
	entropy.o scard-opensc.o gss-genr.o umac.o jpake.o schnorr.o
74
	entropy.o scard-opensc.o gss-genr.o umac.o jpake.o schnorr.o \
75
	kexgssc.o
75
76
76
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
77
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
77
	sshconnect.o sshconnect1.o sshconnect2.o mux.o
78
	sshconnect.o sshconnect1.o sshconnect2.o mux.o
Lines 84-90 Link Here
84
	auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-jpake.o \
85
	auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-jpake.o \
85
	monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o \
86
	monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o \
86
	auth-krb5.o \
87
	auth-krb5.o \
87
	auth2-gss.o gss-serv.o gss-serv-krb5.o \
88
	auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o\
88
	loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
89
	loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
89
	audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o
90
	audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o
90
91
(-)auth2-gss.c.orig (-2 / +42 lines)
Lines 1-7 Link Here
1
/* $OpenBSD: auth2-gss.c,v 1.16 2007/10/29 00:52:45 dtucker Exp $ */
1
/* $OpenBSD: auth2-gss.c,v 1.16 2007/10/29 00:52:45 dtucker Exp $ */
2
2
3
/*
3
/*
4
 * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
4
 * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved.
5
 *
5
 *
6
 * Redistribution and use in source and binary forms, with or without
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
7
 * modification, are permitted provided that the following conditions
Lines 52-57 Link Here
52
static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt);
52
static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt);
53
static void input_gssapi_errtok(int, u_int32_t, void *);
53
static void input_gssapi_errtok(int, u_int32_t, void *);
54
54
55
/* 
56
 * The 'gssapi_keyex' userauth mechanism.
57
 */
58
static int
59
userauth_gsskeyex(Authctxt *authctxt)
60
{
61
	int authenticated = 0;
62
	Buffer b;
63
	gss_buffer_desc mic, gssbuf;
64
	u_int len;
65
66
	mic.value = packet_get_string(&len);
67
	mic.length = len;
68
69
	packet_check_eom();
70
71
	ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service,
72
	    "gssapi-keyex");
73
74
	gssbuf.value = buffer_ptr(&b);
75
	gssbuf.length = buffer_len(&b);
76
77
	/* gss_kex_context is NULL with privsep, so we can't check it here */
78
	if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, 
79
	    &gssbuf, &mic))))
80
		authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
81
	
82
	buffer_free(&b);
83
	xfree(mic.value);
84
85
	return (authenticated);
86
}
87
55
/*
88
/*
56
 * We only support those mechanisms that we know about (ie ones that we know
89
 * We only support those mechanisms that we know about (ie ones that we know
57
 * how to check local user kuserok and the like)
90
 * how to check local user kuserok and the like)
Lines 279-285 Link Here
279
	gssbuf.length = buffer_len(&b);
312
	gssbuf.length = buffer_len(&b);
280
313
281
	if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic))))
314
	if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic))))
282
		authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
315
		authenticated = 
316
		    PRIVSEP(ssh_gssapi_userok(authctxt->user));
283
	else
317
	else
284
		logit("GSSAPI MIC check failed");
318
		logit("GSSAPI MIC check failed");
285
319
Lines 294-299 Link Here
294
	userauth_finish(authctxt, authenticated, "gssapi-with-mic");
328
	userauth_finish(authctxt, authenticated, "gssapi-with-mic");
295
}
329
}
296
330
331
Authmethod method_gsskeyex = {
332
	"gssapi-keyex",
333
	userauth_gsskeyex,
334
	&options.gss_authentication
335
};
336
297
Authmethod method_gssapi = {
337
Authmethod method_gssapi = {
298
	"gssapi-with-mic",
338
	"gssapi-with-mic",
299
	userauth_gssapi,
339
	userauth_gssapi,
(-)auth2.c.orig (+2 lines)
Lines 69-74 Link Here
69
extern Authmethod method_kbdint;
69
extern Authmethod method_kbdint;
70
extern Authmethod method_hostbased;
70
extern Authmethod method_hostbased;
71
#ifdef GSSAPI
71
#ifdef GSSAPI
72
extern Authmethod method_gsskeyex;
72
extern Authmethod method_gssapi;
73
extern Authmethod method_gssapi;
73
#endif
74
#endif
74
#ifdef JPAKE
75
#ifdef JPAKE
Lines 79-84 Link Here
79
	&method_none,
80
	&method_none,
80
	&method_pubkey,
81
	&method_pubkey,
81
#ifdef GSSAPI
82
#ifdef GSSAPI
83
	&method_gsskeyex,
82
	&method_gssapi,
84
	&method_gssapi,
83
#endif
85
#endif
84
#ifdef JPAKE
86
#ifdef JPAKE
(-)gss-genr.c.orig (-2 / +177 lines)
Lines 1-7 Link Here
1
/* $OpenBSD: gss-genr.c,v 1.19 2007/06/12 11:56:15 dtucker Exp $ */
1
/* $OpenBSD: gss-genr.c,v 1.19 2007/06/12 11:56:15 dtucker Exp $ */
2
2
3
/*
3
/*
4
 * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved.
4
 * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
5
 *
5
 *
6
 * Redistribution and use in source and binary forms, with or without
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
7
 * modification, are permitted provided that the following conditions
Lines 39-50 Link Here
39
#include "buffer.h"
39
#include "buffer.h"
40
#include "log.h"
40
#include "log.h"
41
#include "ssh2.h"
41
#include "ssh2.h"
42
#include "cipher.h"
43
#include "key.h"
44
#include "kex.h"
45
#include <openssl/evp.h>
42
46
43
#include "ssh-gss.h"
47
#include "ssh-gss.h"
44
48
45
extern u_char *session_id2;
49
extern u_char *session_id2;
46
extern u_int session_id2_len;
50
extern u_int session_id2_len;
47
51
52
typedef struct {
53
	char *encoded;
54
	gss_OID oid;
55
} ssh_gss_kex_mapping;
56
57
/*
58
 * XXX - It would be nice to find a more elegant way of handling the
59
 * XXX   passing of the key exchange context to the userauth routines
60
 */
61
62
Gssctxt *gss_kex_context = NULL;
63
64
static ssh_gss_kex_mapping *gss_enc2oid = NULL;
65
66
int 
67
ssh_gssapi_oid_table_ok() {
68
	return (gss_enc2oid != NULL);
69
}
70
71
/*
72
 * Return a list of the gss-group1-sha1 mechanisms supported by this program
73
 *
74
 * We test mechanisms to ensure that we can use them, to avoid starting
75
 * a key exchange with a bad mechanism
76
 */
77
78
char *
79
ssh_gssapi_client_mechanisms(const char *host) {
80
	gss_OID_set gss_supported;
81
	OM_uint32 min_status;
82
83
	if (GSS_ERROR(gss_indicate_mechs(&min_status, &gss_supported)))
84
		return NULL;
85
86
	return(ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism,
87
	    host));
88
}
89
90
char *
91
ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check,
92
    const char *data) {
93
	Buffer buf;
94
	size_t i;
95
	int oidpos, enclen;
96
	char *mechs, *encoded;
97
	u_char digest[EVP_MAX_MD_SIZE];
98
	char deroid[2];
99
	const EVP_MD *evp_md = EVP_md5();
100
	EVP_MD_CTX md;
101
102
	if (gss_enc2oid != NULL) {
103
		for (i = 0; gss_enc2oid[i].encoded != NULL; i++)
104
			xfree(gss_enc2oid[i].encoded);
105
		xfree(gss_enc2oid);
106
	}
107
108
	gss_enc2oid = xmalloc(sizeof(ssh_gss_kex_mapping) *
109
	    (gss_supported->count + 1));
110
111
	buffer_init(&buf);
112
113
	oidpos = 0;
114
	for (i = 0; i < gss_supported->count; i++) {
115
		if (gss_supported->elements[i].length < 128 &&
116
		    (*check)(NULL, &(gss_supported->elements[i]), data)) {
117
118
			deroid[0] = SSH_GSS_OIDTYPE;
119
			deroid[1] = gss_supported->elements[i].length;
120
121
			EVP_DigestInit(&md, evp_md);
122
			EVP_DigestUpdate(&md, deroid, 2);
123
			EVP_DigestUpdate(&md,
124
			    gss_supported->elements[i].elements,
125
			    gss_supported->elements[i].length);
126
			EVP_DigestFinal(&md, digest, NULL);
127
128
			encoded = xmalloc(EVP_MD_size(evp_md) * 2);
129
			enclen = __b64_ntop(digest, EVP_MD_size(evp_md),
130
			    encoded, EVP_MD_size(evp_md) * 2);
131
132
			if (oidpos != 0)
133
				buffer_put_char(&buf, ',');
134
135
			buffer_append(&buf, KEX_GSS_GEX_SHA1_ID,
136
			    sizeof(KEX_GSS_GEX_SHA1_ID) - 1);
137
			buffer_append(&buf, encoded, enclen);
138
			buffer_put_char(&buf, ',');
139
			buffer_append(&buf, KEX_GSS_GRP1_SHA1_ID, 
140
			    sizeof(KEX_GSS_GRP1_SHA1_ID) - 1);
141
			buffer_append(&buf, encoded, enclen);
142
			buffer_put_char(&buf, ',');
143
			buffer_append(&buf, KEX_GSS_GRP14_SHA1_ID,
144
			    sizeof(KEX_GSS_GRP14_SHA1_ID) - 1);
145
			buffer_append(&buf, encoded, enclen);
146
147
			gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]);
148
			gss_enc2oid[oidpos].encoded = encoded;
149
			oidpos++;
150
		}
151
	}
152
	gss_enc2oid[oidpos].oid = NULL;
153
	gss_enc2oid[oidpos].encoded = NULL;
154
155
	buffer_put_char(&buf, '\0');
156
157
	mechs = xmalloc(buffer_len(&buf));
158
	buffer_get(&buf, mechs, buffer_len(&buf));
159
	buffer_free(&buf);
160
161
	if (strlen(mechs) == 0) {
162
		xfree(mechs);
163
		mechs = NULL;
164
	}
165
	
166
	return (mechs);
167
}
168
169
gss_OID
170
ssh_gssapi_id_kex(Gssctxt *ctx, char *name, int kex_type) {
171
	int i = 0;
172
	
173
	switch (kex_type) {
174
	case KEX_GSS_GRP1_SHA1:
175
		if (strlen(name) < sizeof(KEX_GSS_GRP1_SHA1_ID))
176
			return GSS_C_NO_OID;
177
		name += sizeof(KEX_GSS_GRP1_SHA1_ID) - 1;
178
		break;
179
	case KEX_GSS_GRP14_SHA1:
180
		if (strlen(name) < sizeof(KEX_GSS_GRP14_SHA1_ID))
181
			return GSS_C_NO_OID;
182
		name += sizeof(KEX_GSS_GRP14_SHA1_ID) - 1;
183
		break;
184
	case KEX_GSS_GEX_SHA1:
185
		if (strlen(name) < sizeof(KEX_GSS_GEX_SHA1_ID))
186
			return GSS_C_NO_OID;
187
		name += sizeof(KEX_GSS_GEX_SHA1_ID) - 1;
188
		break;
189
	default:
190
		return GSS_C_NO_OID;
191
	}
192
193
	while (gss_enc2oid[i].encoded != NULL &&
194
	    strcmp(name, gss_enc2oid[i].encoded) != 0)
195
		i++;
196
197
	if (gss_enc2oid[i].oid != NULL && ctx != NULL)
198
		ssh_gssapi_set_oid(ctx, gss_enc2oid[i].oid);
199
200
	return gss_enc2oid[i].oid;
201
}
202
48
/* Check that the OID in a data stream matches that in the context */
203
/* Check that the OID in a data stream matches that in the context */
49
int
204
int
50
ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len)
205
ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len)
Lines 229-234 Link Here
229
OM_uint32
384
OM_uint32
230
ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash)
385
ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash)
231
{
386
{
387
	if (ctx == NULL) 
388
		return -1;
389
232
	if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context,
390
	if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context,
233
	    GSS_C_QOP_DEFAULT, buffer, hash)))
391
	    GSS_C_QOP_DEFAULT, buffer, hash)))
234
		ssh_gssapi_error(ctx);
392
		ssh_gssapi_error(ctx);
Lines 236-241 Link Here
236
	return (ctx->major);
394
	return (ctx->major);
237
}
395
}
238
396
397
/* Priviledged when used by server */
398
OM_uint32
399
ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
400
{
401
	if (ctx == NULL)
402
		return -1;
403
404
	ctx->major = gss_verify_mic(&ctx->minor, ctx->context,
405
	    gssbuf, gssmic, NULL);
406
407
	return (ctx->major);
408
}
409
239
void
410
void
240
ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service,
411
ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service,
241
    const char *context)
412
    const char *context)
Lines 254-259 Link Here
254
	gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
425
	gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
255
	OM_uint32 major, minor;
426
	OM_uint32 major, minor;
256
	gss_OID_desc spnego_oid = {6, (void *)"\x2B\x06\x01\x05\x05\x02"};
427
	gss_OID_desc spnego_oid = {6, (void *)"\x2B\x06\x01\x05\x05\x02"};
428
	Gssctxt *intctx = NULL;
429
430
	if (ctx == NULL)
431
		ctx = &intctx;
257
432
258
	/* RFC 4462 says we MUST NOT do SPNEGO */
433
	/* RFC 4462 says we MUST NOT do SPNEGO */
259
	if (oid->length == spnego_oid.length && 
434
	if (oid->length == spnego_oid.length && 
Lines 272-278 Link Here
272
			    GSS_C_NO_BUFFER);
447
			    GSS_C_NO_BUFFER);
273
	}
448
	}
274
449
275
	if (GSS_ERROR(major)) 
450
	if (GSS_ERROR(major) || intctx != NULL) 
276
		ssh_gssapi_delete_ctx(ctx);
451
		ssh_gssapi_delete_ctx(ctx);
277
452
278
	return (!GSS_ERROR(major));
453
	return (!GSS_ERROR(major));
(-)gss-serv.c.orig (-12 / +27 lines)
Lines 1-7 Link Here
1
/* $OpenBSD: gss-serv.c,v 1.22 2008/05/08 12:02:23 djm Exp $ */
1
/* $OpenBSD: gss-serv.c,v 1.22 2008/05/08 12:02:23 djm Exp $ */
2
2
3
/*
3
/*
4
 * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
4
 * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
5
 *
5
 *
6
 * Redistribution and use in source and binary forms, with or without
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
7
 * modification, are permitted provided that the following conditions
Lines 48-53 Link Here
48
#include "servconf.h"
48
#include "servconf.h"
49
49
50
#include "ssh-gss.h"
50
#include "ssh-gss.h"
51
#include "monitor_wrap.h"
51
52
52
extern ServerOptions options;
53
extern ServerOptions options;
53
54
Lines 124-129 Link Here
124
}
125
}
125
126
126
/* Unprivileged */
127
/* Unprivileged */
128
char *
129
ssh_gssapi_server_mechanisms() {
130
	gss_OID_set	supported;
131
132
	ssh_gssapi_supported_oids(&supported);
133
	return (ssh_gssapi_kex_mechs(supported, &ssh_gssapi_server_check_mech,
134
	    NULL));
135
}
136
137
/* Unprivileged */
138
int
139
ssh_gssapi_server_check_mech(Gssctxt **dum, gss_OID oid, const char *data) {
140
	Gssctxt *ctx = NULL;
141
	int res;
142
 
143
	res = !GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx, oid)));
144
	ssh_gssapi_delete_ctx(&ctx);
145
146
	return (res);
147
}
148
149
/* Unprivileged */
127
void
150
void
128
ssh_gssapi_supported_oids(gss_OID_set *oidset)
151
ssh_gssapi_supported_oids(gss_OID_set *oidset)
129
{
152
{
Lines 133-139 Link Here
133
	gss_OID_set supported;
156
	gss_OID_set supported;
134
157
135
	gss_create_empty_oid_set(&min_status, oidset);
158
	gss_create_empty_oid_set(&min_status, oidset);
136
	gss_indicate_mechs(&min_status, &supported);
159
160
	if (GSS_ERROR(gss_indicate_mechs(&min_status, &supported)))
161
		return;
137
162
138
	while (supported_mechs[i]->name != NULL) {
163
	while (supported_mechs[i]->name != NULL) {
139
		if (GSS_ERROR(gss_test_oid_set_member(&min_status,
164
		if (GSS_ERROR(gss_test_oid_set_member(&min_status,
Lines 362-375 Link Here
362
	return (0);
387
	return (0);
363
}
388
}
364
389
365
/* Privileged */
366
OM_uint32
367
ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
368
{
369
	ctx->major = gss_verify_mic(&ctx->minor, ctx->context,
370
	    gssbuf, gssmic, NULL);
371
372
	return (ctx->major);
373
}
374
375
#endif
390
#endif
(-)kex.c.orig (+18 lines)
Lines 49-54 Link Here
49
#include "dispatch.h"
49
#include "dispatch.h"
50
#include "monitor.h"
50
#include "monitor.h"
51
51
52
#ifdef GSSAPI
53
#include "ssh-gss.h"
54
#endif
55
52
#define KEX_COOKIE_LEN	16
56
#define KEX_COOKIE_LEN	16
53
57
54
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
58
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Lines 327-332 Link Here
327
		k->kex_type = KEX_DH_GEX_SHA256;
331
		k->kex_type = KEX_DH_GEX_SHA256;
328
		k->evp_md = evp_ssh_sha256();
332
		k->evp_md = evp_ssh_sha256();
329
#endif
333
#endif
334
#ifdef GSSAPI
335
	} else if (strncmp(k->name, KEX_GSS_GEX_SHA1_ID,
336
	    sizeof(KEX_GSS_GEX_SHA1_ID) - 1) == 0) {
337
		k->kex_type = KEX_GSS_GEX_SHA1;
338
		k->evp_md = EVP_sha1();
339
	} else if (strncmp(k->name, KEX_GSS_GRP1_SHA1_ID,
340
	    sizeof(KEX_GSS_GRP1_SHA1_ID) - 1) == 0) {
341
		k->kex_type = KEX_GSS_GRP1_SHA1;
342
		k->evp_md = EVP_sha1();
343
	} else if (strncmp(k->name, KEX_GSS_GRP14_SHA1_ID,
344
	    sizeof(KEX_GSS_GRP14_SHA1_ID) - 1) == 0) {
345
		k->kex_type = KEX_GSS_GRP14_SHA1;
346
		k->evp_md = EVP_sha1();
347
#endif
330
	} else
348
	} else
331
		fatal("bad kex alg %s", k->name);
349
		fatal("bad kex alg %s", k->name);
332
}
350
}
(-)kex.h.orig (+13 lines)
Lines 64-69 Link Here
64
	KEX_DH_GRP14_SHA1,
64
	KEX_DH_GRP14_SHA1,
65
	KEX_DH_GEX_SHA1,
65
	KEX_DH_GEX_SHA1,
66
	KEX_DH_GEX_SHA256,
66
	KEX_DH_GEX_SHA256,
67
	KEX_GSS_GRP1_SHA1,
68
	KEX_GSS_GRP14_SHA1,
69
	KEX_GSS_GEX_SHA1,
67
	KEX_MAX
70
	KEX_MAX
68
};
71
};
69
72
Lines 119-124 Link Here
119
	sig_atomic_t done;
122
	sig_atomic_t done;
120
	int	flags;
123
	int	flags;
121
	const EVP_MD *evp_md;
124
	const EVP_MD *evp_md;
125
#ifdef GSSAPI
126
	int	gss_deleg_creds;
127
	int	gss_trust_dns;
128
	char    *gss_host;
129
#endif
122
	char	*client_version_string;
130
	char	*client_version_string;
123
	char	*server_version_string;
131
	char	*server_version_string;
124
	int	(*verify_host_key)(Key *);
132
	int	(*verify_host_key)(Key *);
Lines 141-146 Link Here
141
void	 kexgex_client(Kex *);
149
void	 kexgex_client(Kex *);
142
void	 kexgex_server(Kex *);
150
void	 kexgex_server(Kex *);
143
151
152
#ifdef GSSAPI
153
void	kexgss_client(Kex *);
154
void	kexgss_server(Kex *);
155
#endif
156
144
void
157
void
145
kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int,
158
kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int,
146
    BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *);
159
    BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *);
(-)kexgssc.c (+327 lines)
Added Link Here
1
/*
2
 * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
14
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
 */
24
25
#include "includes.h"
26
27
#ifdef GSSAPI
28
29
#include "includes.h"
30
31
#include <openssl/crypto.h>
32
#include <openssl/bn.h>
33
34
#include <string.h>
35
36
#include "xmalloc.h"
37
#include "buffer.h"
38
#include "ssh2.h"
39
#include "key.h"
40
#include "cipher.h"
41
#include "kex.h"
42
#include "log.h"
43
#include "packet.h"
44
#include "dh.h"
45
46
#include "ssh-gss.h"
47
48
void
49
kexgss_client(Kex *kex) {
50
	gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
51
	gss_buffer_desc recv_tok, gssbuf, msg_tok, *token_ptr;
52
	Gssctxt *ctxt;
53
	OM_uint32 maj_status, min_status, ret_flags;
54
	u_int klen, kout, slen = 0, hashlen, strlen;
55
	DH *dh; 
56
	BIGNUM *dh_server_pub = NULL;
57
	BIGNUM *shared_secret = NULL;
58
	BIGNUM *p = NULL;
59
	BIGNUM *g = NULL;	
60
	u_char *kbuf, *hash;
61
	u_char *serverhostkey = NULL;
62
	u_char *empty = "";
63
	char *msg;
64
	char *lang;
65
	int type = 0;
66
	int first = 1;
67
	int nbits = 0, min = DH_GRP_MIN, max = DH_GRP_MAX;
68
69
	/* Initialise our GSSAPI world */	
70
	ssh_gssapi_build_ctx(&ctxt);
71
	if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type) 
72
	    == GSS_C_NO_OID)
73
		fatal("Couldn't identify host exchange");
74
75
	if (ssh_gssapi_import_name(ctxt, kex->gss_host))
76
		fatal("Couldn't import hostname");
77
	
78
	switch (kex->kex_type) {
79
	case KEX_GSS_GRP1_SHA1:
80
		dh = dh_new_group1();
81
		break;
82
	case KEX_GSS_GRP14_SHA1:
83
		dh = dh_new_group14();
84
		break;
85
	case KEX_GSS_GEX_SHA1:
86
		debug("Doing group exchange\n");
87
		nbits = dh_estimate(kex->we_need * 8);
88
		packet_start(SSH2_MSG_KEXGSS_GROUPREQ);
89
		packet_put_int(min);
90
		packet_put_int(nbits);
91
		packet_put_int(max);
92
93
		packet_send();
94
95
		packet_read_expect(SSH2_MSG_KEXGSS_GROUP);
96
97
		if ((p = BN_new()) == NULL)
98
			fatal("BN_new() failed");
99
		packet_get_bignum2(p);
100
		if ((g = BN_new()) == NULL)
101
			fatal("BN_new() failed");
102
		packet_get_bignum2(g);
103
		packet_check_eom();
104
105
		if (BN_num_bits(p) < min || BN_num_bits(p) > max)
106
			fatal("GSSGRP_GEX group out of range: %d !< %d !< %d",
107
			    min, BN_num_bits(p), max);
108
109
		dh = dh_new_group(g, p);
110
		break;
111
	default:
112
		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
113
	}
114
	
115
	/* Step 1 - e is dh->pub_key */
116
	dh_gen_key(dh, kex->we_need * 8);
117
118
	/* This is f, we initialise it now to make life easier */
119
	dh_server_pub = BN_new();
120
	if (dh_server_pub == NULL)
121
		fatal("dh_server_pub == NULL");
122
123
	token_ptr = GSS_C_NO_BUFFER;
124
			 
125
	do {
126
		debug("Calling gss_init_sec_context");
127
		
128
		maj_status = ssh_gssapi_init_ctx(ctxt,
129
		    kex->gss_deleg_creds, token_ptr, &send_tok,
130
		    &ret_flags);
131
132
		if (GSS_ERROR(maj_status)) {
133
			if (send_tok.length != 0) {
134
				packet_start(SSH2_MSG_KEXGSS_CONTINUE);
135
				packet_put_string(send_tok.value,
136
				    send_tok.length);
137
			}
138
			fatal("gss_init_context failed");
139
		}
140
141
		/* If we've got an old receive buffer get rid of it */
142
		if (token_ptr != GSS_C_NO_BUFFER)
143
			xfree(recv_tok.value);
144
145
		if (maj_status == GSS_S_COMPLETE) {
146
			/* If mutual state flag is not true, kex fails */
147
			if (!(ret_flags & GSS_C_MUTUAL_FLAG))
148
				fatal("Mutual authentication failed");
149
150
			/* If integ avail flag is not true kex fails */
151
			if (!(ret_flags & GSS_C_INTEG_FLAG))
152
				fatal("Integrity check failed");
153
		}
154
155
		/* 
156
		 * If we have data to send, then the last message that we
157
		 * received cannot have been a 'complete'. 
158
		 */
159
		if (send_tok.length != 0) {
160
			if (first) {
161
				packet_start(SSH2_MSG_KEXGSS_INIT);
162
				packet_put_string(send_tok.value,
163
				    send_tok.length);
164
				packet_put_bignum2(dh->pub_key);
165
				first = 0;
166
			} else {
167
				packet_start(SSH2_MSG_KEXGSS_CONTINUE);
168
				packet_put_string(send_tok.value,
169
				    send_tok.length);
170
			}
171
			packet_send();
172
			gss_release_buffer(&min_status, &send_tok);
173
174
			/* If we've sent them data, they should reply */
175
			do {	
176
				type = packet_read();
177
				if (type == SSH2_MSG_KEXGSS_HOSTKEY) {
178
					debug("Received KEXGSS_HOSTKEY");
179
					if (serverhostkey)
180
						fatal("Server host key received more than once");
181
					serverhostkey = 
182
					    packet_get_string(&slen);
183
				}
184
			} while (type == SSH2_MSG_KEXGSS_HOSTKEY);
185
186
			switch (type) {
187
			case SSH2_MSG_KEXGSS_CONTINUE:
188
				debug("Received GSSAPI_CONTINUE");
189
				if (maj_status == GSS_S_COMPLETE) 
190
					fatal("GSSAPI Continue received from server when complete");
191
				recv_tok.value = packet_get_string(&strlen);
192
				recv_tok.length = strlen; 
193
				break;
194
			case SSH2_MSG_KEXGSS_COMPLETE:
195
				debug("Received GSSAPI_COMPLETE");
196
				packet_get_bignum2(dh_server_pub);
197
				msg_tok.value =  packet_get_string(&strlen);
198
				msg_tok.length = strlen; 
199
200
				/* Is there a token included? */
201
				if (packet_get_char()) {
202
					recv_tok.value=
203
					    packet_get_string(&strlen);
204
					recv_tok.length = strlen;
205
					/* If we're already complete - protocol error */
206
					if (maj_status == GSS_S_COMPLETE)
207
						packet_disconnect("Protocol error: received token when complete");
208
					} else {
209
						/* No token included */
210
						if (maj_status != GSS_S_COMPLETE)
211
							packet_disconnect("Protocol error: did not receive final token");
212
				}
213
				break;
214
			case SSH2_MSG_KEXGSS_ERROR:
215
				debug("Received Error");
216
				maj_status = packet_get_int();
217
				min_status = packet_get_int();
218
				msg = packet_get_string(NULL);
219
				lang = packet_get_string(NULL);
220
				fatal("GSSAPI Error: \n%.400s",msg);
221
			default:
222
				packet_disconnect("Protocol error: didn't expect packet type %d",
223
		    		type);
224
			}
225
			token_ptr = &recv_tok;
226
		} else {
227
			/* No data, and not complete */
228
			if (maj_status != GSS_S_COMPLETE)
229
				fatal("Not complete, and no token output");
230
		}
231
	} while (maj_status & GSS_S_CONTINUE_NEEDED);
232
233
	/* 
234
	 * We _must_ have received a COMPLETE message in reply from the 
235
	 * server, which will have set dh_server_pub and msg_tok 
236
	 */
237
238
	if (type != SSH2_MSG_KEXGSS_COMPLETE)
239
		fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it");
240
241
	/* Check f in range [1, p-1] */
242
	if (!dh_pub_is_valid(dh, dh_server_pub))
243
		packet_disconnect("bad server public DH value");
244
245
	/* compute K=f^x mod p */
246
	klen = DH_size(dh);
247
	kbuf = xmalloc(klen);
248
	kout = DH_compute_key(kbuf, dh_server_pub, dh);
249
	if (kout < 0)
250
		fatal("DH_compute_key: failed");
251
252
	shared_secret = BN_new();
253
	if (shared_secret == NULL)
254
		fatal("kexgss_client: BN_new failed");
255
256
	if (BN_bin2bn(kbuf, kout, shared_secret) == NULL)
257
		fatal("kexdh_client: BN_bin2bn failed");
258
259
	memset(kbuf, 0, klen);
260
	xfree(kbuf);
261
262
	switch (kex->kex_type) {
263
	case KEX_GSS_GRP1_SHA1:
264
	case KEX_GSS_GRP14_SHA1:
265
		kex_dh_hash( kex->client_version_string, 
266
		    kex->server_version_string,
267
		    buffer_ptr(&kex->my), buffer_len(&kex->my),
268
		    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
269
		    (serverhostkey ? serverhostkey : empty), slen,
270
		    dh->pub_key,	/* e */
271
		    dh_server_pub,	/* f */
272
		    shared_secret,	/* K */
273
		    &hash, &hashlen
274
		);
275
		break;
276
	case KEX_GSS_GEX_SHA1:
277
		kexgex_hash(
278
		    kex->evp_md,
279
		    kex->client_version_string,
280
		    kex->server_version_string,
281
		    buffer_ptr(&kex->my), buffer_len(&kex->my),
282
		    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
283
		    (serverhostkey ? serverhostkey : empty), slen,
284
 		    min, nbits, max,
285
		    dh->p, dh->g,
286
		    dh->pub_key,
287
		    dh_server_pub,
288
		    shared_secret,
289
		    &hash, &hashlen
290
		);
291
		break;
292
	default:
293
		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
294
	}
295
296
	gssbuf.value = hash;
297
	gssbuf.length = hashlen;
298
299
	/* Verify that the hash matches the MIC we just got. */
300
	if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok)))
301
		packet_disconnect("Hash's MIC didn't verify");
302
303
	xfree(msg_tok.value);
304
305
	DH_free(dh);
306
	if (serverhostkey)
307
		xfree(serverhostkey);
308
	BN_clear_free(dh_server_pub);
309
310
	/* save session id */
311
	if (kex->session_id == NULL) {
312
		kex->session_id_len = hashlen;
313
		kex->session_id = xmalloc(kex->session_id_len);
314
		memcpy(kex->session_id, hash, kex->session_id_len);
315
	}
316
317
	if (gss_kex_context == NULL)
318
		gss_kex_context = ctxt;
319
	else
320
		ssh_gssapi_delete_ctx(&ctxt);
321
322
	kex_derive_keys(kex, hash, hashlen, shared_secret);
323
	BN_clear_free(shared_secret);
324
	kex_finish(kex);
325
}
326
327
#endif /* GSSAPI */
(-)kexgsss.c (+280 lines)
Added Link Here
1
/*
2
 * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
14
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
 */
24
25
#include "includes.h"
26
27
#ifdef GSSAPI
28
29
#include <string.h>
30
31
#include <openssl/crypto.h>
32
#include <openssl/bn.h>
33
34
#include "xmalloc.h"
35
#include "buffer.h"
36
#include "ssh2.h"
37
#include "key.h"
38
#include "cipher.h"
39
#include "kex.h"
40
#include "log.h"
41
#include "packet.h"
42
#include "dh.h"
43
#include "ssh-gss.h"
44
#include "monitor_wrap.h"
45
46
void
47
kexgss_server(Kex *kex)
48
{
49
	OM_uint32 maj_status, min_status;
50
	
51
	/* 
52
	 * Some GSSAPI implementations use the input value of ret_flags (an
53
 	 * output variable) as a means of triggering mechanism specific 
54
 	 * features. Initializing it to zero avoids inadvertently 
55
 	 * activating this non-standard behaviour.
56
	 */
57
58
	OM_uint32 ret_flags = 0;
59
	gss_buffer_desc gssbuf, recv_tok, msg_tok;
60
	gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
61
	Gssctxt *ctxt = NULL;
62
	u_int slen, klen, kout, hashlen;
63
	u_char *kbuf, *hash;
64
	DH *dh;
65
	int min = -1, max = -1, nbits = -1;
66
	BIGNUM *shared_secret = NULL;
67
	BIGNUM *dh_client_pub = NULL;
68
	int type = 0;
69
	gss_OID oid;
70
	char *mechs;
71
72
	/* Initialise GSSAPI */
73
74
	/* If we're rekeying, privsep means that some of the private structures
75
	 * in the GSSAPI code are no longer available. This kludges them back
76
	 * into life
77
	 */
78
	if (!ssh_gssapi_oid_table_ok()) 
79
		if ((mechs = ssh_gssapi_server_mechanisms()))
80
			xfree(mechs);
81
82
	debug2("%s: Identifying %s", __func__, kex->name);
83
	oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type);
84
	if (oid == GSS_C_NO_OID)
85
	   fatal("Unknown gssapi mechanism");
86
87
	debug2("%s: Acquiring credentials", __func__);
88
89
	if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid))))
90
		fatal("Unable to acquire credentials for the server");
91
92
	switch (kex->kex_type) {
93
	case KEX_GSS_GRP1_SHA1:
94
		dh = dh_new_group1();
95
		break;
96
	case KEX_GSS_GRP14_SHA1:
97
		dh = dh_new_group14();
98
		break;
99
	case KEX_GSS_GEX_SHA1:
100
		debug("Doing group exchange");
101
		packet_read_expect(SSH2_MSG_KEXGSS_GROUPREQ);
102
		min = packet_get_int();
103
		nbits = packet_get_int();
104
		max = packet_get_int();
105
		min = MAX(DH_GRP_MIN, min);
106
		max = MIN(DH_GRP_MAX, max);
107
		packet_check_eom();
108
		if (max < min || nbits < min || max < nbits)
109
			fatal("GSS_GEX, bad parameters: %d !< %d !< %d",
110
			    min, nbits, max);
111
		dh = PRIVSEP(choose_dh(min, nbits, max));
112
		if (dh == NULL)
113
			packet_disconnect("Protocol error: no matching group found");
114
115
		packet_start(SSH2_MSG_KEXGSS_GROUP);
116
		packet_put_bignum2(dh->p);
117
		packet_put_bignum2(dh->g);
118
		packet_send();
119
120
		packet_write_wait();
121
		break;
122
	default:
123
		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
124
	}
125
126
	dh_gen_key(dh, kex->we_need * 8);
127
128
	do {
129
		debug("Wait SSH2_MSG_GSSAPI_INIT");
130
		type = packet_read();
131
		switch(type) {
132
		case SSH2_MSG_KEXGSS_INIT:
133
			if (dh_client_pub != NULL) 
134
				fatal("Received KEXGSS_INIT after initialising");
135
			recv_tok.value = packet_get_string(&slen);
136
			recv_tok.length = slen; 
137
138
			if ((dh_client_pub = BN_new()) == NULL)
139
				fatal("dh_client_pub == NULL");
140
141
			packet_get_bignum2(dh_client_pub);
142
143
			/* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */
144
			break;
145
		case SSH2_MSG_KEXGSS_CONTINUE:
146
			recv_tok.value = packet_get_string(&slen);
147
			recv_tok.length = slen; 
148
			break;
149
		default:
150
			packet_disconnect(
151
			    "Protocol error: didn't expect packet type %d",
152
			    type);
153
		}
154
155
		maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok, 
156
		    &send_tok, &ret_flags));
157
158
		xfree(recv_tok.value);
159
160
		if (maj_status != GSS_S_COMPLETE && send_tok.length == 0)
161
			fatal("Zero length token output when incomplete");
162
163
		if (dh_client_pub == NULL)
164
			fatal("No client public key");
165
		
166
		if (maj_status & GSS_S_CONTINUE_NEEDED) {
167
			debug("Sending GSSAPI_CONTINUE");
168
			packet_start(SSH2_MSG_KEXGSS_CONTINUE);
169
			packet_put_string(send_tok.value, send_tok.length);
170
			packet_send();
171
			gss_release_buffer(&min_status, &send_tok);
172
		}
173
	} while (maj_status & GSS_S_CONTINUE_NEEDED);
174
175
	if (GSS_ERROR(maj_status)) {
176
		if (send_tok.length > 0) {
177
			packet_start(SSH2_MSG_KEXGSS_CONTINUE);
178
			packet_put_string(send_tok.value, send_tok.length);
179
			packet_send();
180
		}
181
		fatal("accept_ctx died");
182
	}
183
184
	if (!(ret_flags & GSS_C_MUTUAL_FLAG))
185
		fatal("Mutual Authentication flag wasn't set");
186
187
	if (!(ret_flags & GSS_C_INTEG_FLAG))
188
		fatal("Integrity flag wasn't set");
189
	
190
	if (!dh_pub_is_valid(dh, dh_client_pub))
191
		packet_disconnect("bad client public DH value");
192
193
	klen = DH_size(dh);
194
	kbuf = xmalloc(klen); 
195
	kout = DH_compute_key(kbuf, dh_client_pub, dh);
196
	if (kout < 0)
197
		fatal("DH_compute_key: failed");
198
199
	shared_secret = BN_new();
200
	if (shared_secret == NULL)
201
		fatal("kexgss_server: BN_new failed");
202
203
	if (BN_bin2bn(kbuf, kout, shared_secret) == NULL)
204
		fatal("kexgss_server: BN_bin2bn failed");
205
206
	memset(kbuf, 0, klen);
207
	xfree(kbuf);
208
209
	switch (kex->kex_type) {
210
	case KEX_GSS_GRP1_SHA1:
211
	case KEX_GSS_GRP14_SHA1:
212
		kex_dh_hash(
213
		    kex->client_version_string, kex->server_version_string,
214
		    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
215
		    buffer_ptr(&kex->my), buffer_len(&kex->my),
216
		    NULL, 0, /* Change this if we start sending host keys */
217
		    dh_client_pub, dh->pub_key, shared_secret,
218
		    &hash, &hashlen
219
		);
220
		break;
221
	case KEX_GSS_GEX_SHA1:
222
		kexgex_hash(
223
		    kex->evp_md,
224
		    kex->client_version_string, kex->server_version_string,
225
		    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
226
		    buffer_ptr(&kex->my), buffer_len(&kex->my),
227
		    NULL, 0,
228
		    min, nbits, max,
229
		    dh->p, dh->g,
230
		    dh_client_pub,
231
		    dh->pub_key,
232
		    shared_secret,
233
		    &hash, &hashlen
234
		);
235
		break;
236
	default:
237
		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
238
	}
239
240
	BN_clear_free(dh_client_pub);
241
242
	if (kex->session_id == NULL) {
243
		kex->session_id_len = hashlen;
244
		kex->session_id = xmalloc(kex->session_id_len);
245
		memcpy(kex->session_id, hash, kex->session_id_len);
246
	}
247
248
	gssbuf.value = hash;
249
	gssbuf.length = hashlen;
250
251
	if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt,&gssbuf,&msg_tok))))
252
		fatal("Couldn't get MIC");
253
254
	packet_start(SSH2_MSG_KEXGSS_COMPLETE);
255
	packet_put_bignum2(dh->pub_key);
256
	packet_put_string(msg_tok.value,msg_tok.length);
257
258
	if (send_tok.length != 0) {
259
		packet_put_char(1); /* true */
260
		packet_put_string(send_tok.value, send_tok.length);
261
	} else {
262
		packet_put_char(0); /* false */
263
	}
264
	packet_send();
265
266
	gss_release_buffer(&min_status, &send_tok);
267
	gss_release_buffer(&min_status, &msg_tok);
268
269
	if (gss_kex_context == NULL)
270
		gss_kex_context = ctxt;
271
	else 
272
		ssh_gssapi_delete_ctx(&ctxt);
273
274
	DH_free(dh);
275
276
	kex_derive_keys(kex, hash, hashlen, shared_secret);
277
	BN_clear_free(shared_secret);
278
	kex_finish(kex);
279
}
280
#endif /* GSSAPI */
(-)key.c.orig (+2 lines)
Lines 764-769 Link Here
764
		return KEY_RSA;
764
		return KEY_RSA;
765
	} else if (strcmp(name, "ssh-dss") == 0) {
765
	} else if (strcmp(name, "ssh-dss") == 0) {
766
		return KEY_DSA;
766
		return KEY_DSA;
767
	} else if (strcmp(name, "null") == 0) {
768
		return KEY_NULL;
767
	}
769
	}
768
	debug2("key_type_from_name: unknown key type '%s'", name);
770
	debug2("key_type_from_name: unknown key type '%s'", name);
769
	return KEY_UNSPEC;
771
	return KEY_UNSPEC;
(-)key.h.orig (+1 lines)
Lines 34-39 Link Here
34
	KEY_RSA1,
34
	KEY_RSA1,
35
	KEY_RSA,
35
	KEY_RSA,
36
	KEY_DSA,
36
	KEY_DSA,
37
	KEY_NULL,
37
	KEY_UNSPEC
38
	KEY_UNSPEC
38
};
39
};
39
enum fp_type {
40
enum fp_type {
(-)monitor.c.orig (+77 lines)
Lines 170-175 Link Here
170
int mm_answer_gss_accept_ctx(int, Buffer *);
170
int mm_answer_gss_accept_ctx(int, Buffer *);
171
int mm_answer_gss_userok(int, Buffer *);
171
int mm_answer_gss_userok(int, Buffer *);
172
int mm_answer_gss_checkmic(int, Buffer *);
172
int mm_answer_gss_checkmic(int, Buffer *);
173
int mm_answer_gss_sign(int, Buffer *);
173
#endif
174
#endif
174
175
175
#ifdef SSH_AUDIT_EVENTS
176
#ifdef SSH_AUDIT_EVENTS
Lines 239-244 Link Here
239
    {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx},
240
    {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx},
240
    {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
241
    {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
241
    {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic},
242
    {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic},
243
    {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign},
242
#endif
244
#endif
243
#ifdef JPAKE
245
#ifdef JPAKE
244
    {MONITOR_REQ_JPAKE_GET_PWDATA, MON_ONCE, mm_answer_jpake_get_pwdata},
246
    {MONITOR_REQ_JPAKE_GET_PWDATA, MON_ONCE, mm_answer_jpake_get_pwdata},
Lines 251-256 Link Here
251
};
253
};
252
254
253
struct mon_table mon_dispatch_postauth20[] = {
255
struct mon_table mon_dispatch_postauth20[] = {
256
#ifdef GSSAPI
257
    {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx},
258
    {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx},
259
    {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign},
260
#endif
254
    {MONITOR_REQ_MODULI, 0, mm_answer_moduli},
261
    {MONITOR_REQ_MODULI, 0, mm_answer_moduli},
255
    {MONITOR_REQ_SIGN, 0, mm_answer_sign},
262
    {MONITOR_REQ_SIGN, 0, mm_answer_sign},
256
    {MONITOR_REQ_PTY, 0, mm_answer_pty},
263
    {MONITOR_REQ_PTY, 0, mm_answer_pty},
Lines 355-360 Link Here
355
		/* Permit requests for moduli and signatures */
362
		/* Permit requests for moduli and signatures */
356
		monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
363
		monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
357
		monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
364
		monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
365
#ifdef GSSAPI
366
		/* and for the GSSAPI key exchange */
367
		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
368
#endif
358
	} else {
369
	} else {
359
		mon_dispatch = mon_dispatch_proto15;
370
		mon_dispatch = mon_dispatch_proto15;
360
371
Lines 441-446 Link Here
441
		monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
452
		monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
442
		monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
453
		monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
443
		monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
454
		monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
455
#ifdef GSSAPI
456
		/* and for the GSSAPI key exchange */
457
		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
458
#endif		
444
	} else {
459
	} else {
445
		mon_dispatch = mon_dispatch_postauth15;
460
		mon_dispatch = mon_dispatch_postauth15;
446
		monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
461
		monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
Lines 1699-1704 Link Here
1699
	kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
1714
	kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
1700
	kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
1715
	kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
1701
	kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
1716
	kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
1717
#ifdef GSSAPI
1718
	if (options.gss_keyex) {
1719
		kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
1720
		kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
1721
		kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
1722
	}
1723
#endif
1702
	kex->server = 1;
1724
	kex->server = 1;
1703
	kex->hostkey_type = buffer_get_int(m);
1725
	kex->hostkey_type = buffer_get_int(m);
1704
	kex->kex_type = buffer_get_int(m);
1726
	kex->kex_type = buffer_get_int(m);
Lines 1898-1903 Link Here
1898
	OM_uint32 major;
1920
	OM_uint32 major;
1899
	u_int len;
1921
	u_int len;
1900
1922
1923
	if (!options.gss_authentication && !options.gss_keyex)
1924
		fatal("In GSSAPI monitor when GSSAPI is disabled");
1925
1901
	goid.elements = buffer_get_string(m, &len);
1926
	goid.elements = buffer_get_string(m, &len);
1902
	goid.length = len;
1927
	goid.length = len;
1903
1928
Lines 1925-1930 Link Here
1925
	OM_uint32 flags = 0; /* GSI needs this */
1950
	OM_uint32 flags = 0; /* GSI needs this */
1926
	u_int len;
1951
	u_int len;
1927
1952
1953
	if (!options.gss_authentication && !options.gss_keyex)
1954
		fatal("In GSSAPI monitor when GSSAPI is disabled");
1955
1928
	in.value = buffer_get_string(m, &len);
1956
	in.value = buffer_get_string(m, &len);
1929
	in.length = len;
1957
	in.length = len;
1930
	major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags);
1958
	major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags);
Lines 1942-1947 Link Here
1942
		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
1970
		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
1943
		monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
1971
		monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
1944
		monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
1972
		monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
1973
		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1);
1945
	}
1974
	}
1946
	return (0);
1975
	return (0);
1947
}
1976
}
Lines 1953-1958 Link Here
1953
	OM_uint32 ret;
1982
	OM_uint32 ret;
1954
	u_int len;
1983
	u_int len;
1955
1984
1985
	if (!options.gss_authentication && !options.gss_keyex)
1986
		fatal("In GSSAPI monitor when GSSAPI is disabled");
1987
1956
	gssbuf.value = buffer_get_string(m, &len);
1988
	gssbuf.value = buffer_get_string(m, &len);
1957
	gssbuf.length = len;
1989
	gssbuf.length = len;
1958
	mic.value = buffer_get_string(m, &len);
1990
	mic.value = buffer_get_string(m, &len);
Lines 1979-1984 Link Here
1979
{
2011
{
1980
	int authenticated;
2012
	int authenticated;
1981
2013
2014
	if (!options.gss_authentication && !options.gss_keyex)
2015
		fatal("In GSSAPI monitor when GSSAPI is disabled");
2016
1982
	authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user);
2017
	authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user);
1983
2018
1984
	buffer_clear(m);
2019
	buffer_clear(m);
Lines 1992-1997 Link Here
1992
	/* Monitor loop will terminate if authenticated */
2027
	/* Monitor loop will terminate if authenticated */
1993
	return (authenticated);
2028
	return (authenticated);
1994
}
2029
}
2030
2031
int 
2032
mm_answer_gss_sign(int socket, Buffer *m)
2033
{
2034
	gss_buffer_desc data;
2035
	gss_buffer_desc hash = GSS_C_EMPTY_BUFFER;
2036
	OM_uint32 major, minor;
2037
	u_int len;
2038
2039
	if (!options.gss_authentication && !options.gss_keyex)
2040
		fatal("In GSSAPI monitor when GSSAPI is disabled");
2041
2042
	data.value = buffer_get_string(m, &len);
2043
	data.length = len;
2044
	if (data.length != 20) 
2045
		fatal("%s: data length incorrect: %d", __func__, 
2046
		    (int) data.length);
2047
2048
	/* Save the session ID on the first time around */
2049
	if (session_id2_len == 0) {
2050
		session_id2_len = data.length;
2051
		session_id2 = xmalloc(session_id2_len);
2052
		memcpy(session_id2, data.value, session_id2_len);
2053
	}
2054
	major = ssh_gssapi_sign(gsscontext, &data, &hash);
2055
2056
	xfree(data.value);
2057
2058
	buffer_clear(m);
2059
	buffer_put_int(m, major);
2060
	buffer_put_string(m, hash.value, hash.length);
2061
2062
	mm_request_send(socket, MONITOR_ANS_GSSSIGN, m);
2063
2064
	gss_release_buffer(&minor, &hash);
2065
2066
	/* Turn on getpwnam permissions */
2067
	monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
2068
2069
	return (0);
2070
}
2071
1995
#endif /* GSSAPI */
2072
#endif /* GSSAPI */
1996
2073
1997
#ifdef JPAKE
2074
#ifdef JPAKE
(-)monitor.h.orig (+1 lines)
Lines 53-58 Link Here
53
	MONITOR_REQ_GSSSTEP, MONITOR_ANS_GSSSTEP,
53
	MONITOR_REQ_GSSSTEP, MONITOR_ANS_GSSSTEP,
54
	MONITOR_REQ_GSSUSEROK, MONITOR_ANS_GSSUSEROK,
54
	MONITOR_REQ_GSSUSEROK, MONITOR_ANS_GSSUSEROK,
55
	MONITOR_REQ_GSSCHECKMIC, MONITOR_ANS_GSSCHECKMIC,
55
	MONITOR_REQ_GSSCHECKMIC, MONITOR_ANS_GSSCHECKMIC,
56
	MONITOR_REQ_GSSSIGN, MONITOR_ANS_GSSSIGN,
56
	MONITOR_REQ_PAM_START,
57
	MONITOR_REQ_PAM_START,
57
	MONITOR_REQ_PAM_ACCOUNT, MONITOR_ANS_PAM_ACCOUNT,
58
	MONITOR_REQ_PAM_ACCOUNT, MONITOR_ANS_PAM_ACCOUNT,
58
	MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX,
59
	MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX,
(-)monitor_wrap.c.orig (+23 lines)
Lines 1256-1261 Link Here
1256
	debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not ");
1256
	debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not ");
1257
	return (authenticated);
1257
	return (authenticated);
1258
}
1258
}
1259
1260
OM_uint32
1261
mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash)
1262
{
1263
	Buffer m;
1264
	OM_uint32 major;
1265
	u_int len;
1266
1267
	buffer_init(&m);
1268
	buffer_put_string(&m, data->value, data->length);
1269
1270
	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSIGN, &m);
1271
	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSIGN, &m);
1272
1273
	major = buffer_get_int(&m);
1274
	hash->value = buffer_get_string(&m, &len);
1275
	hash->length = len;
1276
1277
	buffer_free(&m);
1278
1279
	return(major);
1280
}
1281
1259
#endif /* GSSAPI */
1282
#endif /* GSSAPI */
1260
1283
1261
#ifdef JPAKE
1284
#ifdef JPAKE
(-)monitor_wrap.h.orig (+1 lines)
Lines 59-64 Link Here
59
   gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *);
59
   gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *);
60
int mm_ssh_gssapi_userok(char *user);
60
int mm_ssh_gssapi_userok(char *user);
61
OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
61
OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
62
OM_uint32 mm_ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t);
62
#endif
63
#endif
63
64
64
#ifdef USE_PAM
65
#ifdef USE_PAM
(-)readconf.c.orig (-1 / +10 lines)
Lines 127-133 Link Here
127
	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
127
	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
128
	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
128
	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
129
	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
129
	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
130
	oGssTrustDns, 
130
	oGssTrustDns, oGssKeyEx,
131
	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
131
	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
132
	oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
132
	oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
133
	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
133
	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
Lines 165-174 Link Here
165
	{ "afstokenpassing", oUnsupported },
165
	{ "afstokenpassing", oUnsupported },
166
#if defined(GSSAPI)
166
#if defined(GSSAPI)
167
	{ "gssapiauthentication", oGssAuthentication },
167
	{ "gssapiauthentication", oGssAuthentication },
168
	{ "gssapikeyexchange", oGssKeyEx },
168
	{ "gssapidelegatecredentials", oGssDelegateCreds },
169
	{ "gssapidelegatecredentials", oGssDelegateCreds },
169
	{ "gssapitrustdns", oGssTrustDns },
170
	{ "gssapitrustdns", oGssTrustDns },
170
#else
171
#else
171
	{ "gssapiauthentication", oUnsupported },
172
	{ "gssapiauthentication", oUnsupported },
173
	{ "gssapikeyexchange", oUnsupported },
172
	{ "gssapidelegatecredentials", oUnsupported },
174
	{ "gssapidelegatecredentials", oUnsupported },
173
	{ "gssapitrustdns", oUnsupported },
175
	{ "gssapitrustdns", oUnsupported },
174
#endif
176
#endif
Lines 456-461 Link Here
456
		intptr = &options->gss_authentication;
458
		intptr = &options->gss_authentication;
457
		goto parse_flag;
459
		goto parse_flag;
458
460
461
	case oGssKeyEx:
462
		intptr = &options->gss_keyex;
463
		goto parse_flag;
464
459
	case oGssDelegateCreds:
465
	case oGssDelegateCreds:
460
		intptr = &options->gss_deleg_creds;
466
		intptr = &options->gss_deleg_creds;
461
		goto parse_flag;
467
		goto parse_flag;
Lines 1015-1020 Link Here
1015
	options->pubkey_authentication = -1;
1021
	options->pubkey_authentication = -1;
1016
	options->challenge_response_authentication = -1;
1022
	options->challenge_response_authentication = -1;
1017
	options->gss_authentication = -1;
1023
	options->gss_authentication = -1;
1024
	options->gss_keyex = -1;
1018
	options->gss_deleg_creds = -1;
1025
	options->gss_deleg_creds = -1;
1019
	options->gss_trust_dns = -1;
1026
	options->gss_trust_dns = -1;
1020
	options->password_authentication = -1;
1027
	options->password_authentication = -1;
Lines 1107-1112 Link Here
1107
		options->challenge_response_authentication = 1;
1114
		options->challenge_response_authentication = 1;
1108
	if (options->gss_authentication == -1)
1115
	if (options->gss_authentication == -1)
1109
		options->gss_authentication = 0;
1116
		options->gss_authentication = 0;
1117
	if (options->gss_keyex == -1)
1118
		options->gss_keyex = 0;
1110
	if (options->gss_deleg_creds == -1)
1119
	if (options->gss_deleg_creds == -1)
1111
		options->gss_deleg_creds = 0;
1120
		options->gss_deleg_creds = 0;
1112
	if (options->gss_trust_dns == -1)
1121
	if (options->gss_trust_dns == -1)
(-)readconf.h.orig (+1 lines)
Lines 44-49 Link Here
44
	int     challenge_response_authentication;
44
	int     challenge_response_authentication;
45
					/* Try S/Key or TIS, authentication. */
45
					/* Try S/Key or TIS, authentication. */
46
	int     gss_authentication;	/* Try GSS authentication */
46
	int     gss_authentication;	/* Try GSS authentication */
47
	int     gss_keyex;		/* Try GSS key exchange */
47
	int     gss_deleg_creds;	/* Delegate GSS credentials */
48
	int     gss_deleg_creds;	/* Delegate GSS credentials */
48
	int	gss_trust_dns;		/* Trust DNS for GSS canonicalization */
49
	int	gss_trust_dns;		/* Trust DNS for GSS canonicalization */
49
	int     password_authentication;	/* Try password
50
	int     password_authentication;	/* Try password
(-)servconf.c.orig (-1 / +11 lines)
Lines 92-97 Link Here
92
	options->kerberos_ticket_cleanup = -1;
92
	options->kerberos_ticket_cleanup = -1;
93
	options->kerberos_get_afs_token = -1;
93
	options->kerberos_get_afs_token = -1;
94
	options->gss_authentication=-1;
94
	options->gss_authentication=-1;
95
	options->gss_keyex = -1;
95
	options->gss_cleanup_creds = -1;
96
	options->gss_cleanup_creds = -1;
96
	options->gss_strict_acceptor = -1;
97
	options->gss_strict_acceptor = -1;
97
	options->password_authentication = -1;
98
	options->password_authentication = -1;
Lines 211-220 Link Here
211
		options->kerberos_get_afs_token = 0;
212
		options->kerberos_get_afs_token = 0;
212
	if (options->gss_authentication == -1)
213
	if (options->gss_authentication == -1)
213
		options->gss_authentication = 0;
214
		options->gss_authentication = 0;
215
	if (options->gss_keyex == -1)
216
		options->gss_keyex = 0;
214
	if (options->gss_cleanup_creds == -1)
217
	if (options->gss_cleanup_creds == -1)
215
		options->gss_cleanup_creds = 1;
218
		options->gss_cleanup_creds = 1;
216
	if (options->gss_strict_acceptor == -1)
219
	if (options->gss_strict_acceptor == -1)
217
		options->gss_strict_acceptor = 0;
220
		options->gss_strict_acceptor = 1;
218
	if (options->password_authentication == -1)
221
	if (options->password_authentication == -1)
219
		options->password_authentication = 1;
222
		options->password_authentication = 1;
220
	if (options->kbd_interactive_authentication == -1)
223
	if (options->kbd_interactive_authentication == -1)
Lines 306-311 Link Here
306
	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
309
	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
307
	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
310
	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
308
	sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
311
	sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
312
	sGssKeyEx,
309
	sAcceptEnv, sPermitTunnel,
313
	sAcceptEnv, sPermitTunnel,
310
	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
314
	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
311
	sUsePrivilegeSeparation, sAllowAgentForwarding,
315
	sUsePrivilegeSeparation, sAllowAgentForwarding,
Lines 369-378 Link Here
369
	{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
373
	{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
370
	{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
374
	{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
371
	{ "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
375
	{ "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
376
	{ "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
372
#else
377
#else
373
	{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
378
	{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
374
	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
379
	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
375
	{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
380
	{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
381
	{ "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
376
#endif
382
#endif
377
	{ "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
383
	{ "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
378
	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
384
	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
Lines 897-902 Link Here
897
		intptr = &options->gss_authentication;
903
		intptr = &options->gss_authentication;
898
		goto parse_flag;
904
		goto parse_flag;
899
905
906
	case sGssKeyEx:
907
		intptr = &options->gss_keyex;
908
		goto parse_flag;
909
900
	case sGssCleanupCreds:
910
	case sGssCleanupCreds:
901
		intptr = &options->gss_cleanup_creds;
911
		intptr = &options->gss_cleanup_creds;
902
		goto parse_flag;
912
		goto parse_flag;
(-)servconf.h.orig (+1 lines)
Lines 91-96 Link Here
91
	int     kerberos_get_afs_token;		/* If true, try to get AFS token if
91
	int     kerberos_get_afs_token;		/* If true, try to get AFS token if
92
						 * authenticated with Kerberos. */
92
						 * authenticated with Kerberos. */
93
	int     gss_authentication;	/* If true, permit GSSAPI authentication */
93
	int     gss_authentication;	/* If true, permit GSSAPI authentication */
94
	int     gss_keyex;		/* If true, permit GSSAPI key exchange */
94
	int     gss_cleanup_creds;	/* If true, destroy cred cache on logout */
95
	int     gss_cleanup_creds;	/* If true, destroy cred cache on logout */
95
	int 	gss_strict_acceptor;	/* If true, restrict the GSSAPI acceptor name */
96
	int 	gss_strict_acceptor;	/* If true, restrict the GSSAPI acceptor name */
96
	int     password_authentication;	/* If true, permit password
97
	int     password_authentication;	/* If true, permit password
(-)ssh-gss.h.orig (+19 lines)
Lines 60-65 Link Here
60
60
61
#define SSH_GSS_OIDTYPE 0x06
61
#define SSH_GSS_OIDTYPE 0x06
62
62
63
#define SSH2_MSG_KEXGSS_INIT                            30
64
#define SSH2_MSG_KEXGSS_CONTINUE                        31
65
#define SSH2_MSG_KEXGSS_COMPLETE                        32
66
#define SSH2_MSG_KEXGSS_HOSTKEY                         33
67
#define SSH2_MSG_KEXGSS_ERROR                           34
68
#define SSH2_MSG_KEXGSS_GROUPREQ			40
69
#define SSH2_MSG_KEXGSS_GROUP				41
70
#define KEX_GSS_GRP1_SHA1_ID				"gss-group1-sha1-"
71
#define KEX_GSS_GRP14_SHA1_ID				"gss-group14-sha1-"
72
#define KEX_GSS_GEX_SHA1_ID				"gss-gex-sha1-"
73
63
typedef struct {
74
typedef struct {
64
	char *filename;
75
	char *filename;
65
	char *envvar;
76
	char *envvar;
Lines 97-102 Link Here
97
} Gssctxt;
108
} Gssctxt;
98
109
99
extern ssh_gssapi_mech *supported_mechs[];
110
extern ssh_gssapi_mech *supported_mechs[];
111
extern Gssctxt *gss_kex_context;
100
112
101
int  ssh_gssapi_check_oid(Gssctxt *, void *, size_t);
113
int  ssh_gssapi_check_oid(Gssctxt *, void *, size_t);
102
void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t);
114
void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t);
Lines 119-124 Link Here
119
int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *);
131
int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *);
120
132
121
/* In the server */
133
/* In the server */
134
typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *);
135
char *ssh_gssapi_client_mechanisms(const char *host);
136
char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, const char *);
137
gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int);
138
int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *);
122
OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
139
OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
123
int ssh_gssapi_userok(char *name);
140
int ssh_gssapi_userok(char *name);
124
OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
141
OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
Lines 126-131 Link Here
126
void ssh_gssapi_cleanup_creds(void);
143
void ssh_gssapi_cleanup_creds(void);
127
void ssh_gssapi_storecreds(void);
144
void ssh_gssapi_storecreds(void);
128
145
146
char *ssh_gssapi_server_mechanisms(void);
147
int ssh_gssapi_oid_table_ok();
129
#endif /* GSSAPI */
148
#endif /* GSSAPI */
130
149
131
#endif /* _SSH_GSS_H */
150
#endif /* _SSH_GSS_H */
(-)ssh_config.orig (+2 lines)
Lines 26-31 Link Here
26
#   HostbasedAuthentication no
26
#   HostbasedAuthentication no
27
#   GSSAPIAuthentication no
27
#   GSSAPIAuthentication no
28
#   GSSAPIDelegateCredentials no
28
#   GSSAPIDelegateCredentials no
29
#   GSSAPIKeyExchange no
30
#   GSSAPITrustDNS no
29
#   BatchMode no
31
#   BatchMode no
30
#   CheckHostIP yes
32
#   CheckHostIP yes
31
#   AddressFamily any
33
#   AddressFamily any
(-)ssh_config.5.orig (+6 lines)
Lines 478-483 Link Here
478
The default is
478
The default is
479
.Dq no .
479
.Dq no .
480
Note that this option applies to protocol version 2 only.
480
Note that this option applies to protocol version 2 only.
481
.It Cm GSSAPIKeyExchange
482
Specifies whether key exchange based on GSSAPI may be used. When using
483
GSSAPI key exchange the server need not have a host key.
484
The default is
485
.Dq no .
486
Note that this option applies to protocol version 2 only.
481
.It Cm GSSAPIDelegateCredentials
487
.It Cm GSSAPIDelegateCredentials
482
Forward (delegate) credentials to the server.
488
Forward (delegate) credentials to the server.
483
The default is
489
The default is
(-)sshconnect2.c.orig (-3 / +104 lines)
Lines 104-112 Link Here
104
{
104
{
105
	Kex *kex;
105
	Kex *kex;
106
106
107
#ifdef GSSAPI
108
	char *orig = NULL, *gss = NULL;
109
	char *gss_host = NULL;
110
#endif
111
107
	xxx_host = host;
112
	xxx_host = host;
108
	xxx_hostaddr = hostaddr;
113
	xxx_hostaddr = hostaddr;
109
114
115
#ifdef GSSAPI
116
	if (options.gss_keyex) {
117
		/* Add the GSSAPI mechanisms currently supported on this 
118
		 * client to the key exchange algorithm proposal */
119
		orig = myproposal[PROPOSAL_KEX_ALGS];
120
121
		if (options.gss_trust_dns)
122
			gss_host = (char *)get_canonical_hostname(1);
123
		else
124
			gss_host = host;
125
126
		gss = ssh_gssapi_client_mechanisms(gss_host);
127
		if (gss) {
128
			debug("Offering GSSAPI proposal: %s", gss);
129
			xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
130
			    "%s,%s", gss, orig);
131
		}
132
	}
133
#endif
134
110
	if (options.ciphers == (char *)-1) {
135
	if (options.ciphers == (char *)-1) {
111
		logit("No valid ciphers for protocol version 2 given, using defaults.");
136
		logit("No valid ciphers for protocol version 2 given, using defaults.");
112
		options.ciphers = NULL;
137
		options.ciphers = NULL;
Lines 134-139 Link Here
134
		myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
159
		myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
135
		    options.hostkeyalgorithms;
160
		    options.hostkeyalgorithms;
136
161
162
#ifdef GSSAPI
163
	/* If we've got GSSAPI algorithms, then we also support the
164
	 * 'null' hostkey, as a last resort */
165
	if (options.gss_keyex && gss) {
166
		orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
167
		xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], 
168
		    "%s,null", orig);
169
		xfree(gss);
170
	}
171
#endif
172
137
	if (options.rekey_limit)
173
	if (options.rekey_limit)
138
		packet_set_rekey_limit((u_int32_t)options.rekey_limit);
174
		packet_set_rekey_limit((u_int32_t)options.rekey_limit);
139
175
Lines 143-152 Link Here
143
	kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
179
	kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
144
	kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
180
	kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
145
	kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
181
	kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
182
#ifdef GSSAPI
183
	if (options.gss_keyex) {
184
		kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client;
185
		kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_client;
186
		kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client;
187
	}
188
#endif
146
	kex->client_version_string=client_version_string;
189
	kex->client_version_string=client_version_string;
147
	kex->server_version_string=server_version_string;
190
	kex->server_version_string=server_version_string;
148
	kex->verify_host_key=&verify_host_key_callback;
191
	kex->verify_host_key=&verify_host_key_callback;
149
192
193
#ifdef GSSAPI
194
	if (options.gss_keyex) {
195
		kex->gss_deleg_creds = options.gss_deleg_creds;
196
		kex->gss_trust_dns = options.gss_trust_dns;
197
		kex->gss_host = gss_host;
198
	}
199
#endif
200
150
	xxx_kex = kex;
201
	xxx_kex = kex;
151
202
152
	dispatch_run(DISPATCH_BLOCK, &kex->done, kex);
203
	dispatch_run(DISPATCH_BLOCK, &kex->done, kex);
Lines 235-240 Link Here
235
void	input_gssapi_hash(int type, u_int32_t, void *);
286
void	input_gssapi_hash(int type, u_int32_t, void *);
236
void	input_gssapi_error(int, u_int32_t, void *);
287
void	input_gssapi_error(int, u_int32_t, void *);
237
void	input_gssapi_errtok(int, u_int32_t, void *);
288
void	input_gssapi_errtok(int, u_int32_t, void *);
289
int	userauth_gsskeyex(Authctxt *authctxt);
238
#endif
290
#endif
239
291
240
void	userauth(Authctxt *, char *);
292
void	userauth(Authctxt *, char *);
Lines 250-255 Link Here
250
302
251
Authmethod authmethods[] = {
303
Authmethod authmethods[] = {
252
#ifdef GSSAPI
304
#ifdef GSSAPI
305
	{"gssapi-keyex",
306
		userauth_gsskeyex,
307
		&options.gss_authentication,
308
		NULL},
253
	{"gssapi-with-mic",
309
	{"gssapi-with-mic",
254
		userauth_gssapi,
310
		userauth_gssapi,
255
		NULL,
311
		NULL,
Lines 552-558 Link Here
552
	 * once. */
608
	 * once. */
553
609
554
	if (gss_supported == NULL)
610
	if (gss_supported == NULL)
555
		gss_indicate_mechs(&min, &gss_supported);
611
		if (GSS_ERROR(gss_indicate_mechs(&min, &gss_supported))) {
612
			gss_supported = NULL;
613
			return 0;
614
		}
556
615
557
	/* Check to see if the mechanism is usable before we offer it */
616
	/* Check to see if the mechanism is usable before we offer it */
558
	while (mech < gss_supported->count && !ok) {
617
	while (mech < gss_supported->count && !ok) {
Lines 656-663 Link Here
656
{
715
{
657
	Authctxt *authctxt = ctxt;
716
	Authctxt *authctxt = ctxt;
658
	Gssctxt *gssctxt;
717
	Gssctxt *gssctxt;
659
	int oidlen;
718
	u_int oidlen;
660
	char *oidv;
719
	u_char *oidv;
661
720
662
	if (authctxt == NULL)
721
	if (authctxt == NULL)
663
		fatal("input_gssapi_response: no authentication context");
722
		fatal("input_gssapi_response: no authentication context");
Lines 767-772 Link Here
767
	xfree(msg);
826
	xfree(msg);
768
	xfree(lang);
827
	xfree(lang);
769
}
828
}
829
830
int
831
userauth_gsskeyex(Authctxt *authctxt)
832
{
833
	Buffer b;
834
	gss_buffer_desc gssbuf;
835
	gss_buffer_desc mic = GSS_C_EMPTY_BUFFER;
836
	OM_uint32 ms;
837
838
	static int attempt = 0;
839
	if (attempt++ >= 1)
840
		return (0);
841
842
	if (gss_kex_context == NULL) {
843
		debug("No valid Key exchange context"); 
844
		return (0);
845
	}
846
847
	ssh_gssapi_buildmic(&b, authctxt->server_user, authctxt->service,
848
	    "gssapi-keyex");
849
850
	gssbuf.value = buffer_ptr(&b);
851
	gssbuf.length = buffer_len(&b);
852
853
	if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) {
854
		buffer_free(&b);
855
		return (0);
856
	}
857
858
	packet_start(SSH2_MSG_USERAUTH_REQUEST);
859
	packet_put_cstring(authctxt->server_user);
860
	packet_put_cstring(authctxt->service);
861
	packet_put_cstring(authctxt->method->name);
862
	packet_put_string(mic.value, mic.length);
863
	packet_send();
864
865
	buffer_free(&b);
866
	gss_release_buffer(&ms, &mic);
867
868
	return (1);
869
}
870
770
#endif /* GSSAPI */
871
#endif /* GSSAPI */
771
872
772
int
873
int
(-)sshd.c.orig (+52 lines)
Lines 1534-1543 Link Here
1534
		logit("Disabling protocol version 1. Could not load host key");
1534
		logit("Disabling protocol version 1. Could not load host key");
1535
		options.protocol &= ~SSH_PROTO_1;
1535
		options.protocol &= ~SSH_PROTO_1;
1536
	}
1536
	}
1537
#ifndef GSSAPI
1538
	/* The GSSAPI key exchange can run without a host key */
1537
	if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) {
1539
	if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) {
1538
		logit("Disabling protocol version 2. Could not load host key");
1540
		logit("Disabling protocol version 2. Could not load host key");
1539
		options.protocol &= ~SSH_PROTO_2;
1541
		options.protocol &= ~SSH_PROTO_2;
1540
	}
1542
	}
1543
#endif
1541
	if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) {
1544
	if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) {
1542
		logit("sshd: no hostkeys available -- exiting.");
1545
		logit("sshd: no hostkeys available -- exiting.");
1543
		exit(1);
1546
		exit(1);
Lines 2252-2263 Link Here
2252
2255
2253
	myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types();
2256
	myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types();
2254
2257
2258
#ifdef GSSAPI
2259
	{
2260
	char *orig;
2261
	char *gss = NULL;
2262
	char *newstr = NULL;
2263
	orig = myproposal[PROPOSAL_KEX_ALGS];
2264
2265
	/* 
2266
	 * If we don't have a host key, then there's no point advertising
2267
	 * the other key exchange algorithms
2268
	 */
2269
2270
	if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0)
2271
		orig = NULL;
2272
2273
	if (options.gss_keyex)
2274
		gss = ssh_gssapi_server_mechanisms();
2275
	else
2276
		gss = NULL;
2277
2278
	if (gss && orig)
2279
		xasprintf(&newstr, "%s,%s", gss, orig);
2280
	else if (gss)
2281
		newstr = gss;
2282
	else if (orig)
2283
		newstr = orig;
2284
2285
	/* 
2286
	 * If we've got GSSAPI mechanisms, then we've got the 'null' host
2287
	 * key alg, but we can't tell people about it unless its the only
2288
  	 * host key algorithm we support
2289
	 */
2290
	if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0)
2291
		myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null";
2292
2293
	if (newstr)
2294
		myproposal[PROPOSAL_KEX_ALGS] = newstr;
2295
	else
2296
		fatal("No supported key exchange algorithms");
2297
	}
2298
#endif
2299
2255
	/* start key exchange */
2300
	/* start key exchange */
2256
	kex = kex_setup(myproposal);
2301
	kex = kex_setup(myproposal);
2257
	kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
2302
	kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
2258
	kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
2303
	kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
2259
	kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
2304
	kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
2260
	kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
2305
	kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
2306
#ifdef GSSAPI
2307
	if (options.gss_keyex) {
2308
		kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
2309
		kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
2310
		kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
2311
	}
2312
#endif
2261
	kex->server = 1;
2313
	kex->server = 1;
2262
	kex->client_version_string=client_version_string;
2314
	kex->client_version_string=client_version_string;
2263
	kex->server_version_string=server_version_string;
2315
	kex->server_version_string=server_version_string;
(-)sshd_config.orig (+1 lines)
Lines 74-79 Link Here
74
#GSSAPIAuthentication no
74
#GSSAPIAuthentication no
75
#GSSAPICleanupCredentials yes
75
#GSSAPICleanupCredentials yes
76
#GSSAPIStrictAcceptorCheck yes
76
#GSSAPIStrictAcceptorCheck yes
77
#GSSAPIKeyExchange no
77
78
78
# Set this to 'yes' to enable PAM authentication, account processing, 
79
# Set this to 'yes' to enable PAM authentication, account processing, 
79
# and session processing. If this is enabled, PAM authentication will 
80
# and session processing. If this is enabled, PAM authentication will 
(-)sshd_config.5.orig (+6 lines)
Lines 374-379 Link Here
374
The default is
374
The default is
375
.Dq no .
375
.Dq no .
376
Note that this option applies to protocol version 2 only.
376
Note that this option applies to protocol version 2 only.
377
.It Cm GSSAPIKeyExchange
378
Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange
379
doesn't rely on ssh keys to verify host identity.
380
The default is
381
.Dq no .
382
Note that this option applies to protocol version 2 only.
377
.It Cm GSSAPICleanupCredentials
383
.It Cm GSSAPICleanupCredentials
378
Specifies whether to automatically destroy the user's credentials cache
384
Specifies whether to automatically destroy the user's credentials cache
379
on logout.
385
on logout.

Return to bug 1242