X-Git-Url: http://andersk.mit.edu/gitweb/gssapi-openssh.git/blobdiff_plain/f4b9ce4247d2e3d2e22b167b76a8530368767651..77fa2ab46721bcc01b898b7df0aa85c170931c06:/openssh/gss-serv-gsi.c diff --git a/openssh/gss-serv-gsi.c b/openssh/gss-serv-gsi.c index d8714e3..bd72536 100644 --- a/openssh/gss-serv-gsi.c +++ b/openssh/gss-serv-gsi.c @@ -27,16 +27,42 @@ #ifdef GSSAPI #ifdef GSI -#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; + #include +static int ssh_gssapi_gsi_userok(ssh_gssapi_client *client, char *name); +static int ssh_gssapi_gsi_localname(ssh_gssapi_client *client, char **user); +static void ssh_gssapi_gsi_storecreds(ssh_gssapi_client *client); +static void ssh_gssapi_gsi_updatecreds(ssh_gssapi_ccache *store, + ssh_gssapi_client *client); + +ssh_gssapi_mech gssapi_gsi_mech = { + "dZuIebMjgUqaxvbF7hDbAw==", + "GSI", + {9, "\x2B\x06\x01\x04\x01\x9B\x50\x01\x01"}, + NULL, + &ssh_gssapi_gsi_userok, + &ssh_gssapi_gsi_localname, + &ssh_gssapi_gsi_storecreds, + &ssh_gssapi_gsi_updatecreds +}; + /* * Check if this user is OK to login under GSI. User has been authenticated * as identity in global 'client_name.value' and is trying to log in as passed @@ -48,112 +74,165 @@ static int ssh_gssapi_gsi_userok(ssh_gssapi_client *client, char *name) { int authorized = 0; + globus_result_t res; +#ifdef HAVE_GLOBUS_GSS_ASSIST_MAP_AND_AUTHORIZE + char lname[256] = ""; +#endif - /* This returns 0 on success */ - authorized = (globus_gss_assist_userok(client->name.value, - name) == 0); +#ifdef GLOBUS_GSI_GSS_ASSIST_MODULE + if (globus_module_activate(GLOBUS_GSI_GSS_ASSIST_MODULE) != 0) { + return 0; + } +#endif + +/* use new globus_gss_assist_map_and_authorize() interface if available */ +#ifdef HAVE_GLOBUS_GSS_ASSIST_MAP_AND_AUTHORIZE + debug("calling globus_gss_assist_map_and_authorize()"); + if (GLOBUS_SUCCESS != + (res = globus_gss_assist_map_and_authorize(client->context, "ssh", + name, lname, 256))) { + debug("%s", globus_error_print_chain(globus_error_get(res))); + } else if (lname && lname[0] && strcmp(name, lname) != 0) { + debug("GSI user maps to %s, not %s", lname, name); + } else { + authorized = 1; + } +#else + debug("calling globus_gss_assist_userok()"); + if (GLOBUS_SUCCESS != + (res = (globus_gss_assist_userok(client->displayname.value, + name)))) { + debug("%s", globus_error_print_chain(globus_error_get(res))); + } else { + authorized = 1; + } +#endif - debug("GSI user %s is%s authorized as target user %s", - (char *) client->name.value, - (authorized ? "" : " not"), - name); + logit("GSI user %s is%s authorized as target user %s", + (char *) client->displayname.value, (authorized ? "" : " not"), name); return authorized; } /* - * Handle setting up child environment for GSI. - * - * Make sure that this is called _after_ we've setuid to the user. + * Return the local username associated with the GSI credentials. + */ +int +ssh_gssapi_gsi_localname(ssh_gssapi_client *client, char **user) +{ + globus_result_t res; +#ifdef HAVE_GLOBUS_GSS_ASSIST_MAP_AND_AUTHORIZE + char lname[256] = ""; +#endif + +#ifdef GLOBUS_GSI_GSS_ASSIST_MODULE + if (globus_module_activate(GLOBUS_GSI_GSS_ASSIST_MODULE) != 0) { + return 0; + } +#endif + +/* use new globus_gss_assist_map_and_authorize() interface if available */ +#ifdef HAVE_GLOBUS_GSS_ASSIST_MAP_AND_AUTHORIZE + debug("calling globus_gss_assist_map_and_authorize()"); + if (GLOBUS_SUCCESS != + (res = globus_gss_assist_map_and_authorize(client->context, "ssh", + NULL, lname, 256))) { + debug("%s", globus_error_print_chain(globus_error_get(res))); + logit("failed to map GSI user %s", (char *)client->displayname.value); + return 0; + } + *user = strdup(lname); +#else + debug("calling globus_gss_assist_gridmap()"); + if (GLOBUS_SUCCESS != + (res = globus_gss_assist_gridmap(client->displayname.value, user))) { + debug("%s", globus_error_print_chain(globus_error_get(res))); + logit("failed to map GSI user %s", (char *)client->displayname.value); + return 0; + } +#endif + + logit("GSI user %s mapped to target user %s", + (char *) client->displayname.value, *user); + + return 1; +} + +/* + * Export GSI credentials to disk. */ static void ssh_gssapi_gsi_storecreds(ssh_gssapi_client *client) { OM_uint32 major_status; OM_uint32 minor_status; + gss_buffer_desc export_cred = GSS_C_EMPTY_BUFFER; + char * p; + if (!client || !client->creds) { + return; + } + + major_status = gss_export_cred(&minor_status, + client->creds, + GSS_C_NO_OID, + 1, + &export_cred); + if (GSS_ERROR(major_status) && major_status != GSS_S_UNAVAILABLE) { + Gssctxt *ctx; + ssh_gssapi_build_ctx(&ctx); + ctx->major = major_status; + ctx->minor = minor_status; + ssh_gssapi_set_oid(ctx, &gssapi_gsi_mech.oid); + ssh_gssapi_error(ctx); + ssh_gssapi_delete_ctx(&ctx); + return; + } - if (client->creds != NULL) - { - char *creds_env = NULL; - - /* - * This is the current hack with the GSI gssapi library to - * export credentials to disk. - */ - - debug("Exporting delegated credentials"); - - minor_status = 0xdee0; /* Magic value */ - major_status = - gss_inquire_cred(&minor_status, - client->creds, - (gss_name_t *) &creds_env, - NULL, - NULL, - NULL); - - if ((major_status == GSS_S_COMPLETE) && - (minor_status == 0xdee1) && - (creds_env != NULL)) - { - char *value; - - /* - * String is of the form: - * X509_USER_DELEG_PROXY=filename - * so we parse out the filename - * and then set X509_USER_PROXY - * to point at it. - */ - value = strchr(creds_env, '='); - - if (value != NULL) - { - *value = '\0'; - value++; + p = strchr((char *) export_cred.value, '='); + if (p == NULL) { + logit("Failed to parse exported credentials string '%.100s'", + (char *)export_cred.value); + gss_release_buffer(&minor_status, &export_cred); + return; + } + *p++ = '\0'; + if (strcmp((char *)export_cred.value,"X509_USER_DELEG_PROXY") == 0) { + client->store.envvar = strdup("X509_USER_PROXY"); + } else { + client->store.envvar = strdup((char *)export_cred.value); + } + if (access(p, R_OK) == 0) { + if (client->store.filename) { + if (rename(p, client->store.filename) < 0) { + logit("Failed to rename %s to %s: %s", p, + client->store.filename, strerror(errno)); + xfree(client->store.filename); + client->store.filename = strdup(p); + } else { + p = client->store.filename; + } + } else { + client->store.filename = strdup(p); + } + } + client->store.envval = strdup(p); #ifdef USE_PAM - do_pam_putenv("X509_USER_PROXY",value); + if (options.use_pam) + do_pam_putenv(client->store.envvar, client->store.envval); #endif - client->store.filename=NULL; - client->store.envvar="X509_USER_PROXY"; - client->store.envval=strdup(value); - - return; - } - else - { - log("Failed to parse delegated credentials string '%s'", - creds_env); - } - } - else - { - log("Failed to export delegated credentials (error %ld)", - major_status); - } - } + gss_release_buffer(&minor_status, &export_cred); } -ssh_gssapi_mech gssapi_gsi_mech_old = { - "N3+k7/4wGxHyuP8Yxi4RhA==", - "GSI", - {9, "\x2B\x06\x01\x04\x01\x9B\x50\x01\x01"} - NULL, - &ssh_gssapi_gsi_userok, - NULL, - &ssh_gssapi_gsi_storecreds -}; - -ssh_gssapi_mech gssapi_gsi_mech = { - "dZuIebMjgUqaxvbF7hDbAw==", - "GSI", - {9, "\x2B\x06\x01\x04\x01\x9B\x50\x01\x01"} - NULL, - &ssh_gssapi_gsi_userok, - NULL, - &ssh_gssapi_gsi_storecreds -}; +/* + * Export updated GSI credentials to disk. + */ +static int +ssh_gssapi_gsi_updatecreds(ssh_gssapi_ccache *store,ssh_gssapi_client *client) +{ + ssh_gssapi_gsi_storecreds(client); + return 1; +} #endif /* GSI */ #endif /* GSSAPI */