summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Friedl <markus@cvs.openbsd.org>2003-11-17 11:06:08 +0000
committerMarkus Friedl <markus@cvs.openbsd.org>2003-11-17 11:06:08 +0000
commit20e60ea9fc40f1f7e837c7da4c0e70d379a45d64 (patch)
tree9fa42ba1df57cf5dc826786ea8044ea457e5f655
parentcd450b0f54675b3659be24aca9e4c3938dcd657b (diff)
replace "gssapi" with "gssapi-with-mic"; from Simon Wilkinson; test + ok jakob.
-rw-r--r--usr.bin/ssh/auth2-gss.c68
-rw-r--r--usr.bin/ssh/gss-genr.c27
-rw-r--r--usr.bin/ssh/gss-serv.c12
-rw-r--r--usr.bin/ssh/monitor.c36
-rw-r--r--usr.bin/ssh/monitor.h3
-rw-r--r--usr.bin/ssh/monitor_wrap.c21
-rw-r--r--usr.bin/ssh/monitor_wrap.h3
-rw-r--r--usr.bin/ssh/ssh-gss.h7
-rw-r--r--usr.bin/ssh/sshconnect2.c36
9 files changed, 185 insertions, 28 deletions
diff --git a/usr.bin/ssh/auth2-gss.c b/usr.bin/ssh/auth2-gss.c
index 84fb384f954..220862dc8f0 100644
--- a/usr.bin/ssh/auth2-gss.c
+++ b/usr.bin/ssh/auth2-gss.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-gss.c,v 1.5 2003/11/02 11:01:03 markus Exp $ */
+/* $OpenBSD: auth2-gss.c,v 1.6 2003/11/17 11:06:07 markus Exp $ */
/*
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@@ -43,6 +43,7 @@
extern ServerOptions options;
static void input_gssapi_token(int type, u_int32_t plen, void *ctxt);
+static void input_gssapi_mic(int type, u_int32_t plen, void *ctxt);
static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt);
static void input_gssapi_errtok(int, u_int32_t, void *);
@@ -129,7 +130,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
Gssctxt *gssctxt;
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
gss_buffer_desc recv_tok;
- OM_uint32 maj_status, min_status;
+ OM_uint32 maj_status, min_status, flags;
u_int len;
if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
@@ -142,7 +143,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
packet_check_eom();
maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok,
- &send_tok, NULL));
+ &send_tok, &flags));
xfree(recv_tok.value);
@@ -154,7 +155,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
}
authctxt->postponed = 0;
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
- userauth_finish(authctxt, 0, "gssapi");
+ userauth_finish(authctxt, 0, "gssapi-with-mic");
} else {
if (send_tok.length != 0) {
packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
@@ -163,8 +164,13 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
}
if (maj_status == GSS_S_COMPLETE) {
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
- dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
- &input_gssapi_exchange_complete);
+ if (flags & GSS_C_INTEG_FLAG)
+ dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC,
+ &input_gssapi_mic);
+ else
+ dispatch_set(
+ SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
+ &input_gssapi_exchange_complete);
}
}
@@ -224,9 +230,8 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
gssctxt = authctxt->methoddata;
/*
- * We don't need to check the status, because the stored credentials
- * which userok uses are only populated once the context init step
- * has returned complete.
+ * We don't need to check the status, because we're only enabled in
+ * the dispatcher once the exchange is complete
*/
packet_check_eom();
@@ -236,12 +241,53 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
authctxt->postponed = 0;
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
+ dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
+ dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
+ userauth_finish(authctxt, authenticated, "gssapi-with-mic");
+}
+
+static void
+input_gssapi_mic(int type, u_int32_t plen, void *ctxt)
+{
+ Authctxt *authctxt = ctxt;
+ Gssctxt *gssctxt;
+ int authenticated = 0;
+ Buffer b;
+ gss_buffer_desc mic, gssbuf;
+ u_int len;
+
+ if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
+ fatal("No authentication or GSSAPI context");
+
+ gssctxt = authctxt->methoddata;
+
+ mic.value = packet_get_string(&len);
+ mic.length = len;
+
+ ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service,
+ "gssapi-with-mic");
+
+ gssbuf.value = buffer_ptr(&b);
+ gssbuf.length = buffer_len(&b);
+
+ if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic))))
+ authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
+ else
+ logit("GSSAPI MIC check failed");
+
+ buffer_free(&b);
+ xfree(mic.value);
+
+ authctxt->postponed = 0;
+ dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
+ dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
+ dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
- userauth_finish(authctxt, authenticated, "gssapi");
+ userauth_finish(authctxt, authenticated, "gssapi-with-mic");
}
Authmethod method_gssapi = {
- "gssapi",
+ "gssapi-with-mic",
userauth_gssapi,
&options.gss_authentication
};
diff --git a/usr.bin/ssh/gss-genr.c b/usr.bin/ssh/gss-genr.c
index bda12d6f1b5..6b7caad0e7b 100644
--- a/usr.bin/ssh/gss-genr.c
+++ b/usr.bin/ssh/gss-genr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gss-genr.c,v 1.1 2003/08/22 10:56:09 markus Exp $ */
+/* $OpenBSD: gss-genr.c,v 1.2 2003/11/17 11:06:07 markus Exp $ */
/*
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@@ -33,9 +33,12 @@
#include "compat.h"
#include "log.h"
#include "monitor_wrap.h"
+#include "ssh2.h"
#include "ssh-gss.h"
+extern u_char *session_id2;
+extern u_int session_id2_len;
/* Check that the OID in a data stream matches that in the context */
int
@@ -245,6 +248,28 @@ ssh_gssapi_acquire_cred(Gssctxt *ctx)
}
OM_uint32
+ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash)
+{
+ if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context,
+ GSS_C_QOP_DEFAULT, buffer, hash)))
+ ssh_gssapi_error(ctx);
+
+ return (ctx->major);
+}
+
+void
+ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service,
+ const char *context)
+{
+ buffer_init(b);
+ buffer_put_string(b, session_id2, session_id2_len);
+ buffer_put_char(b, SSH2_MSG_USERAUTH_REQUEST);
+ buffer_put_cstring(b, user);
+ buffer_put_cstring(b, service);
+ buffer_put_cstring(b, context);
+}
+
+OM_uint32
ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) {
if (*ctx)
ssh_gssapi_delete_ctx(ctx);
diff --git a/usr.bin/ssh/gss-serv.c b/usr.bin/ssh/gss-serv.c
index 6574f9750b4..de32a3f2ea0 100644
--- a/usr.bin/ssh/gss-serv.c
+++ b/usr.bin/ssh/gss-serv.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gss-serv.c,v 1.4 2003/09/23 20:17:11 markus Exp $ */
+/* $OpenBSD: gss-serv.c,v 1.5 2003/11/17 11:06:07 markus Exp $ */
/*
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@@ -287,4 +287,14 @@ ssh_gssapi_userok(char *user)
return (0);
}
+/* Priviledged */
+OM_uint32
+ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
+{
+ ctx->major = gss_verify_mic(&ctx->minor, ctx->context,
+ gssbuf, gssmic, NULL);
+
+ return (ctx->major);
+}
+
#endif
diff --git a/usr.bin/ssh/monitor.c b/usr.bin/ssh/monitor.c
index 7a64ae4d74a..27f8dc237f9 100644
--- a/usr.bin/ssh/monitor.c
+++ b/usr.bin/ssh/monitor.c
@@ -25,7 +25,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: monitor.c,v 1.51 2003/11/04 08:54:09 djm Exp $");
+RCSID("$OpenBSD: monitor.c,v 1.52 2003/11/17 11:06:07 markus Exp $");
#include <openssl/dh.h>
@@ -125,6 +125,7 @@ int mm_answer_sessid(int, Buffer *);
int mm_answer_gss_setup_ctx(int, Buffer *);
int mm_answer_gss_accept_ctx(int, Buffer *);
int mm_answer_gss_userok(int, Buffer *);
+int mm_answer_gss_checkmic(int, Buffer *);
#endif
static Authctxt *authctxt;
@@ -176,6 +177,7 @@ struct mon_table mon_dispatch_proto20[] = {
{MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx},
{MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx},
{MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
+ {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic},
#endif
{0, 0, NULL}
};
@@ -1598,15 +1600,43 @@ mm_answer_gss_accept_ctx(int socket, Buffer *m)
gss_release_buffer(&minor, &out);
- /* Complete - now we can do signing */
if (major==GSS_S_COMPLETE) {
monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
+ monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
}
return (0);
}
int
+mm_answer_gss_checkmic(int socket, Buffer *m)
+{
+ gss_buffer_desc gssbuf, mic;
+ OM_uint32 ret;
+ u_int len;
+
+ gssbuf.value = buffer_get_string(m, &len);
+ gssbuf.length = len;
+ mic.value = buffer_get_string(m, &len);
+ mic.length = len;
+
+ ret = ssh_gssapi_checkmic(gsscontext, &gssbuf, &mic);
+
+ xfree(gssbuf.value);
+ xfree(mic.value);
+
+ buffer_clear(m);
+ buffer_put_int(m, ret);
+
+ mm_request_send(socket, MONITOR_ANS_GSSCHECKMIC, m);
+
+ if (!GSS_ERROR(ret))
+ monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
+
+ return (0);
+}
+
+int
mm_answer_gss_userok(int socket, Buffer *m)
{
int authenticated;
@@ -1619,7 +1649,7 @@ mm_answer_gss_userok(int socket, Buffer *m)
debug3("%s: sending result %d", __func__, authenticated);
mm_request_send(socket, MONITOR_ANS_GSSUSEROK, m);
- auth_method="gssapi";
+ auth_method="gssapi-with-mic";
/* Monitor loop will terminate if authenticated */
return (authenticated);
diff --git a/usr.bin/ssh/monitor.h b/usr.bin/ssh/monitor.h
index 2afbfed6f44..c3476080623 100644
--- a/usr.bin/ssh/monitor.h
+++ b/usr.bin/ssh/monitor.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor.h,v 1.12 2003/09/23 20:17:11 markus Exp $ */
+/* $OpenBSD: monitor.h,v 1.13 2003/11/17 11:06:07 markus Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -52,6 +52,7 @@ enum monitor_reqtype {
MONITOR_REQ_GSSSETUP, MONITOR_ANS_GSSSETUP,
MONITOR_REQ_GSSSTEP, MONITOR_ANS_GSSSTEP,
MONITOR_REQ_GSSUSEROK, MONITOR_ANS_GSSUSEROK,
+ MONITOR_REQ_GSSCHECKMIC, MONITOR_ANS_GSSCHECKMIC,
MONITOR_REQ_TERM
};
diff --git a/usr.bin/ssh/monitor_wrap.c b/usr.bin/ssh/monitor_wrap.c
index 6b7408dd294..5d6712389a7 100644
--- a/usr.bin/ssh/monitor_wrap.c
+++ b/usr.bin/ssh/monitor_wrap.c
@@ -25,7 +25,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: monitor_wrap.c,v 1.34 2003/10/15 09:48:45 markus Exp $");
+RCSID("$OpenBSD: monitor_wrap.c,v 1.35 2003/11/17 11:06:07 markus Exp $");
#include <openssl/bn.h>
#include <openssl/dh.h>
@@ -1005,6 +1005,25 @@ mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in,
return (major);
}
+OM_uint32
+mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
+{
+ Buffer m;
+ OM_uint32 major;
+
+ buffer_init(&m);
+ buffer_put_string(&m, gssbuf->value, gssbuf->length);
+ buffer_put_string(&m, gssmic->value, gssmic->length);
+
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, &m);
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSCHECKMIC,
+ &m);
+
+ major = buffer_get_int(&m);
+ buffer_free(&m);
+ return(major);
+}
+
int
mm_ssh_gssapi_userok(char *user)
{
diff --git a/usr.bin/ssh/monitor_wrap.h b/usr.bin/ssh/monitor_wrap.h
index f03222aef73..d36d4424402 100644
--- a/usr.bin/ssh/monitor_wrap.h
+++ b/usr.bin/ssh/monitor_wrap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor_wrap.h,v 1.12 2003/09/23 20:17:11 markus Exp $ */
+/* $OpenBSD: monitor_wrap.h,v 1.13 2003/11/17 11:06:07 markus Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -62,6 +62,7 @@ OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **ctxt, gss_OID oid);
OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *ctxt,
gss_buffer_desc *recv, gss_buffer_desc *send, OM_uint32 *flags);
int mm_ssh_gssapi_userok(char *user);
+OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
#endif
struct Session;
diff --git a/usr.bin/ssh/ssh-gss.h b/usr.bin/ssh/ssh-gss.h
index 05e056c953f..1d01d85d3b5 100644
--- a/usr.bin/ssh/ssh-gss.h
+++ b/usr.bin/ssh/ssh-gss.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-gss.h,v 1.3 2003/10/02 08:26:53 markus Exp $ */
+/* $OpenBSD: ssh-gss.h,v 1.4 2003/11/17 11:06:07 markus Exp $ */
/*
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
*
@@ -38,6 +38,7 @@
#define SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE 63
#define SSH2_MSG_USERAUTH_GSSAPI_ERROR 64
#define SSH2_MSG_USERAUTH_GSSAPI_ERRTOK 65
+#define SSH2_MSG_USERAUTH_GSSAPI_MIC 66
#define SSH_GSS_OIDTYPE 0x06
@@ -96,11 +97,13 @@ void ssh_gssapi_error(Gssctxt *ctx);
char *ssh_gssapi_last_error(Gssctxt *ctxt, OM_uint32 *maj, OM_uint32 *min);
void ssh_gssapi_build_ctx(Gssctxt **ctx);
void ssh_gssapi_delete_ctx(Gssctxt **ctx);
+OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t);
OM_uint32 ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid);
+void ssh_gssapi_buildmic(Buffer *, const char *, const char *, const char *);
/* In the server */
int ssh_gssapi_userok(char *name);
-
+OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
void ssh_gssapi_do_child(char ***envp, u_int *envsizep);
void ssh_gssapi_cleanup_creds(void);
void ssh_gssapi_storecreds(void);
diff --git a/usr.bin/ssh/sshconnect2.c b/usr.bin/ssh/sshconnect2.c
index 2f65629e63e..ca7859160a6 100644
--- a/usr.bin/ssh/sshconnect2.c
+++ b/usr.bin/ssh/sshconnect2.c
@@ -23,7 +23,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: sshconnect2.c,v 1.131 2003/11/17 09:45:39 djm Exp $");
+RCSID("$OpenBSD: sshconnect2.c,v 1.132 2003/11/17 11:06:07 markus Exp $");
#include "ssh.h"
#include "ssh2.h"
@@ -220,7 +220,7 @@ static char *authmethods_get(void);
Authmethod authmethods[] = {
#ifdef GSSAPI
- {"gssapi",
+ {"gssapi-with-mic",
userauth_gssapi,
&options.gss_authentication,
NULL},
@@ -541,10 +541,12 @@ process_gssapi_token(void *ctxt, gss_buffer_t recv_tok)
Authctxt *authctxt = ctxt;
Gssctxt *gssctxt = authctxt->methoddata;
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
- OM_uint32 status, ms;
+ gss_buffer_desc gssbuf, mic;
+ OM_uint32 status, ms, flags;
+ Buffer b;
status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
- recv_tok, &send_tok, NULL);
+ recv_tok, &send_tok, &flags);
if (send_tok.length > 0) {
if (GSS_ERROR(status))
@@ -558,9 +560,29 @@ process_gssapi_token(void *ctxt, gss_buffer_t recv_tok)
}
if (status == GSS_S_COMPLETE) {
- /* If that succeeded, send a exchange complete message */
- packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);
- packet_send();
+ /* send either complete or MIC, depending on mechanism */
+ if (!(flags & GSS_C_INTEG_FLAG)) {
+ packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);
+ packet_send();
+ } else {
+ ssh_gssapi_buildmic(&b, authctxt->server_user,
+ authctxt->service, "gssapi-with-mic");
+
+ gssbuf.value = buffer_ptr(&b);
+ gssbuf.length = buffer_len(&b);
+
+ status = ssh_gssapi_sign(gssctxt, &gssbuf, &mic);
+
+ if (!GSS_ERROR(status)) {
+ packet_start(SSH2_MSG_USERAUTH_GSSAPI_MIC);
+ packet_put_string(mic.value, mic.length);
+
+ packet_send();
+ }
+
+ buffer_free(&b);
+ gss_release_buffer(&ms, &mic);
+ }
}
return status;