diff options
Diffstat (limited to 'usr/src/cmd/ssh/libssh/common/ssh-gss.c')
| -rw-r--r-- | usr/src/cmd/ssh/libssh/common/ssh-gss.c | 782 |
1 files changed, 0 insertions, 782 deletions
diff --git a/usr/src/cmd/ssh/libssh/common/ssh-gss.c b/usr/src/cmd/ssh/libssh/common/ssh-gss.c deleted file mode 100644 index 37aeb04873..0000000000 --- a/usr/src/cmd/ssh/libssh/common/ssh-gss.c +++ /dev/null @@ -1,782 +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 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" - -#ifdef GSSAPI - -#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 "log.h" -#include "compat.h" -#include "xlist.h" - -#include <netdb.h> - -#include "ssh-gss.h" - -#ifdef HAVE_GSS_OID_TO_MECH -#include <gssapi/gssapi_ext.h> -#endif /* HAVE_GSS_OID_TO_MECH */ - -typedef struct { - char *encoded; - gss_OID oid; -} ssh_gss_kex_mapping; - -static ssh_gss_kex_mapping **gss_enc2oid = NULL; - -static void ssh_gssapi_encode_oid_for_kex(const gss_OID oid, char **enc_name); -static char *ssh_gssapi_make_kexalgs_list(gss_OID_set mechs, - const char *old_kexalgs); - -/* - * Populate gss_enc2oid table and return list of kexnames. - * - * If called with both mechs == GSS_C_NULL_OID_SET and kexname_list == NULL - * then cached gss_enc2oid table is cleaned up. - */ -void -ssh_gssapi_mech_oids_to_kexnames(const gss_OID_set mechs, char **kexname_list) -{ - ssh_gss_kex_mapping **new_gss_enc2oid, **p; - Buffer buf; - char *enc_name; - int i; - - if (kexname_list != NULL) - *kexname_list = NULL; /* default to failed */ - - if (mechs != GSS_C_NULL_OID_SET || kexname_list == NULL) { - /* Cleanup gss_enc2oid table */ - for (p = gss_enc2oid; p != NULL && *p != NULL; p++) { - if ((*p)->encoded) - xfree((*p)->encoded); - ssh_gssapi_release_oid(&(*p)->oid); - xfree(*p); - } - if (gss_enc2oid) - xfree(gss_enc2oid); - } - - if (mechs == GSS_C_NULL_OID_SET && kexname_list == NULL) - return; /* nothing left to do */ - - if (mechs) { - gss_OID mech; - /* Populate gss_enc2oid table */ - new_gss_enc2oid = xmalloc(sizeof (ssh_gss_kex_mapping *) * - (mechs->count + 1)); - memset(new_gss_enc2oid, 0, - sizeof (ssh_gss_kex_mapping *) * (mechs->count + 1)); - - for (i = 0; i < mechs->count; i++) { - mech = &mechs->elements[i]; - ssh_gssapi_encode_oid_for_kex((const gss_OID)mech, - &enc_name); - - if (!enc_name) - continue; - - new_gss_enc2oid[i] = - xmalloc(sizeof (ssh_gss_kex_mapping)); - (new_gss_enc2oid[i])->encoded = enc_name; - (new_gss_enc2oid[i])->oid = - ssh_gssapi_dup_oid(&mechs->elements[i]); - } - - /* Do this last to avoid run-ins with fatal_cleanups */ - gss_enc2oid = new_gss_enc2oid; - } - - if (!kexname_list) - return; /* nothing left to do */ - - /* Make kex name list */ - buffer_init(&buf); - for (p = gss_enc2oid; p && *p; p++) { - buffer_put_char(&buf, ','); - buffer_append(&buf, (*p)->encoded, strlen((*p)->encoded)); - } - - if (buffer_len(&buf) == 0) { - buffer_free(&buf); - return; - } - - buffer_consume(&buf, 1); /* consume leading ',' */ - buffer_put_char(&buf, '\0'); - - *kexname_list = xstrdup(buffer_ptr(&buf)); - buffer_free(&buf); -} - -void -ssh_gssapi_mech_oid_to_kexname(const gss_OID mech, char **kexname) -{ - ssh_gss_kex_mapping **p; - - if (mech == GSS_C_NULL_OID || !kexname) - return; - - *kexname = NULL; /* default to not found */ - if (gss_enc2oid) { - for (p = gss_enc2oid; p && *p; p++) { - if (mech->length == (*p)->oid->length && - memcmp(mech->elements, (*p)->oid->elements, - mech->length) == 0) - *kexname = xstrdup((*p)->encoded); - } - } - - if (*kexname) - return; /* found */ - - ssh_gssapi_encode_oid_for_kex(mech, kexname); -} - -void -ssh_gssapi_oid_of_kexname(const char *kexname, gss_OID *mech) -{ - ssh_gss_kex_mapping **p; - - if (!mech || !kexname || !*kexname) - return; - - *mech = GSS_C_NULL_OID; /* default to not found */ - - if (!gss_enc2oid) - return; - - for (p = gss_enc2oid; p && *p; p++) { - if (strcmp(kexname, (*p)->encoded) == 0) { - *mech = (*p)->oid; - return; - } - } -} - -static -void -ssh_gssapi_encode_oid_for_kex(const gss_OID oid, char **enc_name) -{ - Buffer buf; - OM_uint32 oidlen; - uint_t enclen; - const EVP_MD *evp_md = EVP_md5(); - EVP_MD_CTX md; - uchar_t digest[EVP_MAX_MD_SIZE]; - char *encoded; - - if (oid == GSS_C_NULL_OID || !enc_name) - return; - - *enc_name = NULL; - - oidlen = oid->length; - - /* No GSS mechs have OIDs as long as 128 -- simplify DER encoding */ - if (oidlen > 128) - return; /* fail gracefully */ - - /* - * NOTE: If we need to support SSH_BUG_GSSAPI_BER this is where - * we'd do it. - * - * That means using "Se3H81ismmOC3OE+FwYCiQ==" for the Kerberos - * V mech and "N3+k7/4wGxHyuP8Yxi4RhA==" for the GSI mech. Ick. - */ - - buffer_init(&buf); - - /* UNIVERSAL class tag for OBJECT IDENTIFIER */ - buffer_put_char(&buf, 0x06); - buffer_put_char(&buf, oidlen); /* one octet DER length -- see above */ - - /* OID elements */ - buffer_append(&buf, oid->elements, oidlen); - - /* Make digest */ - EVP_DigestInit(&md, evp_md); - EVP_DigestUpdate(&md, buffer_ptr(&buf), buffer_len(&buf)); - EVP_DigestFinal(&md, digest, NULL); - buffer_free(&buf); - - /* Base 64 encoding */ - encoded = xmalloc(EVP_MD_size(evp_md)*2); - enclen = __b64_ntop(digest, EVP_MD_size(evp_md), - encoded, EVP_MD_size(evp_md) * 2); - buffer_init(&buf); - buffer_append(&buf, KEX_GSS_SHA1, sizeof (KEX_GSS_SHA1) - 1); - buffer_append(&buf, encoded, enclen); - buffer_put_char(&buf, '\0'); - - debug2("GSS-API Mechanism encoded as %s", encoded); - xfree(encoded); - - *enc_name = xstrdup(buffer_ptr(&buf)); - buffer_free(&buf); -} - -static char * -ssh_gssapi_make_kexalgs_list(gss_OID_set mechs, const char *old_kexalgs) -{ - char *gss_kexalgs, *new_kexalgs; - int len; - - if (mechs == GSS_C_NULL_OID_SET) - return (xstrdup(old_kexalgs)); /* never null */ - - ssh_gssapi_mech_oids_to_kexnames(mechs, &gss_kexalgs); - - if (gss_kexalgs == NULL || *gss_kexalgs == '\0') - return (xstrdup(old_kexalgs)); /* never null */ - - if (old_kexalgs == NULL || *old_kexalgs == '\0') - return (gss_kexalgs); - - len = strlen(old_kexalgs) + strlen(gss_kexalgs) + 2; - new_kexalgs = xmalloc(len); - (void) snprintf(new_kexalgs, len, "%s,%s", gss_kexalgs, old_kexalgs); - xfree(gss_kexalgs); - - return (new_kexalgs); -} - -void -ssh_gssapi_modify_kex(Kex *kex, gss_OID_set mechs, char **proposal) -{ - char *kexalgs, *orig_kexalgs, *p; - char **hostalg, *orig_hostalgs, *new_hostalgs; - char **hostalgs; - gss_OID_set dup_mechs; - OM_uint32 maj, min; - int i; - - if (kex == NULL || proposal == NULL || - proposal[PROPOSAL_KEX_ALGS] == NULL) { - fatal("INTERNAL ERROR (%s)", __func__); - } - - orig_hostalgs = proposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; - - if (kex->mechs == GSS_C_NULL_OID_SET && mechs == GSS_C_NULL_OID_SET) - return; /* didn't offer GSS last time, not offering now */ - - if (kex->mechs == GSS_C_NULL_OID_SET || mechs == GSS_C_NULL_OID_SET) - goto mod_offer; /* didn't offer last time or not offering now */ - - /* Check if mechs is congruent to kex->mechs (last offered) */ - if (kex->mechs->count == mechs->count) { - int present, matches = 0; - - for (i = 0; i < mechs->count; i++) { - maj = gss_test_oid_set_member(&min, - &kex->mechs->elements[i], mechs, &present); - - if (GSS_ERROR(maj)) { - mechs = GSS_C_NULL_OID_SET; - break; - } - - matches += (present) ? 1 : 0; - } - - if (matches == kex->mechs->count) - return; /* no change in offer from last time */ - } - -mod_offer: - /* - * Remove previously offered mechs from PROPOSAL_KEX_ALGS proposal - * - * ASSUMPTION: GSS-API kex algs always go in front, so removing - * them is a matter of skipping them. - */ - p = kexalgs = orig_kexalgs = proposal[PROPOSAL_KEX_ALGS]; - while (p != NULL && *p != '\0' && - strncmp(p, KEX_GSS_SHA1, strlen(KEX_GSS_SHA1)) == 0) { - - if ((p = strchr(p, ',')) == NULL) - break; - p++; - kexalgs = p; - - } - kexalgs = proposal[PROPOSAL_KEX_ALGS] = xstrdup(kexalgs); - xfree(orig_kexalgs); - - (void) gss_release_oid_set(&min, &kex->mechs); /* ok if !kex->mechs */ - - /* Not offering GSS kex algorithms now -> all done */ - if (mechs == GSS_C_NULL_OID_SET) - return; - - /* Remember mechs we're offering */ - maj = gss_create_empty_oid_set(&min, &dup_mechs); - if (GSS_ERROR(maj)) - return; - for (i = 0; i < mechs->count; i++) { - maj = gss_add_oid_set_member(&min, &mechs->elements[i], - &dup_mechs); - - if (GSS_ERROR(maj)) { - (void) gss_release_oid_set(&min, &dup_mechs); - return; - } - } - - /* Add mechs to kex algorithms ... */ - proposal[PROPOSAL_KEX_ALGS] = ssh_gssapi_make_kexalgs_list(mechs, - kexalgs); - xfree(kexalgs); - kex->mechs = dup_mechs; /* remember what we offer now */ - - /* - * ... and add null host key alg, if it wasn't there before, but - * not if we're the server and we have other host key algs to - * offer. - * - * NOTE: Never remove "null" host key alg once added. - */ - if (orig_hostalgs == NULL || *orig_hostalgs == '\0') { - proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = xstrdup("null"); - } else if (!kex->server) { - hostalgs = xsplit(orig_hostalgs, ','); - for (hostalg = hostalgs; *hostalg != NULL; hostalg++) { - if (strcmp(*hostalg, "null") == 0) { - xfree_split_list(hostalgs); - return; - } - } - xfree_split_list(hostalgs); - - if (kex->mechs != GSS_C_NULL_OID_SET) { - int len; - - len = strlen(orig_hostalgs) + sizeof (",null"); - new_hostalgs = xmalloc(len); - (void) snprintf(new_hostalgs, len, "%s,null", - orig_hostalgs); - proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = new_hostalgs; - } - - xfree(orig_hostalgs); - } -} - -/* - * Yes, we harcode OIDs for some things, for now it's all we can do. - * - * We have to reference particular mechanisms due to lack of generality - * in the GSS-API in several areas: authorization, mapping principal - * names to usernames, "storing" delegated credentials, and discovering - * whether a mechanism is a pseudo-mechanism that negotiates mechanisms. - * - * Even if they were in some header file or if __gss_mech_to_oid() - * and/or __gss_oid_to_mech() were standard we'd still have to hardcode - * the mechanism names, and since the mechanisms have no standard names - * other than their OIDs it's actually worse [less portable] to hardcode - * names than OIDs, so we hardcode OIDs. - * - * SPNEGO is a difficult problem though -- it MUST NOT be used in SSHv2, - * but that's true of all possible pseudo-mechanisms that can perform - * mechanism negotiation, and SPNEGO could have new OIDs in the future. - * Ideally we could query each mechanism for its feature set and then - * ignore any mechanisms that negotiate mechanisms, but, alas, there's - * no interface to do that. - * - * In the future, if the necessary generic GSS interfaces for the issues - * listed above are made available (even if they differ by platform, as - * we can expect authorization interfaces will), then we can stop - * referencing specific mechanism OIDs here. - */ -int -ssh_gssapi_is_spnego(gss_OID oid) -{ - return (oid->length == 6 && - memcmp("\053\006\001\005\005\002", oid->elements, 6) == 0); -} - -int -ssh_gssapi_is_krb5(gss_OID oid) -{ - return (oid->length == 9 && - memcmp("\x2A\x86\x48\x86\xF7\x12\x01\x02\x02", - oid->elements, 9) == 0); -} - -int -ssh_gssapi_is_dh(gss_OID oid) -{ - return (oid->length == 9 && - memcmp("\053\006\004\001\052\002\032\002\005", - oid->elements, 9) == 0); -} - -int -ssh_gssapi_is_gsi(gss_OID oid) -{ - return (oid->length == 9 && - memcmp("\x2B\x06\x01\x04\x01\x9B\x50\x01\x01", - oid->elements, 9) == 0); -} - -const char * -ssh_gssapi_oid_to_name(gss_OID oid) -{ -#ifdef HAVE_GSS_OID_TO_MECH - return (__gss_oid_to_mech(oid)); -#else - if (ssh_gssapi_is_krb5(oid)) - return ("Kerberos"); - if (ssh_gssapi_is_gsi(oid)) - return ("GSI"); - return ("(unknown)"); -#endif /* HAVE_GSS_OID_TO_MECH */ -} - -char * -ssh_gssapi_oid_to_str(gss_OID oid) -{ -#ifdef HAVE_GSS_OID_TO_STR - gss_buffer_desc str_buf; - char *str; - OM_uint32 maj, min; - - maj = gss_oid_to_str(&min, oid, &str_buf); - - if (GSS_ERROR(maj)) - return (xstrdup("<gss_oid_to_str() failed>")); - - str = xmalloc(str_buf.length + 1); - memset(str, 0, str_buf.length + 1); - strlcpy(str, str_buf.value, str_buf.length + 1); - (void) gss_release_buffer(&min, &str_buf); - - return (str); -#else - return (xstrdup("<gss_oid_to_str() unsupported>")); -#endif /* HAVE_GSS_OID_TO_STR */ -} - -/* Check that the OID in a data stream matches that in the context */ -int -ssh_gssapi_check_mech_oid(Gssctxt *ctx, void *data, size_t len) -{ - - return (ctx != NULL && ctx->desired_mech != GSS_C_NULL_OID && - ctx->desired_mech->length == len && - memcmp(ctx->desired_mech->elements, data, len) == 0); -} - -/* Set the contexts OID from a data stream */ -void -ssh_gssapi_set_oid_data(Gssctxt *ctx, void *data, size_t len) -{ - if (ctx->actual_mech != GSS_C_NULL_OID) { - xfree(ctx->actual_mech->elements); - xfree(ctx->actual_mech); - } - ctx->actual_mech = xmalloc(sizeof (gss_OID_desc)); - ctx->actual_mech->length = len; - ctx->actual_mech->elements = xmalloc(len); - memcpy(ctx->actual_mech->elements, data, len); -} - -/* Set the contexts OID */ -void -ssh_gssapi_set_oid(Gssctxt *ctx, gss_OID oid) -{ - ssh_gssapi_set_oid_data(ctx, oid->elements, oid->length); -} - -/* All this effort to report an error ... */ - -void -ssh_gssapi_error(Gssctxt *ctxt, const char *where) -{ - char *errmsg = ssh_gssapi_last_error(ctxt, NULL, NULL); - - if (where != NULL) - debug("GSS-API error while %s: %s", where, errmsg); - else - debug("GSS-API error: %s", errmsg); - - /* ssh_gssapi_last_error() can't return NULL */ - xfree(errmsg); -} - -char * -ssh_gssapi_last_error(Gssctxt *ctxt, OM_uint32 *major_status, - OM_uint32 *minor_status) -{ - OM_uint32 lmin, more; - OM_uint32 maj, min; - gss_OID mech = GSS_C_NULL_OID; - gss_buffer_desc msg; - Buffer b; - char *ret; - - buffer_init(&b); - - if (ctxt) { - /* Get status codes from the Gssctxt */ - maj = ctxt->major; - min = ctxt->minor; - /* Output them if desired */ - if (major_status) - *major_status = maj; - if (minor_status) - *minor_status = min; - /* Get mechanism for minor status display */ - mech = (ctxt->actual_mech != GSS_C_NULL_OID) ? - ctxt->actual_mech : ctxt->desired_mech; - } else if (major_status && minor_status) { - maj = *major_status; - min = *major_status; - } else { - maj = GSS_S_COMPLETE; - min = 0; - } - - more = 0; - /* The GSSAPI error */ - do { - gss_display_status(&lmin, maj, GSS_C_GSS_CODE, - GSS_C_NULL_OID, &more, &msg); - - buffer_append(&b, msg.value, msg.length); - buffer_put_char(&b, '\n'); - gss_release_buffer(&lmin, &msg); - } while (more != 0); - - /* The mechanism specific error */ - do { - /* - * If mech == GSS_C_NULL_OID we may get the default - * mechanism, whatever that is, and that may not be - * useful. - */ - gss_display_status(&lmin, min, GSS_C_MECH_CODE, mech, &more, - &msg); - - buffer_append(&b, msg.value, msg.length); - buffer_put_char(&b, '\n'); - - gss_release_buffer(&lmin, &msg); - } while (more != 0); - - buffer_put_char(&b, '\0'); - ret = xstrdup(buffer_ptr(&b)); - buffer_free(&b); - - return (ret); -} - -/* - * Initialise our GSSAPI context. We use this opaque structure to contain all - * of the data which both the client and server need to persist across - * {accept,init}_sec_context calls, so that when we do it from the userauth - * stuff life is a little easier - */ -void -ssh_gssapi_build_ctx(Gssctxt **ctx, int client, gss_OID mech) -{ - Gssctxt *newctx; - - - newctx = (Gssctxt*)xmalloc(sizeof (Gssctxt)); - memset(newctx, 0, sizeof (Gssctxt)); - - - newctx->local = client; - newctx->desired_mech = ssh_gssapi_dup_oid(mech); - - /* This happens to be redundant given the memset() above */ - newctx->major = GSS_S_COMPLETE; - newctx->context = GSS_C_NO_CONTEXT; - newctx->actual_mech = GSS_C_NULL_OID; - newctx->desired_name = GSS_C_NO_NAME; - newctx->src_name = GSS_C_NO_NAME; - newctx->dst_name = GSS_C_NO_NAME; - newctx->creds = GSS_C_NO_CREDENTIAL; - newctx->deleg_creds = GSS_C_NO_CREDENTIAL; - - newctx->default_creds = (*ctx != NULL) ? (*ctx)->default_creds : 0; - - ssh_gssapi_delete_ctx(ctx); - - *ctx = newctx; -} - -gss_OID -ssh_gssapi_dup_oid(gss_OID oid) -{ - gss_OID new_oid; - - new_oid = xmalloc(sizeof (gss_OID_desc)); - - new_oid->elements = xmalloc(oid->length); - new_oid->length = oid->length; - memcpy(new_oid->elements, oid->elements, oid->length); - - return (new_oid); -} - -gss_OID -ssh_gssapi_make_oid(size_t length, void *elements) -{ - gss_OID_desc oid; - - oid.length = length; - oid.elements = elements; - - return (ssh_gssapi_dup_oid(&oid)); -} - -void -ssh_gssapi_release_oid(gss_OID *oid) -{ - OM_uint32 min; - - if (oid && *oid == GSS_C_NULL_OID) - return; - (void) gss_release_oid(&min, oid); - - if (*oid == GSS_C_NULL_OID) - return; /* libgss did own this gss_OID and released it */ - - xfree((*oid)->elements); - xfree(*oid); - *oid = GSS_C_NULL_OID; -} - -struct gss_name { - gss_OID name_type; - gss_buffer_t external_name; - gss_OID mech_type; - void *mech_name; -}; - -/* Delete our context, providing it has been built correctly */ -void -ssh_gssapi_delete_ctx(Gssctxt **ctx) -{ - OM_uint32 ms; - - if ((*ctx) == NULL) - return; - - if ((*ctx)->context != GSS_C_NO_CONTEXT) - gss_delete_sec_context(&ms, &(*ctx)->context, GSS_C_NO_BUFFER); -#if 0 - /* XXX */ - if ((*ctx)->desired_mech != GSS_C_NULL_OID) - ssh_gssapi_release_oid(&(*ctx)->desired_mech); -#endif - if ((*ctx)->actual_mech != GSS_C_NULL_OID) - (void) ssh_gssapi_release_oid(&(*ctx)->actual_mech); - if ((*ctx)->desired_name != GSS_C_NO_NAME) - gss_release_name(&ms, &(*ctx)->desired_name); -#if 0 - if ((*ctx)->src_name != GSS_C_NO_NAME) - gss_release_name(&ms, &(*ctx)->src_name); -#endif - if ((*ctx)->dst_name != GSS_C_NO_NAME) - gss_release_name(&ms, &(*ctx)->dst_name); - if ((*ctx)->creds != GSS_C_NO_CREDENTIAL) - gss_release_cred(&ms, &(*ctx)->creds); - if ((*ctx)->deleg_creds != GSS_C_NO_CREDENTIAL) - gss_release_cred(&ms, &(*ctx)->deleg_creds); - - xfree(*ctx); - *ctx = NULL; -} - -/* Create a GSS hostbased service principal name for a given server hostname */ -int -ssh_gssapi_import_name(Gssctxt *ctx, const char *server_host) -{ - gss_buffer_desc name_buf; - int ret; - - /* Build target principal */ - name_buf.length = strlen(SSH_GSS_HOSTBASED_SERVICE) + - strlen(server_host) + 1; /* +1 for '@' */ - name_buf.value = xmalloc(name_buf.length + 1); /* +1 for NUL */ - ret = snprintf(name_buf.value, name_buf.length + 1, "%s@%s", - SSH_GSS_HOSTBASED_SERVICE, server_host); - - debug3("%s: snprintf() returned %d, expected %d", __func__, ret, - name_buf.length); - - ctx->major = gss_import_name(&ctx->minor, &name_buf, - GSS_C_NT_HOSTBASED_SERVICE, &ctx->desired_name); - - if (GSS_ERROR(ctx->major)) { - ssh_gssapi_error(ctx, "calling GSS_Import_name()"); - return (0); - } - - xfree(name_buf.value); - - return (1); -} - -OM_uint32 -ssh_gssapi_get_mic(Gssctxt *ctx, gss_buffer_desc *buffer, gss_buffer_desc *hash) -{ - - ctx->major = gss_get_mic(&ctx->minor, ctx->context, - GSS_C_QOP_DEFAULT, buffer, hash); - if (GSS_ERROR(ctx->major)) - ssh_gssapi_error(ctx, "while getting MIC"); - return (ctx->major); -} - -OM_uint32 -ssh_gssapi_verify_mic(Gssctxt *ctx, gss_buffer_desc *buffer, - gss_buffer_desc *hash) -{ - gss_qop_t qop; - - ctx->major = gss_verify_mic(&ctx->minor, ctx->context, buffer, - hash, &qop); - if (GSS_ERROR(ctx->major)) - ssh_gssapi_error(ctx, "while verifying MIC"); - return (ctx->major); -} -#endif /* GSSAPI */ |
