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

📄 gensec_gssapi.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 4 页
字号:
		DEBUG(1, ("Aquiring initiator credentials failed\n"));		return NT_STATUS_UNSUCCESSFUL;	}	gensec_gssapi_state->client_cred = gcc;	if (!talloc_reference(gensec_gssapi_state, gcc)) {		return NT_STATUS_NO_MEMORY;	}		return NT_STATUS_OK;}static NTSTATUS gensec_gssapi_sasl_client_start(struct gensec_security *gensec_security){	NTSTATUS nt_status;	struct gensec_gssapi_state *gensec_gssapi_state;	nt_status = gensec_gssapi_client_start(gensec_security);	if (NT_STATUS_IS_OK(nt_status)) {		gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);		gensec_gssapi_state->sasl = true;	}	return nt_status;}/** * Check if the packet is one for this mechansim *  * @param gensec_security GENSEC state * @param in The request, as a DATA_BLOB * @return Error, INVALID_PARAMETER if it's not a packet for us *                or NT_STATUS_OK if the packet is ok.  */static NTSTATUS gensec_gssapi_magic(struct gensec_security *gensec_security, 				    const DATA_BLOB *in) {	if (gensec_gssapi_check_oid(in, GENSEC_OID_KERBEROS5)) {		return NT_STATUS_OK;	} else {		return NT_STATUS_INVALID_PARAMETER;	}}/** * Next state function for the GSSAPI GENSEC mechanism *  * @param gensec_gssapi_state GSSAPI State * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on * @param in The request, as a DATA_BLOB * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent,  *                or NT_STATUS_OK if the user is authenticated.  */static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, 				   TALLOC_CTX *out_mem_ctx, 				   const DATA_BLOB in, DATA_BLOB *out) {	struct gensec_gssapi_state *gensec_gssapi_state		= talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);	NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;	OM_uint32 maj_stat, min_stat;	OM_uint32 min_stat2;	gss_buffer_desc input_token, output_token;	gss_OID gss_oid_p = NULL;	input_token.length = in.length;	input_token.value = in.data;	switch (gensec_gssapi_state->sasl_state) {	case STAGE_GSS_NEG:	{		switch (gensec_security->gensec_role) {		case GENSEC_CLIENT:		{			maj_stat = gss_init_sec_context(&min_stat, 							gensec_gssapi_state->client_cred->creds,							&gensec_gssapi_state->gssapi_context, 							gensec_gssapi_state->server_name, 							gensec_gssapi_state->gss_oid,							gensec_gssapi_state->want_flags, 							0, 							gensec_gssapi_state->input_chan_bindings,							&input_token, 							&gss_oid_p,							&output_token, 							&gensec_gssapi_state->got_flags, /* ret flags */							NULL);			if (gss_oid_p) {				gensec_gssapi_state->gss_oid = gss_oid_p;			}			break;		}		case GENSEC_SERVER:		{			maj_stat = gss_accept_sec_context(&min_stat, 							  &gensec_gssapi_state->gssapi_context, 							  gensec_gssapi_state->server_cred->creds,							  &input_token, 							  gensec_gssapi_state->input_chan_bindings,							  &gensec_gssapi_state->client_name, 							  &gss_oid_p,							  &output_token, 							  &gensec_gssapi_state->got_flags, 							  NULL, 							  &gensec_gssapi_state->delegated_cred_handle);			if (gss_oid_p) {				gensec_gssapi_state->gss_oid = gss_oid_p;			}			break;		}		default:			return NT_STATUS_INVALID_PARAMETER;					}		gensec_gssapi_state->gss_exchange_count++;		if (maj_stat == GSS_S_COMPLETE) {			*out = data_blob_talloc(out_mem_ctx, output_token.value, output_token.length);			gss_release_buffer(&min_stat2, &output_token);						if (gensec_gssapi_state->got_flags & GSS_C_DELEG_FLAG) {				DEBUG(5, ("gensec_gssapi: credentials were delegated\n"));			} else {				DEBUG(5, ("gensec_gssapi: NO credentials were delegated\n"));			}			/* We may have been invoked as SASL, so there			 * is more work to do */			if (gensec_gssapi_state->sasl) {				/* Due to a very subtle interaction				 * with SASL and the LDAP libs, we				 * must ensure the data pointer is 				 * != NULL, but the length is 0.  				 *				 * This ensures we send a 'zero				 * length' (rather than NULL) response 				 */								if (!out->data) {					out->data = (uint8_t *)talloc_strdup(out_mem_ctx, "\0");				}				gensec_gssapi_state->sasl_state = STAGE_SASL_SSF_NEG;				return NT_STATUS_MORE_PROCESSING_REQUIRED;			} else {				gensec_gssapi_state->sasl_state = STAGE_DONE;				if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {					DEBUG(5, ("GSSAPI Connection will be cryptographicly sealed\n"));				} else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {					DEBUG(5, ("GSSAPI Connection will be cryptographicly signed\n"));				} else {					DEBUG(5, ("GSSAPI Connection will have no cryptographic protection\n"));				}				return NT_STATUS_OK;			}		} else if (maj_stat == GSS_S_CONTINUE_NEEDED) {			*out = data_blob_talloc(out_mem_ctx, output_token.value, output_token.length);			gss_release_buffer(&min_stat2, &output_token);						return NT_STATUS_MORE_PROCESSING_REQUIRED;		} else if (gss_oid_equal(gensec_gssapi_state->gss_oid, gss_mech_krb5)) {			switch (min_stat) {			case KRB5_KDC_UNREACH:				DEBUG(3, ("Cannot reach a KDC we require: %s\n",					  gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));				return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */			case KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN:				DEBUG(3, ("Server is not registered with our KDC: %s\n", 					  gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));				return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */			case KRB5KRB_AP_ERR_MSG_TYPE:				/* garbage input, possibly from the auto-mech detection */				return NT_STATUS_INVALID_PARAMETER;			default:				DEBUG(1, ("GSS Update(krb5)(%d) Update failed: %s\n", 					  gensec_gssapi_state->gss_exchange_count,					  gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));				return nt_status;			}		} else {			DEBUG(1, ("GSS Update(%d) failed: %s\n", 				  gensec_gssapi_state->gss_exchange_count,				  gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));			return nt_status;		}		break;	}	/* These last two stages are only done if we were invoked as SASL */	case STAGE_SASL_SSF_NEG:	{		switch (gensec_security->gensec_role) {		case GENSEC_CLIENT:		{			uint8_t maxlength_proposed[4]; 			uint8_t maxlength_accepted[4]; 			uint8_t security_supported;			int conf_state;			gss_qop_t qop_state;			input_token.length = in.length;			input_token.value = in.data;			/* As a client, we have just send a			 * zero-length blob to the server (after the			 * normal GSSAPI exchange), and it has replied			 * with it's SASL negotiation */						maj_stat = gss_unwrap(&min_stat, 					      gensec_gssapi_state->gssapi_context, 					      &input_token,					      &output_token, 					      &conf_state,					      &qop_state);			if (GSS_ERROR(maj_stat)) {				DEBUG(1, ("gensec_gssapi_update: GSS UnWrap of SASL protection negotiation failed: %s\n", 					  gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));				return NT_STATUS_ACCESS_DENIED;			}						if (output_token.length < 4) {				return NT_STATUS_INVALID_PARAMETER;			}			memcpy(maxlength_proposed, output_token.value, 4);			gss_release_buffer(&min_stat, &output_token);			/* first byte is the proposed security */			security_supported = maxlength_proposed[0];			maxlength_proposed[0] = '\0';						/* Rest is the proposed max wrap length */			gensec_gssapi_state->max_wrap_buf_size = MIN(RIVAL(maxlength_proposed, 0), 								     gensec_gssapi_state->max_wrap_buf_size);			gensec_gssapi_state->sasl_protection = 0;			if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {				if (security_supported & NEG_SEAL) {					gensec_gssapi_state->sasl_protection |= NEG_SEAL;				}			} else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {				if (security_supported & NEG_SIGN) {					gensec_gssapi_state->sasl_protection |= NEG_SIGN;				}			} else if (security_supported & NEG_NONE) {				gensec_gssapi_state->sasl_protection |= NEG_NONE;			} else {				DEBUG(1, ("Remote server does not support unprotected connections"));				return NT_STATUS_ACCESS_DENIED;			}			/* Send back the negotiated max length */			RSIVAL(maxlength_accepted, 0, gensec_gssapi_state->max_wrap_buf_size);			maxlength_accepted[0] = gensec_gssapi_state->sasl_protection;						input_token.value = maxlength_accepted;			input_token.length = sizeof(maxlength_accepted);			maj_stat = gss_wrap(&min_stat, 					    gensec_gssapi_state->gssapi_context, 					    false,					    GSS_C_QOP_DEFAULT,					    &input_token,					    &conf_state,					    &output_token);			if (GSS_ERROR(maj_stat)) {				DEBUG(1, ("GSS Update(SSF_NEG): GSS Wrap failed: %s\n", 					  gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));				return NT_STATUS_ACCESS_DENIED;			}						*out = data_blob_talloc(out_mem_ctx, output_token.value, output_token.length);			gss_release_buffer(&min_stat, &output_token);			/* quirk:  This changes the value that gensec_have_feature returns, to be that after SASL negotiation */			gensec_gssapi_state->sasl_state = STAGE_DONE;			if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {				DEBUG(3, ("SASL/GSSAPI Connection to server will be cryptographicly sealed\n"));			} else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {				DEBUG(3, ("SASL/GSSAPI Connection to server will be cryptographicly signed\n"));			} else {				DEBUG(3, ("SASL/GSSAPI Connection to server will have no cryptographicly protection\n"));			}			return NT_STATUS_OK;		}		case GENSEC_SERVER:		{			uint8_t maxlength_proposed[4]; 			uint8_t security_supported = 0x0;			int conf_state;			/* As a server, we have just been sent a zero-length blob (note this, but it isn't fatal) */			if (in.length != 0) {				DEBUG(1, ("SASL/GSSAPI: client sent non-zero length starting SASL negotiation!\n"));			}						/* Give the client some idea what we will support */			  			RSIVAL(maxlength_proposed, 0, gensec_gssapi_state->max_wrap_buf_size);			/* first byte is the proposed security */			maxlength_proposed[0] = '\0';						gensec_gssapi_state->sasl_protection = 0;			if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {				security_supported |= NEG_SEAL;			} 			if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {				security_supported |= NEG_SIGN;			}			if (security_supported == 0) {				/* If we don't support anything, this must be 0 */				RSIVAL(maxlength_proposed, 0, 0x0);			}			/* TODO:  We may not wish to support this */			security_supported |= NEG_NONE;			maxlength_proposed[0] = security_supported;						input_token.value = maxlength_proposed;			input_token.length = sizeof(maxlength_proposed);			maj_stat = gss_wrap(&min_stat, 					    gensec_gssapi_state->gssapi_context, 					    false,					    GSS_C_QOP_DEFAULT,					    &input_token,					    &conf_state,					    &output_token);			if (GSS_ERROR(maj_stat)) {				DEBUG(1, ("GSS Update(SSF_NEG): GSS Wrap failed: %s\n", 					  gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));				return NT_STATUS_ACCESS_DENIED;			}						*out = data_blob_talloc(out_mem_ctx, output_token.value, output_token.length);			gss_release_buffer(&min_stat, &output_token);			gensec_gssapi_state->sasl_state = STAGE_SASL_SSF_ACCEPT;			return NT_STATUS_MORE_PROCESSING_REQUIRED;		}		default:  			return NT_STATUS_INVALID_PARAMETER;					}	}	/* This is s server-only stage */	case STAGE_SASL_SSF_ACCEPT:	{		uint8_t maxlength_accepted[4]; 		uint8_t security_accepted;		int conf_state;		gss_qop_t qop_state;		input_token.length = in.length;		input_token.value = in.data;					maj_stat = gss_unwrap(&min_stat, 				      gensec_gssapi_state->gssapi_context, 				      &input_token,				      &output_token, 				      &conf_state,				      &qop_state);		if (GSS_ERROR(maj_stat)) {			DEBUG(1, ("gensec_gssapi_update: GSS UnWrap of SASL protection negotiation failed: %s\n", 				  gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));			return NT_STATUS_ACCESS_DENIED;		}			

⌨️ 快捷键说明

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