summaryrefslogtreecommitdiff
path: root/usr/src/cmd/ssh/sshd/gss-serv.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/ssh/sshd/gss-serv.c')
-rw-r--r--usr/src/cmd/ssh/sshd/gss-serv.c516
1 files changed, 0 insertions, 516 deletions
diff --git a/usr/src/cmd/ssh/sshd/gss-serv.c b/usr/src/cmd/ssh/sshd/gss-serv.c
deleted file mode 100644
index 7ff525c306..0000000000
--- a/usr/src/cmd/ssh/sshd/gss-serv.c
+++ /dev/null
@@ -1,516 +0,0 @@
-/*
- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include "includes.h"
-
-#ifdef GSSAPI
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include "includes.h"
-#include "ssh.h"
-#include "ssh2.h"
-#include "xmalloc.h"
-#include "buffer.h"
-#include "bufaux.h"
-#include "packet.h"
-#include "compat.h"
-#include <openssl/evp.h>
-#include "cipher.h"
-#include "kex.h"
-#include "auth.h"
-#include "log.h"
-#include "channels.h"
-#include "session.h"
-#include "dispatch.h"
-#include "servconf.h"
-#include "uidswap.h"
-#include "compat.h"
-#include <pwd.h>
-
-#include "ssh-gss.h"
-
-extern char **environ;
-
-extern ServerOptions options;
-extern uchar_t *session_id2;
-extern int session_id2_len;
-
-Gssctxt *xxx_gssctxt;
-
-void
-ssh_gssapi_server_kex_hook(Kex *kex, char **proposal)
-{
- gss_OID_set mechs = GSS_C_NULL_OID_SET;
-
- if (kex == NULL || !kex->server)
- fatal("INTERNAL ERROR (%s)", __func__);
-
- ssh_gssapi_server_mechs(&mechs);
- ssh_gssapi_modify_kex(kex, mechs, proposal);
-}
-
-void
-ssh_gssapi_server_mechs(gss_OID_set *mechs)
-{
- static gss_OID_set supported = GSS_C_NULL_OID_SET;
- gss_OID_set s, acquired, indicated = GSS_C_NULL_OID_SET;
- gss_cred_id_t creds;
- OM_uint32 maj, min;
- int i;
-
- if (!mechs) {
- (void) gss_release_oid_set(&min, &supported);
- return;
- }
-
- if (supported != GSS_C_NULL_OID_SET) {
- *mechs = supported;
- return;
- }
-
- *mechs = GSS_C_NULL_OID_SET;
-
- maj = gss_create_empty_oid_set(&min, &s);
- if (GSS_ERROR(maj)) {
- debug("Could not allocate GSS-API resources (%s)",
- ssh_gssapi_last_error(NULL, &maj, &min));
- return;
- }
-
- maj = gss_indicate_mechs(&min, &indicated);
- if (GSS_ERROR(maj)) {
- debug("No GSS-API mechanisms are installed");
- return;
- }
-
- maj = gss_acquire_cred(&min, GSS_C_NO_NAME, 0, indicated,
- GSS_C_ACCEPT, &creds, &acquired, NULL);
-
- if (GSS_ERROR(maj))
- debug("Failed to acquire GSS-API credentials for any "
- "mechanisms (%s)", ssh_gssapi_last_error(NULL, &maj, &min));
-
- (void) gss_release_oid_set(&min, &indicated);
- (void) gss_release_cred(&min, &creds);
-
- if (acquired == GSS_C_NULL_OID_SET || acquired->count == 0)
- return;
-
- for (i = 0; i < acquired->count; i++) {
- if (ssh_gssapi_is_spnego(&acquired->elements[i]))
- continue;
-
- maj = gss_add_oid_set_member(&min, &acquired->elements[i], &s);
- if (GSS_ERROR(maj)) {
- debug("Could not allocate GSS-API resources (%s)",
- ssh_gssapi_last_error(NULL, &maj, &min));
- return;
- }
- }
- (void) gss_release_oid_set(&min, &acquired);
-
- if (s->count) {
- supported = s;
- *mechs = s;
- }
-}
-
-/*
- * Wrapper around accept_sec_context. Requires that the context contains:
- *
- * oid
- * credentials (from ssh_gssapi_acquire_cred)
- */
-/* Priviledged */
-OM_uint32
-ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_t recv_tok,
- gss_buffer_t send_tok)
-{
- /*
- * Acquiring a cred for the ctx->desired_mech for GSS_C_NO_NAME
- * may well be probably better than using GSS_C_NO_CREDENTIAL
- * and then checking that ctx->desired_mech agrees with
- * ctx->actual_mech...
- */
- ctx->major = gss_accept_sec_context(&ctx->minor, &ctx->context,
- GSS_C_NO_CREDENTIAL, recv_tok, GSS_C_NO_CHANNEL_BINDINGS,
- &ctx->src_name, &ctx->actual_mech, send_tok, &ctx->flags,
- NULL, &ctx->deleg_creds);
-
- if (GSS_ERROR(ctx->major))
- ssh_gssapi_error(ctx, "accepting security context");
-
- if (ctx->major == GSS_S_CONTINUE_NEEDED && send_tok->length == 0)
- fatal("Zero length GSS context token output when "
- "continue needed");
- else if (GSS_ERROR(ctx->major) && send_tok->length == 0)
- debug2("Zero length GSS context error token output");
-
- if (ctx->major == GSS_S_COMPLETE &&
- ctx->desired_mech != GSS_C_NULL_OID &&
- (ctx->desired_mech->length != ctx->actual_mech->length ||
- memcmp(ctx->desired_mech->elements, ctx->actual_mech->elements,
- ctx->desired_mech->length) != 0)) {
-
- gss_OID_set supported;
- OM_uint32 min;
- int present = 0;
-
- debug("The client did not use the GSS-API mechanism it "
- "asked for");
-
- /* Let it slide as long as the mech is supported */
- ssh_gssapi_server_mechs(&supported);
- if (supported != GSS_C_NULL_OID_SET) {
- (void) gss_test_oid_set_member(&min, ctx->actual_mech,
- supported, &present);
- }
- if (!present)
- ctx->major = GSS_S_BAD_MECH;
- }
-
- if (ctx->deleg_creds)
- debug("Received delegated GSS credentials");
-
- if (ctx->major == GSS_S_COMPLETE) {
- ctx->major = gss_inquire_context(&ctx->minor, ctx->context,
- NULL, &ctx->dst_name, NULL, NULL, NULL, NULL,
- &ctx->established);
-
- if (GSS_ERROR(ctx->major)) {
- ssh_gssapi_error(ctx,
- "inquiring established sec context");
- return (ctx->major);
- }
-
- xxx_gssctxt = ctx;
- }
-
- return (ctx->major);
-}
-
-
-/* As user - called through fatal cleanup hook */
-void
-ssh_gssapi_cleanup_creds(Gssctxt *ctx)
-{
-#ifdef HAVE_GSS_STORE_CRED
- /* pam_setcred() will take care of this */
- return;
-#else
- return;
-/* #error "Portability broken in cleanup of stored creds" */
-#endif /* HAVE_GSS_STORE_CRED */
-}
-
-void
-ssh_gssapi_storecreds(Gssctxt *ctx, Authctxt *authctxt)
-{
-#ifdef USE_PAM
- char **penv, **tmp_env;
-#endif /* USE_PAM */
-
- if (authctxt == NULL) {
- error("Missing context while storing GSS-API credentials");
- return;
- }
-
- if (ctx == NULL && xxx_gssctxt == NULL)
- return;
-
- if (ctx == NULL)
- ctx = xxx_gssctxt;
-
- if (!options.gss_cleanup_creds ||
- ctx->deleg_creds == GSS_C_NO_CREDENTIAL) {
- debug3("Not storing delegated GSS credentials"
- " (none delegated)");
- return;
- }
-
- if (!authctxt->valid || authctxt->pw == NULL) {
- debug3("Not storing delegated GSS credentials"
- " for invalid user");
- return;
- }
-
- debug("Storing delegated GSS-API credentials");
-
- /*
- * The GSS-API has a flaw in that it does not provide a
- * mechanism by which delegated credentials can be made
- * available for acquisition by GSS_Acquire_cred() et. al.;
- * gss_store_cred() is the proposed GSS-API extension for
- * generically storing delegated credentials.
- *
- * gss_store_cred() does not speak to how credential stores are
- * referenced. Generically this may be done by switching to the
- * user context of the user in whose default credential store we
- * wish to place delegated credentials. But environment
- * variables could conceivably affect the choice of credential
- * store as well, and perhaps in a mechanism-specific manner.
- *
- * SUNW -- On Solaris the euid selects the current credential
- * store, but PAM modules could select alternate stores by
- * setting, for example, KRB5CCNAME, so we also use the PAM
- * environment temporarily.
- */
-
-#ifdef HAVE_GSS_STORE_CRED
-#ifdef USE_PAM
- /*
- * PAM may have set mechanism-specific variables (e.g.,
- * KRB5CCNAME). fetch_pam_environment() protects against LD_*
- * and other environment variables.
- */
- penv = fetch_pam_environment(authctxt);
- tmp_env = environ;
- environ = penv;
-#endif /* USE_PAM */
- if (authctxt->pw->pw_uid != geteuid()) {
- temporarily_use_uid(authctxt->pw);
- ctx->major = gss_store_cred(&ctx->minor, ctx->deleg_creds,
- GSS_C_INITIATE, GSS_C_NULL_OID, 0, ctx->default_creds,
- NULL, NULL);
- restore_uid();
- } else {
- /* only when logging in as the privileged user used by sshd */
- ctx->major = gss_store_cred(&ctx->minor, ctx->deleg_creds,
- GSS_C_INITIATE, GSS_C_NULL_OID, 0, ctx->default_creds,
- NULL, NULL);
- }
-#ifdef USE_PAM
- environ = tmp_env;
- free_pam_environment(penv);
-#endif /* USE_PAM */
- if (GSS_ERROR(ctx->major))
- ssh_gssapi_error(ctx, "storing delegated credentials");
-
-#else
-#ifdef KRB5_GSS
-#error "MIT/Heimdal krb5-specific code missing in ssh_gssapi_storecreds()"
- if (ssh_gssapi_is_krb5(ctx->mech))
- ssh_gssapi_krb5_storecreds(ctx);
-#endif /* KRB5_GSS */
-#ifdef GSI_GSS
-#error "GSI krb5-specific code missing in ssh_gssapi_storecreds()"
- if (ssh_gssapi_is_gsi(ctx->mech))
- ssh_gssapi_krb5_storecreds(ctx);
-#endif /* GSI_GSS */
-/* #error "Mechanism-specific code missing in ssh_gssapi_storecreds()" */
- return;
-#endif /* HAVE_GSS_STORE_CRED */
-}
-
-void
-ssh_gssapi_do_child(Gssctxt *ctx, char ***envp, uint_t *envsizep)
-{
- /*
- * MIT/Heimdal/GSI specific code goes here.
- *
- * On Solaris there's nothing to do here as the GSS store and
- * related environment variables are to be set by PAM, if at all
- * (no environment variables are needed to address the default
- * credential store -- the euid does that).
- */
-#ifdef KRB5_GSS
-#error "MIT/Heimdal krb5-specific code missing in ssh_gssapi_storecreds()"
-#endif /* KRB5_GSS */
-#ifdef GSI_GSS
-#error "GSI krb5-specific code missing in ssh_gssapi_storecreds()"
-#endif /* GSI_GSS */
-}
-
-int
-ssh_gssapi_userok(Gssctxt *ctx, char *user)
-{
- if (ctx == NULL) {
- debug3("INTERNAL ERROR: %s", __func__);
- return (0);
- }
-
- if (user == NULL || *user == '\0')
- return (0);
-
-#ifdef HAVE___GSS_USEROK
- {
- int user_ok = 0;
-
- ctx->major = __gss_userok(&ctx->minor, ctx->src_name, user,
- &user_ok);
- if (GSS_ERROR(ctx->major)) {
- debug2("__GSS_userok() failed");
- return (0);
- }
-
- if (user_ok)
- return (1);
-
- /* fall through */
- }
-#else
-#ifdef GSSAPI_SIMPLE_USEROK
- {
- /* Mechanism-generic */
- OM_uint32 min;
- gss_buffer_desc buf, ename1, ename2;
- gss_name_t iname, cname;
- int eql;
-
- buf.value = user;
- buf.length = strlen(user);
- ctx->major = gss_import_name(&ctx->minor, &buf,
- GSS_C_NULL_OID, &iname);
- if (GSS_ERROR(ctx->major)) {
- ssh_gssapi_error(ctx,
- "importing name for authorizing initiator");
- goto failed_simple_userok;
- }
-
- ctx->major = gss_canonicalize_name(&ctx->minor, iname,
- ctx->actual_mech, &cname);
- (void) gss_release_name(&min, &iname);
- if (GSS_ERROR(ctx->major)) {
- ssh_gssapi_error(ctx, "canonicalizing name");
- goto failed_simple_userok;
- }
-
- ctx->major = gss_export_name(&ctx->minor, cname, &ename1);
- (void) gss_release_name(&min, &cname);
- if (GSS_ERROR(ctx->major)) {
- ssh_gssapi_error(ctx, "exporting name");
- goto failed_simple_userok;
- }
-
- ctx->major = gss_export_name(&ctx->minor, ctx->src_name,
- &ename2);
- if (GSS_ERROR(ctx->major)) {
- ssh_gssapi_error(ctx,
- "exporting client principal name");
- (void) gss_release_buffer(&min, &ename1);
- goto failed_simple_userok;
- }
-
- eql = (ename1.length == ename2.length &&
- memcmp(ename1.value, ename2.value, ename1.length) == 0);
-
- (void) gss_release_buffer(&min, &ename1);
- (void) gss_release_buffer(&min, &ename2);
-
- if (eql)
- return (1);
- /* fall through */
- }
-failed_simple_userok:
-#endif /* GSSAPI_SIMPLE_USEROK */
-#ifdef HAVE_GSSCRED_API
- {
- /* Mechanism-generic, Solaris-specific */
- OM_uint32 maj;
- uid_t uid;
- struct passwd *pw;
-
- maj = gsscred_name_to_unix_cred(ctx->src_name,
- ctx->actual_mech, &uid, NULL, NULL, NULL);
-
- if (GSS_ERROR(maj))
- goto failed_simple_gsscred_userok;
-
- if ((pw = getpwnam(user)) == NULL)
- goto failed_simple_gsscred_userok;
-
- if (pw->pw_uid == uid)
- return (1);
- /* fall through */
- }
-
-failed_simple_gsscred_userok:
-#endif /* HAVE_GSSCRED_API */
-#ifdef KRB5_GSS
- if (ssh_gssapi_is_krb5(ctx->mech))
- if (ssh_gssapi_krb5_userok(ctx->src_name, user))
- return (1);
-#endif /* KRB5_GSS */
-#ifdef GSI_GSS
- if (ssh_gssapi_is_gsi(ctx->mech))
- if (ssh_gssapi_gsi_userok(ctx->src_name, user))
- return (1);
-#endif /* GSI_GSS */
-#endif /* HAVE___GSS_USEROK */
-
- /* default to not authorized */
- return (0);
-}
-
-char *
-ssh_gssapi_localname(Gssctxt *ctx)
-{
- if (ctx == NULL) {
- debug3("INTERNAL ERROR: %s", __func__);
- return (NULL);
- }
-
- debug2("Mapping initiator GSS-API principal to local username");
-#ifdef HAVE_GSSCRED_API
- {
- /* Mechanism-generic, Solaris-specific */
- OM_uint32 maj;
- uid_t uid;
- struct passwd *pw;
-
- if (ctx->src_name == GSS_C_NO_NAME)
- goto failed_gsscred_localname;
-
- maj = gsscred_name_to_unix_cred(ctx->src_name,
- ctx->actual_mech, &uid, NULL, NULL, NULL);
-
- if (GSS_ERROR(maj))
- goto failed_gsscred_localname;
-
- if ((pw = getpwuid(uid)) == NULL)
- goto failed_gsscred_localname;
-
- debug2("Mapped the initiator to: %s", pw->pw_name);
- return (xstrdup(pw->pw_name));
- }
-failed_gsscred_localname:
-#endif /* HAVE_GSSCRED_API */
-#ifdef KRB5_GSS
-#error "ssh_gssapi_krb5_localname() not implemented"
- if (ssh_gssapi_is_krb5(ctx->mech))
- return (ssh_gssapi_krb5_localname(ctx->src_name));
-#endif /* KRB5_GSS */
-#ifdef GSI_GSS
-#error "ssh_gssapi_gsi_localname() not implemented"
- if (ssh_gssapi_is_gsi(ctx->mech))
- return (ssh_gssapi_gsi_localname(ctx->src_name));
-#endif /* GSI_GSS */
- return (NULL);
-}
-#endif /* GSSAPI */