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

📄 gssapi.c

📁 代理服务器源代码 供大家学习使用,希望大家喜欢
💻 C
📖 第 1 页 / 共 4 页
字号:
	    int user_result = SASL_OK;	    	    user_result = _plug_get_userid(params->utils, &text->user,					   prompt_need);	    	    if ((user_result != SASL_OK) && (user_result != SASL_INTERACT)) {		sasl_gss_free_context_contents(text);		return user_result;	    }		    	    /* free prompts we got */	    if (prompt_need && *prompt_need) {		params->utils->free(*prompt_need);		*prompt_need = NULL;	    }		    	    /* if there are prompts not filled in */	    if (user_result == SASL_INTERACT) {		/* make the prompt list */		int result =		    _plug_make_prompts(params->utils, prompt_need,				       user_result == SASL_INTERACT ?				       "Please enter your authorization name" : NULL, NULL,				       NULL, NULL,				       NULL, NULL,				       NULL, NULL, NULL,				       NULL, NULL, NULL); 		if (result != SASL_OK) return result;				return SASL_INTERACT;	    }	}	    	if (text->server_name == GSS_C_NO_NAME) { /* only once */	    name_token.length = strlen(params->service) + 1 + strlen(params->serverFQDN);	    name_token.value = (char *)params->utils->malloc((name_token.length + 1) * sizeof(char));	    if (name_token.value == NULL) {		sasl_gss_free_context_contents(text);		return SASL_NOMEM;	    }	    if (params->serverFQDN == NULL		|| strlen(params->serverFQDN) == 0) {		SETERROR(text->utils, "GSSAPI Failure: no serverFQDN");		return SASL_FAIL;	    }	    	    sprintf(name_token.value,"%s@%s", params->service, params->serverFQDN);	    	    maj_stat = (*p_krb5_gss_import_name) (&min_stat,					&name_token,					GSS_C_NT_HOSTBASED_SERVICE,					&text->server_name);	    	    params->utils->free(name_token.value);	    name_token.value = NULL;	    	    if (GSS_ERROR(maj_stat)) {		sasl_gss_seterror(text->utils, maj_stat, min_stat);		sasl_gss_free_context_contents(text);		return SASL_FAIL;	    }	}	    	if (serverinlen == 0)	    input_token = GSS_C_NO_BUFFER;	if (serverinlen) {	    real_input_token.value = (void *)serverin;	    real_input_token.length = serverinlen;	}	else if (text->gss_ctx != GSS_C_NO_CONTEXT ) {	    /* This can't happen under GSSAPI: we have a non-null context	     * and no input from the server.  However, thanks to Imap,	     * which discards our first output, this happens all the time.	     * Throw away the context and try again. */	    maj_stat = (*p_krb5_gss_delete_sec_context) (&min_stat,&text->gss_ctx,GSS_C_NO_BUFFER);	    text->gss_ctx = GSS_C_NO_CONTEXT;	}	    	/* Setup req_flags properly */	req_flags = GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG;	if(params->props.max_ssf > params->external_ssf) {	    /* We are requesting a security layer */	    req_flags |= GSS_C_INTEG_FLAG;	    /* Any SSF bigger than 1 is confidentiality. */	    /* Let's check if the client of the API requires confidentiality,	       and it wasn't already provided by an external layer */	    if(params->props.max_ssf - params->external_ssf > 1) {		/* We want to try for privacy */		req_flags |= GSS_C_CONF_FLAG;	    }	}		maj_stat = (*p_krb5_gss_init_sec_context)(&min_stat,					GSS_C_NO_CREDENTIAL,					&text->gss_ctx,					text->server_name,					GSS_C_NO_OID,					req_flags,					0,					GSS_C_NO_CHANNEL_BINDINGS,					input_token,					NULL,					output_token,					&out_req_flags,					NULL);		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;	}	*clientoutlen = output_token->length;	    	if (output_token->value) {	    if (clientout) {		ret = _plug_buf_alloc(text->utils, &(text->out_buf),				      &(text->out_buf_len), *clientoutlen);		if(ret != SASL_OK) {		    (*p_krb5_gss_release_buffer)(&min_stat, output_token);		    return ret;		}		memcpy(text->out_buf, output_token->value, *clientoutlen);		*clientout = text->out_buf;	    }	    	    (*p_krb5_gss_release_buffer)(&min_stat, output_token);	}		if (maj_stat == GSS_S_COMPLETE) {	    maj_stat = (*p_krb5_gss_inquire_context)(&min_stat,					   text->gss_ctx,					   &text->client_name,					   NULL,       /* targ_name */					   NULL,       /* lifetime */					   NULL,       /* mech */					   /* FIX ME: Should check the resulting flags here */					   NULL,       /* flags */					   NULL,       /* local init */					   NULL);      /* open */	    	    if (GSS_ERROR(maj_stat)) {		sasl_gss_seterror(text->utils, maj_stat, min_stat);		sasl_gss_free_context_contents(text);		return SASL_FAIL;	    }	    	    name_token.length = 0;	    maj_stat = (*p_krb5_gss_display_name)(&min_stat,					text->client_name,					&name_token,					NULL);	    	    if (GSS_ERROR(maj_stat)) {		if (name_token.value)		    (*p_krb5_gss_release_buffer)(&min_stat, &name_token);		SETERROR(text->utils, "GSSAPI Failure");		sasl_gss_free_context_contents(text);		return SASL_FAIL;	    }	    	    if (text->user && text->user[0]) {		ret = params->canon_user(params->utils->conn,					 text->user, 0,					 SASL_CU_AUTHZID, oparams);		if (ret == SASL_OK) 		    ret = params->canon_user(params->utils->conn,					     name_token.value, 0,					     SASL_CU_AUTHID, oparams);	    } else {		ret = params->canon_user(params->utils->conn,					 name_token.value, 0,					 SASL_CU_AUTHID | SASL_CU_AUTHZID,					 oparams);	    }	    (*p_krb5_gss_release_buffer)(&min_stat, &name_token);	     	    if (ret != SASL_OK) return ret;	    	    /* Switch to ssf negotiation */	    text->state = SASL_GSSAPI_STATE_SSFCAP;	}		return SASL_CONTINUE;    case SASL_GSSAPI_STATE_SSFCAP: {	sasl_security_properties_t *secprops = &(params->props);	unsigned int alen, external = params->external_ssf;	sasl_ssf_t need, allowed;	char serverhas, mychoice;		real_input_token.value = (void *) serverin;	real_input_token.length = serverinlen;		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);	    if (output_token->value)		(*p_krb5_gss_release_buffer)(&min_stat, output_token);	    return SASL_FAIL;	}		/* taken from kerberos.c */	if (secprops->min_ssf > (K5_MAX_SSF + external)) {	    return SASL_TOOWEAK;	} else if (secprops->min_ssf > secprops->max_ssf) {	    return SASL_BADPARAM;	}		/* need bits of layer -- sasl_ssf_t is unsigned so be careful */	if (secprops->max_ssf >= external) {	    allowed = secprops->max_ssf - external;	} else {	    allowed = 0;	}	if (secprops->min_ssf >= external) {	    need = secprops->min_ssf - external;	} else {	    /* good to go */	    need = 0;	}		/* bit mask of server support */	serverhas = ((char *)output_token->value)[0];		/* if client didn't set use strongest layer available */	if (allowed >= K5_MAX_SSF && need <= K5_MAX_SSF && (serverhas & 4)) {	    /* encryption */	    oparams->encode = &gssapi_privacy_encode;	    oparams->decode = &gssapi_decode;	    /* FIX ME: Need to extract the proper value here */	    oparams->mech_ssf = K5_MAX_SSF;	    mychoice = 4;	} else if (allowed >= 1 && need <= 1 && (serverhas & 2)) {	    /* integrity */	    oparams->encode = &gssapi_integrity_encode;	    oparams->decode = &gssapi_decode;	    oparams->mech_ssf = 1;	    mychoice = 2;	} else if (need <= 0 && (serverhas & 1)) {	    /* no layer */	    oparams->encode = NULL;	    oparams->decode = NULL;	    oparams->mech_ssf = 0;	    mychoice = 1;	} else {	    /* there's no appropriate layering for us! */	    sasl_gss_free_context_contents(text);	    return SASL_TOOWEAK;	}	        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);		/* oparams->user is always set, due to canon_user requirements.	 * Make sure the client actually requested it though, by checking	 * if our context was set.	 */	if (text->user && text->user[0])	    alen = strlen(oparams->user);	else	    alen = 0;		input_token->length = 4 + alen;	input_token->value =	    (char *)params->utils->malloc((input_token->length + 1)*sizeof(char));	if (input_token->value == NULL) {	    sasl_gss_free_context_contents(text);	    return SASL_NOMEM;	}		if (alen)	    memcpy((char *)input_token->value+4,oparams->user,alen);	/* build up our security properties token */        if (params->props.maxbufsize > 0xFFFFFF) {            /* make sure maxbufsize isn't too large */            /* maxbufsize = 0xFFFFFF */            ((unsigned char *)input_token->value)[1] = 0xFF;            ((unsigned char *)input_token->value)[2] = 0xFF;            ((unsigned char *)input_token->value)[3] = 0xFF;        } else {            ((unsigned char *)input_token->value)[1] =                 (params->props.maxbufsize >> 16) & 0xFF;            ((unsigned char *)input_token->value)[2] =                 (params->props.maxbufsize >> 8) & 0xFF;            ((unsigned char *)input_token->value)[3] =                 (params->props.maxbufsize >> 0) & 0xFF;        }	((unsigned char *)input_token->value)[0] = mychoice;		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);		params->utils->free(input_token->value);	input_token->value = NULL;		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 (clientoutlen)	    *clientoutlen = output_token->length;	if (output_token->value) {	    if (clientout) {		ret = _plug_buf_alloc(text->utils, &(text->out_buf),				      &(text->out_buf_len), *clientoutlen);		if (ret != SASL_OK) {		   (*p_krb5_gss_release_buffer)(&min_stat, output_token);		    return ret;		}		memcpy(text->out_buf, output_token->value, *clientoutlen);		*clientout = text->out_buf;	    }	    	    (*p_krb5_gss_release_buffer)(&min_stat, output_token);	}		text->state = SASL_GSSAPI_STATE_AUTHENTICATED;		oparams->doneflag = 1;		/* used by layers */	_plug_decode_init(&text->decode_context, text->utils,			  (params->props.maxbufsize > 0xFFFFFF) ? 0xFFFFFF :			  params->props.maxbufsize);		return SASL_OK;    }	    default:	params->utils->log(NULL, SASL_LOG_ERR,			   "Invalid GSSAPI client step %d\n", text->state);	return SASL_FAIL;    }        return SASL_FAIL; /* should never get here */}static const unsigned long gssapi_required_prompts[] = {    SASL_CB_LIST_END};  static sasl_client_plug_t gssapi_client_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_NEEDSERVERFQDN	| SASL_FEAT_WANT_CLIENT_FIRST	| SASL_FEAT_ALLOWS_PROXY,	/* features */	gssapi_required_prompts,	/* required_prompts */	NULL,				/* glob_context */	&gssapi_client_mech_new,	/* mech_new */	&gssapi_client_mech_step,	/* mech_step */	&gssapi_common_mech_dispose,	/* mech_dispose */	NULL,				/* mech_free */	NULL,				/* idle */	NULL,				/* spare */	NULL				/* spare */    }};int gssapiv2_client_plug_init(const sasl_utils_t *utils __attribute__((unused)), 			      int maxversion,			      int *out_version, 			      sasl_client_plug_t **pluglist,			      int *plugcount){    if (maxversion < SASL_CLIENT_PLUG_VERSION) {	SETERROR(utils, "Version mismatch in GSSAPI");	return SASL_BADVERS;    }        *out_version = SASL_CLIENT_PLUG_VERSION;    *pluglist = gssapi_client_plugins;    *plugcount = 1;        return SASL_OK;}#endif

⌨️ 快捷键说明

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