- djm@cvs.openbsd.org 2003/11/17 09:45:39
[msg.c msg.h sshconnect2.c ssh-keysign.c]
return error on msg send/receive failure (rather than fatal); ok markus@
+ - markus@cvs.openbsd.org 2003/11/17 11:06:07
+ [auth2-gss.c gss-genr.c gss-serv.c monitor.c monitor.h monitor_wrap.c]
+ [monitor_wrap.h sshconnect2.c ssh-gss.h]
+ replace "gssapi" with "gssapi-with-mic"; from Simon Wilkinson;
+ test + ok jakob.
- (djm) Bug #632: Don't call pam_end indirectly from within kbd-int
conversation function
- (djm) Export environment variables from authentication subprocess to
-/* $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.
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 *);
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))
packet_check_eom();
maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok,
- &send_tok, NULL));
+ &send_tok, &flags));
xfree(recv_tok.value);
}
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);
}
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);
}
}
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();
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
};
-/* $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.
#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
return (ctx->major);
}
+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)
-/* $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.
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
*/
#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>
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;
{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}
};
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)
{
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);
-/* $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>
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_PAM_START,
MONITOR_REQ_PAM_ACCOUNT, MONITOR_ANS_PAM_ACCOUNT,
MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX,
*/
#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>
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)
{
-/* $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>
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
#ifdef USE_PAM
-/* $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.
*
#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
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);
*/
#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 "openbsd-compat/sys-queue.h"
Authmethod authmethods[] = {
#ifdef GSSAPI
- {"gssapi",
+ {"gssapi-with-mic",
userauth_gssapi,
&options.gss_authentication,
NULL},
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))
}
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;