⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gssapi.c

📁 代理服务器源代码 供大家学习使用,希望大家喜欢
💻 C
📖 第 1 页 / 共 4 页
字号:
#ifdef BUILD_GSSAPI_PLUGIN/* GSSAPI SASL plugin * Leif Johansson * Rob Siemborski (SASL v2 Conversion) * $Id$ *//*  * Copyright (c) 1998-2003 Carnegie Mellon University.  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. * * 3. The name "Carnegie Mellon University" must not be used to *    endorse or promote products derived from this software without *    prior written permission. For permission or any other legal *    details, please contact   *      Office of Technology Transfer *      Carnegie Mellon University *      5000 Forbes Avenue *      Pittsburgh, PA  15213-3890 *      (412) 268-4387, fax: (412) 268-7395 *      tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following *    acknowledgment: *    "This product includes software developed by Computing Services *     at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */#include <stdlib.h>#include <string.h>#include <dlfcn.h>#ifdef HAVE_GSSAPI_H#include <gssapi.h>#else#include <gssapi/gssapi.h>#endif#ifdef WIN32#  include <winsock2.h>#  ifndef R_OK#    define R_OK 04#  endif/* we also need io.h for access() prototype */#  include <io.h>#else#  include <sys/param.h>#  include <sys/socket.h>#  include <netinet/in.h>#  include <arpa/inet.h>#  include <netdb.h>#endif /* WIN32 */#include <fcntl.h>#include <stdio.h>#include <sys/uio.h>#include <sasl.h>#include <saslutil.h>#include <saslplug.h>#include "plugin_common.h"#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#include <errno.h>/*****************************  Common Section  *****************************/static const char plugin_id[] = "$Id$";static const char * GSSAPI_BLANK_STRING = "";#ifndef HAVE_GSS_C_NT_HOSTBASED_SERVICEextern gss_OID gss_nt_service_name;#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name#endif#ifdef WANT_KERBEROS5_3DES/* Check if CyberSafe flag is defined */#ifdef CSF_GSS_C_DES3_FLAG#define K5_MAX_SSF	112#endif/* Heimdal and MIT use the following */#ifdef GSS_KRB5_CONF_C_QOP_DES3_KD#define K5_MAX_SSF	112#endif#endif#ifndef K5_MAX_SSF/* All Kerberos implementations support DES */#define K5_MAX_SSF	56#endif/* GSSAPI SASL Mechanism by Leif Johansson <leifj@matematik.su.se> * inspired by the kerberos mechanism and the gssapi_server and * gssapi_client from the heimdal distribution by Assar Westerlund * <assar@sics.se> and Johan Danielsson <joda@pdc.kth.se>.  * See the configure.in file for details on dependencies. * * Important contributions from Sam Hartman <hartmans@fundsxpress.com>. * * This code was tested with the following distributions of Kerberos: * Heimdal (http://www.pdc.kth.se/heimdal), MIT (http://web.mit.edu/kerberos/www/) * CyberSafe (http://www.cybersafe.com/) and SEAM. */typedef struct context {    int state;        gss_ctx_id_t gss_ctx;    gss_name_t   client_name;    gss_name_t   server_name;    gss_cred_id_t server_creds;    sasl_ssf_t limitssf, requiressf; /* application defined bounds, for the					server */    const sasl_utils_t *utils;        /* layers buffering */    decode_context_t decode_context;        char *encode_buf;                /* For encoding/decoding mem management */    char *decode_buf;    char *decode_once_buf;    unsigned encode_buf_len;    unsigned decode_buf_len;    unsigned decode_once_buf_len;    buffer_info_t *enc_in_buf;        char *out_buf;                   /* per-step mem management */    unsigned out_buf_len;            char *authid; /* hold the authid between steps - server */    const char *user;   /* hold the userid between steps - client */} context_t;enum {    SASL_GSSAPI_STATE_AUTHNEG = 1,    SASL_GSSAPI_STATE_SSFCAP = 2,    SASL_GSSAPI_STATE_SSFREQ = 3,    SASL_GSSAPI_STATE_AUTHENTICATED = 4};/* sasl_gss_log: only logs status string returned from gss_display_status() */#define sasl_gss_log(x,y,z) sasl_gss_seterror_(x,y,z,1)#define sasl_gss_seterror(x,y,z) sasl_gss_seterror_(x,y,z,0)/* Force use of Kerberos v5 GSSAPI library functions even when linked   with GSI GSSAPI libraries. */#ifndef KRB5_LIB_NAME#define KRB5_LIB_NAME "libgssapi_krb5.so"#endif /* KRB5_LIB_NAME */static void *h_krb5lib;static OM_uint32 (*p_krb5_gss_accept_sec_context)    (OM_uint32 *, gss_ctx_id_t *, gss_cred_id_t, gss_buffer_t,     gss_channel_bindings_t, gss_name_t *, gss_OID *, gss_buffer_t,     OM_uint32 *, OM_uint32 *, gss_cred_id_t *);static OM_uint32 (*p_krb5_gss_acquire_cred)    (OM_uint32 *, gss_name_t, OM_uint32, gss_OID_set, gss_cred_usage_t,     gss_cred_id_t *, gss_OID_set *, OM_uint32 *);static OM_uint32 (*p_krb5_gss_compare_name)    (OM_uint32 *, gss_name_t, gss_name_t, int *);static OM_uint32 (*p_krb5_gss_delete_sec_context)    (OM_uint32 *, gss_ctx_id_t *, gss_buffer_t);static OM_uint32 (*p_krb5_gss_display_name)    (OM_uint32 *, gss_name_t, gss_buffer_t, gss_OID *);static OM_uint32 (*p_krb5_gss_display_status)    (OM_uint32 *, OM_uint32, int, gss_OID, OM_uint32 *, gss_buffer_t);static OM_uint32 (*p_krb5_gss_import_name)    (OM_uint32 *, gss_buffer_t, gss_OID, gss_name_t *);static OM_uint32 (*p_krb5_gss_init_sec_context)    (OM_uint32 *, const gss_cred_id_t, gss_ctx_id_t *, const gss_name_t,     const gss_OID, OM_uint32, OM_uint32, const gss_channel_bindings_t,     const gss_buffer_t, gss_OID *, gss_buffer_t, OM_uint32 *, OM_uint32 *);static OM_uint32 (*p_krb5_gss_inquire_context)    (OM_uint32 *, gss_ctx_id_t, gss_name_t *, gss_name_t *,     OM_uint32 *, gss_OID *, OM_uint32 *, int *, int *);static OM_uint32 (*p_krb5_gss_release_buffer)(OM_uint32 *, gss_buffer_t);static OM_uint32 (*p_krb5_gss_release_cred)    (OM_uint32 *, gss_cred_id_t *);static OM_uint32 (*p_krb5_gss_release_name)(OM_uint32 *, gss_name_t *);static OM_uint32 (*p_krb5_gss_unwrap)    (OM_uint32 *, gss_ctx_id_t, gss_buffer_t, gss_buffer_t, int *,     gss_qop_t *);static OM_uint32 (*p_krb5_gss_wrap)    (OM_uint32 *, gss_ctx_id_t, int, gss_qop_t, gss_buffer_t, int *,     gss_buffer_t);static OM_uint32 (*p_krb5_gss_wrap_size_limit)    (OM_uint32 *, gss_ctx_id_t, int, gss_qop_t, OM_uint32, OM_uint32 *);static intsasl_gss_lib_init(const sasl_utils_t *utils){    char *errmsg=NULL, *dlerr=NULL;    if (h_krb5lib) return SASL_OK;    if ((h_krb5lib = dlopen(KRB5_LIB_NAME, RTLD_LAZY)) == NULL) {	errmsg = "Failed to open GSSAPI library";	goto error;    }#define SASL_GSS_DLSYM(x)						\    p_krb5_ ## x = dlsym(h_krb5lib, #x);				\    if (p_krb5_ ## x == NULL) {						\	errmsg = "Failed to dlsym(" #x ")";				\	goto error;							\    }    SASL_GSS_DLSYM(gss_accept_sec_context);    SASL_GSS_DLSYM(gss_acquire_cred);    SASL_GSS_DLSYM(gss_compare_name);    SASL_GSS_DLSYM(gss_delete_sec_context);    SASL_GSS_DLSYM(gss_display_name);    SASL_GSS_DLSYM(gss_display_status);    SASL_GSS_DLSYM(gss_import_name);    SASL_GSS_DLSYM(gss_init_sec_context);    SASL_GSS_DLSYM(gss_inquire_context);    SASL_GSS_DLSYM(gss_release_buffer);    SASL_GSS_DLSYM(gss_release_cred);    SASL_GSS_DLSYM(gss_release_name);    SASL_GSS_DLSYM(gss_unwrap);    SASL_GSS_DLSYM(gss_wrap);    SASL_GSS_DLSYM(gss_wrap_size_limit);    return SASL_OK; error:    dlerr = dlerror();    if (dlerr) {	char *saslerr;	saslerr = malloc(strlen(errmsg)+strlen(dlerr)+3);	sprintf(saslerr, "%s: %s", errmsg, dlerr);	SETERROR(utils, saslerr);	free(saslerr);    } else {	SETERROR(utils, errmsg);    }    if (h_krb5lib) {	dlclose(h_krb5lib);	h_krb5lib = NULL;    }    return SASL_FAIL;}static voidsasl_gss_seterror_(const sasl_utils_t *utils, OM_uint32 maj, OM_uint32 min,	int logonly){    OM_uint32 maj_stat, min_stat;    gss_buffer_desc msg;    OM_uint32 msg_ctx;    int ret;    char *out = NULL;    size_t len, curlen = 0;    const char prefix[] = "GSSAPI Error: ";        if(!utils) return;    if (sasl_gss_lib_init(utils) != SASL_OK) return;        len = sizeof(prefix);    ret = _plug_buf_alloc(utils, &out, &curlen, 256);    if(ret != SASL_OK) return;        strcpy(out, prefix);        msg_ctx = 0;    while (1) {	maj_stat = (*p_krb5_gss_display_status)(&min_stat, maj,				      GSS_C_GSS_CODE, GSS_C_NULL_OID,				      &msg_ctx, &msg);	if(GSS_ERROR(maj_stat)) {	    if (logonly) {		utils->log(utils->conn, SASL_LOG_FAIL,			"GSSAPI Failure: (could not get major error message)");	    } else {		utils->seterror(utils->conn, 0,				"GSSAPI Failure "				"(could not get major error message)");	    }	    utils->free(out);	    return;	}		len += len + msg.length;	ret = _plug_buf_alloc(utils, &out, &curlen, len);		if(ret != SASL_OK) {	    utils->free(out);	    return;	}		strcat(out, msg.value);		(*p_krb5_gss_release_buffer)(&min_stat, &msg);		if (!msg_ctx)	    break;    }        /* Now get the minor status */        len += 2;    ret = _plug_buf_alloc(utils, &out, &curlen, len);    if(ret != SASL_OK) {	utils->free(out);	return;    }        strcat(out, " (");        msg_ctx = 0;    while (1) {	maj_stat = (*p_krb5_gss_display_status)(&min_stat, min,				      GSS_C_MECH_CODE, GSS_C_NULL_OID,				      &msg_ctx, &msg);	if(GSS_ERROR(maj_stat)) {	    if (logonly) {		utils->log(utils->conn, SASL_LOG_FAIL,			"GSSAPI Failure: (could not get minor error message)");	    } else {		utils->seterror(utils->conn, 0,				"GSSAPI Failure "				"(could not get minor error message)");	    }	    utils->free(out);	    return;	}		len += len + msg.length;	ret = _plug_buf_alloc(utils, &out, &curlen, len);		if(ret != SASL_OK) {	    utils->free(out);	    return;	}		strcat(out, msg.value);		(*p_krb5_gss_release_buffer)(&min_stat, &msg);		if (!msg_ctx)	    break;    }        len += 1;    ret = _plug_buf_alloc(utils, &out, &curlen, len);    if(ret != SASL_OK) {	utils->free(out);	return;    }        strcat(out, ")");        if (logonly) {	utils->log(utils->conn, SASL_LOG_FAIL, out);    } else {	utils->seterror(utils->conn, 0, out);    }    utils->free(out);}static int sasl_gss_encode(void *context, const struct iovec *invec, unsigned numiov,		const char **output, unsigned *outputlen, int privacy){    context_t *text = (context_t *)context;    OM_uint32 maj_stat, min_stat;    gss_buffer_t input_token, output_token;    gss_buffer_desc real_input_token, real_output_token;    int ret;    struct buffer_info *inblob, bufinfo;        if(!output) return SASL_BADPARAM;        if (sasl_gss_lib_init(text->utils) != SASL_OK) return SASL_FAIL;        if(numiov > 1) {	ret = _plug_iovec_to_buf(text->utils, invec, numiov, &text->enc_in_buf);	if(ret != SASL_OK) return ret;	inblob = text->enc_in_buf;    } else {	bufinfo.data = invec[0].iov_base;	bufinfo.curlen = invec[0].iov_len;	inblob = &bufinfo;    }        if (text->state != SASL_GSSAPI_STATE_AUTHENTICATED) return SASL_NOTDONE;        input_token = &real_input_token;        real_input_token.value  = inblob->data;    real_input_token.length = inblob->curlen;        output_token = &real_output_token;    output_token->value = NULL;    output_token->length = 0;        maj_stat = (*p_krb5_gss_wrap) (&min_stat,			 text->gss_ctx,			 privacy,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -