Esempio n. 1
0
/*
 * Extract the 'sesssion key' needed by SMB signing and ncacn_np 
 * (for encrypting some passwords).
 * 
 * This breaks all the abstractions, but what do you expect...
 */
static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_security, 
					  TALLOC_CTX *mem_ctx,
					  DATA_BLOB *session_key) 
{
	struct gensec_gssapi_state *gensec_gssapi_state
		= talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
	return gssapi_get_session_key(mem_ctx, gensec_gssapi_state->gssapi_context, session_key, NULL);
}
Esempio n. 2
0
size_t gssapi_get_sig_size(gss_ctx_id_t gssapi_context,
			   const gss_OID mech,
			   uint32_t gss_want_flags,
			   size_t data_size)
{
	TALLOC_CTX *frame = talloc_stackframe();
	size_t sig_size = 0;

	if (gss_want_flags & GSS_C_CONF_FLAG) {
		OM_uint32 min_stat, maj_stat;
		bool want_sealing = true;
		int sealed = 0;
		gss_iov_buffer_desc iov[2];

		if (!(gss_want_flags & GSS_C_DCE_STYLE)) {
			TALLOC_FREE(frame);
			return 0;
		}

		/*
		 * gss_wrap_iov_length() only needs the type and length
		 */
		iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER;
		iov[0].buffer.value = NULL;
		iov[0].buffer.length = 0;
		iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;
		iov[1].buffer.value = NULL;
		iov[1].buffer.length = data_size;

		maj_stat = gss_wrap_iov_length(&min_stat,
					       gssapi_context,
					       want_sealing,
					       GSS_C_QOP_DEFAULT,
					       &sealed,
					       iov, ARRAY_SIZE(iov));
		if (maj_stat) {
			DEBUG(0, ("gss_wrap_iov_length failed with [%s]\n",
				  gssapi_error_string(frame,
						      maj_stat,
						      min_stat,
						      mech)));
			TALLOC_FREE(frame);
			return 0;
		}

		sig_size = iov[0].buffer.length;
	} else if (gss_want_flags & GSS_C_INTEG_FLAG) {
		NTSTATUS status;
		uint32_t keytype;

		status = gssapi_get_session_key(frame,
						gssapi_context,
						NULL, &keytype);
		if (!NT_STATUS_IS_OK(status)) {
			TALLOC_FREE(frame);
			return 0;
		}

		switch (keytype) {
		case ENCTYPE_DES_CBC_MD5:
		case ENCTYPE_DES_CBC_CRC:
		case ENCTYPE_ARCFOUR_HMAC:
		case ENCTYPE_ARCFOUR_HMAC_EXP:
			sig_size = 37;
			break;
		default:
			sig_size = 28;
			break;
		}
	}

	TALLOC_FREE(frame);
	return sig_size;
}
Esempio n. 3
0
/* Try to figure out what features we actually got on the connection */
static bool gensec_gssapi_have_feature(struct gensec_security *gensec_security, 
				       uint32_t feature) 
{
	struct gensec_gssapi_state *gensec_gssapi_state
		= talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
	if (feature & GENSEC_FEATURE_SIGN) {
		/* If we are going GSSAPI SASL, then we honour the second negotiation */
		if (gensec_gssapi_state->sasl 
		    && gensec_gssapi_state->sasl_state == STAGE_DONE) {
			return ((gensec_gssapi_state->sasl_protection & NEG_SIGN) 
				&& (gensec_gssapi_state->gss_got_flags & GSS_C_INTEG_FLAG));
		}
		return gensec_gssapi_state->gss_got_flags & GSS_C_INTEG_FLAG;
	}
	if (feature & GENSEC_FEATURE_SEAL) {
		/* If we are going GSSAPI SASL, then we honour the second negotiation */
		if (gensec_gssapi_state->sasl 
		    && gensec_gssapi_state->sasl_state == STAGE_DONE) {
			return ((gensec_gssapi_state->sasl_protection & NEG_SEAL) 
				 && (gensec_gssapi_state->gss_got_flags & GSS_C_CONF_FLAG));
		}
		return gensec_gssapi_state->gss_got_flags & GSS_C_CONF_FLAG;
	}
	if (feature & GENSEC_FEATURE_SESSION_KEY) {
		/* Only for GSSAPI/Krb5 */
		if (smb_gss_oid_equal(gensec_gssapi_state->gss_oid,
				      gss_mech_krb5)) {
			return true;
		}
	}
	if (feature & GENSEC_FEATURE_DCE_STYLE) {
		return gensec_gssapi_state->gss_got_flags & GSS_C_DCE_STYLE;
	}
	if (feature & GENSEC_FEATURE_NEW_SPNEGO) {
		NTSTATUS status;
		uint32_t keytype;

		if (!(gensec_gssapi_state->gss_got_flags & GSS_C_INTEG_FLAG)) {
			return false;
		}

		if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "force_new_spnego", false)) {
			return true;
		}
		if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "disable_new_spnego", false)) {
			return false;
		}

		status = gssapi_get_session_key(gensec_gssapi_state,
						gensec_gssapi_state->gssapi_context, NULL, &keytype);
		/* 
		 * We should do a proper sig on the mechListMic unless
		 * we know we have to be backwards compatible with
		 * earlier windows versions.  
		 * 
		 * Negotiating a non-krb5
		 * mech for example should be regarded as having
		 * NEW_SPNEGO
		 */
		if (NT_STATUS_IS_OK(status)) {
			switch (keytype) {
			case ENCTYPE_DES_CBC_CRC:
			case ENCTYPE_DES_CBC_MD5:
			case ENCTYPE_ARCFOUR_HMAC:
			case ENCTYPE_DES3_CBC_SHA1:
				return false;
			}
		}
		return true;
	}
	/* We can always do async (rather than strict request/reply) packets.  */
	if (feature & GENSEC_FEATURE_ASYNC_REPLIES) {
		return true;
	}
	if (feature & GENSEC_FEATURE_SIGN_PKT_HEADER) {
		if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
			return true;
		}

		if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
			return true;
		}

		return false;
	}
	return false;
}