X-Git-Url: http://andersk.mit.edu/gitweb/gssapi-openssh.git/blobdiff_plain/f97edba64d1fb2b28ac269fe588396643d271b7b..9f2c8cb950fea61c599edeb9721aca66f4bd61f6:/openssh/gss-serv.c diff --git a/openssh/gss-serv.c b/openssh/gss-serv.c index 365e48d..6fbc09d 100644 --- a/openssh/gss-serv.c +++ b/openssh/gss-serv.c @@ -48,10 +48,12 @@ #include "servconf.h" #include "uidswap.h" +#include "xmalloc.h" #include "ssh-gss.h" #include "monitor_wrap.h" extern ServerOptions options; +extern Authctxt *the_authctxt; static ssh_gssapi_client gssapi_client = { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, @@ -63,14 +65,23 @@ ssh_gssapi_mech gssapi_null_mech = #ifdef KRB5 extern ssh_gssapi_mech gssapi_kerberos_mech; #endif +#ifdef GSI +extern ssh_gssapi_mech gssapi_gsi_mech; +#endif ssh_gssapi_mech* supported_mechs[]= { #ifdef KRB5 &gssapi_kerberos_mech, +#endif +#ifdef GSI + &gssapi_gsi_mech, #endif &gssapi_null_mech, }; +#ifdef GSS_C_GLOBUS_LIMITED_PROXY_FLAG +static int limited = 0; +#endif /* * Acquire credentials for a server running on the current host. @@ -159,7 +170,8 @@ ssh_gssapi_supported_oids(gss_OID_set *oidset) gss_create_empty_oid_set(&min_status, oidset); - if (GSS_ERROR(gss_indicate_mechs(&min_status, &supported))) + /* Ask privileged process what mechanisms it supports. */ + if (GSS_ERROR(PRIVSEP(gss_indicate_mechs(&min_status, &supported)))) return; while (supported_mechs[i]->name != NULL) { @@ -212,6 +224,10 @@ ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *recv_tok, (*flags & GSS_C_INTEG_FLAG))) && (ctx->major == GSS_S_COMPLETE)) { if (ssh_gssapi_getclient(ctx, &gssapi_client)) fatal("Couldn't convert client name"); +#ifdef GSS_C_GLOBUS_LIMITED_PROXY_FLAG + if (flags && (*flags & GSS_C_GLOBUS_LIMITED_PROXY_FLAG)) + limited=1; +#endif } return (status); @@ -231,6 +247,17 @@ ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name) tok = ename->value; +#ifdef GSI /* GSI gss_export_name() is broken. */ + if ((ctx->oid->length == gssapi_gsi_mech.oid.length) && + (memcmp(ctx->oid->elements, gssapi_gsi_mech.oid.elements, + gssapi_gsi_mech.oid.length) == 0)) { + name->length = ename->length; + name->value = xmalloc(ename->length+1); + memcpy(name->value, ename->value, ename->length); + return GSS_S_COMPLETE; + } +#endif + /* * Check that ename is long enough for all of the fixed length * header, and that the initial ID bytes are correct @@ -296,8 +323,11 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) return GSS_S_COMPLETE; } - if ((ctx->major = gss_inquire_cred_by_mech(&ctx->minor, - ctx->client_creds, ctx->oid, &new_name, + /* Call gss_inquire_cred rather than gss_inquire_cred_by_mech + because GSI doesn't support the latter. -jbasney */ + + if ((ctx->major = gss_inquire_cred(&ctx->minor, + ctx->client_creds, &new_name, NULL, NULL, NULL))) { ssh_gssapi_error(ctx); return (ctx->major); @@ -340,9 +370,12 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) if (client->mech == NULL) return GSS_S_FAILURE; + /* Call gss_inquire_cred rather than gss_inquire_cred_by_mech + because GSI doesn't support the latter. -jbasney */ + if (ctx->client_creds && - (ctx->major = gss_inquire_cred_by_mech(&ctx->minor, - ctx->client_creds, ctx->oid, &client->name, NULL, NULL, NULL))) { + (ctx->major = gss_inquire_cred(&ctx->minor, + ctx->client_creds, &client->name, NULL, NULL, NULL))) { ssh_gssapi_error(ctx); return (ctx->major); } @@ -369,6 +402,10 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) /* We can't copy this structure, so we just move the pointer to it */ client->creds = ctx->client_creds; ctx->client_creds = GSS_C_NO_CREDENTIAL; + + /* needed for globus_gss_assist_map_and_authorize() */ + client->context = ctx->context; + return (ctx->major); } @@ -389,6 +426,11 @@ void ssh_gssapi_storecreds(void) { if (gssapi_client.mech && gssapi_client.mech->storecreds) { + if (options.gss_creds_path) { + gssapi_client.store.filename = + expand_authorized_keys(options.gss_creds_path, + the_authctxt->pw); + } (*gssapi_client.mech->storecreds)(&gssapi_client); } else debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); @@ -422,6 +464,12 @@ ssh_gssapi_userok(char *user, struct passwd *pw) debug("No suitable client data"); return 0; } +#ifdef GSS_C_GLOBUS_LIMITED_PROXY_FLAG + if (limited && options.gsi_allow_limited_proxy != 1) { + debug("limited proxy not acceptable for remote login"); + return 0; + } +#endif if (gssapi_client.mech && gssapi_client.mech->userok) if ((*gssapi_client.mech->userok)(&gssapi_client, user)) { gssapi_client.used = 1; @@ -440,6 +488,27 @@ ssh_gssapi_userok(char *user, struct passwd *pw) return (0); } +/* ssh_gssapi_checkmic() moved to gss-genr.c so it can be called by + kexgss_client(). */ + +/* Priviledged */ +int +ssh_gssapi_localname(char **user) +{ + *user = NULL; + if (gssapi_client.displayname.length==0 || + gssapi_client.displayname.value==NULL) { + debug("No suitable client data"); + return(0);; + } + if (gssapi_client.mech && gssapi_client.mech->localname) { + return((*gssapi_client.mech->localname)(&gssapi_client,user)); + } else { + debug("Unknown client authentication type"); + } + return(0); +} + /* These bits are only used for rekeying. The unpriviledged child is running * as the user, the monitor is root. * @@ -461,11 +530,12 @@ static int ssh_gssapi_simple_conv(int n, const struct pam_message **msg, void ssh_gssapi_rekey_creds() { int ok; - int ret; #ifdef USE_PAM + int ret; pam_handle_t *pamh = NULL; struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL}; char *envstr; + char **p;char **pw; #endif if (gssapi_client.store.filename == NULL && @@ -495,6 +565,18 @@ ssh_gssapi_rekey_creds() { if (ret) return; + /* Put ssh pam stack env variables in this new pam stack env + * Using pam-pkinit, KRB5CCNAME is set during do_pam_session + * this addition enables pam-pkinit to access KRB5CCNAME if used + * in sshd-rekey stack too + */ + pw = p = fetch_pam_environment(); + while ( *pw != NULL ) { + pam_putenv(pamh,*pw); + pw++; + } + free_pam_environment(p); + xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, gssapi_client.store.envval); @@ -526,4 +608,10 @@ ssh_gssapi_update_creds(ssh_gssapi_ccache *store) { return ok; } +void +ssh_gssapi_get_client_info(char **userdn, char **mech) { + *userdn = gssapi_client.displayname.value; + *mech = gssapi_client.mech->name; +} + #endif