summaryrefslogtreecommitdiff
path: root/gss-genr.c
diff options
context:
space:
mode:
Diffstat (limited to 'gss-genr.c')
-rw-r--r--gss-genr.c173
1 files changed, 172 insertions, 1 deletions
diff --git a/gss-genr.c b/gss-genr.c
index c2b4f2dd8..dfaa708ea 100644
--- a/gss-genr.c
+++ b/gss-genr.c
@@ -1,7 +1,7 @@
1/* $OpenBSD: gss-genr.c,v 1.6 2005/10/13 22:24:31 stevesk Exp $ */ 1/* $OpenBSD: gss-genr.c,v 1.6 2005/10/13 22:24:31 stevesk Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. 4 * Copyright (c) 2001-2005 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
@@ -32,12 +32,152 @@
32#include "bufaux.h" 32#include "bufaux.h"
33#include "log.h" 33#include "log.h"
34#include "ssh2.h" 34#include "ssh2.h"
35#include <openssl/evp.h>
35 36
36#include "ssh-gss.h" 37#include "ssh-gss.h"
37 38
38extern u_char *session_id2; 39extern u_char *session_id2;
39extern u_int session_id2_len; 40extern u_int session_id2_len;
40 41
42typedef struct {
43 char *encoded;
44 gss_OID oid;
45} ssh_gss_kex_mapping;
46
47/*
48 * XXX - It would be nice to find a more elegant way of handling the
49 * XXX passing of the key exchange context to the userauth routines
50 */
51
52Gssctxt *gss_kex_context = NULL;
53
54static ssh_gss_kex_mapping *gss_enc2oid = NULL;
55
56int
57ssh_gssapi_oid_table_ok() {
58 return (gss_enc2oid != NULL);
59}
60
61/*
62 * Return a list of the gss-group1-sha1 mechanisms supported by this program
63 *
64 * We test mechanisms to ensure that we can use them, to avoid starting
65 * a key exchange with a bad mechanism
66 */
67
68
69char *
70ssh_gssapi_client_mechanisms(const char *host) {
71 gss_OID_set gss_supported;
72 OM_uint32 min_status;
73
74 gss_indicate_mechs(&min_status, &gss_supported);
75
76 return(ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism,
77 (void *)host));
78}
79
80char *
81ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check,
82 void *data) {
83 Buffer buf;
84 int i, oidpos, enclen;
85 char *mechs, *encoded;
86 char digest[EVP_MAX_MD_SIZE];
87 char deroid[2];
88 const EVP_MD *evp_md = EVP_md5();
89 EVP_MD_CTX md;
90
91 if (gss_enc2oid != NULL) {
92 for (i=0;gss_enc2oid[i].encoded!=NULL;i++)
93 xfree(gss_enc2oid[i].encoded);
94 xfree(gss_enc2oid);
95 }
96
97 gss_enc2oid = xmalloc(sizeof(ssh_gss_kex_mapping)*
98 (gss_supported->count+1));
99
100 buffer_init(&buf);
101
102 oidpos = 0;
103 for (i = 0;i < gss_supported->count;i++) {
104 if (gss_supported->elements[i].length < 128 &&
105 (*check)(&(gss_supported->elements[i]), data)) {
106
107 deroid[0] = SSH_GSS_OIDTYPE;
108 deroid[1] = gss_supported->elements[i].length;
109
110 EVP_DigestInit(&md, evp_md);
111 EVP_DigestUpdate(&md, deroid, 2);
112 EVP_DigestUpdate(&md,
113 gss_supported->elements[i].elements,
114 gss_supported->elements[i].length);
115 EVP_DigestFinal(&md, digest, NULL);
116
117 encoded = xmalloc(EVP_MD_size(evp_md)*2);
118 enclen = __b64_ntop(digest, EVP_MD_size(evp_md),
119 encoded, EVP_MD_size(evp_md)*2);
120
121 if (oidpos != 0)
122 buffer_put_char(&buf, ',');
123
124 buffer_append(&buf, KEX_GSS_GEX_SHA1_ID,
125 sizeof(KEX_GSS_GEX_SHA1_ID)-1);
126 buffer_append(&buf, encoded, enclen);
127 buffer_put_char(&buf,',');
128 buffer_append(&buf, KEX_GSS_GRP1_SHA1_ID,
129 sizeof(KEX_GSS_GRP1_SHA1_ID)-1);
130 buffer_append(&buf, encoded, enclen);
131
132 gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]);
133 gss_enc2oid[oidpos].encoded = encoded;
134 oidpos++;
135 }
136 }
137 gss_enc2oid[oidpos].oid = NULL;
138 gss_enc2oid[oidpos].encoded = NULL;
139
140 buffer_put_char(&buf, '\0');
141
142 mechs = xmalloc(buffer_len(&buf));
143 buffer_get(&buf, mechs, buffer_len(&buf));
144 buffer_free(&buf);
145
146 if (strlen(mechs) == 0) {
147 xfree(mechs);
148 mechs = NULL;
149 }
150
151 return (mechs);
152}
153
154gss_OID
155ssh_gssapi_id_kex(Gssctxt *ctx, char *name, int *gex) {
156 int i = 0;
157
158 if (strncmp(name, KEX_GSS_GRP1_SHA1_ID,
159 sizeof(KEX_GSS_GRP1_SHA1_ID)-1) == 0) {
160 name+=sizeof(KEX_GSS_GRP1_SHA1_ID)-1;
161 *gex = 0;
162 } else if (strncmp(name, KEX_GSS_GEX_SHA1_ID,
163 sizeof(KEX_GSS_GEX_SHA1_ID)-1) == 0) {
164 name+=sizeof(KEX_GSS_GEX_SHA1_ID)-1;
165 *gex = 1;
166 } else {
167 return NULL;
168 }
169
170 while (gss_enc2oid[i].encoded != NULL &&
171 strcmp(name, gss_enc2oid[i].encoded) != 0) {
172 i++;
173 }
174
175 if (gss_enc2oid[i].oid != NULL && ctx != NULL)
176 ssh_gssapi_set_oid(ctx, gss_enc2oid[i].oid);
177
178 return gss_enc2oid[i].oid;
179}
180
41/* Check that the OID in a data stream matches that in the context */ 181/* Check that the OID in a data stream matches that in the context */
42int 182int
43ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len) 183ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len)
@@ -248,6 +388,9 @@ ssh_gssapi_acquire_cred(Gssctxt *ctx)
248OM_uint32 388OM_uint32
249ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) 389ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash)
250{ 390{
391 if (ctx == NULL)
392 return -1;
393
251 if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context, 394 if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context,
252 GSS_C_QOP_DEFAULT, buffer, hash))) 395 GSS_C_QOP_DEFAULT, buffer, hash)))
253 ssh_gssapi_error(ctx); 396 ssh_gssapi_error(ctx);
@@ -255,6 +398,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash)
255 return (ctx->major); 398 return (ctx->major);
256} 399}
257 400
401/* Priviledged when used by server */
402OM_uint32
403ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
404{
405 if (ctx == NULL)
406 return -1;
407
408 ctx->major = gss_verify_mic(&ctx->minor, ctx->context,
409 gssbuf, gssmic, NULL);
410
411 return (ctx->major);
412}
413
258void 414void
259ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service, 415ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service,
260 const char *context) 416 const char *context)
@@ -277,4 +433,19 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid)
277 return (ssh_gssapi_acquire_cred(*ctx)); 433 return (ssh_gssapi_acquire_cred(*ctx));
278} 434}
279 435
436int
437ssh_gssapi_check_mechanism(gss_OID oid, void *host) {
438 Gssctxt * ctx = NULL;
439 gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
440 OM_uint32 major, minor;
441
442 ssh_gssapi_build_ctx(&ctx);
443 ssh_gssapi_set_oid(ctx, oid);
444 ssh_gssapi_import_name(ctx, host);
445 major = ssh_gssapi_init_ctx(ctx, 0, GSS_C_NO_BUFFER, &token, NULL);
446 gss_release_buffer(&minor, &token);
447 ssh_gssapi_delete_ctx(&ctx);
448 return (!GSS_ERROR(major));
449}
450
280#endif /* GSSAPI */ 451#endif /* GSSAPI */