[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.
This commit is contained in:
Damien Miller 2003-11-17 22:18:21 +11:00
parent c756e9b56e
commit 0425d40194
10 changed files with 191 additions and 29 deletions

View File

@ -43,6 +43,11 @@
- 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
@ -1467,4 +1472,4 @@
- Fix sshd BindAddress and -b options for systems using fake-getaddrinfo.
Report from murple@murple.net, diagnosis from dtucker@zip.com.au
$Id: ChangeLog,v 1.3111 2003/11/17 10:41:42 djm Exp $
$Id: ChangeLog,v 1.3112 2003/11/17 11:18:21 djm Exp $

View File

@ -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");
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-with-mic");
}
Authmethod method_gssapi = {
"gssapi",
"gssapi-with-mic",
userauth_gssapi,
&options.gss_authentication
};

View File

@ -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
@ -244,6 +247,28 @@ ssh_gssapi_acquire_cred(Gssctxt *ctx)
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)

View File

@ -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

View File

@ -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>
@ -134,6 +134,7 @@ int mm_answer_pam_free_ctx(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;
@ -193,6 +194,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}
};
@ -1781,14 +1783,42 @@ 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)
{
@ -1802,7 +1832,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);

View File

@ -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_PAM_START,
MONITOR_REQ_PAM_ACCOUNT, MONITOR_ANS_PAM_ACCOUNT,
MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX,

View File

@ -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>
@ -1134,6 +1134,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)
{

View File

@ -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
#ifdef USE_PAM

View File

@ -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.
*
@ -50,6 +50,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
@ -108,11 +109,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);

View File

@ -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 "openbsd-compat/sys-queue.h"
@ -222,7 +222,7 @@ static char *authmethods_get(void);
Authmethod authmethods[] = {
#ifdef GSSAPI
{"gssapi",
{"gssapi-with-mic",
userauth_gssapi,
&options.gss_authentication,
NULL},
@ -543,10 +543,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))
@ -560,9 +562,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;