X-Git-Url: http://andersk.mit.edu/gitweb/gssapi-openssh.git/blobdiff_plain/5ff39d34a50802bab296b50eb09d097062e07f03..4834571d2b8116cdc3e2d6b04ccd35d5ea484f6f:/openssh/gss-serv-krb5.c diff --git a/openssh/gss-serv-krb5.c b/openssh/gss-serv-krb5.c index c7f3ad1..bea0eae 100644 --- a/openssh/gss-serv-krb5.c +++ b/openssh/gss-serv-krb5.c @@ -1,3 +1,5 @@ +/* $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. * @@ -27,42 +29,39 @@ #ifdef GSSAPI #ifdef KRB5 -#include "auth.h" -#include "auth-pam.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 -#define krb5_get_err_text(context,code) error_message(code) +# 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 krb5_context krb_context = NULL; - -/* We've been using a wrongly encoded mechanism ID for yonks */ - -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 -}; - ssh_gssapi_mech gssapi_kerberos_mech = { "toWM5Slw5Ew8Mqkay+al2g==", "Kerberos", @@ -72,58 +71,58 @@ ssh_gssapi_mech gssapi_kerberos_mech = { &ssh_gssapi_krb5_localname, &ssh_gssapi_krb5_storecreds }; - -/* Initialise the krb5 library, so we can use it for those bits that - * GSSAPI won't do */ -static int -ssh_gssapi_krb5_init() { +/* Initialise the krb5 library, for the stuff that GSSAPI won't do */ + +static int +ssh_gssapi_krb5_init(void) +{ krb5_error_code problem; - - if (krb_context !=NULL) + + if (krb_context != NULL) return 1; - + problem = krb5_init_context(&krb_context); if (problem) { - log("Cannot initialize krb5 context"); + logit("Cannot initialize krb5 context"); return 0; } - krb5_init_ets(krb_context); - return 1; -} + return 1; +} -/* Check if this user is OK to login. This only works with krb5 - other +/* 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) { +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->name.value, - &princ))) { - log("krb5_parse_name(): %.100s", - krb5_get_err_text(krb_context,retval)); + + 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; - log("Authorized to %s, krb5 principal %s (krb5_kuserok)",name, - (char *)client->name.value); - } - else + 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; } + /* Retrieve the local username associated with a set of Kerberos * credentials. Hopefully we can use this for the 'empty' username * logins discussed in the draft */ @@ -135,9 +134,9 @@ ssh_gssapi_krb5_localname(ssh_gssapi_client *client, char **user) { if (ssh_gssapi_krb5_init() == 0) return 0; - if ((retval=krb5_parse_name(krb_context, client->name.value, + if ((retval=krb5_parse_name(krb_context, client->displayname.value, &princ))) { - log("krb5_parse_name(): %.100s", + logit("krb5_parse_name(): %.100s", krb5_get_err_text(krb_context,retval)); return 0; } @@ -153,82 +152,59 @@ ssh_gssapi_krb5_localname(ssh_gssapi_client *client, char **user) { return(1); } -/* Make sure that this is called _after_ we've setuid to the user */ - -/* This writes out any forwarded credentials. Its specific to the Kerberos - * GSSAPI mechanism - * - * We assume that our caller has made sure that the user has selected - * delegated credentials, and that the client_creds structure is correctly - * populated. - */ +/* 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) { +ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) +{ krb5_ccache ccache; krb5_error_code problem; krb5_principal princ; - char ccname[35]; - static char name[40]; - int tmpfd; - OM_uint32 maj_status,min_status; + 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"); + if (client->creds == NULL) { + debug("No credentials stored"); return; } - + if (ssh_gssapi_krb5_init() == 0) return; - if (options.gss_use_session_ccache) { - snprintf(ccname,sizeof(ccname),"/tmp/krb5cc_%d_XXXXXX",geteuid()); - - if ((tmpfd = mkstemp(ccname))==-1) { - log("mkstemp(): %.100s", strerror(errno)); - return; - } - if (fchmod(tmpfd, S_IRUSR | S_IWUSR) == -1) { - log("fchmod(): %.100s", strerror(errno)); - close(tmpfd); - return; - } - } else { - snprintf(ccname,sizeof(ccname),"/tmp/krb5cc_%d",geteuid()); - tmpfd = open(ccname, O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR); - if (tmpfd == -1) { - log("open(): %.100s", strerror(errno)); - return; - } - } - - close(tmpfd); - snprintf(name, sizeof(name), "FILE:%s",ccname); - - if ((problem = krb5_cc_resolve(krb_context, name, &ccache))) { - log("krb5_cc_default(): %.100s", - krb5_get_err_text(krb_context,problem)); - return; - } - - if ((problem = krb5_parse_name(krb_context, client->name.value, - &princ))) { - log("krb5_parse_name(): %.100s", - krb5_get_err_text(krb_context,problem)); - krb5_cc_destroy(krb_context,ccache); +#ifdef HEIMDAL + 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; } - +#else + 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, + 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))) { - log("krb5_cc_initialize(): %.100s", - krb5_get_err_text(krb_context,problem)); - krb5_free_principal(krb_context,princ); - krb5_cc_destroy(krb_context,ccache); + 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); + + krb5_free_principal(krb_context, princ); #ifdef MECHGLUE krb5_cred_handle = @@ -239,22 +215,29 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) { #endif if ((maj_status = gss_krb5_copy_ccache(&min_status, - client->creds, - ccache))) { - log("gss_krb5_copy_ccache() failed"); - krb5_cc_destroy(krb_context,ccache); + krb5_cred_handle, ccache))) { + logit("gss_krb5_copy_ccache() failed"); + krb5_cc_destroy(krb_context, ccache); return; } - - krb5_cc_close(krb_context,ccache); + + new_ccname = krb5_cc_get_name(krb_context, ccache); + + client->store.envvar = "KRB5CCNAME"; +#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 - do_pam_putenv("KRB5CCNAME",name); + if (options.use_pam) + do_pam_putenv(client->store.envvar, client->store.envval); #endif - client->store.filename=strdup(ccname); - client->store.envvar="KRB5CCNAME"; - client->store.envval=strdup(name); + krb5_cc_close(krb_context, ccache); return; }