mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-31 01:35:11 +02:00
- markus@cvs.openbsd.org 2003/08/22 10:56:09
[auth2.c auth2-gss.c auth.h compat.c compat.h gss-genr.c gss-serv-krb5.c gss-serv.c monitor.c monitor.h monitor_wrap.c monitor_wrap.h readconf.c readconf.h servconf.c servconf.h session.c session.h ssh-gss.h ssh_config.5 sshconnect2.c sshd_config sshd_config.5] support GSS API user authentication; patches from Simon Wilkinson, stripped down and tested by Jakob and myself.
This commit is contained in:
parent
30912f7259
commit
0efd155c3c
10
ChangeLog
10
ChangeLog
@ -2,6 +2,14 @@
|
|||||||
- (djm) Bug #629: Mark ssh_config option "pamauthenticationviakbdint"
|
- (djm) Bug #629: Mark ssh_config option "pamauthenticationviakbdint"
|
||||||
as deprecated. Remove mention from README.privsep. Patch from
|
as deprecated. Remove mention from README.privsep. Patch from
|
||||||
aet AT cc.hut.fi
|
aet AT cc.hut.fi
|
||||||
|
- (dtucker) OpenBSD CVS Sync
|
||||||
|
- markus@cvs.openbsd.org 2003/08/22 10:56:09
|
||||||
|
[auth2.c auth2-gss.c auth.h compat.c compat.h gss-genr.c gss-serv-krb5.c
|
||||||
|
gss-serv.c monitor.c monitor.h monitor_wrap.c monitor_wrap.h readconf.c
|
||||||
|
readconf.h servconf.c servconf.h session.c session.h ssh-gss.h
|
||||||
|
ssh_config.5 sshconnect2.c sshd_config sshd_config.5]
|
||||||
|
support GSS API user authentication; patches from Simon Wilkinson,
|
||||||
|
stripped down and tested by Jakob and myself.
|
||||||
|
|
||||||
20030825
|
20030825
|
||||||
- (djm) Bug #621: Select OpenSC keys by usage attributes. Patch from
|
- (djm) Bug #621: Select OpenSC keys by usage attributes. Patch from
|
||||||
@ -874,4 +882,4 @@
|
|||||||
- Fix sshd BindAddress and -b options for systems using fake-getaddrinfo.
|
- Fix sshd BindAddress and -b options for systems using fake-getaddrinfo.
|
||||||
Report from murple@murple.net, diagnosis from dtucker@zip.com.au
|
Report from murple@murple.net, diagnosis from dtucker@zip.com.au
|
||||||
|
|
||||||
$Id: ChangeLog,v 1.2906 2003/08/26 00:48:14 djm Exp $
|
$Id: ChangeLog,v 1.2907 2003/08/26 01:49:55 dtucker Exp $
|
||||||
|
3
auth.h
3
auth.h
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: auth.h,v 1.43 2003/07/22 13:35:22 markus Exp $ */
|
/* $OpenBSD: auth.h,v 1.44 2003/08/22 10:56:08 markus Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||||
@ -67,6 +67,7 @@ struct Authctxt {
|
|||||||
krb5_principal krb5_user;
|
krb5_principal krb5_user;
|
||||||
char *krb5_ticket_file;
|
char *krb5_ticket_file;
|
||||||
#endif
|
#endif
|
||||||
|
void *methoddata;
|
||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
* Every authentication method has to handle authentication requests for
|
* Every authentication method has to handle authentication requests for
|
||||||
|
243
auth2-gss.c
Normal file
243
auth2-gss.c
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
/* $OpenBSD: auth2-gss.c,v 1.1 2003/08/22 10:56:08 markus Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "includes.h"
|
||||||
|
|
||||||
|
#ifdef GSSAPI
|
||||||
|
|
||||||
|
#include "auth.h"
|
||||||
|
#include "ssh2.h"
|
||||||
|
#include "xmalloc.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "dispatch.h"
|
||||||
|
#include "servconf.h"
|
||||||
|
#include "compat.h"
|
||||||
|
#include "packet.h"
|
||||||
|
#include "monitor_wrap.h"
|
||||||
|
|
||||||
|
#include "ssh-gss.h"
|
||||||
|
|
||||||
|
extern ServerOptions options;
|
||||||
|
|
||||||
|
static void input_gssapi_token(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 *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We only support those mechanisms that we know about (ie ones that we know
|
||||||
|
* how to check local user kuserok and the like
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
userauth_gssapi(Authctxt *authctxt)
|
||||||
|
{
|
||||||
|
gss_OID_desc oid = {0, NULL};
|
||||||
|
Gssctxt *ctxt = NULL;
|
||||||
|
int mechs;
|
||||||
|
gss_OID_set supported;
|
||||||
|
int present;
|
||||||
|
OM_uint32 ms;
|
||||||
|
u_int len;
|
||||||
|
char *doid = NULL;
|
||||||
|
|
||||||
|
if (!authctxt->valid || authctxt->user == NULL)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
mechs = packet_get_int();
|
||||||
|
if (mechs == 0) {
|
||||||
|
debug("Mechanism negotiation is not supported");
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssh_gssapi_supported_oids(&supported);
|
||||||
|
do {
|
||||||
|
mechs--;
|
||||||
|
|
||||||
|
if (doid)
|
||||||
|
xfree(doid);
|
||||||
|
|
||||||
|
doid = packet_get_string(&len);
|
||||||
|
|
||||||
|
if (doid[0] != SSH_GSS_OIDTYPE || doid[1] != len-2) {
|
||||||
|
logit("Mechanism OID received using the old encoding form");
|
||||||
|
oid.elements = doid;
|
||||||
|
oid.length = len;
|
||||||
|
} else {
|
||||||
|
oid.elements = doid + 2;
|
||||||
|
oid.length = len - 2;
|
||||||
|
}
|
||||||
|
gss_test_oid_set_member(&ms, &oid, supported, &present);
|
||||||
|
} while (mechs > 0 && !present);
|
||||||
|
|
||||||
|
gss_release_oid_set(&ms, &supported);
|
||||||
|
|
||||||
|
if (!present) {
|
||||||
|
xfree(doid);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, &oid))))
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
authctxt->methoddata=(void *)ctxt;
|
||||||
|
|
||||||
|
packet_start(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE);
|
||||||
|
|
||||||
|
/* Return OID in same format as we received it*/
|
||||||
|
packet_put_string(doid, len);
|
||||||
|
|
||||||
|
packet_send();
|
||||||
|
xfree(doid);
|
||||||
|
|
||||||
|
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token);
|
||||||
|
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok);
|
||||||
|
authctxt->postponed = 1;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
input_gssapi_token(int type, u_int32_t plen, void *ctxt)
|
||||||
|
{
|
||||||
|
Authctxt *authctxt = ctxt;
|
||||||
|
Gssctxt *gssctxt;
|
||||||
|
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
|
||||||
|
gss_buffer_desc recv_tok;
|
||||||
|
OM_uint32 maj_status, min_status;
|
||||||
|
u_int len;
|
||||||
|
|
||||||
|
if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
|
||||||
|
fatal("No authentication or GSSAPI context");
|
||||||
|
|
||||||
|
gssctxt = authctxt->methoddata;
|
||||||
|
recv_tok.value = packet_get_string(&len);
|
||||||
|
recv_tok.length = len; /* u_int vs. size_t */
|
||||||
|
|
||||||
|
packet_check_eom();
|
||||||
|
|
||||||
|
maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok,
|
||||||
|
&send_tok, NULL));
|
||||||
|
|
||||||
|
xfree(recv_tok.value);
|
||||||
|
|
||||||
|
if (GSS_ERROR(maj_status)) {
|
||||||
|
if (send_tok.length != 0) {
|
||||||
|
packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK);
|
||||||
|
packet_put_string(send_tok.value, send_tok.length);
|
||||||
|
packet_send();
|
||||||
|
}
|
||||||
|
authctxt->postponed = 0;
|
||||||
|
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
|
||||||
|
userauth_finish(authctxt, 0, "gssapi");
|
||||||
|
} else {
|
||||||
|
if (send_tok.length != 0) {
|
||||||
|
packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
|
||||||
|
packet_put_string(send_tok.value, send_tok.length);
|
||||||
|
packet_send();
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gss_release_buffer(&min_status, &send_tok);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
|
||||||
|
{
|
||||||
|
Authctxt *authctxt = ctxt;
|
||||||
|
Gssctxt *gssctxt;
|
||||||
|
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
|
||||||
|
gss_buffer_desc recv_tok;
|
||||||
|
OM_uint32 maj_status;
|
||||||
|
|
||||||
|
if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
|
||||||
|
fatal("No authentication or GSSAPI context");
|
||||||
|
|
||||||
|
gssctxt = authctxt->methoddata;
|
||||||
|
recv_tok.value = packet_get_string(&recv_tok.length);
|
||||||
|
|
||||||
|
packet_check_eom();
|
||||||
|
|
||||||
|
/* Push the error token into GSSAPI to see what it says */
|
||||||
|
maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok,
|
||||||
|
&send_tok, NULL));
|
||||||
|
|
||||||
|
xfree(recv_tok.value);
|
||||||
|
|
||||||
|
/* We can't return anything to the client, even if we wanted to */
|
||||||
|
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
|
||||||
|
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
|
||||||
|
|
||||||
|
/* The client will have already moved on to the next auth */
|
||||||
|
|
||||||
|
gss_release_buffer(&maj_status, &send_tok);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is called when the client thinks we've completed authentication.
|
||||||
|
* It should only be enabled in the dispatch handler by the function above,
|
||||||
|
* which only enables it once the GSSAPI exchange is complete.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
|
||||||
|
{
|
||||||
|
Authctxt *authctxt = ctxt;
|
||||||
|
Gssctxt *gssctxt;
|
||||||
|
int authenticated;
|
||||||
|
|
||||||
|
if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
|
||||||
|
fatal("No authentication or GSSAPI context");
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
packet_check_eom();
|
||||||
|
|
||||||
|
authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
|
||||||
|
|
||||||
|
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_EXCHANGE_COMPLETE, NULL);
|
||||||
|
userauth_finish(authctxt, authenticated, "gssapi");
|
||||||
|
}
|
||||||
|
|
||||||
|
Authmethod method_gssapi = {
|
||||||
|
"gssapi",
|
||||||
|
userauth_gssapi,
|
||||||
|
&options.gss_authentication
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* GSSAPI */
|
18
auth2.c
18
auth2.c
@ -23,7 +23,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: auth2.c,v 1.99 2003/06/24 08:23:46 markus Exp $");
|
RCSID("$OpenBSD: auth2.c,v 1.100 2003/08/22 10:56:08 markus Exp $");
|
||||||
|
|
||||||
#include "ssh2.h"
|
#include "ssh2.h"
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
@ -36,6 +36,10 @@ RCSID("$OpenBSD: auth2.c,v 1.99 2003/06/24 08:23:46 markus Exp $");
|
|||||||
#include "pathnames.h"
|
#include "pathnames.h"
|
||||||
#include "monitor_wrap.h"
|
#include "monitor_wrap.h"
|
||||||
|
|
||||||
|
#ifdef GSSAPI
|
||||||
|
#include "ssh-gss.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* import */
|
/* import */
|
||||||
extern ServerOptions options;
|
extern ServerOptions options;
|
||||||
extern u_char *session_id2;
|
extern u_char *session_id2;
|
||||||
@ -53,10 +57,16 @@ extern Authmethod method_hostbased;
|
|||||||
#ifdef KRB5
|
#ifdef KRB5
|
||||||
extern Authmethod method_kerberos;
|
extern Authmethod method_kerberos;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef GSSAPI
|
||||||
|
extern Authmethod method_gssapi;
|
||||||
|
#endif
|
||||||
|
|
||||||
Authmethod *authmethods[] = {
|
Authmethod *authmethods[] = {
|
||||||
&method_none,
|
&method_none,
|
||||||
&method_pubkey,
|
&method_pubkey,
|
||||||
|
#ifdef GSSAPI
|
||||||
|
&method_gssapi,
|
||||||
|
#endif
|
||||||
&method_passwd,
|
&method_passwd,
|
||||||
&method_kbdint,
|
&method_kbdint,
|
||||||
&method_hostbased,
|
&method_hostbased,
|
||||||
@ -184,6 +194,12 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
|
|||||||
}
|
}
|
||||||
/* reset state */
|
/* reset state */
|
||||||
auth2_challenge_stop(authctxt);
|
auth2_challenge_stop(authctxt);
|
||||||
|
|
||||||
|
#ifdef GSSAPI
|
||||||
|
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
|
||||||
|
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
authctxt->postponed = 0;
|
authctxt->postponed = 0;
|
||||||
|
|
||||||
/* try to authenticate user */
|
/* try to authenticate user */
|
||||||
|
8
compat.c
8
compat.c
@ -23,7 +23,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: compat.c,v 1.67 2003/04/08 20:21:28 itojun Exp $");
|
RCSID("$OpenBSD: compat.c,v 1.68 2003/08/22 10:56:09 markus Exp $");
|
||||||
|
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
@ -79,7 +79,11 @@ compat_datafellows(const char *version)
|
|||||||
{ "OpenSSH_2.5.3*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
|
{ "OpenSSH_2.5.3*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
|
||||||
{ "OpenSSH_2.*,"
|
{ "OpenSSH_2.*,"
|
||||||
"OpenSSH_3.0*,"
|
"OpenSSH_3.0*,"
|
||||||
"OpenSSH_3.1*", SSH_BUG_EXTEOF},
|
"OpenSSH_3.1*", SSH_BUG_EXTEOF|SSH_BUG_GSSAPI_BER},
|
||||||
|
{ "OpenSSH_3.2*,"
|
||||||
|
"OpenSSH_3.3*,"
|
||||||
|
"OpenSSH_3.4*,"
|
||||||
|
"OpenSSH_3.5*", SSH_BUG_GSSAPI_BER},
|
||||||
{ "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
|
{ "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
|
||||||
{ "OpenSSH*", 0 },
|
{ "OpenSSH*", 0 },
|
||||||
{ "*MindTerm*", 0 },
|
{ "*MindTerm*", 0 },
|
||||||
|
3
compat.h
3
compat.h
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: compat.h,v 1.34 2003/04/01 10:31:26 markus Exp $ */
|
/* $OpenBSD: compat.h,v 1.35 2003/08/22 10:56:09 markus Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
|
* Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
|
||||||
@ -56,6 +56,7 @@
|
|||||||
#define SSH_BUG_K5USER 0x00400000
|
#define SSH_BUG_K5USER 0x00400000
|
||||||
#define SSH_BUG_PROBE 0x00800000
|
#define SSH_BUG_PROBE 0x00800000
|
||||||
#define SSH_BUG_FIRSTKEX 0x01000000
|
#define SSH_BUG_FIRSTKEX 0x01000000
|
||||||
|
#define SSH_BUG_GSSAPI_BER 0x02000000
|
||||||
|
|
||||||
void enable_compat13(void);
|
void enable_compat13(void);
|
||||||
void enable_compat20(void);
|
void enable_compat20(void);
|
||||||
|
256
gss-genr.c
Normal file
256
gss-genr.c
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
/* $OpenBSD: gss-genr.c,v 1.1 2003/08/22 10:56:09 markus Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "includes.h"
|
||||||
|
|
||||||
|
#ifdef GSSAPI
|
||||||
|
|
||||||
|
#include "xmalloc.h"
|
||||||
|
#include "bufaux.h"
|
||||||
|
#include "compat.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "monitor_wrap.h"
|
||||||
|
|
||||||
|
#include "ssh-gss.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Check that the OID in a data stream matches that in the context */
|
||||||
|
int
|
||||||
|
ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len)
|
||||||
|
{
|
||||||
|
return (ctx != NULL && ctx->oid != GSS_C_NO_OID &&
|
||||||
|
ctx->oid->length == len &&
|
||||||
|
memcmp(ctx->oid->elements, data, len) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the contexts OID from a data stream */
|
||||||
|
void
|
||||||
|
ssh_gssapi_set_oid_data(Gssctxt *ctx, void *data, size_t len)
|
||||||
|
{
|
||||||
|
if (ctx->oid != GSS_C_NO_OID) {
|
||||||
|
xfree(ctx->oid->elements);
|
||||||
|
xfree(ctx->oid);
|
||||||
|
}
|
||||||
|
ctx->oid = xmalloc(sizeof(gss_OID_desc));
|
||||||
|
ctx->oid->length = len;
|
||||||
|
ctx->oid->elements = xmalloc(len);
|
||||||
|
memcpy(ctx->oid->elements, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the contexts OID */
|
||||||
|
void
|
||||||
|
ssh_gssapi_set_oid(Gssctxt *ctx, gss_OID oid)
|
||||||
|
{
|
||||||
|
ssh_gssapi_set_oid_data(ctx, oid->elements, oid->length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All this effort to report an error ... */
|
||||||
|
void
|
||||||
|
ssh_gssapi_error(Gssctxt *ctxt)
|
||||||
|
{
|
||||||
|
debug("%s", ssh_gssapi_last_error(ctxt, NULL, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
ssh_gssapi_last_error(Gssctxt *ctxt,
|
||||||
|
OM_uint32 *major_status, OM_uint32 *minor_status)
|
||||||
|
{
|
||||||
|
OM_uint32 lmin;
|
||||||
|
gss_buffer_desc msg = GSS_C_EMPTY_BUFFER;
|
||||||
|
OM_uint32 ctx;
|
||||||
|
Buffer b;
|
||||||
|
char *ret;
|
||||||
|
|
||||||
|
buffer_init(&b);
|
||||||
|
|
||||||
|
if (major_status != NULL)
|
||||||
|
*major_status = ctxt->major;
|
||||||
|
if (minor_status != NULL)
|
||||||
|
*minor_status = ctxt->minor;
|
||||||
|
|
||||||
|
ctx = 0;
|
||||||
|
/* The GSSAPI error */
|
||||||
|
do {
|
||||||
|
gss_display_status(&lmin, ctxt->major,
|
||||||
|
GSS_C_GSS_CODE, GSS_C_NULL_OID, &ctx, &msg);
|
||||||
|
|
||||||
|
buffer_append(&b, msg.value, msg.length);
|
||||||
|
buffer_put_char(&b, '\n');
|
||||||
|
|
||||||
|
gss_release_buffer(&lmin, &msg);
|
||||||
|
} while (ctx != 0);
|
||||||
|
|
||||||
|
/* The mechanism specific error */
|
||||||
|
do {
|
||||||
|
gss_display_status(&lmin, ctxt->minor,
|
||||||
|
GSS_C_MECH_CODE, GSS_C_NULL_OID, &ctx, &msg);
|
||||||
|
|
||||||
|
buffer_append(&b, msg.value, msg.length);
|
||||||
|
buffer_put_char(&b, '\n');
|
||||||
|
|
||||||
|
gss_release_buffer(&lmin, &msg);
|
||||||
|
} while (ctx != 0);
|
||||||
|
|
||||||
|
buffer_put_char(&b, '\0');
|
||||||
|
ret = xmalloc(buffer_len(&b));
|
||||||
|
buffer_get(&b, ret, buffer_len(&b));
|
||||||
|
buffer_free(&b);
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise our GSSAPI context. We use this opaque structure to contain all
|
||||||
|
* of the data which both the client and server need to persist across
|
||||||
|
* {accept,init}_sec_context calls, so that when we do it from the userauth
|
||||||
|
* stuff life is a little easier
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ssh_gssapi_build_ctx(Gssctxt **ctx)
|
||||||
|
{
|
||||||
|
*ctx = xmalloc(sizeof (Gssctxt));
|
||||||
|
(*ctx)->major = 0;
|
||||||
|
(*ctx)->minor = 0;
|
||||||
|
(*ctx)->context = GSS_C_NO_CONTEXT;
|
||||||
|
(*ctx)->name = GSS_C_NO_NAME;
|
||||||
|
(*ctx)->oid = GSS_C_NO_OID;
|
||||||
|
(*ctx)->creds = GSS_C_NO_CREDENTIAL;
|
||||||
|
(*ctx)->client = GSS_C_NO_NAME;
|
||||||
|
(*ctx)->client_creds = GSS_C_NO_CREDENTIAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delete our context, providing it has been built correctly */
|
||||||
|
void
|
||||||
|
ssh_gssapi_delete_ctx(Gssctxt **ctx)
|
||||||
|
{
|
||||||
|
OM_uint32 ms;
|
||||||
|
|
||||||
|
if ((*ctx) == NULL)
|
||||||
|
return;
|
||||||
|
if ((*ctx)->context != GSS_C_NO_CONTEXT)
|
||||||
|
gss_delete_sec_context(&ms, &(*ctx)->context, GSS_C_NO_BUFFER);
|
||||||
|
if ((*ctx)->name != GSS_C_NO_NAME)
|
||||||
|
gss_release_name(&ms, &(*ctx)->name);
|
||||||
|
if ((*ctx)->oid != GSS_C_NO_OID) {
|
||||||
|
xfree((*ctx)->oid->elements);
|
||||||
|
xfree((*ctx)->oid);
|
||||||
|
(*ctx)->oid = GSS_C_NO_OID;
|
||||||
|
}
|
||||||
|
if ((*ctx)->creds != GSS_C_NO_CREDENTIAL)
|
||||||
|
gss_release_cred(&ms, &(*ctx)->creds);
|
||||||
|
if ((*ctx)->client != GSS_C_NO_NAME)
|
||||||
|
gss_release_name(&ms, &(*ctx)->client);
|
||||||
|
if ((*ctx)->client_creds != GSS_C_NO_CREDENTIAL)
|
||||||
|
gss_release_cred(&ms, &(*ctx)->client_creds);
|
||||||
|
|
||||||
|
xfree(*ctx);
|
||||||
|
*ctx = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wrapper to init_sec_context
|
||||||
|
* Requires that the context contains:
|
||||||
|
* oid
|
||||||
|
* server name (from ssh_gssapi_import_name)
|
||||||
|
*/
|
||||||
|
OM_uint32
|
||||||
|
ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok,
|
||||||
|
gss_buffer_desc* send_tok, OM_uint32 *flags)
|
||||||
|
{
|
||||||
|
int deleg_flag = 0;
|
||||||
|
|
||||||
|
if (deleg_creds) {
|
||||||
|
deleg_flag = GSS_C_DELEG_FLAG;
|
||||||
|
debug("Delegating credentials");
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->major = gss_init_sec_context(&ctx->minor,
|
||||||
|
GSS_C_NO_CREDENTIAL, &ctx->context, ctx->name, ctx->oid,
|
||||||
|
GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag,
|
||||||
|
0, NULL, recv_tok, NULL, send_tok, flags, NULL);
|
||||||
|
|
||||||
|
if (GSS_ERROR(ctx->major))
|
||||||
|
ssh_gssapi_error(ctx);
|
||||||
|
|
||||||
|
return (ctx->major);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a service name for the given host */
|
||||||
|
OM_uint32
|
||||||
|
ssh_gssapi_import_name(Gssctxt *ctx, const char *host)
|
||||||
|
{
|
||||||
|
gss_buffer_desc gssbuf;
|
||||||
|
|
||||||
|
gssbuf.length = sizeof("host@") + strlen(host);
|
||||||
|
gssbuf.value = xmalloc(gssbuf.length);
|
||||||
|
snprintf(gssbuf.value, gssbuf.length, "host@%s", host);
|
||||||
|
|
||||||
|
if ((ctx->major = gss_import_name(&ctx->minor,
|
||||||
|
&gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name)))
|
||||||
|
ssh_gssapi_error(ctx);
|
||||||
|
|
||||||
|
xfree(gssbuf.value);
|
||||||
|
return (ctx->major);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Acquire credentials for a server running on the current host.
|
||||||
|
* Requires that the context structure contains a valid OID
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Returns a GSSAPI error code */
|
||||||
|
OM_uint32
|
||||||
|
ssh_gssapi_acquire_cred(Gssctxt *ctx)
|
||||||
|
{
|
||||||
|
OM_uint32 status;
|
||||||
|
char lname[MAXHOSTNAMELEN];
|
||||||
|
gss_OID_set oidset;
|
||||||
|
|
||||||
|
gss_create_empty_oid_set(&status, &oidset);
|
||||||
|
gss_add_oid_set_member(&status, ctx->oid, &oidset);
|
||||||
|
|
||||||
|
if (gethostname(lname, MAXHOSTNAMELEN))
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname)))
|
||||||
|
return (ctx->major);
|
||||||
|
|
||||||
|
if ((ctx->major = gss_acquire_cred(&ctx->minor,
|
||||||
|
ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL)))
|
||||||
|
ssh_gssapi_error(ctx);
|
||||||
|
|
||||||
|
gss_release_oid_set(&status, &oidset);
|
||||||
|
return (ctx->major);
|
||||||
|
}
|
||||||
|
|
||||||
|
OM_uint32
|
||||||
|
ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) {
|
||||||
|
if (*ctx)
|
||||||
|
ssh_gssapi_delete_ctx(ctx);
|
||||||
|
ssh_gssapi_build_ctx(ctx);
|
||||||
|
ssh_gssapi_set_oid(*ctx, oid);
|
||||||
|
return (ssh_gssapi_acquire_cred(*ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* GSSAPI */
|
168
gss-serv-krb5.c
Normal file
168
gss-serv-krb5.c
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
/* $OpenBSD: gss-serv-krb5.c,v 1.1 2003/08/22 10:56:09 markus Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "includes.h"
|
||||||
|
|
||||||
|
#ifdef GSSAPI
|
||||||
|
#ifdef KRB5
|
||||||
|
|
||||||
|
#include "auth.h"
|
||||||
|
#include "xmalloc.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "servconf.h"
|
||||||
|
|
||||||
|
#include "ssh-gss.h"
|
||||||
|
|
||||||
|
extern ServerOptions options;
|
||||||
|
|
||||||
|
#include <krb5.h>
|
||||||
|
|
||||||
|
static krb5_context krb_context = NULL;
|
||||||
|
|
||||||
|
/* Initialise the krb5 library, for the stuff that GSSAPI won't do */
|
||||||
|
|
||||||
|
static int
|
||||||
|
ssh_gssapi_krb5_init()
|
||||||
|
{
|
||||||
|
krb5_error_code problem;
|
||||||
|
|
||||||
|
if (krb_context != NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
problem = krb5_init_context(&krb_context);
|
||||||
|
if (problem) {
|
||||||
|
logit("Cannot initialize krb5 context");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
krb5_init_ets(krb_context);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if this user is OK to login. This only works with krb5 - other
|
||||||
|
* GSSAPI mechanisms will need their own.
|
||||||
|
* Returns true if the user is OK to log in, otherwise returns 0
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
|
||||||
|
{
|
||||||
|
krb5_principal princ;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
if (ssh_gssapi_krb5_init() == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((retval = krb5_parse_name(krb_context, client->exportedname.value,
|
||||||
|
&princ))) {
|
||||||
|
logit("krb5_parse_name(): %.100s",
|
||||||
|
krb5_get_err_text(krb_context, retval));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (krb5_kuserok(krb_context, princ, name)) {
|
||||||
|
retval = 1;
|
||||||
|
logit("Authorized to %s, krb5 principal %s (krb5_kuserok)",
|
||||||
|
name, (char *)client->displayname.value);
|
||||||
|
} else
|
||||||
|
retval = 0;
|
||||||
|
|
||||||
|
krb5_free_principal(krb_context, princ);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This writes out any forwarded credentials from the structure populated
|
||||||
|
* during userauth. Called after we have setuid to the user */
|
||||||
|
|
||||||
|
static void
|
||||||
|
ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
|
||||||
|
{
|
||||||
|
krb5_ccache ccache;
|
||||||
|
krb5_error_code problem;
|
||||||
|
krb5_principal princ;
|
||||||
|
OM_uint32 maj_status, min_status;
|
||||||
|
|
||||||
|
if (client->creds == NULL) {
|
||||||
|
debug("No credentials stored");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ssh_gssapi_krb5_init() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((problem = krb5_cc_gen_new(krb_context, &krb5_fcc_ops, &ccache))) {
|
||||||
|
logit("krb5_cc_gen_new(): %.100s",
|
||||||
|
krb5_get_err_text(krb_context, problem));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((problem = krb5_parse_name(krb_context,
|
||||||
|
client->exportedname.value, &princ))) {
|
||||||
|
logit("krb5_parse_name(): %.100s",
|
||||||
|
krb5_get_err_text(krb_context, problem));
|
||||||
|
krb5_cc_destroy(krb_context, ccache);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) {
|
||||||
|
logit("krb5_cc_initialize(): %.100s",
|
||||||
|
krb5_get_err_text(krb_context, problem));
|
||||||
|
krb5_free_principal(krb_context, princ);
|
||||||
|
krb5_cc_destroy(krb_context, ccache);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
krb5_free_principal(krb_context, princ);
|
||||||
|
|
||||||
|
if ((maj_status = gss_krb5_copy_ccache(&min_status,
|
||||||
|
client->creds, ccache))) {
|
||||||
|
logit("gss_krb5_copy_ccache() failed");
|
||||||
|
krb5_cc_destroy(krb_context, ccache);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache));
|
||||||
|
client->store.envvar = "KRB5CCNAME";
|
||||||
|
client->store.envval = xstrdup(client->store.filename);
|
||||||
|
|
||||||
|
krb5_cc_close(krb_context, ccache);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssh_gssapi_mech gssapi_kerberos_mech = {
|
||||||
|
"toWM5Slw5Ew8Mqkay+al2g==",
|
||||||
|
"Kerberos",
|
||||||
|
{9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"},
|
||||||
|
NULL,
|
||||||
|
&ssh_gssapi_krb5_userok,
|
||||||
|
NULL,
|
||||||
|
&ssh_gssapi_krb5_storecreds
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* KRB5 */
|
||||||
|
|
||||||
|
#endif /* GSSAPI */
|
291
gss-serv.c
Normal file
291
gss-serv.c
Normal file
@ -0,0 +1,291 @@
|
|||||||
|
/* $OpenBSD: gss-serv.c,v 1.1 2003/08/22 10:56:09 markus Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "includes.h"
|
||||||
|
|
||||||
|
#ifdef GSSAPI
|
||||||
|
|
||||||
|
#include "bufaux.h"
|
||||||
|
#include "compat.h"
|
||||||
|
#include "auth.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "channels.h"
|
||||||
|
#include "session.h"
|
||||||
|
#include "servconf.h"
|
||||||
|
#include "monitor_wrap.h"
|
||||||
|
#include "xmalloc.h"
|
||||||
|
#include "getput.h"
|
||||||
|
|
||||||
|
#include "ssh-gss.h"
|
||||||
|
|
||||||
|
extern ServerOptions options;
|
||||||
|
|
||||||
|
static ssh_gssapi_client gssapi_client =
|
||||||
|
{ GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER,
|
||||||
|
GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL}};
|
||||||
|
|
||||||
|
ssh_gssapi_mech gssapi_null_mech =
|
||||||
|
{ NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL};
|
||||||
|
|
||||||
|
#ifdef KRB5
|
||||||
|
extern ssh_gssapi_mech gssapi_kerberos_mech;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ssh_gssapi_mech* supported_mechs[]= {
|
||||||
|
#ifdef KRB5
|
||||||
|
&gssapi_kerberos_mech,
|
||||||
|
#endif
|
||||||
|
&gssapi_null_mech,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Unpriviledged */
|
||||||
|
void
|
||||||
|
ssh_gssapi_supported_oids(gss_OID_set *oidset)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
OM_uint32 min_status;
|
||||||
|
int present;
|
||||||
|
gss_OID_set supported;
|
||||||
|
|
||||||
|
gss_create_empty_oid_set(&min_status, oidset);
|
||||||
|
gss_indicate_mechs(&min_status, &supported);
|
||||||
|
|
||||||
|
while (supported_mechs[i]->name != NULL) {
|
||||||
|
if (GSS_ERROR(gss_test_oid_set_member(&min_status,
|
||||||
|
&supported_mechs[i]->oid, supported, &present)))
|
||||||
|
present = 0;
|
||||||
|
if (present)
|
||||||
|
gss_add_oid_set_member(&min_status,
|
||||||
|
&supported_mechs[i]->oid, oidset);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Wrapper around accept_sec_context
|
||||||
|
* Requires that the context contains:
|
||||||
|
* oid
|
||||||
|
* credentials (from ssh_gssapi_acquire_cred)
|
||||||
|
*/
|
||||||
|
/* Priviledged */
|
||||||
|
OM_uint32
|
||||||
|
ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *recv_tok,
|
||||||
|
gss_buffer_desc *send_tok, OM_uint32 *flags)
|
||||||
|
{
|
||||||
|
OM_uint32 status;
|
||||||
|
gss_OID mech;
|
||||||
|
|
||||||
|
ctx->major = gss_accept_sec_context(&ctx->minor,
|
||||||
|
&ctx->context, ctx->creds, recv_tok,
|
||||||
|
GSS_C_NO_CHANNEL_BINDINGS, &ctx->client, &mech,
|
||||||
|
send_tok, flags, NULL, &ctx->client_creds);
|
||||||
|
|
||||||
|
if (GSS_ERROR(ctx->major))
|
||||||
|
ssh_gssapi_error(ctx);
|
||||||
|
|
||||||
|
if (ctx->client_creds)
|
||||||
|
debug("Received some client credentials");
|
||||||
|
else
|
||||||
|
debug("Got no client credentials");
|
||||||
|
|
||||||
|
status = ctx->major;
|
||||||
|
|
||||||
|
/* Now, if we're complete and we have the right flags, then
|
||||||
|
* we flag the user as also having been authenticated
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (((flags == NULL) || ((*flags & GSS_C_MUTUAL_FLAG) &&
|
||||||
|
(*flags & GSS_C_INTEG_FLAG))) && (ctx->major == GSS_S_COMPLETE)) {
|
||||||
|
if (ssh_gssapi_getclient(ctx, &gssapi_client))
|
||||||
|
fatal("Couldn't convert client name");
|
||||||
|
}
|
||||||
|
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This parses an exported name, extracting the mechanism specific portion
|
||||||
|
* to use for ACL checking. It verifies that the name belongs the mechanism
|
||||||
|
* originally selected.
|
||||||
|
*/
|
||||||
|
static OM_uint32
|
||||||
|
ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name)
|
||||||
|
{
|
||||||
|
char *tok;
|
||||||
|
OM_uint32 offset;
|
||||||
|
OM_uint32 oidl;
|
||||||
|
|
||||||
|
tok=ename->value;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check that ename is long enough for all of the fixed length
|
||||||
|
* header, and that the initial ID bytes are correct
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (ename->length<6 || memcmp(tok,"\x04\x01", 2)!=0)
|
||||||
|
return GSS_S_FAILURE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extract the OID, and check it. Here GSSAPI breaks with tradition
|
||||||
|
* and does use the OID type and length bytes. To confuse things
|
||||||
|
* there are two lengths - the first including these, and the
|
||||||
|
* second without.
|
||||||
|
*/
|
||||||
|
|
||||||
|
oidl = GET_16BIT(tok+2); /* length including next two bytes */
|
||||||
|
oidl = oidl-2; /* turn it into the _real_ length of the variable OID */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check the BER encoding for correct type and length, that the
|
||||||
|
* string is long enough and that the OID matches that in our context
|
||||||
|
*/
|
||||||
|
if (tok[4] != 0x06 || tok[5] != oidl ||
|
||||||
|
ename->length < oidl+6 ||
|
||||||
|
!ssh_gssapi_check_oid(ctx,tok+6,oidl))
|
||||||
|
return GSS_S_FAILURE;
|
||||||
|
|
||||||
|
offset = oidl+6;
|
||||||
|
|
||||||
|
if (ename->length < offset+4)
|
||||||
|
return GSS_S_FAILURE;
|
||||||
|
|
||||||
|
name->length = GET_32BIT(tok+offset);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
if (ename->length < offset+name->length)
|
||||||
|
return GSS_S_FAILURE;
|
||||||
|
|
||||||
|
name->value = xmalloc(name->length);
|
||||||
|
memcpy(name->value,tok+offset,name->length);
|
||||||
|
|
||||||
|
return GSS_S_COMPLETE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Extract the client details from a given context. This can only reliably
|
||||||
|
* be called once for a context */
|
||||||
|
|
||||||
|
/* Priviledged (called from accept_secure_ctx) */
|
||||||
|
OM_uint32
|
||||||
|
ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
gss_buffer_desc ename;
|
||||||
|
|
||||||
|
client->mech = NULL;
|
||||||
|
|
||||||
|
while (supported_mechs[i]->name != NULL) {
|
||||||
|
if (supported_mechs[i]->oid.length == ctx->oid->length &&
|
||||||
|
(memcmp(supported_mechs[i]->oid.elements,
|
||||||
|
ctx->oid->elements, ctx->oid->length) == 0))
|
||||||
|
client->mech = supported_mechs[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client->mech == NULL)
|
||||||
|
return GSS_S_FAILURE;
|
||||||
|
|
||||||
|
if ((ctx->major = gss_display_name(&ctx->minor, ctx->client,
|
||||||
|
&client->displayname, NULL))) {
|
||||||
|
ssh_gssapi_error(ctx);
|
||||||
|
return (ctx->major);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ctx->major = gss_export_name(&ctx->minor, ctx->client,
|
||||||
|
&ename))) {
|
||||||
|
ssh_gssapi_error(ctx);
|
||||||
|
return (ctx->major);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ctx->major = ssh_gssapi_parse_ename(ctx,&ename,
|
||||||
|
&client->exportedname))) {
|
||||||
|
return (ctx->major);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We can't copy this structure, so we just move the pointer to it */
|
||||||
|
client->creds = ctx->client_creds;
|
||||||
|
ctx->client_creds = GSS_C_NO_CREDENTIAL;
|
||||||
|
return (ctx->major);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* As user - called through fatal cleanup hook */
|
||||||
|
void
|
||||||
|
ssh_gssapi_cleanup_creds(void *ignored)
|
||||||
|
{
|
||||||
|
if (gssapi_client.store.filename != NULL) {
|
||||||
|
/* Unlink probably isn't sufficient */
|
||||||
|
debug("removing gssapi cred file\"%s\"", gssapi_client.store.filename);
|
||||||
|
unlink(gssapi_client.store.filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* As user */
|
||||||
|
void
|
||||||
|
ssh_gssapi_storecreds(void)
|
||||||
|
{
|
||||||
|
if (gssapi_client.mech && gssapi_client.mech->storecreds) {
|
||||||
|
(*gssapi_client.mech->storecreds)(&gssapi_client);
|
||||||
|
if (options.gss_cleanup_creds)
|
||||||
|
fatal_add_cleanup(ssh_gssapi_cleanup_creds, NULL);
|
||||||
|
} else
|
||||||
|
debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This allows GSSAPI methods to do things to the childs environment based
|
||||||
|
* on the passed authentication process and credentials.
|
||||||
|
*/
|
||||||
|
/* As user */
|
||||||
|
void
|
||||||
|
ssh_gssapi_do_child(char ***envp, u_int *envsizep)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (gssapi_client.store.envvar != NULL &&
|
||||||
|
gssapi_client.store.envval != NULL) {
|
||||||
|
|
||||||
|
debug("Setting %s to %s", gssapi_client.store.envvar,
|
||||||
|
gssapi_client.store.envval);
|
||||||
|
child_set_env(envp, envsizep, gssapi_client.store.envvar,
|
||||||
|
gssapi_client.store.envval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Priviledged */
|
||||||
|
int
|
||||||
|
ssh_gssapi_userok(char *user)
|
||||||
|
{
|
||||||
|
if (gssapi_client.exportedname.length == 0 ||
|
||||||
|
gssapi_client.exportedname.value == NULL) {
|
||||||
|
debug("No suitable client data");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (gssapi_client.mech && gssapi_client.mech->userok)
|
||||||
|
return ((*gssapi_client.mech->userok)(&gssapi_client, user));
|
||||||
|
else
|
||||||
|
debug("ssh_gssapi_userok: Unknown GSSAPI mechanism");
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
92
monitor.c
92
monitor.c
@ -25,7 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: monitor.c,v 1.45 2003/07/22 13:35:22 markus Exp $");
|
RCSID("$OpenBSD: monitor.c,v 1.46 2003/08/22 10:56:09 markus Exp $");
|
||||||
|
|
||||||
#include <openssl/dh.h>
|
#include <openssl/dh.h>
|
||||||
|
|
||||||
@ -59,6 +59,11 @@ RCSID("$OpenBSD: monitor.c,v 1.45 2003/07/22 13:35:22 markus Exp $");
|
|||||||
#include "ssh2.h"
|
#include "ssh2.h"
|
||||||
#include "mpaux.h"
|
#include "mpaux.h"
|
||||||
|
|
||||||
|
#ifdef GSSAPI
|
||||||
|
#include "ssh-gss.h"
|
||||||
|
static Gssctxt *gsscontext = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Imports */
|
/* Imports */
|
||||||
extern ServerOptions options;
|
extern ServerOptions options;
|
||||||
extern u_int utmp_len;
|
extern u_int utmp_len;
|
||||||
@ -128,6 +133,11 @@ int mm_answer_pam_free_ctx(int, Buffer *);
|
|||||||
#ifdef KRB5
|
#ifdef KRB5
|
||||||
int mm_answer_krb5(int, Buffer *);
|
int mm_answer_krb5(int, Buffer *);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef GSSAPI
|
||||||
|
int mm_answer_gss_setup_ctx(int, Buffer *);
|
||||||
|
int mm_answer_gss_accept_ctx(int, Buffer *);
|
||||||
|
int mm_answer_gss_userok(int, Buffer *);
|
||||||
|
#endif
|
||||||
|
|
||||||
static Authctxt *authctxt;
|
static Authctxt *authctxt;
|
||||||
static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */
|
static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */
|
||||||
@ -184,6 +194,11 @@ struct mon_table mon_dispatch_proto20[] = {
|
|||||||
{MONITOR_REQ_KEYVERIFY, MON_AUTH, mm_answer_keyverify},
|
{MONITOR_REQ_KEYVERIFY, MON_AUTH, mm_answer_keyverify},
|
||||||
#ifdef KRB5
|
#ifdef KRB5
|
||||||
{MONITOR_REQ_KRB5, MON_ONCE|MON_AUTH, mm_answer_krb5},
|
{MONITOR_REQ_KRB5, MON_ONCE|MON_AUTH, mm_answer_krb5},
|
||||||
|
#endif
|
||||||
|
#ifdef GSSAPI
|
||||||
|
{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},
|
||||||
#endif
|
#endif
|
||||||
{0, 0, NULL}
|
{0, 0, NULL}
|
||||||
};
|
};
|
||||||
@ -357,7 +372,6 @@ monitor_child_postauth(struct monitor *pmonitor)
|
|||||||
monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
|
monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
|
||||||
monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
|
monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
|
||||||
monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
|
monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
mon_dispatch = mon_dispatch_postauth15;
|
mon_dispatch = mon_dispatch_postauth15;
|
||||||
monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
|
monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
|
||||||
@ -1769,3 +1783,77 @@ monitor_reinit(struct monitor *mon)
|
|||||||
mon->m_recvfd = pair[0];
|
mon->m_recvfd = pair[0];
|
||||||
mon->m_sendfd = pair[1];
|
mon->m_sendfd = pair[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef GSSAPI
|
||||||
|
int
|
||||||
|
mm_answer_gss_setup_ctx(int socket, Buffer *m)
|
||||||
|
{
|
||||||
|
gss_OID_desc oid;
|
||||||
|
OM_uint32 major;
|
||||||
|
u_int len;
|
||||||
|
|
||||||
|
oid.elements = buffer_get_string(m, &len);
|
||||||
|
oid.length = len;
|
||||||
|
|
||||||
|
major = ssh_gssapi_server_ctx(&gsscontext, &oid);
|
||||||
|
|
||||||
|
xfree(oid.elements);
|
||||||
|
|
||||||
|
buffer_clear(m);
|
||||||
|
buffer_put_int(m, major);
|
||||||
|
|
||||||
|
mm_request_send(socket,MONITOR_ANS_GSSSETUP, m);
|
||||||
|
|
||||||
|
/* Now we have a context, enable the step */
|
||||||
|
monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 1);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
mm_answer_gss_accept_ctx(int socket, Buffer *m)
|
||||||
|
{
|
||||||
|
gss_buffer_desc in;
|
||||||
|
gss_buffer_desc out = GSS_C_EMPTY_BUFFER;
|
||||||
|
OM_uint32 major,minor;
|
||||||
|
OM_uint32 flags = 0; /* GSI needs this */
|
||||||
|
|
||||||
|
in.value = buffer_get_string(m, &in.length);
|
||||||
|
major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags);
|
||||||
|
xfree(in.value);
|
||||||
|
|
||||||
|
buffer_clear(m);
|
||||||
|
buffer_put_int(m, major);
|
||||||
|
buffer_put_string(m, out.value, out.length);
|
||||||
|
buffer_put_int(m, flags);
|
||||||
|
mm_request_send(socket, MONITOR_ANS_GSSSTEP, 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);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
mm_answer_gss_userok(int socket, Buffer *m)
|
||||||
|
{
|
||||||
|
int authenticated;
|
||||||
|
|
||||||
|
authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user);
|
||||||
|
|
||||||
|
buffer_clear(m);
|
||||||
|
buffer_put_int(m, authenticated);
|
||||||
|
|
||||||
|
debug3("%s: sending result %d", __func__, authenticated);
|
||||||
|
mm_request_send(socket, MONITOR_ANS_GSSUSEROK, m);
|
||||||
|
|
||||||
|
auth_method="gssapi";
|
||||||
|
|
||||||
|
/* Monitor loop will terminate if authenticated */
|
||||||
|
return (authenticated);
|
||||||
|
}
|
||||||
|
#endif /* GSSAPI */
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: monitor.h,v 1.9 2003/07/22 13:35:22 markus Exp $ */
|
/* $OpenBSD: monitor.h,v 1.10 2003/08/22 10:56:09 markus Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||||
@ -50,6 +50,9 @@ enum monitor_reqtype {
|
|||||||
MONITOR_REQ_RSACHALLENGE, MONITOR_ANS_RSACHALLENGE,
|
MONITOR_REQ_RSACHALLENGE, MONITOR_ANS_RSACHALLENGE,
|
||||||
MONITOR_REQ_RSARESPONSE, MONITOR_ANS_RSARESPONSE,
|
MONITOR_REQ_RSARESPONSE, MONITOR_ANS_RSARESPONSE,
|
||||||
MONITOR_REQ_KRB5, MONITOR_ANS_KRB5,
|
MONITOR_REQ_KRB5, MONITOR_ANS_KRB5,
|
||||||
|
MONITOR_REQ_GSSSETUP, MONITOR_ANS_GSSSETUP,
|
||||||
|
MONITOR_REQ_GSSSTEP, MONITOR_ANS_GSSSTEP,
|
||||||
|
MONITOR_REQ_GSSUSEROK, MONITOR_ANS_GSSUSEROK,
|
||||||
MONITOR_REQ_PAM_START,
|
MONITOR_REQ_PAM_START,
|
||||||
MONITOR_REQ_PAM_ACCOUNT, MONITOR_ANS_PAM_ACCOUNT,
|
MONITOR_REQ_PAM_ACCOUNT, MONITOR_ANS_PAM_ACCOUNT,
|
||||||
MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX,
|
MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX,
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: monitor_wrap.c,v 1.28 2003/07/22 13:35:22 markus Exp $");
|
RCSID("$OpenBSD: monitor_wrap.c,v 1.29 2003/08/22 10:56:09 markus Exp $");
|
||||||
|
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
#include <openssl/dh.h>
|
#include <openssl/dh.h>
|
||||||
@ -53,6 +53,10 @@ RCSID("$OpenBSD: monitor_wrap.c,v 1.28 2003/07/22 13:35:22 markus Exp $");
|
|||||||
#include "channels.h"
|
#include "channels.h"
|
||||||
#include "session.h"
|
#include "session.h"
|
||||||
|
|
||||||
|
#ifdef GSSAPI
|
||||||
|
#include "ssh-gss.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Imports */
|
/* Imports */
|
||||||
extern int compat20;
|
extern int compat20;
|
||||||
extern Newkeys *newkeys[];
|
extern Newkeys *newkeys[];
|
||||||
@ -1100,4 +1104,69 @@ mm_auth_krb5(void *ctx, void *argp, char **userp, void *resp)
|
|||||||
buffer_free(&m);
|
buffer_free(&m);
|
||||||
return (success);
|
return (success);
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* KRB5 */
|
||||||
|
|
||||||
|
#ifdef GSSAPI
|
||||||
|
OM_uint32
|
||||||
|
mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid)
|
||||||
|
{
|
||||||
|
Buffer m;
|
||||||
|
OM_uint32 major;
|
||||||
|
|
||||||
|
/* Client doesn't get to see the context */
|
||||||
|
*ctx = NULL;
|
||||||
|
|
||||||
|
buffer_init(&m);
|
||||||
|
buffer_put_string(&m, oid->elements, oid->length);
|
||||||
|
|
||||||
|
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, &m);
|
||||||
|
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, &m);
|
||||||
|
|
||||||
|
major = buffer_get_int(&m);
|
||||||
|
|
||||||
|
buffer_free(&m);
|
||||||
|
return (major);
|
||||||
|
}
|
||||||
|
|
||||||
|
OM_uint32
|
||||||
|
mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in,
|
||||||
|
gss_buffer_desc *out, OM_uint32 *flags)
|
||||||
|
{
|
||||||
|
Buffer m;
|
||||||
|
OM_uint32 major;
|
||||||
|
|
||||||
|
buffer_init(&m);
|
||||||
|
buffer_put_string(&m, in->value, in->length);
|
||||||
|
|
||||||
|
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, &m);
|
||||||
|
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, &m);
|
||||||
|
|
||||||
|
major = buffer_get_int(&m);
|
||||||
|
out->value = buffer_get_string(&m, &out->length);
|
||||||
|
if (flags)
|
||||||
|
*flags = buffer_get_int(&m);
|
||||||
|
|
||||||
|
buffer_free(&m);
|
||||||
|
|
||||||
|
return (major);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
mm_ssh_gssapi_userok(char *user)
|
||||||
|
{
|
||||||
|
Buffer m;
|
||||||
|
int authenticated = 0;
|
||||||
|
|
||||||
|
buffer_init(&m);
|
||||||
|
|
||||||
|
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m);
|
||||||
|
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK,
|
||||||
|
&m);
|
||||||
|
|
||||||
|
authenticated = buffer_get_int(&m);
|
||||||
|
|
||||||
|
buffer_free(&m);
|
||||||
|
debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not ");
|
||||||
|
return (authenticated);
|
||||||
|
}
|
||||||
|
#endif /* GSSAPI */
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: monitor_wrap.h,v 1.9 2003/07/22 13:35:22 markus Exp $ */
|
/* $OpenBSD: monitor_wrap.h,v 1.10 2003/08/22 10:56:09 markus Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||||
@ -55,6 +55,14 @@ int mm_auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **);
|
|||||||
int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *);
|
int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *);
|
||||||
BIGNUM *mm_auth_rsa_generate_challenge(Key *);
|
BIGNUM *mm_auth_rsa_generate_challenge(Key *);
|
||||||
|
|
||||||
|
#ifdef GSSAPI
|
||||||
|
#include "ssh-gss.h"
|
||||||
|
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);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_PAM
|
#ifdef USE_PAM
|
||||||
void mm_start_pam(char *);
|
void mm_start_pam(char *);
|
||||||
u_int mm_do_pam_account(void);
|
u_int mm_do_pam_account(void);
|
||||||
|
26
readconf.c
26
readconf.c
@ -12,7 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: readconf.c,v 1.117 2003/08/13 09:07:09 markus Exp $");
|
RCSID("$OpenBSD: readconf.c,v 1.118 2003/08/22 10:56:09 markus Exp $");
|
||||||
|
|
||||||
#include "ssh.h"
|
#include "ssh.h"
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
@ -105,7 +105,7 @@ typedef enum {
|
|||||||
oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
|
oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
|
||||||
oClearAllForwardings, oNoHostAuthenticationForLocalhost,
|
oClearAllForwardings, oNoHostAuthenticationForLocalhost,
|
||||||
oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
|
oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
|
||||||
oAddressFamily,
|
oAddressFamily, oGssAuthentication, oGssDelegateCreds,
|
||||||
oDeprecated, oUnsupported
|
oDeprecated, oUnsupported
|
||||||
} OpCodes;
|
} OpCodes;
|
||||||
|
|
||||||
@ -140,6 +140,14 @@ static struct {
|
|||||||
{ "kerberostgtpassing", oUnsupported },
|
{ "kerberostgtpassing", oUnsupported },
|
||||||
#endif
|
#endif
|
||||||
{ "afstokenpassing", oUnsupported },
|
{ "afstokenpassing", oUnsupported },
|
||||||
|
#if defined(GSSAPI)
|
||||||
|
{ "gssapiauthentication", oGssAuthentication },
|
||||||
|
{ "gssapidelegatecreds", oGssDelegateCreds },
|
||||||
|
{ "gssapidelegatecredentials", oGssDelegateCreds },
|
||||||
|
#else
|
||||||
|
{ "gssapiauthentication", oUnsupported },
|
||||||
|
{ "gssapidelegatecredentials", oUnsupported },
|
||||||
|
#endif
|
||||||
{ "fallbacktorsh", oDeprecated },
|
{ "fallbacktorsh", oDeprecated },
|
||||||
{ "usersh", oDeprecated },
|
{ "usersh", oDeprecated },
|
||||||
{ "identityfile", oIdentityFile },
|
{ "identityfile", oIdentityFile },
|
||||||
@ -389,6 +397,14 @@ parse_flag:
|
|||||||
intptr = &options->kerberos_tgt_passing;
|
intptr = &options->kerberos_tgt_passing;
|
||||||
goto parse_flag;
|
goto parse_flag;
|
||||||
|
|
||||||
|
case oGssAuthentication:
|
||||||
|
intptr = &options->gss_authentication;
|
||||||
|
goto parse_flag;
|
||||||
|
|
||||||
|
case oGssDelegateCreds:
|
||||||
|
intptr = &options->gss_deleg_creds;
|
||||||
|
goto parse_flag;
|
||||||
|
|
||||||
case oBatchMode:
|
case oBatchMode:
|
||||||
intptr = &options->batch_mode;
|
intptr = &options->batch_mode;
|
||||||
goto parse_flag;
|
goto parse_flag;
|
||||||
@ -813,6 +829,8 @@ initialize_options(Options * options)
|
|||||||
options->challenge_response_authentication = -1;
|
options->challenge_response_authentication = -1;
|
||||||
options->kerberos_authentication = -1;
|
options->kerberos_authentication = -1;
|
||||||
options->kerberos_tgt_passing = -1;
|
options->kerberos_tgt_passing = -1;
|
||||||
|
options->gss_authentication = -1;
|
||||||
|
options->gss_deleg_creds = -1;
|
||||||
options->password_authentication = -1;
|
options->password_authentication = -1;
|
||||||
options->kbd_interactive_authentication = -1;
|
options->kbd_interactive_authentication = -1;
|
||||||
options->kbd_interactive_devices = NULL;
|
options->kbd_interactive_devices = NULL;
|
||||||
@ -887,6 +905,10 @@ fill_default_options(Options * options)
|
|||||||
options->kerberos_authentication = 1;
|
options->kerberos_authentication = 1;
|
||||||
if (options->kerberos_tgt_passing == -1)
|
if (options->kerberos_tgt_passing == -1)
|
||||||
options->kerberos_tgt_passing = 1;
|
options->kerberos_tgt_passing = 1;
|
||||||
|
if (options->gss_authentication == -1)
|
||||||
|
options->gss_authentication = 1;
|
||||||
|
if (options->gss_deleg_creds == -1)
|
||||||
|
options->gss_deleg_creds = 0;
|
||||||
if (options->password_authentication == -1)
|
if (options->password_authentication == -1)
|
||||||
options->password_authentication = 1;
|
options->password_authentication = 1;
|
||||||
if (options->kbd_interactive_authentication == -1)
|
if (options->kbd_interactive_authentication == -1)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: readconf.h,v 1.53 2003/08/13 08:46:30 markus Exp $ */
|
/* $OpenBSD: readconf.h,v 1.54 2003/08/22 10:56:09 markus Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
@ -42,6 +42,8 @@ typedef struct {
|
|||||||
/* Try S/Key or TIS, authentication. */
|
/* Try S/Key or TIS, authentication. */
|
||||||
int kerberos_authentication; /* Try Kerberos authentication. */
|
int kerberos_authentication; /* Try Kerberos authentication. */
|
||||||
int kerberos_tgt_passing; /* Try Kerberos TGT passing. */
|
int kerberos_tgt_passing; /* Try Kerberos TGT passing. */
|
||||||
|
int gss_authentication; /* Try GSS authentication */
|
||||||
|
int gss_deleg_creds; /* Delegate GSS credentials */
|
||||||
int password_authentication; /* Try password
|
int password_authentication; /* Try password
|
||||||
* authentication. */
|
* authentication. */
|
||||||
int kbd_interactive_authentication; /* Try keyboard-interactive auth. */
|
int kbd_interactive_authentication; /* Try keyboard-interactive auth. */
|
||||||
|
24
servconf.c
24
servconf.c
@ -10,7 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: servconf.c,v 1.124 2003/08/13 08:46:30 markus Exp $");
|
RCSID("$OpenBSD: servconf.c,v 1.125 2003/08/22 10:56:09 markus Exp $");
|
||||||
|
|
||||||
#include "ssh.h"
|
#include "ssh.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
@ -73,6 +73,8 @@ initialize_server_options(ServerOptions *options)
|
|||||||
options->kerberos_or_local_passwd = -1;
|
options->kerberos_or_local_passwd = -1;
|
||||||
options->kerberos_ticket_cleanup = -1;
|
options->kerberos_ticket_cleanup = -1;
|
||||||
options->kerberos_tgt_passing = -1;
|
options->kerberos_tgt_passing = -1;
|
||||||
|
options->gss_authentication=-1;
|
||||||
|
options->gss_cleanup_creds = -1;
|
||||||
options->password_authentication = -1;
|
options->password_authentication = -1;
|
||||||
options->kbd_interactive_authentication = -1;
|
options->kbd_interactive_authentication = -1;
|
||||||
options->challenge_response_authentication = -1;
|
options->challenge_response_authentication = -1;
|
||||||
@ -182,6 +184,10 @@ fill_default_server_options(ServerOptions *options)
|
|||||||
options->kerberos_ticket_cleanup = 1;
|
options->kerberos_ticket_cleanup = 1;
|
||||||
if (options->kerberos_tgt_passing == -1)
|
if (options->kerberos_tgt_passing == -1)
|
||||||
options->kerberos_tgt_passing = 0;
|
options->kerberos_tgt_passing = 0;
|
||||||
|
if (options->gss_authentication == -1)
|
||||||
|
options->gss_authentication = 0;
|
||||||
|
if (options->gss_cleanup_creds == -1)
|
||||||
|
options->gss_cleanup_creds = 1;
|
||||||
if (options->password_authentication == -1)
|
if (options->password_authentication == -1)
|
||||||
options->password_authentication = 1;
|
options->password_authentication = 1;
|
||||||
if (options->kbd_interactive_authentication == -1)
|
if (options->kbd_interactive_authentication == -1)
|
||||||
@ -259,6 +265,7 @@ typedef enum {
|
|||||||
sBanner, sUseDNS, sHostbasedAuthentication,
|
sBanner, sUseDNS, sHostbasedAuthentication,
|
||||||
sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
|
sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
|
||||||
sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
|
sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
|
||||||
|
sGssAuthentication, sGssCleanupCreds,
|
||||||
sUsePrivilegeSeparation,
|
sUsePrivilegeSeparation,
|
||||||
sDeprecated, sUnsupported
|
sDeprecated, sUnsupported
|
||||||
} ServerOpCodes;
|
} ServerOpCodes;
|
||||||
@ -305,6 +312,13 @@ static struct {
|
|||||||
{ "kerberostgtpassing", sUnsupported },
|
{ "kerberostgtpassing", sUnsupported },
|
||||||
#endif
|
#endif
|
||||||
{ "afstokenpassing", sUnsupported },
|
{ "afstokenpassing", sUnsupported },
|
||||||
|
#ifdef GSSAPI
|
||||||
|
{ "gssapiauthentication", sGssAuthentication },
|
||||||
|
{ "gssapicleanupcreds", sGssCleanupCreds },
|
||||||
|
#else
|
||||||
|
{ "gssapiauthentication", sUnsupported },
|
||||||
|
{ "gssapicleanupcreds", sUnsupported },
|
||||||
|
#endif
|
||||||
{ "passwordauthentication", sPasswordAuthentication },
|
{ "passwordauthentication", sPasswordAuthentication },
|
||||||
{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
|
{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
|
||||||
{ "challengeresponseauthentication", sChallengeResponseAuthentication },
|
{ "challengeresponseauthentication", sChallengeResponseAuthentication },
|
||||||
@ -623,6 +637,14 @@ parse_flag:
|
|||||||
intptr = &options->kerberos_tgt_passing;
|
intptr = &options->kerberos_tgt_passing;
|
||||||
goto parse_flag;
|
goto parse_flag;
|
||||||
|
|
||||||
|
case sGssAuthentication:
|
||||||
|
intptr = &options->gss_authentication;
|
||||||
|
goto parse_flag;
|
||||||
|
|
||||||
|
case sGssCleanupCreds:
|
||||||
|
intptr = &options->gss_cleanup_creds;
|
||||||
|
goto parse_flag;
|
||||||
|
|
||||||
case sPasswordAuthentication:
|
case sPasswordAuthentication:
|
||||||
intptr = &options->password_authentication;
|
intptr = &options->password_authentication;
|
||||||
goto parse_flag;
|
goto parse_flag;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: servconf.h,v 1.63 2003/08/13 08:46:30 markus Exp $ */
|
/* $OpenBSD: servconf.h,v 1.64 2003/08/22 10:56:09 markus Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
@ -82,6 +82,8 @@ typedef struct {
|
|||||||
* file on logout. */
|
* file on logout. */
|
||||||
int kerberos_tgt_passing; /* If true, permit Kerberos TGT
|
int kerberos_tgt_passing; /* If true, permit Kerberos TGT
|
||||||
* passing. */
|
* passing. */
|
||||||
|
int gss_authentication; /* If true, permit GSSAPI authentication */
|
||||||
|
int gss_cleanup_creds; /* If true, destroy cred cache on logout */
|
||||||
int password_authentication; /* If true, permit password
|
int password_authentication; /* If true, permit password
|
||||||
* authentication. */
|
* authentication. */
|
||||||
int kbd_interactive_authentication; /* If true, permit */
|
int kbd_interactive_authentication; /* If true, permit */
|
||||||
|
31
session.c
31
session.c
@ -33,7 +33,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: session.c,v 1.160 2003/08/13 08:33:02 markus Exp $");
|
RCSID("$OpenBSD: session.c,v 1.161 2003/08/22 10:56:09 markus Exp $");
|
||||||
|
|
||||||
#include "ssh.h"
|
#include "ssh.h"
|
||||||
#include "ssh1.h"
|
#include "ssh1.h"
|
||||||
@ -58,6 +58,10 @@ RCSID("$OpenBSD: session.c,v 1.160 2003/08/13 08:33:02 markus Exp $");
|
|||||||
#include "session.h"
|
#include "session.h"
|
||||||
#include "monitor_wrap.h"
|
#include "monitor_wrap.h"
|
||||||
|
|
||||||
|
#ifdef GSSAPI
|
||||||
|
#include "ssh-gss.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* func */
|
/* func */
|
||||||
|
|
||||||
Session *session_new(void);
|
Session *session_new(void);
|
||||||
@ -424,6 +428,12 @@ do_exec_no_pty(Session *s, const char *command)
|
|||||||
}
|
}
|
||||||
#endif /* USE_PAM */
|
#endif /* USE_PAM */
|
||||||
|
|
||||||
|
#ifdef GSSAPI
|
||||||
|
temporarily_use_uid(s->pw);
|
||||||
|
ssh_gssapi_storecreds();
|
||||||
|
restore_uid();
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Fork the child. */
|
/* Fork the child. */
|
||||||
if ((pid = fork()) == 0) {
|
if ((pid = fork()) == 0) {
|
||||||
fatal_remove_all_cleanups();
|
fatal_remove_all_cleanups();
|
||||||
@ -550,6 +560,12 @@ do_exec_pty(Session *s, const char *command)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef GSSAPI
|
||||||
|
temporarily_use_uid(s->pw);
|
||||||
|
ssh_gssapi_storecreds();
|
||||||
|
restore_uid();
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Fork the child. */
|
/* Fork the child. */
|
||||||
if ((pid = fork()) == 0) {
|
if ((pid = fork()) == 0) {
|
||||||
fatal_remove_all_cleanups();
|
fatal_remove_all_cleanups();
|
||||||
@ -807,7 +823,7 @@ check_quietlogin(Session *s, const char *command)
|
|||||||
* Sets the value of the given variable in the environment. If the variable
|
* Sets the value of the given variable in the environment. If the variable
|
||||||
* already exists, its value is overriden.
|
* already exists, its value is overriden.
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
child_set_env(char ***envp, u_int *envsizep, const char *name,
|
child_set_env(char ***envp, u_int *envsizep, const char *name,
|
||||||
const char *value)
|
const char *value)
|
||||||
{
|
{
|
||||||
@ -934,6 +950,13 @@ do_setup_env(Session *s, const char *shell)
|
|||||||
copy_environment(environ, &env, &envsize);
|
copy_environment(environ, &env, &envsize);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef GSSAPI
|
||||||
|
/* Allow any GSSAPI methods that we've used to alter
|
||||||
|
* the childs environment as they see fit
|
||||||
|
*/
|
||||||
|
ssh_gssapi_do_child(&env, &envsize);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!options.use_login) {
|
if (!options.use_login) {
|
||||||
/* Set basic environment. */
|
/* Set basic environment. */
|
||||||
child_set_env(&env, &envsize, "USER", pw->pw_name);
|
child_set_env(&env, &envsize, "USER", pw->pw_name);
|
||||||
@ -2088,4 +2111,8 @@ static void
|
|||||||
do_authenticated2(Authctxt *authctxt)
|
do_authenticated2(Authctxt *authctxt)
|
||||||
{
|
{
|
||||||
server_loop2(authctxt);
|
server_loop2(authctxt);
|
||||||
|
#if defined(GSSAPI)
|
||||||
|
if (options.gss_cleanup_creds)
|
||||||
|
ssh_gssapi_cleanup_creds(NULL);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: session.h,v 1.19 2002/06/30 21:59:45 deraadt Exp $ */
|
/* $OpenBSD: session.h,v 1.20 2003/08/22 10:56:09 markus Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||||
@ -68,4 +68,7 @@ Session *session_new(void);
|
|||||||
Session *session_by_tty(char *);
|
Session *session_by_tty(char *);
|
||||||
void session_close(Session *);
|
void session_close(Session *);
|
||||||
void do_setusercontext(struct passwd *);
|
void do_setusercontext(struct passwd *);
|
||||||
|
void child_set_env(char ***envp, u_int *envsizep, const char *name,
|
||||||
|
const char *value);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
109
ssh-gss.h
Normal file
109
ssh-gss.h
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SSH_GSS_H
|
||||||
|
#define _SSH_GSS_H
|
||||||
|
|
||||||
|
#ifdef GSSAPI
|
||||||
|
|
||||||
|
#include "buffer.h"
|
||||||
|
|
||||||
|
#include <gssapi.h>
|
||||||
|
|
||||||
|
/* draft-ietf-secsh-gsskeyex-06 */
|
||||||
|
#define SSH2_MSG_USERAUTH_GSSAPI_RESPONSE 60
|
||||||
|
#define SSH2_MSG_USERAUTH_GSSAPI_TOKEN 61
|
||||||
|
#define SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE 63
|
||||||
|
#define SSH2_MSG_USERAUTH_GSSAPI_ERROR 64
|
||||||
|
#define SSH2_MSG_USERAUTH_GSSAPI_ERRTOK 65
|
||||||
|
|
||||||
|
#define SSH_GSS_OIDTYPE 0x06
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *filename;
|
||||||
|
char *envvar;
|
||||||
|
char *envval;
|
||||||
|
void *data;
|
||||||
|
} ssh_gssapi_ccache;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
gss_buffer_desc displayname;
|
||||||
|
gss_buffer_desc exportedname;
|
||||||
|
gss_cred_id_t creds;
|
||||||
|
struct ssh_gssapi_mech_struct *mech;
|
||||||
|
ssh_gssapi_ccache store;
|
||||||
|
} ssh_gssapi_client;
|
||||||
|
|
||||||
|
typedef struct ssh_gssapi_mech_struct {
|
||||||
|
char *enc_name;
|
||||||
|
char *name;
|
||||||
|
gss_OID_desc oid;
|
||||||
|
int (*dochild) (ssh_gssapi_client *);
|
||||||
|
int (*userok) (ssh_gssapi_client *, char *);
|
||||||
|
int (*localname) (ssh_gssapi_client *, char **);
|
||||||
|
void (*storecreds) (ssh_gssapi_client *);
|
||||||
|
} ssh_gssapi_mech;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
OM_uint32 major; /* both */
|
||||||
|
OM_uint32 minor; /* both */
|
||||||
|
gss_ctx_id_t context; /* both */
|
||||||
|
gss_name_t name; /* both */
|
||||||
|
gss_OID oid; /* client */
|
||||||
|
gss_cred_id_t creds; /* server */
|
||||||
|
gss_name_t client; /* server */
|
||||||
|
gss_cred_id_t client_creds; /* server */
|
||||||
|
} Gssctxt;
|
||||||
|
|
||||||
|
extern ssh_gssapi_mech *supported_mechs[];
|
||||||
|
|
||||||
|
int ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len);
|
||||||
|
void ssh_gssapi_set_oid_data(Gssctxt *ctx, void *data, size_t len);
|
||||||
|
void ssh_gssapi_set_oid(Gssctxt *ctx, gss_OID oid);
|
||||||
|
void ssh_gssapi_supported_oids(gss_OID_set *oidset);
|
||||||
|
ssh_gssapi_mech *ssh_gssapi_get_ctype(Gssctxt *ctxt);
|
||||||
|
|
||||||
|
OM_uint32 ssh_gssapi_import_name(Gssctxt *ctx, const char *host);
|
||||||
|
OM_uint32 ssh_gssapi_acquire_cred(Gssctxt *ctx);
|
||||||
|
OM_uint32 ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds,
|
||||||
|
gss_buffer_desc *recv_tok, gss_buffer_desc *send_tok, OM_uint32 *flags);
|
||||||
|
OM_uint32 ssh_gssapi_accept_ctx(Gssctxt *ctx,
|
||||||
|
gss_buffer_desc *recv_tok, gss_buffer_desc *send_tok, OM_uint32 *flags);
|
||||||
|
OM_uint32 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *);
|
||||||
|
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_server_ctx(Gssctxt **ctx, gss_OID oid);
|
||||||
|
|
||||||
|
/* In the server */
|
||||||
|
int ssh_gssapi_userok(char *name);
|
||||||
|
|
||||||
|
void ssh_gssapi_do_child(char ***envp, u_int *envsizep);
|
||||||
|
void ssh_gssapi_cleanup_creds(void *ignored);
|
||||||
|
void ssh_gssapi_storecreds(void);
|
||||||
|
|
||||||
|
#endif /* GSSAPI */
|
||||||
|
|
||||||
|
#endif /* _SSH_GSS_H */
|
14
ssh_config.5
14
ssh_config.5
@ -34,7 +34,7 @@
|
|||||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.\" $OpenBSD: ssh_config.5,v 1.17 2003/08/13 08:46:31 markus Exp $
|
.\" $OpenBSD: ssh_config.5,v 1.18 2003/08/22 10:56:09 markus Exp $
|
||||||
.Dd September 25, 1999
|
.Dd September 25, 1999
|
||||||
.Dt SSH_CONFIG 5
|
.Dt SSH_CONFIG 5
|
||||||
.Os
|
.Os
|
||||||
@ -331,6 +331,18 @@ The default is
|
|||||||
Specifies a file to use for the global
|
Specifies a file to use for the global
|
||||||
host key database instead of
|
host key database instead of
|
||||||
.Pa /etc/ssh/ssh_known_hosts .
|
.Pa /etc/ssh/ssh_known_hosts .
|
||||||
|
.It Cm GSSAPIAuthentication
|
||||||
|
Specifies whether authentication based on GSSAPI may be used, either using
|
||||||
|
the result of a successful key exchange, or using GSSAPI user
|
||||||
|
authentication.
|
||||||
|
The default is
|
||||||
|
.Dq yes .
|
||||||
|
Note that this option applies to protocol version 2 only.
|
||||||
|
.It Cm GSSAPIDelegateCredentials
|
||||||
|
Forward (delegate) credentials to the server.
|
||||||
|
The default is
|
||||||
|
.Dq no .
|
||||||
|
Note that this option applies to protocol version 2 only.
|
||||||
.It Cm HostbasedAuthentication
|
.It Cm HostbasedAuthentication
|
||||||
Specifies whether to try rhosts based authentication with public key
|
Specifies whether to try rhosts based authentication with public key
|
||||||
authentication.
|
authentication.
|
||||||
|
252
sshconnect2.c
252
sshconnect2.c
@ -23,7 +23,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: sshconnect2.c,v 1.120 2003/06/24 08:23:46 markus Exp $");
|
RCSID("$OpenBSD: sshconnect2.c,v 1.121 2003/08/22 10:56:09 markus Exp $");
|
||||||
|
|
||||||
#ifdef KRB5
|
#ifdef KRB5
|
||||||
#include <krb5.h>
|
#include <krb5.h>
|
||||||
@ -57,6 +57,10 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.120 2003/06/24 08:23:46 markus Exp $");
|
|||||||
#include "msg.h"
|
#include "msg.h"
|
||||||
#include "pathnames.h"
|
#include "pathnames.h"
|
||||||
|
|
||||||
|
#ifdef GSSAPI
|
||||||
|
#include "ssh-gss.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* import */
|
/* import */
|
||||||
extern char *client_version_string;
|
extern char *client_version_string;
|
||||||
extern char *server_version_string;
|
extern char *server_version_string;
|
||||||
@ -178,6 +182,8 @@ struct Authctxt {
|
|||||||
Sensitive *sensitive;
|
Sensitive *sensitive;
|
||||||
/* kbd-interactive */
|
/* kbd-interactive */
|
||||||
int info_req_seen;
|
int info_req_seen;
|
||||||
|
/* generic */
|
||||||
|
void *methoddata;
|
||||||
};
|
};
|
||||||
struct Authmethod {
|
struct Authmethod {
|
||||||
char *name; /* string to compare against server's list */
|
char *name; /* string to compare against server's list */
|
||||||
@ -201,6 +207,15 @@ int userauth_kbdint(Authctxt *);
|
|||||||
int userauth_hostbased(Authctxt *);
|
int userauth_hostbased(Authctxt *);
|
||||||
int userauth_kerberos(Authctxt *);
|
int userauth_kerberos(Authctxt *);
|
||||||
|
|
||||||
|
#ifdef GSSAPI
|
||||||
|
int userauth_gssapi(Authctxt *authctxt);
|
||||||
|
void input_gssapi_response(int type, u_int32_t, void *);
|
||||||
|
void input_gssapi_token(int type, u_int32_t, void *);
|
||||||
|
void input_gssapi_hash(int type, u_int32_t, void *);
|
||||||
|
void input_gssapi_error(int, u_int32_t, void *);
|
||||||
|
void input_gssapi_errtok(int, u_int32_t, void *);
|
||||||
|
#endif
|
||||||
|
|
||||||
void userauth(Authctxt *, char *);
|
void userauth(Authctxt *, char *);
|
||||||
|
|
||||||
static int sign_and_send_pubkey(Authctxt *, Identity *);
|
static int sign_and_send_pubkey(Authctxt *, Identity *);
|
||||||
@ -213,6 +228,12 @@ static Authmethod *authmethod_lookup(const char *name);
|
|||||||
static char *authmethods_get(void);
|
static char *authmethods_get(void);
|
||||||
|
|
||||||
Authmethod authmethods[] = {
|
Authmethod authmethods[] = {
|
||||||
|
#ifdef GSSAPI
|
||||||
|
{"gssapi",
|
||||||
|
userauth_gssapi,
|
||||||
|
&options.gss_authentication,
|
||||||
|
NULL},
|
||||||
|
#endif
|
||||||
{"hostbased",
|
{"hostbased",
|
||||||
userauth_hostbased,
|
userauth_hostbased,
|
||||||
&options.hostbased_authentication,
|
&options.hostbased_authentication,
|
||||||
@ -283,6 +304,7 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host,
|
|||||||
authctxt.success = 0;
|
authctxt.success = 0;
|
||||||
authctxt.method = authmethod_lookup("none");
|
authctxt.method = authmethod_lookup("none");
|
||||||
authctxt.authlist = NULL;
|
authctxt.authlist = NULL;
|
||||||
|
authctxt.methoddata = NULL;
|
||||||
authctxt.sensitive = sensitive;
|
authctxt.sensitive = sensitive;
|
||||||
authctxt.info_req_seen = 0;
|
authctxt.info_req_seen = 0;
|
||||||
if (authctxt.method == NULL)
|
if (authctxt.method == NULL)
|
||||||
@ -306,6 +328,10 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host,
|
|||||||
void
|
void
|
||||||
userauth(Authctxt *authctxt, char *authlist)
|
userauth(Authctxt *authctxt, char *authlist)
|
||||||
{
|
{
|
||||||
|
if (authctxt->methoddata) {
|
||||||
|
xfree(authctxt->methoddata);
|
||||||
|
authctxt->methoddata = NULL;
|
||||||
|
}
|
||||||
if (authlist == NULL) {
|
if (authlist == NULL) {
|
||||||
authlist = authctxt->authlist;
|
authlist = authctxt->authlist;
|
||||||
} else {
|
} else {
|
||||||
@ -361,6 +387,8 @@ input_userauth_success(int type, u_int32_t seq, void *ctxt)
|
|||||||
fatal("input_userauth_success: no authentication context");
|
fatal("input_userauth_success: no authentication context");
|
||||||
if (authctxt->authlist)
|
if (authctxt->authlist)
|
||||||
xfree(authctxt->authlist);
|
xfree(authctxt->authlist);
|
||||||
|
if (authctxt->methoddata)
|
||||||
|
xfree(authctxt->methoddata);
|
||||||
authctxt->success = 1; /* break out */
|
authctxt->success = 1; /* break out */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -449,6 +477,228 @@ done:
|
|||||||
userauth(authctxt, NULL);
|
userauth(authctxt, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef GSSAPI
|
||||||
|
int
|
||||||
|
userauth_gssapi(Authctxt *authctxt)
|
||||||
|
{
|
||||||
|
Gssctxt *gssctxt = NULL;
|
||||||
|
static gss_OID_set supported = NULL;
|
||||||
|
static int mech = 0;
|
||||||
|
OM_uint32 min;
|
||||||
|
int ok = 0;
|
||||||
|
|
||||||
|
/* Try one GSSAPI method at a time, rather than sending them all at
|
||||||
|
* once. */
|
||||||
|
|
||||||
|
if (supported == NULL)
|
||||||
|
gss_indicate_mechs(&min, &supported);
|
||||||
|
|
||||||
|
/* Check to see if the mechanism is usable before we offer it */
|
||||||
|
while (mech<supported->count && !ok) {
|
||||||
|
if (gssctxt)
|
||||||
|
ssh_gssapi_delete_ctx(&gssctxt);
|
||||||
|
ssh_gssapi_build_ctx(&gssctxt);
|
||||||
|
ssh_gssapi_set_oid(gssctxt, &supported->elements[mech]);
|
||||||
|
|
||||||
|
/* My DER encoding requires length<128 */
|
||||||
|
if (supported->elements[mech].length < 128 &&
|
||||||
|
!GSS_ERROR(ssh_gssapi_import_name(gssctxt,
|
||||||
|
authctxt->host))) {
|
||||||
|
ok = 1; /* Mechanism works */
|
||||||
|
} else {
|
||||||
|
mech++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ok) return 0;
|
||||||
|
|
||||||
|
authctxt->methoddata=(void *)gssctxt;
|
||||||
|
|
||||||
|
packet_start(SSH2_MSG_USERAUTH_REQUEST);
|
||||||
|
packet_put_cstring(authctxt->server_user);
|
||||||
|
packet_put_cstring(authctxt->service);
|
||||||
|
packet_put_cstring(authctxt->method->name);
|
||||||
|
|
||||||
|
packet_put_int(1);
|
||||||
|
|
||||||
|
/* Some servers encode the OID incorrectly (as we used to) */
|
||||||
|
if (datafellows & SSH_BUG_GSSAPI_BER) {
|
||||||
|
packet_put_string(supported->elements[mech].elements,
|
||||||
|
supported->elements[mech].length);
|
||||||
|
} else {
|
||||||
|
packet_put_int((supported->elements[mech].length)+2);
|
||||||
|
packet_put_char(SSH_GSS_OIDTYPE);
|
||||||
|
packet_put_char(supported->elements[mech].length);
|
||||||
|
packet_put_raw(supported->elements[mech].elements,
|
||||||
|
supported->elements[mech].length);
|
||||||
|
}
|
||||||
|
|
||||||
|
packet_send();
|
||||||
|
|
||||||
|
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE, &input_gssapi_response);
|
||||||
|
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token);
|
||||||
|
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERROR, &input_gssapi_error);
|
||||||
|
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok);
|
||||||
|
|
||||||
|
mech++; /* Move along to next candidate */
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
input_gssapi_response(int type, u_int32_t plen, void *ctxt)
|
||||||
|
{
|
||||||
|
Authctxt *authctxt = ctxt;
|
||||||
|
Gssctxt *gssctxt;
|
||||||
|
OM_uint32 status, ms;
|
||||||
|
int oidlen;
|
||||||
|
char *oidv;
|
||||||
|
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
|
||||||
|
|
||||||
|
if (authctxt == NULL)
|
||||||
|
fatal("input_gssapi_response: no authentication context");
|
||||||
|
gssctxt = authctxt->methoddata;
|
||||||
|
|
||||||
|
/* Setup our OID */
|
||||||
|
oidv = packet_get_string(&oidlen);
|
||||||
|
|
||||||
|
if (datafellows & SSH_BUG_GSSAPI_BER) {
|
||||||
|
if (!ssh_gssapi_check_oid(gssctxt, oidv, oidlen))
|
||||||
|
fatal("Server returned different OID than expected");
|
||||||
|
} else {
|
||||||
|
if(oidv[0] != SSH_GSS_OIDTYPE || oidv[1] != oidlen-2) {
|
||||||
|
debug("Badly encoded mechanism OID received");
|
||||||
|
userauth(authctxt, NULL);
|
||||||
|
xfree(oidv);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!ssh_gssapi_check_oid(gssctxt, oidv+2, oidlen-2))
|
||||||
|
fatal("Server returned different OID than expected");
|
||||||
|
}
|
||||||
|
|
||||||
|
packet_check_eom();
|
||||||
|
|
||||||
|
xfree(oidv);
|
||||||
|
|
||||||
|
status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
|
||||||
|
GSS_C_NO_BUFFER, &send_tok, NULL);
|
||||||
|
if (GSS_ERROR(status)) {
|
||||||
|
if (send_tok.length > 0) {
|
||||||
|
packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK);
|
||||||
|
packet_put_string(send_tok.value, send_tok.length);
|
||||||
|
packet_send();
|
||||||
|
gss_release_buffer(&ms, &send_tok);
|
||||||
|
}
|
||||||
|
/* Start again with next method on list */
|
||||||
|
debug("Trying to start again");
|
||||||
|
userauth(authctxt, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We must have data to send */
|
||||||
|
packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
|
||||||
|
packet_put_string(send_tok.value, send_tok.length);
|
||||||
|
packet_send();
|
||||||
|
gss_release_buffer(&ms, &send_tok);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
input_gssapi_token(int type, u_int32_t plen, void *ctxt)
|
||||||
|
{
|
||||||
|
Authctxt *authctxt = ctxt;
|
||||||
|
Gssctxt *gssctxt;
|
||||||
|
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
|
||||||
|
gss_buffer_desc recv_tok;
|
||||||
|
OM_uint32 status, ms;
|
||||||
|
u_int slen;
|
||||||
|
|
||||||
|
if (authctxt == NULL)
|
||||||
|
fatal("input_gssapi_response: no authentication context");
|
||||||
|
gssctxt = authctxt->methoddata;
|
||||||
|
|
||||||
|
recv_tok.value = packet_get_string(&slen);
|
||||||
|
recv_tok.length = slen; /* safe typecast */
|
||||||
|
|
||||||
|
packet_check_eom();
|
||||||
|
|
||||||
|
status=ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
|
||||||
|
&recv_tok, &send_tok, NULL);
|
||||||
|
|
||||||
|
xfree(recv_tok.value);
|
||||||
|
|
||||||
|
if (GSS_ERROR(status)) {
|
||||||
|
if (send_tok.length > 0) {
|
||||||
|
packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK);
|
||||||
|
packet_put_string(send_tok.value, send_tok.length);
|
||||||
|
packet_send();
|
||||||
|
gss_release_buffer(&ms, &send_tok);
|
||||||
|
}
|
||||||
|
/* Start again with the next method in the list */
|
||||||
|
userauth(authctxt, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (send_tok.length > 0) {
|
||||||
|
packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
|
||||||
|
packet_put_string(send_tok.value, send_tok.length);
|
||||||
|
packet_send();
|
||||||
|
gss_release_buffer(&ms, &send_tok);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == GSS_S_COMPLETE) {
|
||||||
|
/* If that succeeded, send a exchange complete message */
|
||||||
|
packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);
|
||||||
|
packet_send();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
|
||||||
|
{
|
||||||
|
Authctxt *authctxt = ctxt;
|
||||||
|
Gssctxt *gssctxt;
|
||||||
|
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
|
||||||
|
gss_buffer_desc recv_tok;
|
||||||
|
OM_uint32 status, ms;
|
||||||
|
|
||||||
|
if (authctxt == NULL)
|
||||||
|
fatal("input_gssapi_response: no authentication context");
|
||||||
|
gssctxt = authctxt->methoddata;
|
||||||
|
|
||||||
|
recv_tok.value = packet_get_string(&recv_tok.length);
|
||||||
|
|
||||||
|
packet_check_eom();
|
||||||
|
|
||||||
|
/* Stick it into GSSAPI and see what it says */
|
||||||
|
status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
|
||||||
|
&recv_tok, &send_tok, NULL);
|
||||||
|
|
||||||
|
xfree(recv_tok.value);
|
||||||
|
gss_release_buffer(&ms, &send_tok);
|
||||||
|
|
||||||
|
/* Server will be returning a failed packet after this one */
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
input_gssapi_error(int type, u_int32_t plen, void *ctxt)
|
||||||
|
{
|
||||||
|
OM_uint32 maj, min;
|
||||||
|
char *msg;
|
||||||
|
char *lang;
|
||||||
|
|
||||||
|
maj=packet_get_int();
|
||||||
|
min=packet_get_int();
|
||||||
|
msg=packet_get_string(NULL);
|
||||||
|
lang=packet_get_string(NULL);
|
||||||
|
|
||||||
|
packet_check_eom();
|
||||||
|
|
||||||
|
debug("Server GSSAPI Error:\n%s\n", msg);
|
||||||
|
xfree(msg);
|
||||||
|
xfree(lang);
|
||||||
|
}
|
||||||
|
#endif /* GSSAPI */
|
||||||
|
|
||||||
int
|
int
|
||||||
userauth_none(Authctxt *authctxt)
|
userauth_none(Authctxt *authctxt)
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# $OpenBSD: sshd_config,v 1.63 2003/08/13 08:46:31 markus Exp $
|
# $OpenBSD: sshd_config,v 1.64 2003/08/22 10:56:09 markus Exp $
|
||||||
|
|
||||||
# This is the sshd server system-wide configuration file. See
|
# This is the sshd server system-wide configuration file. See
|
||||||
# sshd_config(5) for more information.
|
# sshd_config(5) for more information.
|
||||||
@ -63,6 +63,10 @@
|
|||||||
#KerberosTicketCleanup yes
|
#KerberosTicketCleanup yes
|
||||||
#KerberosTgtPassing no
|
#KerberosTgtPassing no
|
||||||
|
|
||||||
|
# GSSAPI options
|
||||||
|
#GSSAPIAuthentication no
|
||||||
|
#GSSAPICleanupCreds yes
|
||||||
|
|
||||||
# Set this to 'yes' to enable PAM authentication (via challenge-response)
|
# Set this to 'yes' to enable PAM authentication (via challenge-response)
|
||||||
# and session processing. Depending on your PAM configuration, this may
|
# and session processing. Depending on your PAM configuration, this may
|
||||||
# bypass the setting of 'PasswordAuthentication'
|
# bypass the setting of 'PasswordAuthentication'
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.\" $OpenBSD: sshd_config.5,v 1.22 2003/08/13 08:46:31 markus Exp $
|
.\" $OpenBSD: sshd_config.5,v 1.23 2003/08/22 10:56:09 markus Exp $
|
||||||
.Dd September 25, 1999
|
.Dd September 25, 1999
|
||||||
.Dt SSHD_CONFIG 5
|
.Dt SSHD_CONFIG 5
|
||||||
.Os
|
.Os
|
||||||
@ -225,6 +225,19 @@ or
|
|||||||
.Dq no .
|
.Dq no .
|
||||||
The default is
|
The default is
|
||||||
.Dq no .
|
.Dq no .
|
||||||
|
.It Cm GSSAPIAuthentication
|
||||||
|
Specifies whether authentication based on GSSAPI may be used, either using
|
||||||
|
the result of a successful key exchange, or using GSSAPI user
|
||||||
|
authentication.
|
||||||
|
The default is
|
||||||
|
.Dq no .
|
||||||
|
Note that this option applies to protocol version 2 only.
|
||||||
|
.It Cm GSSAPICleanupCredentials
|
||||||
|
Specifies whether to automatically destroy the user's credentials cache
|
||||||
|
on logout.
|
||||||
|
The default is
|
||||||
|
.Dq yes .
|
||||||
|
Note that this option applies to protocol version 2 only.
|
||||||
.It Cm HostbasedAuthentication
|
.It Cm HostbasedAuthentication
|
||||||
Specifies whether rhosts or /etc/hosts.equiv authentication together
|
Specifies whether rhosts or /etc/hosts.equiv authentication together
|
||||||
with successful public key client host authentication is allowed
|
with successful public key client host authentication is allowed
|
||||||
|
Loading…
x
Reference in New Issue
Block a user