Пример #1
0
static bool test_internal_dns_query_self(struct torture_context *tctx)
{
	struct dns_connection *conn;
	struct dns_request *req, *resp;
	char *host;
	DNS_ERROR err;

	conn = setup_connection(tctx);
	if (conn == NULL) {
		return false;
	}

	host = talloc_asprintf(tctx, "%s.%s", getenv("DC_SERVER"), get_dns_domain(tctx));
	if (host == NULL) {
		return false;
	}

	err = dns_create_query(conn, host, QTYPE_A, DNS_CLASS_IN, &req);
	if (!ERR_DNS_IS_OK(err)) {
		printf("Failed to create A record query\n");
		return false;
	}

	err = dns_transaction(conn, conn, req, &resp);
	if (!ERR_DNS_IS_OK(err)) {
		printf("Failed to query DNS server\n");
		return false;
	}

	if (dns_response_code(resp->flags) != DNS_NO_ERROR) {
		printf("Query returned %u\n", dns_response_code(resp->flags));
		return false;
	}

	/* FIXME: is there _any_ way to unmarshal the response to check this? */

	return true;
}
Пример #2
0
static DNS_ERROR dns_negotiate_gss_ctx_int( TALLOC_CTX *mem_ctx,
					    struct dns_connection *conn,
					    const char *keyname,
					    const gss_name_t target_name,
					    gss_ctx_id_t *ctx, 
					    enum dns_ServerType srv_type )
{
	struct gss_buffer_desc_struct input_desc, *input_ptr, output_desc;
	OM_uint32 major, minor;
	OM_uint32 ret_flags;
	DNS_ERROR err;

	gss_OID_desc krb5_oid_desc =
		{ 9, (const char *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" };

	*ctx = GSS_C_NO_CONTEXT;
	input_ptr = NULL;

	do {
		major = gss_init_sec_context(
			&minor, NULL, ctx, target_name, &krb5_oid_desc,
			GSS_C_REPLAY_FLAG | GSS_C_MUTUAL_FLAG |
			GSS_C_CONF_FLAG |
			GSS_C_INTEG_FLAG,
			0, NULL, input_ptr, NULL, &output_desc,
			&ret_flags, NULL );

		if (input_ptr != NULL) {
			TALLOC_FREE(input_desc.value);
		}

		if (output_desc.length != 0) {

			struct dns_request *req;
			struct dns_rrec *rec;
			struct dns_buffer *buf;

			time_t t = time(NULL);

			err = dns_create_query(mem_ctx, keyname, QTYPE_TKEY,
					       DNS_CLASS_IN, &req);
			if (!ERR_DNS_IS_OK(err)) goto error;

			err = dns_create_tkey_record(
				req, keyname, "gss.microsoft.com", t,
				t + 86400, DNS_TKEY_MODE_GSSAPI, 0,
				output_desc.length, (uint8 *)output_desc.value,
				&rec );
			if (!ERR_DNS_IS_OK(err)) goto error;

			/* Windows 2000 DNS is broken and requires the
			   TKEY payload in the Answer section instead
			   of the Additional seciton like Windows 2003 */

			if ( srv_type == DNS_SRV_WIN2000 ) {
				err = dns_add_rrec(req, rec, &req->num_answers,
						   &req->answers);
			} else {
				err = dns_add_rrec(req, rec, &req->num_additionals,
						   &req->additionals);
			}
			
			if (!ERR_DNS_IS_OK(err)) goto error;

			err = dns_marshall_request(req, req, &buf);
			if (!ERR_DNS_IS_OK(err)) goto error;

			err = dns_send(conn, buf);
			if (!ERR_DNS_IS_OK(err)) goto error;

			TALLOC_FREE(req);
		}

		gss_release_buffer(&minor, &output_desc);

		if ((major != GSS_S_COMPLETE) &&
		    (major != GSS_S_CONTINUE_NEEDED)) {
			return ERROR_DNS_GSS_ERROR;
		}

		if (major == GSS_S_CONTINUE_NEEDED) {

			struct dns_request *resp;
			struct dns_buffer *buf;
			struct dns_tkey_record *tkey;

			err = dns_receive(mem_ctx, conn, &buf);
			if (!ERR_DNS_IS_OK(err)) goto error;

			err = dns_unmarshall_request(buf, buf, &resp);
			if (!ERR_DNS_IS_OK(err)) goto error;

			/*
			 * TODO: Compare id and keyname
			 */
			
			if ((resp->num_additionals != 1) ||
			    (resp->num_answers == 0) ||
			    (resp->answers[0]->type != QTYPE_TKEY)) {
				err = ERROR_DNS_INVALID_MESSAGE;
				goto error;
			}

			err = dns_unmarshall_tkey_record(
				mem_ctx, resp->answers[0], &tkey);
			if (!ERR_DNS_IS_OK(err)) goto error;

			input_desc.length = tkey->key_length;
			input_desc.value = talloc_move(mem_ctx, &tkey->key);

			input_ptr = &input_desc;

			TALLOC_FREE(buf);
		}

	} while ( major == GSS_S_CONTINUE_NEEDED );

	/* If we arrive here, we have a valid security context */

	err = ERROR_DNS_SUCCESS;

      error:

	return err;
}