X-Git-Url: http://www.project-moonshot.org/gitweb/?p=openssh.git;a=blobdiff_plain;f=gss-serv.c;h=2a6bfbfb7bf0de491e0b584e4bdd49616ac712c6;hp=2ec7ea19c2da3fb41f1ed55ba02d94ef56ab5117;hb=afca9d259be1d594e282f9a80714e4be12fea16e;hpb=0bf87176543b3874dfd9e1a2ad928fe78388669d diff --git a/gss-serv.c b/gss-serv.c index 2ec7ea1..2a6bfbf 100644 --- a/gss-serv.c +++ b/gss-serv.c @@ -1,7 +1,7 @@ /* $OpenBSD: gss-serv.c,v 1.22 2008/05/08 12:02:23 djm Exp $ */ /* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -45,27 +45,17 @@ #include "channels.h" #include "session.h" #include "misc.h" +#include "servconf.h" +#include "uidswap.h" #include "ssh-gss.h" +#include "monitor_wrap.h" + +extern ServerOptions options; static ssh_gssapi_client gssapi_client = { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, - GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL}}; - -ssh_gssapi_mech gssapi_null_mech = - { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL}; - -#ifdef KRB5 -extern ssh_gssapi_mech gssapi_kerberos_mech; -#endif - -ssh_gssapi_mech* supported_mechs[]= { -#ifdef KRB5 - &gssapi_kerberos_mech, -#endif - &gssapi_null_mech, -}; - + GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME, {NULL, NULL, NULL}}; /* * Acquire credentials for a server running on the current host. @@ -81,25 +71,32 @@ ssh_gssapi_acquire_cred(Gssctxt *ctx) char lname[MAXHOSTNAMELEN]; gss_OID_set oidset; - gss_create_empty_oid_set(&status, &oidset); - gss_add_oid_set_member(&status, ctx->oid, &oidset); + if (options.gss_strict_acceptor) { + gss_create_empty_oid_set(&status, &oidset); + gss_add_oid_set_member(&status, ctx->oid, &oidset); - if (gethostname(lname, MAXHOSTNAMELEN)) { - gss_release_oid_set(&status, &oidset); - return (-1); - } + if (gethostname(lname, MAXHOSTNAMELEN)) { + gss_release_oid_set(&status, &oidset); + return (-1); + } + + if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) { + gss_release_oid_set(&status, &oidset); + return (ctx->major); + } + + if ((ctx->major = gss_acquire_cred(&ctx->minor, + ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, + NULL, NULL))) + ssh_gssapi_error(ctx); - if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) { gss_release_oid_set(&status, &oidset); return (ctx->major); + } else { + ctx->name = GSS_C_NO_NAME; + ctx->creds = GSS_C_NO_CREDENTIAL; } - - if ((ctx->major = gss_acquire_cred(&ctx->minor, - ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL))) - ssh_gssapi_error(ctx); - - gss_release_oid_set(&status, &oidset); - return (ctx->major); + return GSS_S_COMPLETE; } /* Privileged */ @@ -114,28 +111,35 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) } /* Unprivileged */ +char * +ssh_gssapi_server_mechanisms() { + gss_OID_set supported; + + ssh_gssapi_supported_oids(&supported); + return (ssh_gssapi_kex_mechs(supported, &ssh_gssapi_server_check_mech, + NULL, NULL)); +} + +/* Unprivileged */ +int +ssh_gssapi_server_check_mech(Gssctxt **dum, gss_OID oid, const char *data, + const char *dummy) { + Gssctxt *ctx = NULL; + int res; + + res = !GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx, oid))); + ssh_gssapi_delete_ctx(&ctx); + + return (res); +} + +/* Unprivileged */ void ssh_gssapi_supported_oids(gss_OID_set *oidset) { - int i = 0; OM_uint32 min_status; - int present; - gss_OID_set supported; - - gss_create_empty_oid_set(&min_status, oidset); - gss_indicate_mechs(&min_status, &supported); - - while (supported_mechs[i]->name != NULL) { - if (GSS_ERROR(gss_test_oid_set_member(&min_status, - &supported_mechs[i]->oid, supported, &present))) - present = 0; - if (present) - gss_add_oid_set_member(&min_status, - &supported_mechs[i]->oid, oidset); - i++; - } - gss_release_oid_set(&min_status, &supported); + gss_indicate_mechs(&min_status, oidset); } @@ -162,7 +166,7 @@ ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *recv_tok, if (ctx->client_creds) debug("Received some client credentials"); - else + else if (ctx->major == GSS_S_COMPLETE) debug("Got no client credentials"); status = ctx->major; @@ -246,29 +250,20 @@ ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name) OM_uint32 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) { - int i = 0; - gss_buffer_desc ename; - client->mech = NULL; - - while (supported_mechs[i]->name != NULL) { - if (supported_mechs[i]->oid.length == ctx->oid->length && - (memcmp(supported_mechs[i]->oid.elements, - ctx->oid->elements, ctx->oid->length) == 0)) - client->mech = supported_mechs[i]; - i++; - } - - if (client->mech == NULL) - return GSS_S_FAILURE; - if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, &client->displayname, NULL))) { ssh_gssapi_error(ctx); return (ctx->major); } + if ((ctx->major = gss_duplicate_name(&ctx->minor, ctx->client, + &client->name))) { + ssh_gssapi_error(ctx); + return (ctx->major); + } + if ((ctx->major = gss_export_name(&ctx->minor, ctx->client, &ename))) { ssh_gssapi_error(ctx); @@ -280,6 +275,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) return (ctx->major); } + gss_release_buffer(&ctx->minor, &ename); + /* 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; @@ -302,10 +299,11 @@ ssh_gssapi_cleanup_creds(void) void ssh_gssapi_storecreds(void) { - if (gssapi_client.mech && gssapi_client.mech->storecreds) { - (*gssapi_client.mech->storecreds)(&gssapi_client); - } else - debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); + OM_uint32 lmin; + + gss_store_cred(&lmin, gssapi_client.creds, + GSS_C_INITIATE, GSS_C_NO_OID, + 1, 1, NULL, NULL); } /* This allows GSSAPI methods to do things to the childs environment based @@ -327,39 +325,52 @@ ssh_gssapi_do_child(char ***envp, u_int *envsizep) /* Privileged */ int -ssh_gssapi_userok(char *user) +ssh_gssapi_userok(char *user, struct passwd *pw) { OM_uint32 lmin; + int userok = 0; if (gssapi_client.exportedname.length == 0 || gssapi_client.exportedname.value == NULL) { debug("No suitable client data"); return 0; } - if (gssapi_client.mech && gssapi_client.mech->userok) - if ((*gssapi_client.mech->userok)(&gssapi_client, user)) - return 1; - else { - /* Destroy delegated credentials if userok fails */ - gss_release_buffer(&lmin, &gssapi_client.displayname); - gss_release_buffer(&lmin, &gssapi_client.exportedname); - gss_release_cred(&lmin, &gssapi_client.creds); - memset(&gssapi_client, 0, sizeof(ssh_gssapi_client)); - return 0; - } - else - debug("ssh_gssapi_userok: Unknown GSSAPI mechanism"); - return (0); + + userok = gss_userok(gssapi_client.name, user); + if (userok) { + gssapi_client.used = 1; + gssapi_client.store.owner = pw; + } else { + /* Destroy delegated credentials if userok fails */ + gss_release_buffer(&lmin, &gssapi_client.displayname); + gss_release_buffer(&lmin, &gssapi_client.exportedname); + gss_release_name(&lmin, &gssapi_client.name); + gss_release_cred(&lmin, &gssapi_client.creds); + memset(&gssapi_client, 0, sizeof(ssh_gssapi_client)); + } + + return (userok); } -/* Privileged */ +/* Priviledged */ OM_uint32 -ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) +ssh_gssapi_localname(char **user) { - ctx->major = gss_verify_mic(&ctx->minor, ctx->context, - gssbuf, gssmic, NULL); + OM_uint32 major_status, lmin; + uid_t uid; + struct passwd *pw; - return (ctx->major); -} + major_status = gss_pname_to_uid(&lmin, gssapi_client.name, + GSS_C_NO_OID, &uid); + if (GSS_ERROR(major_status)) + return (major_status); -#endif + pw = getpwuid(uid); + if (pw == NULL) + return (GSS_S_BAD_NAME); + + *user = xstrdup(pw->pw_name); + + return (GSS_S_COMPLETE); +} +#endif /* GSSAPI */