add krb5 support to ssh/sshd. based on code initially from Daniel Kouril <kouril@informatics.muni.cz> and Björn Grönvall <bg@sics.se>

This commit is contained in:
assar 2001-03-04 00:41:27 +00:00
parent 335ac388ca
commit e625c71295
19 changed files with 817 additions and 107 deletions

View File

@ -144,7 +144,7 @@ auth_krb4_password(struct passwd * pw, const char *password)
kerberos_auth_failure:
krb4_cleanup_proc(NULL);
if (!options.kerberos_or_local_passwd)
if (!options.krb4_or_local_passwd)
return 0;
} else {
/* Logging in as root or no local Kerberos realm. */
@ -283,7 +283,7 @@ auth_krb4(const char *server_user, KTEXT auth, char **client)
#ifdef AFS
int
auth_kerberos_tgt(struct passwd *pw, const char *string)
auth_krb4_tgt(struct passwd *pw, const char *string)
{
CREDENTIALS creds;

254
crypto/dist/ssh/auth-krb5.c vendored Normal file
View File

@ -0,0 +1,254 @@
/*
* Kerberos v5 authentication and ticket-passing routines.
*
* $FreeBSD: src/crypto/openssh/auth-krb5.c,v 1.6 2001/02/13 16:58:04 assar Exp $
*/
#include "includes.h"
#include "ssh.h"
#include "ssh1.h"
#include "packet.h"
#include "xmalloc.h"
#include "log.h"
#include "auth.h"
#ifdef KRB5
#include <krb5.h>
krb5_context ssh_context = NULL;
krb5_auth_context auth_context;
krb5_ccache mem_ccache = NULL; /* Credential cache for acquired ticket */
/* Try krb5 authentication. server_user is passed for logging purposes only,
in auth is received ticket, in client is returned principal from the
ticket */
int
auth_krb5(const char* server_user, krb5_data *auth, krb5_principal *client)
{
krb5_error_code problem;
krb5_principal server = NULL;
krb5_principal tkt_client = NULL;
krb5_data reply;
krb5_ticket *ticket = NULL;
int fd;
int ret;
reply.length = 0;
problem = krb5_init();
if (problem)
return 0;
problem = krb5_auth_con_init(ssh_context, &auth_context);
if (problem) {
log("Kerberos v5 authentication failed: %.100s",
krb5_get_err_text(ssh_context, problem));
return 0;
}
fd = packet_get_connection_in();
problem = krb5_auth_con_setaddrs_from_fd(ssh_context, auth_context, &fd);
if (problem) {
ret = 0;
goto err;
}
problem = krb5_sname_to_principal(ssh_context, NULL, NULL ,
KRB5_NT_SRV_HST, &server);
if (problem) {
ret = 0;
goto err;
}
problem = krb5_rd_req(ssh_context, &auth_context, auth, server, NULL,
NULL, &ticket);
if (problem) {
ret = 0;
goto err;
}
problem = krb5_copy_principal(ssh_context, ticket->client, &tkt_client);
if (problem) {
ret = 0;
goto err;
}
/* if client wants mutual auth */
problem = krb5_mk_rep(ssh_context, auth_context, &reply);
if (problem) {
ret = 0;
goto err;
}
*client = tkt_client;
packet_start(SSH_SMSG_AUTH_KERBEROS_RESPONSE);
packet_put_string((char *) reply.data, reply.length);
packet_send();
packet_write_wait();
ret = 1;
err:
if (server)
krb5_free_principal(ssh_context, server);
if (ticket)
krb5_free_ticket(ssh_context, ticket);
if (reply.length)
xfree(reply.data);
return ret;
}
int
auth_krb5_tgt(char *server_user, krb5_data *tgt, krb5_principal tkt_client)
{
krb5_error_code problem;
krb5_ccache ccache = NULL;
if (ssh_context == NULL) {
goto fail;
}
problem = krb5_cc_gen_new(ssh_context, &krb5_mcc_ops, &ccache);
if (problem) {
goto fail;
}
problem = krb5_cc_initialize(ssh_context, ccache, tkt_client);
if (problem) {
goto fail;
}
problem = krb5_rd_cred2(ssh_context, auth_context, ccache, tgt);
if (problem) {
goto fail;
}
mem_ccache = ccache;
ccache = NULL;
/*
problem = krb5_cc_copy_cache(ssh_context, ccache, mem_ccache);
if (problem) {
mem_ccache = NULL;
goto fail;
}
problem = krb5_cc_destroy(ssh_context, ccache);
if (problem)
goto fail;
*/
#if 0
packet_start(SSH_SMSG_SUCCESS);
packet_send();
packet_write_wait();
#endif
return 1;
fail:
if (ccache)
krb5_cc_destroy(ssh_context, ccache);
#if 0
packet_start(SSH_SMSG_FAILURE);
packet_send();
packet_write_wait();
#endif
return 0;
}
int
auth_krb5_password(struct passwd *pw, const char *password)
{
krb5_error_code problem;
krb5_ccache ccache = NULL;
krb5_principal client = NULL;
int ret;
problem = krb5_init();
if (problem)
return 0;
problem = krb5_parse_name(ssh_context, pw->pw_name, &client);
if (problem) {
ret = 0;
goto out;
}
problem = krb5_cc_gen_new(ssh_context, &krb5_mcc_ops, &ccache);
if (problem) {
ret = 0;
goto out;
}
problem = krb5_cc_initialize(ssh_context, ccache, client);
if (problem) {
ret = 0;
goto out;
}
problem = krb5_verify_user(ssh_context, client, ccache, password, 1, NULL);
if (problem) {
ret = 0;
goto out;
}
/*
problem = krb5_cc_copy_cache(ssh_context, ccache, mem_ccache);
if (problem) {
ret = 0;
mem_ccache = NULL;
goto out;
}
*/
mem_ccache = ccache;
ccache = NULL;
ret = 1;
out:
if (client != NULL)
krb5_free_principal(ssh_context, client);
if (ccache != NULL)
krb5_cc_destroy(ssh_context, ccache);
return ret;
}
void
krb5_cleanup_proc(void *ignore)
{
extern krb5_principal tkt_client;
debug("krb5_cleanup_proc() called");
if (mem_ccache)
krb5_cc_destroy(ssh_context, mem_ccache);
if (tkt_client)
krb5_free_principal(ssh_context, tkt_client);
if (auth_context)
krb5_auth_con_free(ssh_context, auth_context);
if (ssh_context)
krb5_free_context(ssh_context);
}
int
krb5_init(void)
{
krb5_error_code problem;
static int cleanup_registered = 0;
if (ssh_context == NULL) {
problem = krb5_init_context(&ssh_context);
if (problem)
return problem;
krb5_init_ets(ssh_context);
}
if (!cleanup_registered) {
fatal_add_cleanup(krb5_cleanup_proc, NULL);
cleanup_registered = 1;
}
return 0;
}
#endif /* KRB5 */

View File

@ -62,6 +62,14 @@ auth_password(struct passwd * pw, const char *password)
if (*password == '\0' && options.permit_empty_passwd == 0)
return 0;
#ifdef KRB5
if (options.kerberos_authentication == 1) {
if (auth_krb5_password(pw, password))
return 1;
/* Fall back to ordinary passwd authentication. */
}
#endif /* KRB5 */
#ifdef KRB4
if (options.kerberos_authentication == 1) {
int ret = auth_krb4_password(pw, password);

View File

@ -81,6 +81,19 @@ int auth_rsa_read_key(char **cpp, u_int *bitsp, BIGNUM * e, BIGNUM * n);
*/
int auth_rsa_challenge_dialog(RSA *pk);
#ifdef KRB5
#include <krb5.h>
int auth_krb5(const char* server_user, krb5_data *auth,
krb5_principal *client);
int auth_krb5_tgt(char *server_user, krb5_data *tgt,
krb5_principal tkt_client);
int krb5_init(void);
void krb5_cleanup_proc(void *ignore);
int auth_krb5_password(struct passwd *pw, const char *password);
void send_krb5_tgt(krb5_context context, krb5_auth_context auth_context);
int try_krb5_authentication(krb5_context *context, krb5_auth_context *auth_context);
#endif /* KRB5 */
#ifdef KRB4
#include <krb.h>
/*
@ -92,13 +105,19 @@ int auth_krb4(const char *server_user, KTEXT auth, char **client);
int krb4_init(uid_t uid);
void krb4_cleanup_proc(void *ignore);
int auth_krb4_password(struct passwd * pw, const char *password);
int send_krb4_tgt(void);
#ifdef AFS
#include <kafs.h>
/* Accept passed Kerberos v4 ticket-granting ticket and AFS tokens. */
int auth_kerberos_tgt(struct passwd * pw, const char *string);
int auth_krb4_tgt(struct passwd * pw, const char *string);
int auth_afs_token(struct passwd * pw, const char *token_string);
int creds_to_radix(CREDENTIALS *creds, u_char *buf, size_t buflen);
int radix_to_creds(const char *buf, CREDENTIALS *creds);
void send_afs_tokens(void);
#endif /* AFS */
#endif /* KRB4 */

View File

@ -24,6 +24,12 @@ RCSID("$OpenBSD: auth1.c,v 1.17 2001/02/13 22:49:40 markus Exp $");
#include "auth.h"
#include "session.h"
#ifdef KRB5
extern krb5_context ssh_context;
krb5_principal tkt_client = NULL; /* Principal from the received ticket.
Also is used as an indication of succesful krb5 authentization. */
#endif
/* import */
extern ServerOptions options;
extern char *forced_command;
@ -47,7 +53,7 @@ get_authname(int type)
case SSH_CMSG_AUTH_TIS:
case SSH_CMSG_AUTH_TIS_RESPONSE:
return "challenge-response";
#ifdef KRB4
#if defined(KRB4) || defined(KRB5)
case SSH_CMSG_AUTH_KERBEROS:
return "kerberos";
#endif
@ -80,9 +86,12 @@ do_authloop(Authctxt *authctxt)
/* If the user has no password, accept authentication immediately. */
if (options.password_authentication &&
#ifdef KRB5
!options.kerberos_authentication &&
#endif /* KRB5 */
#ifdef KRB4
(!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
#endif
(!options.kerberos_authentication || options.krb4_or_local_passwd) &&
#endif /* KRB4 */
auth_password(pw, "")) {
auth_log(authctxt, 1, "without authentication", "");
return;
@ -105,20 +114,21 @@ do_authloop(Authctxt *authctxt)
/* Process the packet. */
switch (type) {
#ifdef AFS
#ifndef KRB5
case SSH_CMSG_HAVE_KERBEROS_TGT:
if (!options.kerberos_tgt_passing) {
verbose("Kerberos tgt passing disabled.");
if (!options.krb4_tgt_passing) {
verbose("Kerberos v4 tgt passing disabled.");
break;
} else {
/* Accept Kerberos tgt. */
/* Accept Kerberos v4 tgt. */
char *tgt = packet_get_string(&dlen);
packet_integrity_check(plen, 4 + dlen, type);
if (!auth_kerberos_tgt(pw, tgt))
verbose("Kerberos tgt REFUSED for %.100s", authctxt->user);
if (!auth_krb4_tgt(pw, tgt))
verbose("Kerberos v4 tgt REFUSED for %.100s", authctxt->user);
xfree(tgt);
}
continue;
#endif /* !KRB5 */
case SSH_CMSG_HAVE_AFS_TOKEN:
if (!options.afs_token_passing || !k_hasafs()) {
verbose("AFS token passing disabled.");
@ -133,32 +143,66 @@ do_authloop(Authctxt *authctxt)
}
continue;
#endif /* AFS */
#ifdef KRB4
#if defined(KRB4) || defined(KRB5)
case SSH_CMSG_AUTH_KERBEROS:
if (!options.kerberos_authentication) {
verbose("Kerberos authentication disabled.");
break;
} else {
/* Try Kerberos v4 authentication. */
KTEXT_ST auth;
char *tkt_user = NULL;
char *kdata = packet_get_string((u_int *) &auth.length);
packet_integrity_check(plen, 4 + auth.length, type);
unsigned int length;
char *kdata = packet_get_string(&length);
packet_integrity_check(plen, 4 + length, type);
if (authctxt->valid) {
if (auth.length < MAX_KTXT_LEN)
/* 4 == KRB_PROT_VERSION */
if (kdata[0] == 4) {
#ifndef KRB4
verbose("Kerberos v4 authentication disabled.");
#else
/* Try Kerberos v4 authentication. */
KTEXT_ST auth;
char *tkt_user = NULL;
auth.length = length;
if (authctxt->valid) {
if (auth.length < MAX_KTXT_LEN)
memcpy(auth.dat, kdata, auth.length);
authenticated = auth_krb4(pw->pw_name, &auth, &tkt_user);
if (authenticated) {
authenticated = auth_krb4(pw->pw_name, &auth, &tkt_user);
if (authenticated) {
snprintf(info, sizeof info,
" tktuser %.100s", tkt_user);
" tktuser %.100s", tkt_user);
xfree(tkt_user);
}
}
#endif /* KRB4 */
} else {
#ifndef KRB5
verbose("Kerberos v5 authentication disabled.");
#else
krb5_data k5data;
k5data.length = length;
k5data.data = kdata;
#if 0
if (krb5_init_context(&ssh_context)) {
verbose("Error while initializing Kerberos V5.");
break;
}
krb5_init_ets(ssh_context);
#endif
/* pw->name is passed just for logging purposes */
if (authctxt->valid
&& auth_krb5(pw->pw_name, &k5data, &tkt_client)) {
/* authorize client against .k5login */
if (krb5_kuserok(ssh_context,
tkt_client,
pw->pw_name))
authenticated = 1;
}
#endif /* KRB5 */
}
xfree(kdata);
}
break;
#endif /* KRB4 */
#endif /* KRB4 || KRB5 */
case SSH_CMSG_AUTH_RHOSTS:
if (!options.rhosts_authentication) {
@ -276,6 +320,29 @@ do_authloop(Authctxt *authctxt)
}
break;
#ifdef KRB5
case SSH_CMSG_HAVE_KERBEROS_TGT:
/* Passing krb5 ticket */
if (!options.krb5_tgt_passing
/*|| !options.krb5_authentication */) {
}
if (tkt_client == NULL) {
/* passing tgt without krb5 authentication */
}
{
krb5_data tgt;
tgt.data = packet_get_string(&tgt.length);
if (!auth_krb5_tgt(authctxt->user, &tgt, tkt_client))
verbose ("Kerberos V5 TGT refused for %.100s", authctxt->user);
xfree(tgt.data);
break;
}
#endif /* KRB5 */
default:
/*
* Any unknown messages will be ignored (and failure

View File

@ -109,6 +109,10 @@ do_authentication2()
x_authctxt = authctxt; /*XXX*/
#if defined(KRB4) || defined(KRB5)
/* turn off kerberos, not supported by SSH2 */
options.kerberos_authentication = 0;
#endif
/* challenge-reponse is implemented via keyboard interactive */
if (options.challenge_reponse_authentication)
options.kbd_interactive_authentication = 1;

View File

@ -24,6 +24,7 @@
#include "includes.h"
#include "uuencode.h"
#include "auth.h"
RCSID("$OpenBSD: radix.c,v 1.15 2001/01/16 23:58:09 deraadt Exp $");

View File

@ -96,11 +96,14 @@ typedef enum {
oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh,
oChallengeResponseAuthentication, oXAuthLocation,
#ifdef KRB4
#if defined(KRB4) || defined(KRB5)
oKerberosAuthentication,
#endif /* KRB4 */
#endif /* KRB4 || KRB5 */
#ifdef KRB5
oKrb5TgtPassing,
#endif /* KRB5 */
#ifdef AFS
oKerberosTgtPassing, oAFSTokenPassing,
oKrb4TgtPassing, oAFSTokenPassing,
#endif
oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
@ -133,11 +136,14 @@ static struct {
{ "challengeresponseauthentication", oChallengeResponseAuthentication },
{ "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
{ "tisauthentication", oChallengeResponseAuthentication }, /* alias */
#ifdef KRB4
#if defined(KRB4) || defined(KRB5)
{ "kerberosauthentication", oKerberosAuthentication },
#endif /* KRB4 */
#endif /* KRB4 || KRB5 */
#ifdef KRB5
{ "kerberos5tgtpassing", oKrb5TgtPassing },
#endif /* KRB5 */
#ifdef AFS
{ "kerberostgtpassing", oKerberosTgtPassing },
{ "kerberos4tgtpassing", oKrb4TgtPassing },
{ "afstokenpassing", oAFSTokenPassing },
#endif
{ "fallbacktorsh", oFallBackToRsh },
@ -324,21 +330,27 @@ parse_flag:
intptr = &options->challenge_reponse_authentication;
goto parse_flag;
#ifdef KRB4
#if defined(KRB4) || defined(KRB5)
case oKerberosAuthentication:
intptr = &options->kerberos_authentication;
goto parse_flag;
#endif /* KRB4 */
#endif /* KRB4 || KRB5 */
#ifdef KRB5
case oKrb5TgtPassing:
intptr = &options->krb5_tgt_passing;
goto parse_flag;
#endif /* KRB5 */
#ifdef AFS
case oKerberosTgtPassing:
intptr = &options->kerberos_tgt_passing;
case oKrb4TgtPassing:
intptr = &options->krb4_tgt_passing;
goto parse_flag;
case oAFSTokenPassing:
intptr = &options->afs_token_passing;
goto parse_flag;
#endif
#endif /* AFS */
case oFallBackToRsh:
intptr = &options->fallback_to_rsh;
@ -681,13 +693,16 @@ initialize_options(Options * options)
options->rsa_authentication = -1;
options->pubkey_authentication = -1;
options->challenge_reponse_authentication = -1;
#ifdef KRB4
#if defined(KRB4) || defined(KRB5)
options->kerberos_authentication = -1;
#endif
#endif /* KRB4 || KRB5 */
#ifdef KRB5
options->krb5_tgt_passing = -1;
#endif /* KRB5 */
#ifdef AFS
options->kerberos_tgt_passing = -1;
options->krb4_tgt_passing = -1;
options->afs_token_passing = -1;
#endif
#endif /* AFS */
options->password_authentication = -1;
options->kbd_interactive_authentication = -1;
options->kbd_interactive_devices = NULL;
@ -752,13 +767,17 @@ fill_default_options(Options * options)
options->pubkey_authentication = 1;
if (options->challenge_reponse_authentication == -1)
options->challenge_reponse_authentication = 0;
#ifdef KRB4
#if defined(KRB4) || defined(KRB5)
if (options->kerberos_authentication == -1)
options->kerberos_authentication = 1;
#endif /* KRB4 */
#endif /* KRB4 || KRB5 */
#ifdef KRB5
if (options->krb5_tgt_passing == -1)
options->krb5_tgt_passing = 1;
#endif /* KRB5 */
#ifdef AFS
if (options->kerberos_tgt_passing == -1)
options->kerberos_tgt_passing = 1;
if (options->krb4_tgt_passing == -1)
options->krb4_tgt_passing = 1;
if (options->afs_token_passing == -1)
options->afs_token_passing = 1;
#endif /* AFS */

View File

@ -38,14 +38,17 @@ typedef struct {
int pubkey_authentication; /* Try ssh2 pubkey authentication. */
int challenge_reponse_authentication;
/* Try S/Key or TIS, authentication. */
#ifdef KRB4
#if defined(KRB4) || defined(KRB5)
int kerberos_authentication; /* Try Kerberos
* authentication. */
#endif
#endif /* KRB4 || KRB5 */
#ifdef KRB5
int krb5_tgt_passing;
#endif /* KRB5 */
#ifdef AFS
int kerberos_tgt_passing; /* Try Kerberos tgt passing. */
int krb4_tgt_passing; /* Try Kerberos v4 tgt passing. */
int afs_token_passing; /* Try AFS token passing. */
#endif
#endif /* AFS */
int password_authentication; /* Try password
* authentication. */
int kbd_interactive_authentication; /* Try keyboard-interactive auth. */

View File

@ -18,6 +18,9 @@ RCSID("$OpenBSD: servconf.c,v 1.67 2001/02/12 16:16:23 markus Exp $");
#ifdef AFS
#include <kafs.h>
#endif
#ifdef KRB5
#include <krb5.h>
#endif
#include "ssh.h"
#include "log.h"
@ -68,13 +71,18 @@ initialize_server_options(ServerOptions *options)
options->rhosts_rsa_authentication = -1;
options->rsa_authentication = -1;
options->pubkey_authentication = -1;
#ifdef KRB4
#if defined(KRB4) || defined(KRB5)
options->kerberos_authentication = -1;
options->kerberos_or_local_passwd = -1;
options->kerberos_ticket_cleanup = -1;
#endif
#endif /* KRB4 || KRB5 */
#ifdef KRB4
options->krb4_or_local_passwd = -1;
options->krb4_ticket_cleanup = -1;
#endif /* KRB4 */
#ifdef KRB5
options->krb5_tgt_passing = -1;
#endif /* KRB5 */
#ifdef AFS
options->kerberos_tgt_passing = -1;
options->krb4_tgt_passing = -1;
options->afs_token_passing = -1;
#endif
options->password_authentication = -1;
@ -159,17 +167,31 @@ fill_default_server_options(ServerOptions *options)
options->rsa_authentication = 1;
if (options->pubkey_authentication == -1)
options->pubkey_authentication = 1;
#ifdef KRB4
#if defined(KRB4) && defined(KRB5)
if (options->kerberos_authentication == -1)
options->kerberos_authentication =
(access(KEYFILE, R_OK) == 0) ||
(access(krb5_defkeyname, R_OK) == 0);
#elif defined(KRB4)
if (options->kerberos_authentication == -1)
options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
if (options->kerberos_or_local_passwd == -1)
options->kerberos_or_local_passwd = 1;
if (options->kerberos_ticket_cleanup == -1)
options->kerberos_ticket_cleanup = 1;
#elif defined(KRB5)
if (options->kerberos_authentication == -1)
options->kerberos_authentication = (access(krb5_defkeyname, R_OK) == 0);
#endif
#ifdef KRB4
if (options->krb4_or_local_passwd == -1)
options->krb4_or_local_passwd = 1;
if (options->krb4_ticket_cleanup == -1)
options->krb4_ticket_cleanup = 1;
#endif /* KRB4 */
#ifdef KRB5
if (options->krb5_tgt_passing == -1)
options->krb5_tgt_passing = 1;
#endif /* KRB5 */
#ifdef AFS
if (options->kerberos_tgt_passing == -1)
options->kerberos_tgt_passing = 0;
if (options->krb4_tgt_passing == -1)
options->krb4_tgt_passing = 0;
if (options->afs_token_passing == -1)
options->afs_token_passing = k_hasafs();
#endif /* AFS */
@ -203,12 +225,18 @@ typedef enum {
sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
sPermitRootLogin, sLogFacility, sLogLevel,
sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
#if defined(KRB4) || defined(KRB5)
sKerberosAuthentication,
#endif /* KRB4 || KRB5 */
#ifdef KRB4
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
#endif
sKrb4OrLocalPasswd, sKrb4TicketCleanup,
#endif /* KRB4 */
#ifdef KRB5
sKrb5TgtPassing,
#endif /* KRB5 */
#ifdef AFS
sKerberosTgtPassing, sAFSTokenPassing,
#endif
sKrb4TgtPassing, sAFSTokenPassing,
#endif /* AFS */
sChallengeResponseAuthentication,
sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset,
@ -241,15 +269,20 @@ static struct {
{ "rsaauthentication", sRSAAuthentication },
{ "pubkeyauthentication", sPubkeyAuthentication },
{ "dsaauthentication", sPubkeyAuthentication }, /* alias */
#ifdef KRB4
#if defined(KRB4) || defined(KRB5)
{ "kerberosauthentication", sKerberosAuthentication },
{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
{ "kerberosticketcleanup", sKerberosTicketCleanup },
#endif
#endif /* KRB4 || KRB5 */
#ifdef KRB4
{ "kerberosorlocalpasswd", sKrb4OrLocalPasswd },
{ "kerberosticketcleanup", sKrb4TicketCleanup },
#endif /* KRB4 */
#ifdef KRB5
{ "kerberos5tgtpassing", sKrb5TgtPassing },
#endif /* KRB5 */
#ifdef AFS
{ "kerberostgtpassing", sKerberosTgtPassing },
{ "kerberostgtpassing", sKrb4TgtPassing },
{ "afstokenpassing", sAFSTokenPassing },
#endif
#endif /* AFS */
{ "passwordauthentication", sPasswordAuthentication },
{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
{ "challengeresponseauthentication", sChallengeResponseAuthentication },
@ -521,29 +554,37 @@ parse_flag:
intptr = &options->pubkey_authentication;
goto parse_flag;
#ifdef KRB4
#if defined(KRB4) || defined(KRB5)
case sKerberosAuthentication:
intptr = &options->kerberos_authentication;
goto parse_flag;
#endif /* KRB4 || KRB5 */
case sKerberosOrLocalPasswd:
intptr = &options->kerberos_or_local_passwd;
#ifdef KRB4
case sKrb4OrLocalPasswd:
intptr = &options->krb4_or_local_passwd;
goto parse_flag;
case sKerberosTicketCleanup:
intptr = &options->kerberos_ticket_cleanup;
case sKrb4TicketCleanup:
intptr = &options->krb4_ticket_cleanup;
goto parse_flag;
#endif
#endif /* KRB4 */
#ifdef KRB5
case sKrb5TgtPassing:
intptr = &options->krb5_tgt_passing;
goto parse_flag;
#endif /* KRB5 */
#ifdef AFS
case sKerberosTgtPassing:
intptr = &options->kerberos_tgt_passing;
case sKrb4TgtPassing:
intptr = &options->krb4_tgt_passing;
goto parse_flag;
case sAFSTokenPassing:
intptr = &options->afs_token_passing;
goto parse_flag;
#endif
#endif /* AFS */
case sPasswordAuthentication:
intptr = &options->password_authentication;

View File

@ -73,22 +73,28 @@ typedef struct {
* authentication. */
int rsa_authentication; /* If true, permit RSA authentication. */
int pubkey_authentication; /* If true, permit ssh2 pubkey authentication. */
#ifdef KRB4
#if defined(KRB4) || defined(KRB5)
int kerberos_authentication; /* If true, permit Kerberos
* authentication. */
int kerberos_or_local_passwd; /* If true, permit kerberos
#endif /* KRB4 || KRB5 */
#ifdef KRB4
int krb4_or_local_passwd; /* If true, permit kerberos
* and any other password
* authentication mechanism,
* such as SecurID or
* /etc/passwd */
int kerberos_ticket_cleanup; /* If true, destroy ticket
int krb4_ticket_cleanup; /* If true, destroy ticket
* file on logout. */
#endif
#endif /* KRB4 */
#ifdef KRB5
int krb5_tgt_passing;
#endif /* KRB5 */
#ifdef AFS
int kerberos_tgt_passing; /* If true, permit Kerberos tgt
int krb4_tgt_passing; /* If true, permit Kerberos tgt
* passing. */
int afs_token_passing; /* If true, permit AFS token passing. */
#endif
#endif /* AFS */
int password_authentication; /* If true, permit password
* authentication. */
int kbd_interactive_authentication; /* If true, permit */

View File

@ -346,7 +346,7 @@ main(int ac, char **av)
break;
#ifdef AFS
case 'k':
options.kerberos_tgt_passing = 0;
options.krb4_tgt_passing = 0;
options.afs_token_passing = 0;
break;
#endif

View File

@ -66,6 +66,9 @@
#define SSH_CMSG_HAVE_KERBEROS_TGT 44 /* credentials (s) */
#define SSH_CMSG_HAVE_AFS_TOKEN 65 /* token (s) */
/* Kerberos IV tickets can't be forwarded. This is an AFS hack! */
#define SSH_CMSG_HAVE_KRB4_TGT SSH_CMSG_HAVE_KERBEROS_TGT /* credentials (s) */
/*
* Authentication methods. New types can be added, but old types should not
* be removed for compatibility. The maximum allowed value is 31.

View File

@ -32,6 +32,10 @@ RCSID("$OpenBSD: sshconnect.c,v 1.97 2001/02/15 23:19:59 markus Exp $");
#include "atomicio.h"
#include "misc.h"
#ifdef KRB5
#include <krb5.h>
#endif
char *client_version_string = NULL;
char *server_version_string = NULL;

View File

@ -25,6 +25,9 @@ RCSID("$OpenBSD: sshconnect1.c,v 1.27 2001/02/15 23:19:59 markus Exp $");
#include <kafs.h>
#include "radix.h"
#endif
#ifdef KRB5
#include <krb5.h>
#endif
#include "ssh.h"
#include "ssh1.h"
@ -43,6 +46,7 @@ RCSID("$OpenBSD: sshconnect1.c,v 1.27 2001/02/15 23:19:59 markus Exp $");
#include "readpass.h"
#include "cipher.h"
#include "canohost.h"
#include "auth.h"
/* Session id for the current session. */
u_char session_id[16];
@ -380,7 +384,7 @@ try_rhosts_rsa_authentication(const char *local_user, RSA * host_key)
#ifdef KRB4
static int
try_kerberos_authentication(void)
try_krb4_authentication(void)
{
KTEXT_ST auth; /* Kerberos data */
char *reply;
@ -495,9 +499,250 @@ try_kerberos_authentication(void)
#endif /* KRB4 */
#ifdef KRB5
int
try_krb5_authentication(krb5_context *context, krb5_auth_context *auth_context)
{
krb5_error_code problem;
const char *tkfile;
struct stat buf;
krb5_ccache ccache = NULL;
krb5_creds req_creds;
krb5_creds *new_creds = NULL;
const char *remotehost;
krb5_data ap;
int type, payload_len;
krb5_ap_rep_enc_part *reply = NULL;
int ret;
memset(&ap, 0, sizeof(ap));
problem = krb5_init_context(context);
if (problem) {
ret = 0;
goto out;
}
tkfile = krb5_cc_default_name(*context);
if (strncmp(tkfile, "FILE:", 5) == 0)
tkfile += 5;
if (stat(tkfile, &buf) == 0 && getuid() != buf.st_uid) {
debug("Kerberos V5: could not get default ccache (permission denied).");
ret = 0;
goto out;
}
problem = krb5_cc_default(*context, &ccache);
if (problem) {
ret = 0;
goto out;
}
memset(&req_creds, 0, sizeof(req_creds));
remotehost = get_canonical_hostname(1);
problem = krb5_sname_to_principal(*context, remotehost,
"host", KRB5_NT_SRV_HST,
&req_creds.server);
if (problem) {
ret = 0;
goto out;
}
problem = krb5_cc_get_principal(*context, ccache, &req_creds.client);
if (problem) {
ret = 0;
goto out;
}
/* creds.session.keytype=ETYPE_DES_CBC_CRC; */
problem = krb5_get_credentials(*context, 0, ccache, &req_creds, &new_creds);
if (problem) {
ret = 0;
goto out;
}
problem = krb5_auth_con_init(*context, auth_context);
if (problem) {
ret = 0;
goto out;
}
/* krb5_auth_con_setflags(ssh_context, auth_context,
KRB5_AUTH_CONTEXT_RET_TIME);
*/
problem = krb5_mk_req_extended(*context, auth_context,
AP_OPTS_MUTUAL_REQUIRED /*| AP_OPTS_USE_SUBKEY*/ ,
NULL, new_creds, &ap);
if (problem) {
ret = 0;
goto out;
}
packet_start(SSH_CMSG_AUTH_KERBEROS);
packet_put_string((char *) ap.data, ap.length);
packet_send();
packet_write_wait();
xfree(ap.data);
ap.length = 0;
type = packet_read(&payload_len);
switch (type) {
case SSH_SMSG_FAILURE:
/* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */
debug("Kerberos V5 authentication failed.");
ret = 0;
break;
case SSH_SMSG_AUTH_KERBEROS_RESPONSE:
/* SSH_SMSG_AUTH_KERBEROS_SUCCESS */
debug("Kerberos V5 authentication accepted.");
/* Get server's response. */
ap.data = packet_get_string((unsigned int *) &ap.length);
packet_integrity_check(payload_len, 4 + ap.length, type);
/* XXX je to dobre? */
problem = krb5_rd_rep(*context, *auth_context, &ap, &reply);
if (problem) {
ret = 0;
}
ret = 1;
break;
default:
packet_disconnect("Protocol error on Kerberos V5 response: %d", type);
ret = 0;
break;
}
out:
if (req_creds.server != NULL)
krb5_free_principal(*context, req_creds.server);
if (req_creds.client != NULL)
krb5_free_principal(*context, req_creds.client);
if (new_creds != NULL)
krb5_free_creds(*context, new_creds);
if (ccache != NULL)
krb5_cc_close(*context, ccache);
if (reply != NULL)
krb5_free_ap_rep_enc_part(*context, reply);
if (ap.length > 0)
krb5_data_free(&ap);
return ret;
}
void
send_krb5_tgt(krb5_context context, krb5_auth_context auth_context)
{
int fd;
int type, payload_len;
krb5_error_code problem;
krb5_data outbuf;
krb5_ccache ccache = NULL;
krb5_creds creds;
krb5_kdc_flags flags;
const char* remotehost = get_canonical_hostname(1);
memset(&creds, 0, sizeof(creds));
memset(&outbuf, 0, sizeof(outbuf));
fd = packet_get_connection_in();
problem = krb5_auth_con_setaddrs_from_fd(context, auth_context, &fd);
if (problem) {
goto out;
}
#if 0
tkfile = krb5_cc_default_name(context);
if (strncmp(tkfile, "FILE:", 5) == 0)
tkfile += 5;
if (stat(tkfile, &buf) == 0 && getuid() != buf.st_uid) {
debug("Kerberos V5: could not get default ccache (permission denied).");
goto out;
}
#endif
problem = krb5_cc_default(context, &ccache);
if (problem) {
goto out;
}
problem = krb5_cc_get_principal(context, ccache, &creds.client);
if (problem) {
goto out;
}
problem = krb5_build_principal(context, &creds.server,
strlen(creds.client->realm),
creds.client->realm,
"krbtgt",
creds.client->realm,
NULL);
if (problem) {
goto out;
}
creds.times.endtime = 0;
flags.i = 0;
flags.b.forwarded = 1;
flags.b.forwardable = krb5_config_get_bool(context, NULL,
"libdefaults", "forwardable", NULL);
problem = krb5_get_forwarded_creds (context,
auth_context,
ccache,
flags.i,
remotehost,
&creds,
&outbuf);
if (problem) {
goto out;
}
packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
packet_put_string((char *)outbuf.data, outbuf.length);
packet_send();
packet_write_wait();
type = packet_read(&payload_len);
switch (type) {
case SSH_SMSG_SUCCESS:
break;
case SSH_SMSG_FAILURE:
break;
default:
break;
}
out:
if (creds.client)
krb5_free_principal(context, creds.client);
if (creds.server)
krb5_free_principal(context, creds.server);
if (ccache)
krb5_cc_close(context, ccache);
if (outbuf.data)
xfree(outbuf.data);
return;
}
#endif /* KRB5 */
#ifdef AFS
int
send_kerberos_tgt(void)
send_krb4_tgt(void)
{
CREDENTIALS *creds;
char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];
@ -943,13 +1188,42 @@ ssh_userauth(
packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER",
type);
#ifdef KRB5
if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) &&
options.kerberos_authentication){
krb5_context ssh_context = NULL;
krb5_auth_context auth_context = NULL;
debug("Trying Kerberos V5 authentication.");
if (try_krb5_authentication(&ssh_context, &auth_context)) {
type = packet_read(&payload_len);
if (type == SSH_SMSG_SUCCESS) {
if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) &&
options.krb5_tgt_passing) {
if (options.cipher == SSH_CIPHER_NONE)
log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");
send_krb5_tgt(ssh_context, auth_context);
}
krb5_auth_con_free(ssh_context, auth_context);
krb5_free_context(ssh_context);
return;
}
if (type != SSH_SMSG_FAILURE)
packet_disconnect("Protocol error: got %d in response to Kerberos5 auth", type);
}
}
#endif /* KRB5 */
#ifdef AFS
/* Try Kerberos tgt passing if the server supports it. */
if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) &&
options.kerberos_tgt_passing) {
options.krb4_tgt_passing) {
if (options.cipher == SSH_CIPHER_NONE)
log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");
(void) send_kerberos_tgt();
(void) send_krb4_tgt();
}
/* Try AFS token passing if the server supports it. */
if ((supported_authentications & (1 << SSH_PASS_AFS_TOKEN)) &&
@ -964,7 +1238,7 @@ ssh_userauth(
if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) &&
options.kerberos_authentication) {
debug("Trying Kerberos authentication.");
if (try_kerberos_authentication()) {
if (try_krb4_authentication()) {
/* The server should respond with success or failure. */
type = packet_read(&payload_len);
if (type == SSH_SMSG_SUCCESS)

View File

@ -82,6 +82,10 @@ int deny_severity = LOG_WARNING;
#define O_NOCTTY 0
#endif
#ifdef KRB5
#include <krb5.h>
#endif /* KRB5 */
extern char *__progname;
/* Server configuration options. */
@ -1126,7 +1130,7 @@ main(int ac, char **av)
"originating port not trusted.");
options.rhosts_authentication = 0;
}
#ifdef KRB4
#if defined(KRB4) && !defined(KRB5)
if (!packet_connection_is_ipv4() &&
options.kerberos_authentication) {
debug("Kerberos Authentication disabled, only available for IPv4.");
@ -1155,7 +1159,7 @@ main(int ac, char **av)
#ifdef KRB4
/* Cleanup user's ticket cache file. */
if (options.kerberos_ticket_cleanup)
if (options.krb4_ticket_cleanup)
(void) dest_tkt();
#endif /* KRB4 */
@ -1229,12 +1233,16 @@ do_ssh1_kex(void)
auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA;
if (options.rsa_authentication)
auth_mask |= 1 << SSH_AUTH_RSA;
#ifdef KRB4
#if defined(KRB4) || defined(KRB5)
if (options.kerberos_authentication)
auth_mask |= 1 << SSH_AUTH_KERBEROS;
#endif
#ifdef KRB5
if (options.krb5_tgt_passing)
auth_mask |= 1 << SSH_PASS_KERBEROS_TGT;
#endif /* KRB5 */
#ifdef AFS
if (options.kerberos_tgt_passing)
if (options.krb4_tgt_passing)
auth_mask |= 1 << SSH_PASS_KERBEROS_TGT;
if (options.afs_token_passing)
auth_mask |= 1 << SSH_PASS_AFS_TOKEN;

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.5 2001/02/14 01:06:50 itojun Exp $
# $NetBSD: Makefile,v 1.6 2001/03/04 00:41:28 assar Exp $
.include <bsd.own.mk>
@ -23,9 +23,9 @@ MKPROFILE= no
libinstall::
.if (${MKKERBEROS} != "no")
CPPFLAGS+= -DKRB5 -DAFS -I${DESTDIR}/usr/include/krb5
CPPFLAGS+= -DKRB4 -I${DESTDIR}/usr/include/kerberosIV
#CPPFLAGS+= -DAFS
#SRCS+= radix.c
SRCS+= radix.c
.endif
.include <bsd.lib.mk>

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.5 2001/02/07 17:05:37 itojun Exp $
# $NetBSD: Makefile,v 1.6 2001/03/04 00:41:28 assar Exp $
.include <bsd.own.mk>
@ -14,10 +14,9 @@ LINKS= ${BINDIR}/ssh ${BINDIR}/slogin
MLINKS= ssh.1 slogin.1
.if (${MKKERBEROS} != "no")
# XXX Needs krb5
#CPPFLAGS+=-DAFS
#LDADD+= -lkrb5 -lkafs -lasn1
#DPADD+= ${LIBKAFS}
CPPFLAGS+=-DKRB5 -DAFS -I${DESTDIR}/usr/include/krb5
LDADD+= -lkrb5 -lkafs -lasn1
DPADD+= ${LIBKRB5} ${LIBKAFS} ${LIBASN1}
CPPFLAGS+=-DKRB4 -I${DESTDIR}/usr/include/kerberosIV
LDADD+= -lkrb -lcom_err -lroken

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.3 2001/02/07 17:05:37 itojun Exp $
# $NetBSD: Makefile,v 1.4 2001/03/04 00:41:28 assar Exp $
.include <bsd.own.mk>
@ -13,10 +13,10 @@ SRCS= sshd.c auth-rhosts.c auth-passwd.c auth-rsa.c auth-rh-rsa.c \
auth-chall.c auth2-chall.c groupaccess.c
.if (${MKKERBEROS} != "no")
# XXX needs krb5
#CPPFLAGS+=-DAFS
#LDADD+= -lkafs
#DPADD+= ${LIBKAFS}
CPPFLAGS+=-DKRB5 -DAFS -I${DESTDIR}/usr/include/krb5
SRCS+= auth-krb5.c
LDADD+= -lkrb5 -lkafs -lasn1
DPADD+= ${LIBKRB5} ${LIBKAFS} ${LIBASN1}
CPPFLAGS+=-DKRB4 -I${DESTDIR}/usr/include/kerberosIV
SRCS+= auth-krb4.c