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

📄 gssapi.c

📁 代理服务器源代码 供大家学习使用,希望大家喜欢
💻 C
📖 第 1 页 / 共 4 页
字号:
	    	    name_without_realm.length = strlen( (char *) name_without_realm.value );	    	    maj_stat = (*p_krb5_gss_import_name) (&min_stat,					&name_without_realm,	    /* Solaris 8/9 gss_import_name doesn't accept GSS_C_NULL_OID here,	       so use GSS_C_NT_USER_NAME instead if available.  */#ifdef HAVE_GSS_C_NT_USER_NAME					GSS_C_NT_USER_NAME,#else					GSS_C_NULL_OID,#endif					&without);	    	    if (GSS_ERROR(maj_stat)) {		params->utils->free(name_without_realm.value);		if (name_token.value)		    (*p_krb5_gss_release_buffer)(&min_stat, &name_token);		if (without)		    (*p_krb5_gss_release_name)(&min_stat, &without);		SETERROR(text->utils, "GSSAPI Failure");		sasl_gss_free_context_contents(text);		return SASL_BADAUTH;	    }	    	    maj_stat = (*p_krb5_gss_compare_name)(&min_stat,					text->client_name,					without,					&equal);	    	    if (GSS_ERROR(maj_stat)) {		params->utils->free(name_without_realm.value);		if (name_token.value)		    (*p_krb5_gss_release_buffer)(&min_stat, &name_token);		if (without)		    (*p_krb5_gss_release_name)(&min_stat, &without);		SETERROR(text->utils, "GSSAPI Failure");		sasl_gss_free_context_contents(text);		return SASL_BADAUTH;	    }	    	    (*p_krb5_gss_release_name)(&min_stat,&without);	} else {	    equal = 0;	}		if (equal) {	    text->authid = strdup(name_without_realm.value);	    	    if (text->authid == NULL) {		MEMERROR(params->utils);		return SASL_NOMEM;	    }	} else {	    text->authid = strdup(name_token.value);	    	    if (text->authid == NULL) {		MEMERROR(params->utils);		return SASL_NOMEM;	    }	}		if (name_token.value)	    (*p_krb5_gss_release_buffer)(&min_stat, &name_token);	if (name_without_realm.value)	    params->utils->free(name_without_realm.value);			/* we have to decide what sort of encryption/integrity/etc.,	   we support */	if (params->props.max_ssf < params->external_ssf) {	    text->limitssf = 0;	} else {	    text->limitssf = params->props.max_ssf - params->external_ssf;	}	if (params->props.min_ssf < params->external_ssf) {	    text->requiressf = 0;	} else {	    text->requiressf = params->props.min_ssf - params->external_ssf;	}		/* build up our security properties token */        if (params->props.maxbufsize > 0xFFFFFF) {            /* make sure maxbufsize isn't too large */            /* maxbufsize = 0xFFFFFF */            sasldata[1] = sasldata[2] = sasldata[3] = 0xFF;        } else {            sasldata[1] = (params->props.maxbufsize >> 16) & 0xFF;            sasldata[2] = (params->props.maxbufsize >> 8) & 0xFF;            sasldata[3] = (params->props.maxbufsize >> 0) & 0xFF;        }	sasldata[0] = 0;	if(text->requiressf != 0 && !params->props.maxbufsize) {	    params->utils->seterror(params->utils->conn, 0,				    "GSSAPI needs a security layer but one is forbidden");	    return SASL_TOOWEAK;	}		if (text->requiressf == 0) {	    sasldata[0] |= 1; /* authentication */	}	if (text->requiressf <= 1 && text->limitssf >= 1	    && params->props.maxbufsize) {	    sasldata[0] |= 2;	}	if (text->requiressf <= K5_MAX_SSF && text->limitssf >= K5_MAX_SSF	    && params->props.maxbufsize) {	    sasldata[0] |= 4;	}		real_input_token.value = (void *)sasldata;	real_input_token.length = 4;		maj_stat = (*p_krb5_gss_wrap)(&min_stat,			    text->gss_ctx,			    0, /* Just integrity checking here */			    GSS_C_QOP_DEFAULT,			    input_token,			    NULL,			    output_token);		if (GSS_ERROR(maj_stat)) {	    sasl_gss_seterror(text->utils, maj_stat, min_stat);	    if (output_token->value)		(*p_krb5_gss_release_buffer)(&min_stat, output_token);	    sasl_gss_free_context_contents(text);	    return SASL_FAIL;	}			if (serveroutlen)	    *serveroutlen = output_token->length;	if (output_token->value) {	    if (serverout) {		ret = _plug_buf_alloc(text->utils, &(text->out_buf),				      &(text->out_buf_len), *serveroutlen);		if(ret != SASL_OK) {		    (*p_krb5_gss_release_buffer)(&min_stat, output_token);		    return ret;		}		memcpy(text->out_buf, output_token->value, *serveroutlen);		*serverout = text->out_buf;	    }	    	    (*p_krb5_gss_release_buffer)(&min_stat, output_token);	}		/* Wait for ssf request and authid */	text->state = SASL_GSSAPI_STATE_SSFREQ; 		return SASL_CONTINUE;    }    case SASL_GSSAPI_STATE_SSFREQ: {	int layerchoice;		real_input_token.value = (void *)clientin;	real_input_token.length = clientinlen;		maj_stat = (*p_krb5_gss_unwrap)(&min_stat,			      text->gss_ctx,			      input_token,			      output_token,			      NULL,			      NULL);		if (GSS_ERROR(maj_stat)) {	    sasl_gss_seterror(text->utils, maj_stat, min_stat);	    sasl_gss_free_context_contents(text);	    return SASL_FAIL;	}		layerchoice = (int)(((char *)(output_token->value))[0]);	if (layerchoice == 1 && text->requiressf == 0) { /* no encryption */	    oparams->encode = NULL;	    oparams->decode = NULL;	    oparams->mech_ssf = 0;	} else if (layerchoice == 2 && text->requiressf <= 1 &&		   text->limitssf >= 1) { /* integrity */	    oparams->encode=&gssapi_integrity_encode;	    oparams->decode=&gssapi_decode;	    oparams->mech_ssf=1;	} else if (layerchoice == 4 && text->requiressf <= K5_MAX_SSF &&		   text->limitssf >= K5_MAX_SSF) { /* privacy */	    oparams->encode = &gssapi_privacy_encode;	    oparams->decode = &gssapi_decode;	    /* FIX ME: Need to extract the proper value here */	    oparams->mech_ssf = K5_MAX_SSF;	} else {	    /* not a supported encryption layer */	    SETERROR(text->utils,		     "protocol violation: client requested invalid layer");	    /* Mark that we attempted negotiation */	    oparams->mech_ssf = 2;	    if (output_token->value)		(*p_krb5_gss_release_buffer)(&min_stat, output_token);	    sasl_gss_free_context_contents(text);	    return SASL_FAIL;	}		if (output_token->length > 4) {	    int ret;	    	    ret = params->canon_user(params->utils->conn,				     ((char *) output_token->value) + 4,				     (output_token->length - 4) * sizeof(char),				     SASL_CU_AUTHZID, oparams);	    	    if (ret != SASL_OK) {		sasl_gss_free_context_contents(text);		return ret;	    }	    	    ret = params->canon_user(params->utils->conn,				     text->authid,				     0, /* strlen(text->authid) */				     SASL_CU_AUTHID, oparams);	    if (ret != SASL_OK) {		sasl_gss_free_context_contents(text);		return ret;	    }	} else if(output_token->length == 4) {	    /* null authzid */	    int ret;	    	    ret = params->canon_user(params->utils->conn,				     text->authid,				     0, /* strlen(text->authid) */				     SASL_CU_AUTHZID | SASL_CU_AUTHID,				     oparams);	    	    if (ret != SASL_OK) {		sasl_gss_free_context_contents(text);		return ret;	    }	    	} else {	    SETERROR(text->utils,		     "token too short");	    (*p_krb5_gss_release_buffer)(&min_stat, output_token);	    sasl_gss_free_context_contents(text);	    return SASL_FAIL;	}			/* No matter what, set the rest of the oparams */	        oparams->maxoutbuf =	    (((unsigned char *) output_token->value)[1] << 16) |            (((unsigned char *) output_token->value)[2] << 8) |            (((unsigned char *) output_token->value)[3] << 0);	if (oparams->mech_ssf) { 	    maj_stat = (*p_krb5_gss_wrap_size_limit)(&min_stat,					    text->gss_ctx,					    1,					    GSS_C_QOP_DEFAULT,					    (OM_uint32) oparams->maxoutbuf,					    &max_input);	    if(max_input > oparams->maxoutbuf) {		/* Heimdal appears to get this wrong */		oparams->maxoutbuf -= (max_input - oparams->maxoutbuf);	    } else {		/* This code is actually correct */		oparams->maxoutbuf = max_input;	    }    	}		(*p_krb5_gss_release_buffer)(&min_stat, output_token);		text->state = SASL_GSSAPI_STATE_AUTHENTICATED;		/* used by layers */	_plug_decode_init(&text->decode_context, text->utils,			  (params->props.maxbufsize > 0xFFFFFF) ? 0xFFFFFF :			  params->props.maxbufsize);		oparams->doneflag = 1;		return SASL_OK;    }        default:	params->utils->log(NULL, SASL_LOG_ERR,			   "Invalid GSSAPI server step %d\n", text->state);	return SASL_FAIL;    }        return SASL_FAIL; /* should never get here */}static sasl_server_plug_t gssapi_server_plugins[] = {    {	"GSSAPI",			/* mech_name */	K5_MAX_SSF,			/* max_ssf */	SASL_SEC_NOPLAINTEXT	| SASL_SEC_NOACTIVE	| SASL_SEC_NOANONYMOUS	| SASL_SEC_MUTUAL_AUTH,		/* security_flags */	SASL_FEAT_WANT_CLIENT_FIRST	| SASL_FEAT_ALLOWS_PROXY,	/* features */	NULL,				/* glob_context */	&gssapi_server_mech_new,	/* mech_new */	&gssapi_server_mech_step,	/* mech_step */	&gssapi_common_mech_dispose,	/* mech_dispose */	NULL,				/* mech_free */	NULL,				/* setpass */	NULL,				/* user_query */	NULL,				/* idle */	NULL,				/* mech_avail */	NULL				/* spare */    }};int gssapiv2_server_plug_init(#ifndef HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY    const sasl_utils_t *utils __attribute__((unused)),#else    const sasl_utils_t *utils,#endif     int maxversion,    int *out_version,    sasl_server_plug_t **pluglist,    int *plugcount){#ifdef HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY    const char *keytab = NULL;    char keytab_path[1024];    unsigned int rl;#endif        if (maxversion < SASL_SERVER_PLUG_VERSION) {	return SASL_BADVERS;    }    #ifdef HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY    /* unfortunately, we don't check for readability of keytab if it's       the standard one, since we don't know where it is */        /* FIXME: This code is broken */        utils->getopt(utils->getopt_context, "GSSAPI", "keytab", &keytab, &rl);    if (keytab != NULL) {	if (access(keytab, R_OK) != 0) {	    utils->log(NULL, SASL_LOG_ERR,		       "Could not find keytab file: %s: %m",		       keytab, errno);	    return SASL_FAIL;	}		if(strlen(keytab) > 1024) {	    utils->log(NULL, SASL_LOG_ERR,		       "path to keytab is > 1024 characters");	    return SASL_BUFOVER;	}		strncpy(keytab_path, keytab, 1024);		gsskrb5_register_acceptor_identity(keytab_path);    }#endif        *out_version = SASL_SERVER_PLUG_VERSION;    *pluglist = gssapi_server_plugins;    *plugcount = 1;          return SASL_OK;}/*****************************  Client Section  *****************************/static int gssapi_client_mech_new(void *glob_context __attribute__((unused)), 				  sasl_client_params_t *params,				  void **conn_context){    context_t *text;        /* holds state are in */    text = gss_new_context(params->utils);    if (text == NULL) {	MEMERROR(params->utils);	return SASL_NOMEM;    }        text->state = SASL_GSSAPI_STATE_AUTHNEG;    text->gss_ctx = GSS_C_NO_CONTEXT;    text->client_name = GSS_C_NO_NAME;    text->server_creds = GSS_C_NO_CREDENTIAL;    *conn_context = text;        return SASL_OK;}static int gssapi_client_mech_step(void *conn_context,				   sasl_client_params_t *params,				   const char *serverin,				   unsigned serverinlen,				   sasl_interact_t **prompt_need,				   const char **clientout,				   unsigned *clientoutlen,				   sasl_out_params_t *oparams){    context_t *text = (context_t *)conn_context;    gss_buffer_t input_token, output_token;    gss_buffer_desc real_input_token, real_output_token;    OM_uint32 maj_stat = 0, min_stat = 0;    OM_uint32 max_input;    gss_buffer_desc name_token;    int ret;    OM_uint32 req_flags = 0, out_req_flags = 0;    input_token = &real_input_token;    output_token = &real_output_token;    output_token->value = NULL;    input_token->value = NULL;     input_token->length = 0;        *clientout = NULL;    *clientoutlen = 0;        if (sasl_gss_lib_init(text->utils) != SASL_OK) return SASL_FAIL;        switch (text->state) {    case SASL_GSSAPI_STATE_AUTHNEG:	/* try to get the userid */	if (text->user == NULL) {

⌨️ 快捷键说明

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