summaryrefslogtreecommitdiff
path: root/auth2-gss.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2004-03-01 02:25:32 +0000
committerColin Watson <cjwatson@debian.org>2004-03-01 02:25:32 +0000
commitea8116a11e3de70036dbc665ccb0d486cf89cac9 (patch)
treed73ccdff78d8608e156465af42e6a1b3527fb2d6 /auth2-gss.c
parente39b311381a5609cc05acf298c42fba196dc524b (diff)
parentf5bda272678ec6dccaa5f29379cf60cb855018e8 (diff)
Merge 3.8p1 to the trunk. This builds and runs, but I haven't tested it
extensively yet. ProtocolKeepAlives is now just a compatibility alias for ServerAliveInterval.
Diffstat (limited to 'auth2-gss.c')
-rw-r--r--auth2-gss.c84
1 files changed, 66 insertions, 18 deletions
diff --git a/auth2-gss.c b/auth2-gss.c
index 75b94b009..9249988d3 100644
--- a/auth2-gss.c
+++ b/auth2-gss.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-gss.c,v 1.3 2003/09/01 20:44:54 markus Exp $ */ 1/* $OpenBSD: auth2-gss.c,v 1.7 2003/11/21 11:57:03 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. 4 * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@@ -43,6 +43,7 @@
43extern ServerOptions options; 43extern ServerOptions options;
44 44
45static void input_gssapi_token(int type, u_int32_t plen, void *ctxt); 45static void input_gssapi_token(int type, u_int32_t plen, void *ctxt);
46static void input_gssapi_mic(int type, u_int32_t plen, void *ctxt);
46static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt); 47static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt);
47static void input_gssapi_errtok(int, u_int32_t, void *); 48static void input_gssapi_errtok(int, u_int32_t, void *);
48 49
@@ -78,17 +79,19 @@ userauth_gssapi(Authctxt *authctxt)
78 if (doid) 79 if (doid)
79 xfree(doid); 80 xfree(doid);
80 81
82 present = 0;
81 doid = packet_get_string(&len); 83 doid = packet_get_string(&len);
82 84
83 if (doid[0] != SSH_GSS_OIDTYPE || doid[1] != len-2) { 85 if (len > 2 &&
84 logit("Mechanism OID received using the old encoding form"); 86 doid[0] == SSH_GSS_OIDTYPE &&
85 oid.elements = doid; 87 doid[1] == len - 2) {
86 oid.length = len;
87 } else {
88 oid.elements = doid + 2; 88 oid.elements = doid + 2;
89 oid.length = len - 2; 89 oid.length = len - 2;
90 gss_test_oid_set_member(&ms, &oid, supported,
91 &present);
92 } else {
93 logit("Badly formed OID received");
90 } 94 }
91 gss_test_oid_set_member(&ms, &oid, supported, &present);
92 } while (mechs > 0 && !present); 95 } while (mechs > 0 && !present);
93 96
94 gss_release_oid_set(&ms, &supported); 97 gss_release_oid_set(&ms, &supported);
@@ -107,7 +110,7 @@ userauth_gssapi(Authctxt *authctxt)
107 110
108 packet_start(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE); 111 packet_start(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE);
109 112
110 /* Return OID in same format as we received it*/ 113 /* Return the OID that we received */
111 packet_put_string(doid, len); 114 packet_put_string(doid, len);
112 115
113 packet_send(); 116 packet_send();
@@ -127,7 +130,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
127 Gssctxt *gssctxt; 130 Gssctxt *gssctxt;
128 gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; 131 gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
129 gss_buffer_desc recv_tok; 132 gss_buffer_desc recv_tok;
130 OM_uint32 maj_status, min_status; 133 OM_uint32 maj_status, min_status, flags;
131 u_int len; 134 u_int len;
132 135
133 if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) 136 if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
@@ -140,7 +143,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
140 packet_check_eom(); 143 packet_check_eom();
141 144
142 maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok, 145 maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok,
143 &send_tok, NULL)); 146 &send_tok, &flags));
144 147
145 xfree(recv_tok.value); 148 xfree(recv_tok.value);
146 149
@@ -152,7 +155,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
152 } 155 }
153 authctxt->postponed = 0; 156 authctxt->postponed = 0;
154 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); 157 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
155 userauth_finish(authctxt, 0, "gssapi"); 158 userauth_finish(authctxt, 0, "gssapi-with-mic");
156 } else { 159 } else {
157 if (send_tok.length != 0) { 160 if (send_tok.length != 0) {
158 packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); 161 packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
@@ -161,8 +164,13 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
161 } 164 }
162 if (maj_status == GSS_S_COMPLETE) { 165 if (maj_status == GSS_S_COMPLETE) {
163 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); 166 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
164 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, 167 if (flags & GSS_C_INTEG_FLAG)
165 &input_gssapi_exchange_complete); 168 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC,
169 &input_gssapi_mic);
170 else
171 dispatch_set(
172 SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
173 &input_gssapi_exchange_complete);
166 } 174 }
167 } 175 }
168 176
@@ -222,9 +230,8 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
222 gssctxt = authctxt->methoddata; 230 gssctxt = authctxt->methoddata;
223 231
224 /* 232 /*
225 * We don't need to check the status, because the stored credentials 233 * We don't need to check the status, because we're only enabled in
226 * which userok uses are only populated once the context init step 234 * the dispatcher once the exchange is complete
227 * has returned complete.
228 */ 235 */
229 236
230 packet_check_eom(); 237 packet_check_eom();
@@ -234,12 +241,53 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
234 authctxt->postponed = 0; 241 authctxt->postponed = 0;
235 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); 242 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
236 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); 243 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
244 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
245 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
246 userauth_finish(authctxt, authenticated, "gssapi-with-mic");
247}
248
249static void
250input_gssapi_mic(int type, u_int32_t plen, void *ctxt)
251{
252 Authctxt *authctxt = ctxt;
253 Gssctxt *gssctxt;
254 int authenticated = 0;
255 Buffer b;
256 gss_buffer_desc mic, gssbuf;
257 u_int len;
258
259 if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
260 fatal("No authentication or GSSAPI context");
261
262 gssctxt = authctxt->methoddata;
263
264 mic.value = packet_get_string(&len);
265 mic.length = len;
266
267 ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service,
268 "gssapi-with-mic");
269
270 gssbuf.value = buffer_ptr(&b);
271 gssbuf.length = buffer_len(&b);
272
273 if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic))))
274 authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
275 else
276 logit("GSSAPI MIC check failed");
277
278 buffer_free(&b);
279 xfree(mic.value);
280
281 authctxt->postponed = 0;
282 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
283 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
284 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
237 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); 285 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
238 userauth_finish(authctxt, authenticated, "gssapi"); 286 userauth_finish(authctxt, authenticated, "gssapi-with-mic");
239} 287}
240 288
241Authmethod method_gssapi = { 289Authmethod method_gssapi = {
242 "gssapi", 290 "gssapi-with-mic",
243 userauth_gssapi, 291 userauth_gssapi,
244 &options.gss_authentication 292 &options.gss_authentication
245}; 293};