summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--auth2-gss.c68
-rw-r--r--gss-genr.c27
-rw-r--r--gss-serv.c12
-rw-r--r--monitor.c36
-rw-r--r--monitor.h3
-rw-r--r--monitor_wrap.c21
-rw-r--r--monitor_wrap.h3
-rw-r--r--ssh-gss.h7
-rw-r--r--sshconnect2.c36
10 files changed, 191 insertions, 29 deletions
diff --git a/ChangeLog b/ChangeLog
index bec42ac50..fb3fdaac5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -43,6 +43,11 @@
43 - djm@cvs.openbsd.org 2003/11/17 09:45:39 43 - djm@cvs.openbsd.org 2003/11/17 09:45:39
44 [msg.c msg.h sshconnect2.c ssh-keysign.c] 44 [msg.c msg.h sshconnect2.c ssh-keysign.c]
45 return error on msg send/receive failure (rather than fatal); ok markus@ 45 return error on msg send/receive failure (rather than fatal); ok markus@
46 - markus@cvs.openbsd.org 2003/11/17 11:06:07
47 [auth2-gss.c gss-genr.c gss-serv.c monitor.c monitor.h monitor_wrap.c]
48 [monitor_wrap.h sshconnect2.c ssh-gss.h]
49 replace "gssapi" with "gssapi-with-mic"; from Simon Wilkinson;
50 test + ok jakob.
46 - (djm) Bug #632: Don't call pam_end indirectly from within kbd-int 51 - (djm) Bug #632: Don't call pam_end indirectly from within kbd-int
47 conversation function 52 conversation function
48 - (djm) Export environment variables from authentication subprocess to 53 - (djm) Export environment variables from authentication subprocess to
@@ -1467,4 +1472,4 @@
1467 - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo. 1472 - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo.
1468 Report from murple@murple.net, diagnosis from dtucker@zip.com.au 1473 Report from murple@murple.net, diagnosis from dtucker@zip.com.au
1469 1474
1470$Id: ChangeLog,v 1.3111 2003/11/17 10:41:42 djm Exp $ 1475$Id: ChangeLog,v 1.3112 2003/11/17 11:18:21 djm Exp $
diff --git a/auth2-gss.c b/auth2-gss.c
index 84fb384f9..220862dc8 100644
--- a/auth2-gss.c
+++ b/auth2-gss.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-gss.c,v 1.5 2003/11/02 11:01:03 markus Exp $ */ 1/* $OpenBSD: auth2-gss.c,v 1.6 2003/11/17 11:06:07 markus 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
@@ -129,7 +130,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
129 Gssctxt *gssctxt; 130 Gssctxt *gssctxt;
130 gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; 131 gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
131 gss_buffer_desc recv_tok; 132 gss_buffer_desc recv_tok;
132 OM_uint32 maj_status, min_status; 133 OM_uint32 maj_status, min_status, flags;
133 u_int len; 134 u_int len;
134 135
135 if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) 136 if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
@@ -142,7 +143,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
142 packet_check_eom(); 143 packet_check_eom();
143 144
144 maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok, 145 maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok,
145 &send_tok, NULL)); 146 &send_tok, &flags));
146 147
147 xfree(recv_tok.value); 148 xfree(recv_tok.value);
148 149
@@ -154,7 +155,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
154 } 155 }
155 authctxt->postponed = 0; 156 authctxt->postponed = 0;
156 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); 157 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
157 userauth_finish(authctxt, 0, "gssapi"); 158 userauth_finish(authctxt, 0, "gssapi-with-mic");
158 } else { 159 } else {
159 if (send_tok.length != 0) { 160 if (send_tok.length != 0) {
160 packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); 161 packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
@@ -163,8 +164,13 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
163 } 164 }
164 if (maj_status == GSS_S_COMPLETE) { 165 if (maj_status == GSS_S_COMPLETE) {
165 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); 166 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
166 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, 167 if (flags & GSS_C_INTEG_FLAG)
167 &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);
168 } 174 }
169 } 175 }
170 176
@@ -224,9 +230,8 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
224 gssctxt = authctxt->methoddata; 230 gssctxt = authctxt->methoddata;
225 231
226 /* 232 /*
227 * 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
228 * which userok uses are only populated once the context init step 234 * the dispatcher once the exchange is complete
229 * has returned complete.
230 */ 235 */
231 236
232 packet_check_eom(); 237 packet_check_eom();
@@ -236,12 +241,53 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
236 authctxt->postponed = 0; 241 authctxt->postponed = 0;
237 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); 242 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
238 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);
239 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); 285 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
240 userauth_finish(authctxt, authenticated, "gssapi"); 286 userauth_finish(authctxt, authenticated, "gssapi-with-mic");
241} 287}
242 288
243Authmethod method_gssapi = { 289Authmethod method_gssapi = {
244 "gssapi", 290 "gssapi-with-mic",
245 userauth_gssapi, 291 userauth_gssapi,
246 &options.gss_authentication 292 &options.gss_authentication
247}; 293};
diff --git a/gss-genr.c b/gss-genr.c
index bda12d6f1..6b7caad0e 100644
--- a/gss-genr.c
+++ b/gss-genr.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: gss-genr.c,v 1.1 2003/08/22 10:56:09 markus Exp $ */ 1/* $OpenBSD: gss-genr.c,v 1.2 2003/11/17 11:06:07 markus 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.
@@ -33,9 +33,12 @@
33#include "compat.h" 33#include "compat.h"
34#include "log.h" 34#include "log.h"
35#include "monitor_wrap.h" 35#include "monitor_wrap.h"
36#include "ssh2.h"
36 37
37#include "ssh-gss.h" 38#include "ssh-gss.h"
38 39
40extern u_char *session_id2;
41extern u_int session_id2_len;
39 42
40/* Check that the OID in a data stream matches that in the context */ 43/* Check that the OID in a data stream matches that in the context */
41int 44int
@@ -245,6 +248,28 @@ ssh_gssapi_acquire_cred(Gssctxt *ctx)
245} 248}
246 249
247OM_uint32 250OM_uint32
251ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash)
252{
253 if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context,
254 GSS_C_QOP_DEFAULT, buffer, hash)))
255 ssh_gssapi_error(ctx);
256
257 return (ctx->major);
258}
259
260void
261ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service,
262 const char *context)
263{
264 buffer_init(b);
265 buffer_put_string(b, session_id2, session_id2_len);
266 buffer_put_char(b, SSH2_MSG_USERAUTH_REQUEST);
267 buffer_put_cstring(b, user);
268 buffer_put_cstring(b, service);
269 buffer_put_cstring(b, context);
270}
271
272OM_uint32
248ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) { 273ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) {
249 if (*ctx) 274 if (*ctx)
250 ssh_gssapi_delete_ctx(ctx); 275 ssh_gssapi_delete_ctx(ctx);
diff --git a/gss-serv.c b/gss-serv.c
index 6574f9750..de32a3f2e 100644
--- a/gss-serv.c
+++ b/gss-serv.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: gss-serv.c,v 1.4 2003/09/23 20:17:11 markus Exp $ */ 1/* $OpenBSD: gss-serv.c,v 1.5 2003/11/17 11:06:07 markus 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.
@@ -287,4 +287,14 @@ ssh_gssapi_userok(char *user)
287 return (0); 287 return (0);
288} 288}
289 289
290/* Priviledged */
291OM_uint32
292ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
293{
294 ctx->major = gss_verify_mic(&ctx->minor, ctx->context,
295 gssbuf, gssmic, NULL);
296
297 return (ctx->major);
298}
299
290#endif 300#endif
diff --git a/monitor.c b/monitor.c
index e83fb45a7..97f1ee9f4 100644
--- a/monitor.c
+++ b/monitor.c
@@ -25,7 +25,7 @@
25 */ 25 */
26 26
27#include "includes.h" 27#include "includes.h"
28RCSID("$OpenBSD: monitor.c,v 1.51 2003/11/04 08:54:09 djm Exp $"); 28RCSID("$OpenBSD: monitor.c,v 1.52 2003/11/17 11:06:07 markus Exp $");
29 29
30#include <openssl/dh.h> 30#include <openssl/dh.h>
31 31
@@ -134,6 +134,7 @@ int mm_answer_pam_free_ctx(int, Buffer *);
134int mm_answer_gss_setup_ctx(int, Buffer *); 134int mm_answer_gss_setup_ctx(int, Buffer *);
135int mm_answer_gss_accept_ctx(int, Buffer *); 135int mm_answer_gss_accept_ctx(int, Buffer *);
136int mm_answer_gss_userok(int, Buffer *); 136int mm_answer_gss_userok(int, Buffer *);
137int mm_answer_gss_checkmic(int, Buffer *);
137#endif 138#endif
138 139
139static Authctxt *authctxt; 140static Authctxt *authctxt;
@@ -193,6 +194,7 @@ struct mon_table mon_dispatch_proto20[] = {
193 {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx}, 194 {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx},
194 {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, 195 {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx},
195 {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, 196 {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
197 {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic},
196#endif 198#endif
197 {0, 0, NULL} 199 {0, 0, NULL}
198}; 200};
@@ -1781,15 +1783,43 @@ mm_answer_gss_accept_ctx(int socket, Buffer *m)
1781 1783
1782 gss_release_buffer(&minor, &out); 1784 gss_release_buffer(&minor, &out);
1783 1785
1784 /* Complete - now we can do signing */
1785 if (major==GSS_S_COMPLETE) { 1786 if (major==GSS_S_COMPLETE) {
1786 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); 1787 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
1787 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); 1788 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
1789 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
1788 } 1790 }
1789 return (0); 1791 return (0);
1790} 1792}
1791 1793
1792int 1794int
1795mm_answer_gss_checkmic(int socket, Buffer *m)
1796{
1797 gss_buffer_desc gssbuf, mic;
1798 OM_uint32 ret;
1799 u_int len;
1800
1801 gssbuf.value = buffer_get_string(m, &len);
1802 gssbuf.length = len;
1803 mic.value = buffer_get_string(m, &len);
1804 mic.length = len;
1805
1806 ret = ssh_gssapi_checkmic(gsscontext, &gssbuf, &mic);
1807
1808 xfree(gssbuf.value);
1809 xfree(mic.value);
1810
1811 buffer_clear(m);
1812 buffer_put_int(m, ret);
1813
1814 mm_request_send(socket, MONITOR_ANS_GSSCHECKMIC, m);
1815
1816 if (!GSS_ERROR(ret))
1817 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
1818
1819 return (0);
1820}
1821
1822int
1793mm_answer_gss_userok(int socket, Buffer *m) 1823mm_answer_gss_userok(int socket, Buffer *m)
1794{ 1824{
1795 int authenticated; 1825 int authenticated;
@@ -1802,7 +1832,7 @@ mm_answer_gss_userok(int socket, Buffer *m)
1802 debug3("%s: sending result %d", __func__, authenticated); 1832 debug3("%s: sending result %d", __func__, authenticated);
1803 mm_request_send(socket, MONITOR_ANS_GSSUSEROK, m); 1833 mm_request_send(socket, MONITOR_ANS_GSSUSEROK, m);
1804 1834
1805 auth_method="gssapi"; 1835 auth_method="gssapi-with-mic";
1806 1836
1807 /* Monitor loop will terminate if authenticated */ 1837 /* Monitor loop will terminate if authenticated */
1808 return (authenticated); 1838 return (authenticated);
diff --git a/monitor.h b/monitor.h
index a153f4168..621a4ad18 100644
--- a/monitor.h
+++ b/monitor.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor.h,v 1.12 2003/09/23 20:17:11 markus Exp $ */ 1/* $OpenBSD: monitor.h,v 1.13 2003/11/17 11:06:07 markus Exp $ */
2 2
3/* 3/*
4 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 4 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -52,6 +52,7 @@ enum monitor_reqtype {
52 MONITOR_REQ_GSSSETUP, MONITOR_ANS_GSSSETUP, 52 MONITOR_REQ_GSSSETUP, MONITOR_ANS_GSSSETUP,
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_PAM_START, 56 MONITOR_REQ_PAM_START,
56 MONITOR_REQ_PAM_ACCOUNT, MONITOR_ANS_PAM_ACCOUNT, 57 MONITOR_REQ_PAM_ACCOUNT, MONITOR_ANS_PAM_ACCOUNT,
57 MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX, 58 MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX,
diff --git a/monitor_wrap.c b/monitor_wrap.c
index fe1460422..c685535d3 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -25,7 +25,7 @@
25 */ 25 */
26 26
27#include "includes.h" 27#include "includes.h"
28RCSID("$OpenBSD: monitor_wrap.c,v 1.34 2003/10/15 09:48:45 markus Exp $"); 28RCSID("$OpenBSD: monitor_wrap.c,v 1.35 2003/11/17 11:06:07 markus Exp $");
29 29
30#include <openssl/bn.h> 30#include <openssl/bn.h>
31#include <openssl/dh.h> 31#include <openssl/dh.h>
@@ -1134,6 +1134,25 @@ mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in,
1134 return (major); 1134 return (major);
1135} 1135}
1136 1136
1137OM_uint32
1138mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
1139{
1140 Buffer m;
1141 OM_uint32 major;
1142
1143 buffer_init(&m);
1144 buffer_put_string(&m, gssbuf->value, gssbuf->length);
1145 buffer_put_string(&m, gssmic->value, gssmic->length);
1146
1147 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, &m);
1148 mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSCHECKMIC,
1149 &m);
1150
1151 major = buffer_get_int(&m);
1152 buffer_free(&m);
1153 return(major);
1154}
1155
1137int 1156int
1138mm_ssh_gssapi_userok(char *user) 1157mm_ssh_gssapi_userok(char *user)
1139{ 1158{
diff --git a/monitor_wrap.h b/monitor_wrap.h
index 76c02f13a..55be10b19 100644
--- a/monitor_wrap.h
+++ b/monitor_wrap.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor_wrap.h,v 1.12 2003/09/23 20:17:11 markus Exp $ */ 1/* $OpenBSD: monitor_wrap.h,v 1.13 2003/11/17 11:06:07 markus Exp $ */
2 2
3/* 3/*
4 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 4 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -62,6 +62,7 @@ OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **ctxt, gss_OID oid);
62OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *ctxt, 62OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *ctxt,
63 gss_buffer_desc *recv, gss_buffer_desc *send, OM_uint32 *flags); 63 gss_buffer_desc *recv, gss_buffer_desc *send, OM_uint32 *flags);
64int mm_ssh_gssapi_userok(char *user); 64int mm_ssh_gssapi_userok(char *user);
65OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
65#endif 66#endif
66 67
67#ifdef USE_PAM 68#ifdef USE_PAM
diff --git a/ssh-gss.h b/ssh-gss.h
index c76648ee0..2b6fe2130 100644
--- a/ssh-gss.h
+++ b/ssh-gss.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-gss.h,v 1.3 2003/10/02 08:26:53 markus Exp $ */ 1/* $OpenBSD: ssh-gss.h,v 1.4 2003/11/17 11:06:07 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. 3 * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
4 * 4 *
@@ -50,6 +50,7 @@
50#define SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE 63 50#define SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE 63
51#define SSH2_MSG_USERAUTH_GSSAPI_ERROR 64 51#define SSH2_MSG_USERAUTH_GSSAPI_ERROR 64
52#define SSH2_MSG_USERAUTH_GSSAPI_ERRTOK 65 52#define SSH2_MSG_USERAUTH_GSSAPI_ERRTOK 65
53#define SSH2_MSG_USERAUTH_GSSAPI_MIC 66
53 54
54#define SSH_GSS_OIDTYPE 0x06 55#define SSH_GSS_OIDTYPE 0x06
55 56
@@ -108,11 +109,13 @@ void ssh_gssapi_error(Gssctxt *ctx);
108char *ssh_gssapi_last_error(Gssctxt *ctxt, OM_uint32 *maj, OM_uint32 *min); 109char *ssh_gssapi_last_error(Gssctxt *ctxt, OM_uint32 *maj, OM_uint32 *min);
109void ssh_gssapi_build_ctx(Gssctxt **ctx); 110void ssh_gssapi_build_ctx(Gssctxt **ctx);
110void ssh_gssapi_delete_ctx(Gssctxt **ctx); 111void ssh_gssapi_delete_ctx(Gssctxt **ctx);
112OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t);
111OM_uint32 ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid); 113OM_uint32 ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid);
114void ssh_gssapi_buildmic(Buffer *, const char *, const char *, const char *);
112 115
113/* In the server */ 116/* In the server */
114int ssh_gssapi_userok(char *name); 117int ssh_gssapi_userok(char *name);
115 118OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
116void ssh_gssapi_do_child(char ***envp, u_int *envsizep); 119void ssh_gssapi_do_child(char ***envp, u_int *envsizep);
117void ssh_gssapi_cleanup_creds(void); 120void ssh_gssapi_cleanup_creds(void);
118void ssh_gssapi_storecreds(void); 121void ssh_gssapi_storecreds(void);
diff --git a/sshconnect2.c b/sshconnect2.c
index 388a25741..f6368aadd 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: sshconnect2.c,v 1.131 2003/11/17 09:45:39 djm Exp $"); 26RCSID("$OpenBSD: sshconnect2.c,v 1.132 2003/11/17 11:06:07 markus Exp $");
27 27
28#include "openbsd-compat/sys-queue.h" 28#include "openbsd-compat/sys-queue.h"
29 29
@@ -222,7 +222,7 @@ static char *authmethods_get(void);
222 222
223Authmethod authmethods[] = { 223Authmethod authmethods[] = {
224#ifdef GSSAPI 224#ifdef GSSAPI
225 {"gssapi", 225 {"gssapi-with-mic",
226 userauth_gssapi, 226 userauth_gssapi,
227 &options.gss_authentication, 227 &options.gss_authentication,
228 NULL}, 228 NULL},
@@ -543,10 +543,12 @@ process_gssapi_token(void *ctxt, gss_buffer_t recv_tok)
543 Authctxt *authctxt = ctxt; 543 Authctxt *authctxt = ctxt;
544 Gssctxt *gssctxt = authctxt->methoddata; 544 Gssctxt *gssctxt = authctxt->methoddata;
545 gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; 545 gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
546 OM_uint32 status, ms; 546 gss_buffer_desc gssbuf, mic;
547 OM_uint32 status, ms, flags;
548 Buffer b;
547 549
548 status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds, 550 status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
549 recv_tok, &send_tok, NULL); 551 recv_tok, &send_tok, &flags);
550 552
551 if (send_tok.length > 0) { 553 if (send_tok.length > 0) {
552 if (GSS_ERROR(status)) 554 if (GSS_ERROR(status))
@@ -560,9 +562,29 @@ process_gssapi_token(void *ctxt, gss_buffer_t recv_tok)
560 } 562 }
561 563
562 if (status == GSS_S_COMPLETE) { 564 if (status == GSS_S_COMPLETE) {
563 /* If that succeeded, send a exchange complete message */ 565 /* send either complete or MIC, depending on mechanism */
564 packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE); 566 if (!(flags & GSS_C_INTEG_FLAG)) {
565 packet_send(); 567 packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);
568 packet_send();
569 } else {
570 ssh_gssapi_buildmic(&b, authctxt->server_user,
571 authctxt->service, "gssapi-with-mic");
572
573 gssbuf.value = buffer_ptr(&b);
574 gssbuf.length = buffer_len(&b);
575
576 status = ssh_gssapi_sign(gssctxt, &gssbuf, &mic);
577
578 if (!GSS_ERROR(status)) {
579 packet_start(SSH2_MSG_USERAUTH_GSSAPI_MIC);
580 packet_put_string(mic.value, mic.length);
581
582 packet_send();
583 }
584
585 buffer_free(&b);
586 gss_release_buffer(&ms, &mic);
587 }
566 } 588 }
567 589
568 return status; 590 return status;