X-Git-Url: http://andersk.mit.edu/gitweb/gssapi-openssh.git/blobdiff_plain/51f1e7024fd6e7881a0a713868d67861ba97fbfb..HEAD:/openssh/gss-serv-krb5.c diff --git a/openssh/gss-serv-krb5.c b/openssh/gss-serv-krb5.c index c1ae5d6..dbf866c 100644 --- a/openssh/gss-serv-krb5.c +++ b/openssh/gss-serv-krb5.c @@ -1,7 +1,7 @@ -/* $OpenBSD: gss-serv-krb5.c,v 1.1 2003/08/22 10:56:09 markus Exp $ */ +/* $OpenBSD: gss-serv-krb5.c,v 1.7 2006/08/03 03:34:42 deraadt Exp $ */ /* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,27 +29,56 @@ #ifdef GSSAPI #ifdef KRB5 -#include "auth.h" +#include + +#include +#include + #include "xmalloc.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" #include "log.h" #include "servconf.h" +#include "buffer.h" #include "ssh-gss.h" extern ServerOptions options; #ifdef HEIMDAL -#include -#else -#include +# include +#elif !defined(MECHGLUE) +# ifdef HAVE_GSSAPI_KRB5_H +# include +# elif HAVE_GSSAPI_GSSAPI_KRB5_H +# include +# endif #endif static krb5_context krb_context = NULL; +static int ssh_gssapi_krb5_init(); +static int ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name); +static int ssh_gssapi_krb5_localname(ssh_gssapi_client *client, char **user); +static void ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client); +static int ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, + ssh_gssapi_client *client); + +ssh_gssapi_mech gssapi_kerberos_mech = { + "toWM5Slw5Ew8Mqkay+al2g==", + "Kerberos", + {9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"}, + NULL, + &ssh_gssapi_krb5_userok, + &ssh_gssapi_krb5_localname, + &ssh_gssapi_krb5_storecreds, + &ssh_gssapi_krb5_updatecreds +}; /* Initialise the krb5 library, for the stuff that GSSAPI won't do */ -static int -ssh_gssapi_krb5_init() +static int +ssh_gssapi_krb5_init(void) { krb5_error_code problem; @@ -61,7 +90,6 @@ ssh_gssapi_krb5_init() logit("Cannot initialize krb5 context"); return 0; } - krb5_init_ets(krb_context); return 1; } @@ -138,7 +166,8 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) krb5_principal princ; OM_uint32 maj_status, min_status; gss_cred_id_t krb5_cred_handle; - + int len; + const char *new_ccname; if (client->creds == NULL) { debug("No credentials stored"); @@ -155,34 +184,14 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) return; } #else - { - int tmpfd; - char ccname[40]; - - snprintf(ccname, sizeof(ccname), - "FILE:/tmp/krb5cc_%d_XXXXXX", geteuid()); - - if ((tmpfd = mkstemp(ccname + strlen("FILE:"))) == -1) { - logit("mkstemp(): %.100s", strerror(errno)); - problem = errno; - return; - } - if (fchmod(tmpfd, S_IRUSR | S_IWUSR) == -1) { - logit("fchmod(): %.100s", strerror(errno)); - close(tmpfd); - problem = errno; - return; - } - close(tmpfd); - if ((problem = krb5_cc_resolve(krb_context, ccname, &ccache))) { - logit("krb5_cc_resolve(): %.100s", - krb5_get_err_text(krb_context, problem)); - return; - } + if ((problem = ssh_krb5_cc_gen(krb_context, &ccache))) { + logit("ssh_krb5_cc_gen(): %.100s", + krb5_get_err_text(krb_context, problem)); + return; } #endif /* #ifdef HEIMDAL */ - if ((problem = krb5_parse_name(krb_context, + if ((problem = krb5_parse_name(krb_context, client->exportedname.value, &princ))) { logit("krb5_parse_name(): %.100s", krb5_get_err_text(krb_context, problem)); @@ -215,13 +224,20 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) return; } - client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache)); + new_ccname = krb5_cc_get_name(krb_context, ccache); + client->store.envvar = "KRB5CCNAME"; - client->store.envval = xstrdup(client->store.filename); +#ifdef USE_CCAPI + xasprintf(&client->store.envval, "API:%s", new_ccname); + client->store.filename = NULL; +#else + xasprintf(&client->store.envval, "FILE:%s", new_ccname); + client->store.filename = xstrdup(new_ccname); +#endif #ifdef USE_PAM if (options.use_pam) - do_pam_putenv(client->store.envvar,client->store.envval); + do_pam_putenv(client->store.envvar, client->store.envval); #endif krb5_cc_close(krb_context, ccache); @@ -229,25 +245,70 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) 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, - &ssh_gssapi_krb5_localname, - &ssh_gssapi_krb5_storecreds -}; +static int +ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, + ssh_gssapi_client *client) +{ + krb5_ccache ccache = NULL; + krb5_principal principal = NULL; + char *name = NULL; + krb5_error_code problem; + OM_uint32 maj_status, min_status; -ssh_gssapi_mech gssapi_kerberos_mech_old = { - "Se3H81ismmOC3OE+FwYCiQ==", - "Kerberos", - {9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"}, - &ssh_gssapi_krb5_init, - &ssh_gssapi_krb5_userok, - &ssh_gssapi_krb5_localname, - &ssh_gssapi_krb5_storecreds -}; + if ((problem = krb5_cc_resolve(krb_context, store->envval, &ccache))) { + logit("krb5_cc_resolve(): %.100s", + krb5_get_err_text(krb_context, problem)); + return 0; + } + + /* Find out who the principal in this cache is */ + if ((problem = krb5_cc_get_principal(krb_context, ccache, + &principal))) { + logit("krb5_cc_get_principal(): %.100s", + krb5_get_err_text(krb_context, problem)); + krb5_cc_close(krb_context, ccache); + return 0; + } + + if ((problem = krb5_unparse_name(krb_context, principal, &name))) { + logit("krb5_unparse_name(): %.100s", + krb5_get_err_text(krb_context, problem)); + krb5_free_principal(krb_context, principal); + krb5_cc_close(krb_context, ccache); + return 0; + } + + + if (strcmp(name,client->exportedname.value)!=0) { + debug("Name in local credentials cache differs. Not storing"); + krb5_free_principal(krb_context, principal); + krb5_cc_close(krb_context, ccache); + krb5_free_unparsed_name(krb_context, name); + return 0; + } + krb5_free_unparsed_name(krb_context, name); + + /* Name matches, so lets get on with it! */ + + if ((problem = krb5_cc_initialize(krb_context, ccache, principal))) { + logit("krb5_cc_initialize(): %.100s", + krb5_get_err_text(krb_context, problem)); + krb5_free_principal(krb_context, principal); + krb5_cc_close(krb_context, ccache); + return 0; + } + + krb5_free_principal(krb_context, principal); + + if ((maj_status = gss_krb5_copy_ccache(&min_status, client->creds, + ccache))) { + logit("gss_krb5_copy_ccache() failed. Sorry!"); + krb5_cc_close(krb_context, ccache); + return 0; + } + + return 1; +} #endif /* KRB5 */