From 12928e80f843efe91b9c9daa5d34fbe7cde7bf08 Mon Sep 17 00:00:00 2001 From: djm Date: Sat, 13 Apr 2002 01:04:40 +0000 Subject: [PATCH] - (djm) Add KrbV support patch from Simon Wilkinson --- CREDITS | 2 +- ChangeLog | 3 ++ Makefile.in | 2 +- acconfig.h | 6 +++ auth-krb5.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++- configure.ac | 43 ++++++++++++++++++- servconf.c | 11 ++++- sshconnect1.c | 52 +++++++++++++++++++++-- 8 files changed, 225 insertions(+), 9 deletions(-) diff --git a/CREDITS b/CREDITS index bcc0359a..1acb3f83 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 diff --git a/ChangeLog b/ChangeLog index 60c11694..e5799df0 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 diff --git a/Makefile.in b/Makefile.in index f8e78e5b..385d6ef2 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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 b7bb1c40..ebf50f4c 100644 --- a/acconfig.h +++ b/acconfig.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 5011c54f..cbbb553d 100644 --- a/configure.ac +++ b/configure.ac @@ -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; -- 2.45.1