summaryrefslogtreecommitdiff
path: root/gss-genr.c
diff options
context:
space:
mode:
Diffstat (limited to 'gss-genr.c')
-rw-r--r--gss-genr.c156
1 files changed, 156 insertions, 0 deletions
diff --git a/gss-genr.c b/gss-genr.c
index c2b4f2dd8..2a905f5e9 100644
--- a/gss-genr.c
+++ b/gss-genr.c
@@ -32,12 +32,137 @@
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
56/*
57 * Return a list of the gss-group1-sha1 mechanisms supported by this program
58 *
59 * We test mechanisms to ensure that we can use them, to avoid starting
60 * a key exchange with a bad mechanism
61 */
62
63
64char *
65ssh_gssapi_client_mechanisms(char *host) {
66 gss_OID_set gss_supported;
67 OM_uint32 min_status;
68
69 gss_indicate_mechs(&min_status, &gss_supported);
70
71 return(ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism,
72 (void *)host));
73}
74
75char *
76ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check,
77 void *data) {
78 Buffer buf;
79 int i, oidpos, enclen;
80 char *mechs, *encoded;
81 char digest[EVP_MAX_MD_SIZE];
82 char deroid[2];
83 const EVP_MD *evp_md = EVP_md5();
84 EVP_MD_CTX md;
85
86 evp_md = EVP_md5();
87
88 if (gss_enc2oid != NULL) {
89 for (i=0;gss_enc2oid[i].encoded!=NULL;i++)
90 xfree(gss_enc2oid[i].encoded);
91 xfree(gss_enc2oid);
92 }
93
94 gss_enc2oid = xmalloc(sizeof(ssh_gss_kex_mapping)*
95 (gss_supported->count+1));
96
97 buffer_init(&buf);
98
99 oidpos = 0;
100 for (i=0;i<gss_supported->count;i++) {
101 if (gss_supported->elements[i].length<128 &&
102 (*check)(&(gss_supported->elements[i]), data)) {
103
104 deroid[0] = SSH_GSS_OIDTYPE;
105 deroid[1] = gss_supported->elements[i].length;
106 EVP_DigestInit(&md, evp_md);
107 EVP_DigestUpdate(&md, deroid, 2);
108 EVP_DigestUpdate(&md,
109 gss_supported->elements[i].elements,
110 gss_supported->elements[i].length);
111 EVP_DigestFinal(&md, digest, NULL);
112
113 encoded = xmalloc(EVP_MD_size(evp_md)*2);
114 enclen = __b64_ntop(digest, EVP_MD_size(evp_md),
115 encoded, EVP_MD_size(evp_md)*2);
116
117 if (oidpos != 0)
118 buffer_put_char(&buf,',');
119
120 buffer_append(&buf, KEX_GSS_SHA1,
121 sizeof(KEX_GSS_SHA1)-1);
122 buffer_append(&buf, encoded, enclen);
123
124 gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]);
125 gss_enc2oid[oidpos].encoded = encoded;
126 oidpos++;
127 }
128 }
129 gss_enc2oid[oidpos].oid = NULL;
130 gss_enc2oid[oidpos].encoded = NULL;
131
132 buffer_put_char(&buf,'\0');
133
134 mechs = xmalloc(buffer_len(&buf));
135 buffer_get(&buf, mechs, buffer_len(&buf));
136 buffer_free(&buf);
137
138 if (strlen(mechs) == 0) {
139 xfree(mechs);
140 mechs = NULL;
141 }
142
143 return (mechs);
144}
145
146gss_OID
147ssh_gssapi_id_kex(Gssctxt *ctx, char *name) {
148 int i = 0;
149
150 if (strncmp(name, KEX_GSS_SHA1, sizeof(KEX_GSS_SHA1)-1) != 0)
151 return NULL;
152
153 name+=sizeof(KEX_GSS_SHA1)-1; /* Skip ID string */
154
155 while (gss_enc2oid[i].encoded != NULL &&
156 strcmp(name,gss_enc2oid[i].encoded)!=0) {
157 i++;
158 }
159
160 if (gss_enc2oid[i].oid != NULL && ctx != NULL)
161 ssh_gssapi_set_oid(ctx,gss_enc2oid[i].oid);
162
163 return gss_enc2oid[i].oid;
164}
165
41/* Check that the OID in a data stream matches that in the context */ 166/* Check that the OID in a data stream matches that in the context */
42int 167int
43ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len) 168ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len)
@@ -248,6 +373,9 @@ ssh_gssapi_acquire_cred(Gssctxt *ctx)
248OM_uint32 373OM_uint32
249ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) 374ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash)
250{ 375{
376 if (ctx == NULL)
377 return -1;
378
251 if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context, 379 if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context,
252 GSS_C_QOP_DEFAULT, buffer, hash))) 380 GSS_C_QOP_DEFAULT, buffer, hash)))
253 ssh_gssapi_error(ctx); 381 ssh_gssapi_error(ctx);
@@ -255,6 +383,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash)
255 return (ctx->major); 383 return (ctx->major);
256} 384}
257 385
386/* Priviledged when used by server */
387OM_uint32
388ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
389{
390 if (ctx == NULL)
391 return -1;
392
393 ctx->major = gss_verify_mic(&ctx->minor, ctx->context,
394 gssbuf, gssmic, NULL);
395
396 return (ctx->major);
397}
398
258void 399void
259ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service, 400ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service,
260 const char *context) 401 const char *context)
@@ -277,4 +418,19 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid)
277 return (ssh_gssapi_acquire_cred(*ctx)); 418 return (ssh_gssapi_acquire_cred(*ctx));
278} 419}
279 420
421int
422ssh_gssapi_check_mechanism(gss_OID oid, void *host) {
423 Gssctxt * ctx = NULL;
424 gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
425 OM_uint32 major, minor;
426
427 ssh_gssapi_build_ctx(&ctx);
428 ssh_gssapi_set_oid(ctx, oid);
429 ssh_gssapi_import_name(ctx, host);
430 major = ssh_gssapi_init_ctx(ctx, 0, GSS_C_NO_BUFFER, &token, NULL);
431 gss_release_buffer(&minor, &token);
432 ssh_gssapi_delete_ctx(&ctx);
433 return (!GSS_ERROR(major));
434}
435
280#endif /* GSSAPI */ 436#endif /* GSSAPI */