From fd4c9eee25e4e796b714477c3fbb0286ebe50fb7 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sat, 13 Apr 2002 11:04:40 +1000 Subject: - (djm) Add KrbV support patch from Simon Wilkinson --- CREDITS | 4 +- ChangeLog | 5 ++- Makefile.in | 4 +- acconfig.h | 8 +++- auth-krb5.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- configure.ac | 45 +++++++++++++++++++++-- servconf.c | 11 +++++- sshconnect1.c | 52 ++++++++++++++++++++++++-- 8 files changed, 230 insertions(+), 14 deletions(-) diff --git a/CREDITS b/CREDITS index d0b320a5..ef267530 100644 --- a/CREDITS +++ b/CREDITS @@ -75,7 +75,7 @@ Philippe WILLEM - Bugfixes Phill Camp - login code fix Rip Loomis - Solaris package support, fixes SAKAI Kiyotaka - Multiple bugfixes -Simon Wilkinson - PAM fixes +Simon Wilkinson - PAM fixes, Compat with MIT KrbV Svante Signell - Bugfixes Thomas Neumann - Shadow passwords Tim Rice - Portability & SCO fixes @@ -90,5 +90,5 @@ Apologies to anyone I have missed. Damien Miller -$Id: CREDITS,v 1.65 2002/03/05 03:38:35 mouring Exp $ +$Id: CREDITS,v 1.66 2002/04/13 01:04:40 djm Exp $ diff --git a/ChangeLog b/ChangeLog index a6d20ed1..486e3505 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +20020413 + - (djm) Add KrbV support patch from Simon Wilkinson + 20020412 - (stevesk) [auth-sia.[ch]] add BSD license from Chris Adams - (tim) [configure.ac] add to msghdr tests. Change -L @@ -8231,4 +8234,4 @@ - Wrote replacements for strlcpy and mkdtemp - Released 1.0pre1 -$Id: ChangeLog,v 1.2050 2002/04/12 18:51:22 mouring Exp $ +$Id: ChangeLog,v 1.2051 2002/04/13 01:04:40 djm Exp $ diff --git a/Makefile.in b/Makefile.in index 32f95409..4e0744c3 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.201 2002/04/05 16:11:46 mouring Exp $ +# $Id: Makefile.in,v 1.202 2002/04/13 01:04:41 djm Exp $ prefix=@prefix@ exec_prefix=@exec_prefix@ @@ -54,7 +54,7 @@ LIBSSH_OBJS=atomicio.o authfd.o authfile.o bufaux.o buffer.o canohost.o channels SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o sshtty.o readconf.o clientloop.o -SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth-chall.o auth2-chall.o auth-rhosts.o auth-options.o auth-krb4.o auth-pam.o auth2-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o auth-sia.o sshpty.o sshlogin.o loginrec.o servconf.o serverloop.o md5crypt.o session.o groupaccess.o auth-skey.o auth-bsdauth.o monitor_mm.o monitor.o +SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth-chall.o auth2-chall.o auth-rhosts.o auth-options.o auth-krb4.o auth-krb5.o auth-pam.o auth2-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o auth-sia.o sshpty.o sshlogin.o loginrec.o servconf.o serverloop.o md5crypt.o session.o groupaccess.o auth-skey.o auth-bsdauth.o monitor_mm.o monitor.o MANPAGES = scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out MANPAGES_IN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 diff --git a/acconfig.h b/acconfig.h index 3f9e56a9..84bf60f0 100644 --- a/acconfig.h +++ b/acconfig.h @@ -1,4 +1,4 @@ -/* $Id: acconfig.h,v 1.130 2002/04/12 03:35:40 tim Exp $ */ +/* $Id: acconfig.h,v 1.131 2002/04/13 01:04:41 djm Exp $ */ #ifndef _CONFIG_H #define _CONFIG_H @@ -192,6 +192,12 @@ /* Define if compiler implements __func__ */ #undef HAVE___func__ +/* Define if you want Kerberos 5 support */ +#undef KRB5 + +/* Define this if you are using the Heimdal version of Kerberos V5 */ +#undef HEIMDAL + /* Define if you want Kerberos 4 support */ #undef KRB4 diff --git a/auth-krb5.c b/auth-krb5.c index f878b511..76c2419a 100644 --- a/auth-krb5.c +++ b/auth-krb5.c @@ -41,6 +41,9 @@ RCSID("$OpenBSD: auth-krb5.c,v 1.8 2002/03/19 10:49:35 markus Exp $"); #ifdef KRB5 #include +#ifndef HEIMDAL +#define krb5_get_err_text(context,code) error_message(code) +#endif /* !HEIMDAL */ extern ServerOptions options; @@ -93,8 +96,15 @@ auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client) goto err; fd = packet_get_connection_in(); +#ifdef HEIMDAL problem = krb5_auth_con_setaddrs_from_fd(authctxt->krb5_ctx, authctxt->krb5_auth_ctx, &fd); +#else + problem = krb5_auth_con_genaddrs(authctxt->krb5_ctx, + authctxt->krb5_auth_ctx,fd, + KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR | + KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR); +#endif if (problem) goto err; @@ -108,8 +118,14 @@ auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client) if (problem) goto err; +#ifdef HEIMDAL problem = krb5_copy_principal(authctxt->krb5_ctx, ticket->client, &authctxt->krb5_user); +#else + problem = krb5_copy_principal(authctxt->krb5_ctx, + ticket->enc_part2->client, + &authctxt->krb5_user); +#endif if (problem) goto err; @@ -160,13 +176,37 @@ auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt) krb5_error_code problem; krb5_ccache ccache = NULL; char *pname; + krb5_creds **creds; if (authctxt->pw == NULL || authctxt->krb5_user == NULL) return (0); temporarily_use_uid(authctxt->pw); +#ifdef HEIMDAL problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, &ccache); +#else +{ + char ccname[40]; + int tmpfd; + + snprintf(ccname,sizeof(ccname),"FILE:/tmp/krb5cc_%d_XXXXXX",geteuid()); + + if ((tmpfd = mkstemp(ccname+strlen("FILE:")))==-1) { + log("mkstemp(): %.100s", strerror(errno)); + problem = errno; + goto fail; + } + if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) { + log("fchmod(): %.100s", strerror(errno)); + close(tmpfd); + problem = errno; + goto fail; + } + close(tmpfd); + problem = krb5_cc_resolve(authctxt->krb5_ctx, ccname, &ccache); +} +#endif if (problem) goto fail; @@ -175,10 +215,20 @@ auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt) if (problem) goto fail; +#ifdef HEIMDAL problem = krb5_rd_cred2(authctxt->krb5_ctx, authctxt->krb5_auth_ctx, ccache, tgt); if (problem) goto fail; +#else + problem = krb5_rd_cred(authctxt->krb5_ctx, authctxt->krb5_auth_ctx, + tgt, &creds, NULL); + if (problem) + goto fail; + problem = krb5_cc_store_cred(authctxt->krb5_ctx, ccache, *creds); + if (problem) + goto fail; +#endif authctxt->krb5_fwd_ccache = ccache; ccache = NULL; @@ -211,6 +261,12 @@ auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt) int auth_krb5_password(Authctxt *authctxt, const char *password) { +#ifndef HEIMDAL + krb5_creds creds; + krb5_principal server; + char ccname[40]; + int tmpfd; +#endif krb5_error_code problem; if (authctxt->pw == NULL) @@ -227,6 +283,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password) if (problem) goto out; +#ifdef HEIMDAL problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops, &authctxt->krb5_fwd_ccache); if (problem) @@ -245,13 +302,69 @@ auth_krb5_password(Authctxt *authctxt, const char *password) if (problem) goto out; +#else + problem = krb5_get_init_creds_password(authctxt->krb5_ctx, &creds, + authctxt->krb5_user, (char *)password, NULL, NULL, 0, NULL, NULL); + if (problem) + goto out; + + problem = krb5_sname_to_principal(authctxt->krb5_ctx, NULL, NULL, + KRB5_NT_SRV_HST, &server); + if (problem) + goto out; + + restore_uid(); + problem = krb5_verify_init_creds(authctxt->krb5_ctx, &creds, server, + NULL, NULL, NULL); + krb5_free_principal(authctxt->krb5_ctx, server); + temporarily_use_uid(authctxt->pw); + if (problem) + goto out; + + if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, + authctxt->pw->pw_name)) { + problem = -1; + goto out; + } + + snprintf(ccname,sizeof(ccname),"FILE:/tmp/krb5cc_%d_XXXXXX",geteuid()); + + if ((tmpfd = mkstemp(ccname+strlen("FILE:")))==-1) { + log("mkstemp(): %.100s", strerror(errno)); + problem = errno; + goto out; + } + + if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) { + log("fchmod(): %.100s", strerror(errno)); + close(tmpfd); + problem = errno; + goto out; + } + close(tmpfd); + + problem = krb5_cc_resolve(authctxt->krb5_ctx, ccname, &authctxt->krb5_fwd_ccache); + if (problem) + goto out; + + problem = krb5_cc_initialize(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache, + authctxt->krb5_user); + if (problem) + goto out; + + problem= krb5_cc_store_cred(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache, + &creds); + if (problem) + goto out; +#endif + authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache); out: restore_uid(); if (problem) { - if (authctxt->krb5_ctx != NULL) + if (authctxt->krb5_ctx != NULL && problem!=-1) debug("Kerberos password authentication failed: %s", krb5_get_err_text(authctxt->krb5_ctx, problem)); else diff --git a/configure.ac b/configure.ac index c0cce4bd..9516bf7f 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.43 2002/04/12 17:26:23 tim Exp $ +# $Id: configure.ac,v 1.44 2002/04/13 01:04:41 djm Exp $ AC_INIT AC_CONFIG_SRCDIR([ssh.c]) @@ -1747,7 +1747,45 @@ AC_ARG_WITH(opensc, ] ) -# Check whether user wants Kerberos support +# Check whether user wants Kerberos 5 support +KRB5_MSG="no" +AC_ARG_WITH(kerberos5, + [ --with-kerberos5=PATH Enable Kerberos 5 support], + [ + if test "x$withval" != "xno" ; then + if test "x$withval" = "xyes" ; then + KRB5ROOT="/usr/local" + else + KRB5ROOT=${withval} + fi + CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include" + LDFLAGS="$LDFLAGS -L${KRB5ROOT}/lib" + AC_DEFINE(KRB5) + KRB5_MSG="yes" + AC_MSG_CHECKING(whether we are using Heimdal) + AC_TRY_COMPILE([ #include ], + [ char *tmp = heimdal_version; ], + [ AC_MSG_RESULT(yes) + AC_DEFINE(HEIMDAL) + K5LIBS="-lkrb5 -ldes -lcom_err -lasn1 -lroken" + ], + [ AC_MSG_RESULT(no) + K5LIBS="-lkrb5 -lk5crypto -lcom_err" + ] + ) + if test ! -z "$need_dash_r" ; then + LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib" + fi + if test ! -z "$blibpath" ; then + blibpath="$blibpath:${KRB5ROOT}/lib" + fi + AC_CHECK_LIB(resolv, dn_expand, , ) + + KRB5=yes + fi + ] +) +# Check whether user wants Kerberos 4 support KRB4_MSG="no" AC_ARG_WITH(kerberos4, [ --with-kerberos4=PATH Enable Kerberos 4 support], @@ -1827,7 +1865,7 @@ AC_ARG_WITH(afs, fi ] ) -LIBS="$LIBS $KLIBS" +LIBS="$LIBS $KLIBS $K5LIBS" # Looking for programs, paths and files AC_ARG_WITH(rsh, @@ -2399,6 +2437,7 @@ echo " sshd default user PATH: $H" echo " Manpage format: $MANTYPE" echo " PAM support: ${PAM_MSG}" echo " KerberosIV support: $KRB4_MSG" +echo " KerberosV support: $KRB5_MSG" echo " Smartcard support: $SCARD_MSG" echo " AFS support: $AFS_MSG" echo " S/KEY support: $SKEY_MSG" diff --git a/servconf.c b/servconf.c index 8e6ee5bb..8b5ee7bf 100644 --- a/servconf.c +++ b/servconf.c @@ -12,8 +12,17 @@ #include "includes.h" RCSID("$OpenBSD: servconf.c,v 1.105 2002/03/20 19:12:24 stevesk Exp $"); -#if defined(KRB4) || defined(KRB5) +#if defined(KRB4) +#include +#endif +#if defined(KRB5) +#ifdef HEIMDAL #include +#else +/* Bodge - but then, so is using the kerberos IV KEYFILE to get a Kerberos V + * keytab */ +#define KEYFILE "/etc/krb5.keytab" +#endif #endif #ifdef AFS #include diff --git a/sshconnect1.c b/sshconnect1.c index 39369413..3b5c7186 100644 --- a/sshconnect1.c +++ b/sshconnect1.c @@ -23,6 +23,9 @@ RCSID("$OpenBSD: sshconnect1.c,v 1.49 2002/03/14 15:24:27 markus Exp $"); #endif #ifdef KRB5 #include +#ifndef HEIMDAL +#define krb5_get_err_text(context,code) error_message(code) +#endif /* !HEIMDAL */ #endif #ifdef AFS #include @@ -521,6 +524,23 @@ try_krb5_authentication(krb5_context *context, krb5_auth_context *auth_context) ret = 0; goto out; } + + problem = krb5_auth_con_init(*context, auth_context); + if (problem) { + debug("Kerberos v5: krb5_auth_con_init failed"); + ret = 0; + goto out; + } + +#ifndef HEIMDAL + problem = krb5_auth_con_setflags(*context, *auth_context, + KRB5_AUTH_CONTEXT_RET_TIME); + if (problem) { + debug("Keberos v5: krb5_auth_con_setflags failed"); + ret = 0; + goto out; + } +#endif tkfile = krb5_cc_default_name(*context); if (strncmp(tkfile, "FILE:", 5) == 0) @@ -597,7 +617,11 @@ try_krb5_authentication(krb5_context *context, krb5_auth_context *auth_context) if (reply != NULL) krb5_free_ap_rep_enc_part(*context, reply); if (ap.length > 0) +#ifdef HEIMDAL krb5_data_free(&ap); +#else + krb5_free_data_contents(*context, &ap); +#endif return (ret); } @@ -610,7 +634,11 @@ send_krb5_tgt(krb5_context context, krb5_auth_context auth_context) krb5_data outbuf; krb5_ccache ccache = NULL; krb5_creds creds; +#ifdef HEIMDAL krb5_kdc_flags flags; +#else + int forwardable; +#endif const char *remotehost; memset(&creds, 0, sizeof(creds)); @@ -618,7 +646,13 @@ send_krb5_tgt(krb5_context context, krb5_auth_context auth_context) fd = packet_get_connection_in(); +#ifdef HEIMDAL problem = krb5_auth_con_setaddrs_from_fd(context, auth_context, &fd); +#else + problem = krb5_auth_con_genaddrs(context, auth_context, fd, + KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR | + KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR); +#endif if (problem) goto out; @@ -630,23 +664,35 @@ send_krb5_tgt(krb5_context context, krb5_auth_context auth_context) if (problem) goto out; + remotehost = get_canonical_hostname(1); + +#ifdef HEIMDAL problem = krb5_build_principal(context, &creds.server, strlen(creds.client->realm), creds.client->realm, "krbtgt", creds.client->realm, NULL); +#else + problem = krb5_build_principal(context, &creds.server, + creds.client->realm.length, creds.client->realm.data, + "host", remotehost, NULL); +#endif if (problem) goto out; creds.times.endtime = 0; +#ifdef HEIMDAL flags.i = 0; flags.b.forwarded = 1; flags.b.forwardable = krb5_config_get_bool(context, NULL, "libdefaults", "forwardable", NULL); - - remotehost = get_canonical_hostname(1); - problem = krb5_get_forwarded_creds(context, auth_context, ccache, flags.i, remotehost, &creds, &outbuf); +#else + forwardable = 1; + problem = krb5_fwd_tgt_creds(context, auth_context, remotehost, + creds.client, creds.server, ccache, forwardable, &outbuf); +#endif + if (problem) goto out; -- cgit v1.2.3