Beispiel #1
0
static bool write_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token)
{
	asn1_push_tag(asn1, ASN1_CONTEXT(1));
	asn1_push_tag(asn1, ASN1_SEQUENCE(0));

	asn1_push_tag(asn1, ASN1_CONTEXT(0));
	asn1_write_enumerated(asn1, token->negResult);
	asn1_pop_tag(asn1);

	if (token->supportedMech) {
		asn1_push_tag(asn1, ASN1_CONTEXT(1));
		asn1_write_OID(asn1, token->supportedMech);
		asn1_pop_tag(asn1);
	}

	if (token->responseToken.data) {
		asn1_push_tag(asn1, ASN1_CONTEXT(2));
		asn1_write_OctetString(asn1, token->responseToken.data,
				       token->responseToken.length);
		asn1_pop_tag(asn1);
	}

	if (token->mechListMIC.data) {
		asn1_push_tag(asn1, ASN1_CONTEXT(3));
		asn1_write_OctetString(asn1, token->mechListMIC.data,
				      token->mechListMIC.length);
		asn1_pop_tag(asn1);
	}

	asn1_pop_tag(asn1);
	asn1_pop_tag(asn1);

	return !asn1->has_error;
}
Beispiel #2
0
/*
  generate a minimal SPNEGO response packet.  Doesn't contain much.
*/
DATA_BLOB spnego_gen_auth_response_and_mic(TALLOC_CTX *ctx,
        NTSTATUS nt_status,
        const char *mechOID,
        DATA_BLOB *reply,
        DATA_BLOB *mechlistMIC)
{
    ASN1_DATA *data;
    DATA_BLOB ret;
    uint8 negResult;

    if (NT_STATUS_IS_OK(nt_status)) {
        negResult = SPNEGO_ACCEPT_COMPLETED;
    } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
        negResult = SPNEGO_ACCEPT_INCOMPLETE;
    } else {
        negResult = SPNEGO_REJECT;
    }

    data = asn1_init(talloc_tos());
    if (data == NULL) {
        return data_blob_null;
    }

    asn1_push_tag(data, ASN1_CONTEXT(1));
    asn1_push_tag(data, ASN1_SEQUENCE(0));
    asn1_push_tag(data, ASN1_CONTEXT(0));
    asn1_write_enumerated(data, negResult);
    asn1_pop_tag(data);

    if (mechOID) {
        asn1_push_tag(data,ASN1_CONTEXT(1));
        asn1_write_OID(data, mechOID);
        asn1_pop_tag(data);
    }

    if (reply && reply->data != NULL) {
        asn1_push_tag(data,ASN1_CONTEXT(2));
        asn1_write_OctetString(data, reply->data, reply->length);
        asn1_pop_tag(data);
    }

    if (mechlistMIC && mechlistMIC->data != NULL) {
        asn1_push_tag(data, ASN1_CONTEXT(3));
        asn1_write_OctetString(data,
                               mechlistMIC->data,
                               mechlistMIC->length);
        asn1_pop_tag(data);
    }

    asn1_pop_tag(data);
    asn1_pop_tag(data);

    ret = data_blob_talloc(ctx, data->data, data->length);
    asn1_free(data);
    return ret;
}
Beispiel #3
0
/*
 generate a SPNEGO auth packet. This will contain the encrypted passwords
*/
DATA_BLOB spnego_gen_auth(TALLOC_CTX *ctx, DATA_BLOB blob)
{
	ASN1_DATA *data;
	DATA_BLOB ret = data_blob_null;

	data = asn1_init(talloc_tos());
	if (data == NULL) {
		return data_blob_null;
	}

	if (!asn1_push_tag(data, ASN1_CONTEXT(1))) goto err;
	if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
	if (!asn1_push_tag(data, ASN1_CONTEXT(2))) goto err;
	if (!asn1_write_OctetString(data,blob.data,blob.length)) goto err;
	if (!asn1_pop_tag(data)) goto err;
	if (!asn1_pop_tag(data)) goto err;
	if (!asn1_pop_tag(data)) goto err;

	if (!asn1_extract_blob(data, ctx, &ret)) {
		goto err;
	}

 err:

	asn1_free(data);

	return ret;
}
Beispiel #4
0
DATA_BLOB spnego_gen_negTokenInit(TALLOC_CTX *ctx,
                                  const char *OIDs[],
                                  DATA_BLOB *psecblob,
                                  const char *principal)
{
    int i;
    ASN1_DATA *data;
    DATA_BLOB ret;

    data = asn1_init(talloc_tos());
    if (data == NULL) {
        return data_blob_null;
    }

    asn1_push_tag(data,ASN1_APPLICATION(0));
    asn1_write_OID(data,OID_SPNEGO);
    asn1_push_tag(data,ASN1_CONTEXT(0));
    asn1_push_tag(data,ASN1_SEQUENCE(0));

    asn1_push_tag(data,ASN1_CONTEXT(0));
    asn1_push_tag(data,ASN1_SEQUENCE(0));
    for (i=0; OIDs[i]; i++) {
        asn1_write_OID(data,OIDs[i]);
    }
    asn1_pop_tag(data);
    asn1_pop_tag(data);

    if (psecblob && psecblob->length && psecblob->data) {
        asn1_push_tag(data, ASN1_CONTEXT(2));
        asn1_write_OctetString(data,psecblob->data,
                               psecblob->length);
        asn1_pop_tag(data);
    }

    if (principal) {
        asn1_push_tag(data, ASN1_CONTEXT(3));
        asn1_push_tag(data, ASN1_SEQUENCE(0));
        asn1_push_tag(data, ASN1_CONTEXT(0));
        asn1_write_GeneralString(data,principal);
        asn1_pop_tag(data);
        asn1_pop_tag(data);
        asn1_pop_tag(data);
    }

    asn1_pop_tag(data);
    asn1_pop_tag(data);

    asn1_pop_tag(data);

    if (data->has_error) {
        DEBUG(1,("Failed to build negTokenInit at offset %d\n", (int)data->ofs));
    }

    ret = data_blob_talloc(ctx, data->data, data->length);
    asn1_free(data);

    return ret;
}
Beispiel #5
0
static bool write_negTokenTarg(struct asn1_data *asn1, struct spnego_negTokenTarg *token)
{
    asn1_push_tag(asn1, ASN1_CONTEXT(1));
    asn1_push_tag(asn1, ASN1_SEQUENCE(0));

    if (token->negResult != SPNEGO_NONE_RESULT) {
        asn1_push_tag(asn1, ASN1_CONTEXT(0));
        asn1_write_enumerated(asn1, token->negResult);
        asn1_pop_tag(asn1);
    }

    if (token->supportedMech) {
        asn1_push_tag(asn1, ASN1_CONTEXT(1));
        asn1_write_OID(asn1, token->supportedMech);
        asn1_pop_tag(asn1);
    }

    if (token->responseToken.data) {
        asn1_push_tag(asn1, ASN1_CONTEXT(2));
        asn1_write_OctetString(asn1, token->responseToken.data,
                               token->responseToken.length);
        asn1_pop_tag(asn1);
    }

    if (token->mechListMIC.data) {
        asn1_push_tag(asn1, ASN1_CONTEXT(3));
        asn1_write_OctetString(asn1, token->mechListMIC.data,
                               token->mechListMIC.length);
        asn1_pop_tag(asn1);
    }

    asn1_pop_tag(asn1);
    asn1_pop_tag(asn1);

    return !asn1->has_error;
}
Beispiel #6
0
/*
 generate a SPNEGO auth packet. This will contain the encrypted passwords
*/
DATA_BLOB spnego_gen_auth(DATA_BLOB blob)
{
	ASN1_DATA data;
	DATA_BLOB ret;

	memset(&data, 0, sizeof(data));

	asn1_push_tag(&data, ASN1_CONTEXT(1));
	asn1_push_tag(&data, ASN1_SEQUENCE(0));
	asn1_push_tag(&data, ASN1_CONTEXT(2));
	asn1_write_OctetString(&data,blob.data,blob.length);	
	asn1_pop_tag(&data);
	asn1_pop_tag(&data);
	asn1_pop_tag(&data);

	ret = data_blob(data.data, data.length);

	asn1_free(&data);

	return ret;
}
Beispiel #7
0
/*
  generate a minimal SPNEGO response packet.  Doesn't contain much.
*/
DATA_BLOB spnego_gen_auth_response(DATA_BLOB *reply, NTSTATUS nt_status,
				   const char *mechOID)
{
	ASN1_DATA data;
	DATA_BLOB ret;
	uint8 negResult;

	if (NT_STATUS_IS_OK(nt_status)) {
		negResult = SPNEGO_NEG_RESULT_ACCEPT;
	} else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
		negResult = SPNEGO_NEG_RESULT_INCOMPLETE; 
	} else {
		negResult = SPNEGO_NEG_RESULT_REJECT; 
	}

	ZERO_STRUCT(data);

	asn1_push_tag(&data, ASN1_CONTEXT(1));
	asn1_push_tag(&data, ASN1_SEQUENCE(0));
	asn1_push_tag(&data, ASN1_CONTEXT(0));
	asn1_write_enumerated(&data, negResult);
	asn1_pop_tag(&data);

	if (reply->data != NULL) {
		asn1_push_tag(&data,ASN1_CONTEXT(1));
		asn1_write_OID(&data, mechOID);
		asn1_pop_tag(&data);
		
		asn1_push_tag(&data,ASN1_CONTEXT(2));
		asn1_write_OctetString(&data, reply->data, reply->length);
		asn1_pop_tag(&data);
	}

	asn1_pop_tag(&data);
	asn1_pop_tag(&data);

	ret = data_blob(data.data, data.length);
	asn1_free(&data);
	return ret;
}
Beispiel #8
0
/*
  generate a negTokenTarg packet given a list of OIDs and a security blob
*/
DATA_BLOB gen_negTokenTarg(const char *OIDs[], DATA_BLOB blob)
{
	int i;
	ASN1_DATA data;
	DATA_BLOB ret;

	memset(&data, 0, sizeof(data));

	asn1_push_tag(&data, ASN1_APPLICATION(0));
	asn1_write_OID(&data,OID_SPNEGO);
	asn1_push_tag(&data, ASN1_CONTEXT(0));
	asn1_push_tag(&data, ASN1_SEQUENCE(0));

	asn1_push_tag(&data, ASN1_CONTEXT(0));
	asn1_push_tag(&data, ASN1_SEQUENCE(0));
	for (i=0; OIDs[i]; i++) {
		asn1_write_OID(&data,OIDs[i]);
	}
	asn1_pop_tag(&data);
	asn1_pop_tag(&data);

	asn1_push_tag(&data, ASN1_CONTEXT(2));
	asn1_write_OctetString(&data,blob.data,blob.length);
	asn1_pop_tag(&data);

	asn1_pop_tag(&data);
	asn1_pop_tag(&data);

	asn1_pop_tag(&data);

	if (data.has_error) {
		DEBUG(1,("Failed to build negTokenTarg at offset %d\n", (int)data.ofs));
		asn1_free(&data);
	}

	ret = data_blob(data.data, data.length);
	asn1_free(&data);

	return ret;
}
Beispiel #9
0
/*
 generate a SPNEGO auth packet. This will contain the encrypted passwords
*/
DATA_BLOB spnego_gen_auth(TALLOC_CTX *ctx, DATA_BLOB blob)
{
    ASN1_DATA *data;
    DATA_BLOB ret;

    data = asn1_init(talloc_tos());
    if (data == NULL) {
        return data_blob_null;
    }

    asn1_push_tag(data, ASN1_CONTEXT(1));
    asn1_push_tag(data, ASN1_SEQUENCE(0));
    asn1_push_tag(data, ASN1_CONTEXT(2));
    asn1_write_OctetString(data,blob.data,blob.length);
    asn1_pop_tag(data);
    asn1_pop_tag(data);
    asn1_pop_tag(data);

    ret = data_blob_talloc(ctx, data->data, data->length);

    asn1_free(data);

    return ret;
}
Beispiel #10
0
static bool write_negTokenInit(struct asn1_data *asn1, struct spnego_negTokenInit *token)
{
    asn1_push_tag(asn1, ASN1_CONTEXT(0));
    asn1_push_tag(asn1, ASN1_SEQUENCE(0));

    /* Write mechTypes */
    if (token->mechTypes && *token->mechTypes) {
        int i;

        asn1_push_tag(asn1, ASN1_CONTEXT(0));
        asn1_push_tag(asn1, ASN1_SEQUENCE(0));
        for (i = 0; token->mechTypes[i]; i++) {
            asn1_write_OID(asn1, token->mechTypes[i]);
        }
        asn1_pop_tag(asn1);
        asn1_pop_tag(asn1);
    }

    /* write reqFlags */
    if (token->reqFlags & SPNEGO_REQ_FLAG) {
        int flags = token->reqFlags & ~SPNEGO_REQ_FLAG;

        asn1_push_tag(asn1, ASN1_CONTEXT(1));
        asn1_write_Integer(asn1, flags);
        asn1_pop_tag(asn1);
    }

    /* write mechToken */
    if (token->mechToken.data) {
        asn1_push_tag(asn1, ASN1_CONTEXT(2));
        asn1_write_OctetString(asn1, token->mechToken.data,
                               token->mechToken.length);
        asn1_pop_tag(asn1);
    }

    /* write mechListMIC */
    if (token->mechListMIC.data) {
        asn1_push_tag(asn1, ASN1_CONTEXT(3));
#if 0
        /* This is what RFC 2478 says ... */
        asn1_write_OctetString(asn1, token->mechListMIC.data,
                               token->mechListMIC.length);
#else
        /* ... but unfortunately this is what Windows
           sends/expects */
        asn1_push_tag(asn1, ASN1_SEQUENCE(0));
        asn1_push_tag(asn1, ASN1_CONTEXT(0));
        asn1_push_tag(asn1, ASN1_GENERAL_STRING);
        asn1_write(asn1, token->mechListMIC.data,
                   token->mechListMIC.length);
        asn1_pop_tag(asn1);
        asn1_pop_tag(asn1);
        asn1_pop_tag(asn1);
#endif
        asn1_pop_tag(asn1);
    }

    asn1_pop_tag(asn1);
    asn1_pop_tag(asn1);

    return !asn1->has_error;
}
Beispiel #11
0
/*
  do a cldap netlogon query
*/
static int send_cldap_netlogon(int sock, const char *domain, 
			       const char *hostname, unsigned ntversion)
{
	ASN1_DATA data;
	char ntver[4];
#ifdef CLDAP_USER_QUERY
	char aac[4];

	SIVAL(aac, 0, 0x00000180);
#endif
	SIVAL(ntver, 0, ntversion);

	memset(&data, 0, sizeof(data));

	asn1_push_tag(&data,ASN1_SEQUENCE(0));
	asn1_write_Integer(&data, 4);
	asn1_push_tag(&data, ASN1_APPLICATION(3));
	asn1_write_OctetString(&data, NULL, 0);
	asn1_write_enumerated(&data, 0);
	asn1_write_enumerated(&data, 0);
	asn1_write_Integer(&data, 0);
	asn1_write_Integer(&data, 0);
	asn1_write_BOOLEAN2(&data, False);
	asn1_push_tag(&data, ASN1_CONTEXT(0));

	if (domain) {
		asn1_push_tag(&data, ASN1_CONTEXT(3));
		asn1_write_OctetString(&data, "DnsDomain", 9);
		asn1_write_OctetString(&data, domain, strlen(domain));
		asn1_pop_tag(&data);
	}

	asn1_push_tag(&data, ASN1_CONTEXT(3));
	asn1_write_OctetString(&data, "Host", 4);
	asn1_write_OctetString(&data, hostname, strlen(hostname));
	asn1_pop_tag(&data);

#ifdef CLDAP_USER_QUERY
	asn1_push_tag(&data, ASN1_CONTEXT(3));
	asn1_write_OctetString(&data, "User", 4);
	asn1_write_OctetString(&data, "SAMBA$", 6);
	asn1_pop_tag(&data);

	asn1_push_tag(&data, ASN1_CONTEXT(3));
	asn1_write_OctetString(&data, "AAC", 4);
	asn1_write_OctetString(&data, aac, 4);
	asn1_pop_tag(&data);
#endif

	asn1_push_tag(&data, ASN1_CONTEXT(3));
	asn1_write_OctetString(&data, "NtVer", 5);
	asn1_write_OctetString(&data, ntver, 4);
	asn1_pop_tag(&data);

	asn1_pop_tag(&data);

	asn1_push_tag(&data,ASN1_SEQUENCE(0));
	asn1_write_OctetString(&data, "NetLogon", 8);
	asn1_pop_tag(&data);
	asn1_pop_tag(&data);
	asn1_pop_tag(&data);

	if (data.has_error) {
		DEBUG(2,("Failed to build cldap netlogon at offset %d\n", (int)data.ofs));
		asn1_free(&data);
		return -1;
	}

	if (write(sock, data.data, data.length) != (ssize_t)data.length) {
		DEBUG(2,("failed to send cldap query (%s)\n", strerror(errno)));
		asn1_free(&data);
		return -1;
	}

	asn1_free(&data);

	return 0;
}
Beispiel #12
0
/* This implements kerberos password change protocol as specified in 
 * kerb-chg-password-02.txt and kerberos-set-passwd-02.txt
 * as well as microsoft version of the protocol 
 * as specified in kerberos-set-passwd-00.txt
 */
static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password)
{
        char* princ_part1 = NULL;
	char* princ_part2 = NULL;
	char* realm = NULL;
	char* c;
	char* princ;

	ASN1_DATA *req;
	DATA_BLOB ret;


	princ = SMB_STRDUP(principal);

	if ((c = strchr_m(princ, '/')) == NULL) {
		c = princ; 
	} else {
		*c = '\0';
		c++;
		princ_part1 = princ;
	}

	princ_part2 = c;

	if ((c = strchr_m(c, '@')) != NULL) {
		*c = '\0';
		c++;
		realm = c;
	} else {
		/* We must have a realm component. */
		return data_blob_null;
	}

	req = asn1_init(talloc_tos());
	if (req == NULL) {
		return data_blob_null;
	}

	asn1_push_tag(req, ASN1_SEQUENCE(0));
	asn1_push_tag(req, ASN1_CONTEXT(0));
	asn1_write_OctetString(req, password, strlen(password));
	asn1_pop_tag(req);

	asn1_push_tag(req, ASN1_CONTEXT(1));
	asn1_push_tag(req, ASN1_SEQUENCE(0));

	asn1_push_tag(req, ASN1_CONTEXT(0));
	asn1_write_Integer(req, 1);
	asn1_pop_tag(req);

	asn1_push_tag(req, ASN1_CONTEXT(1));
	asn1_push_tag(req, ASN1_SEQUENCE(0));

	if (princ_part1) {
		asn1_write_GeneralString(req, princ_part1);
	}
	
	asn1_write_GeneralString(req, princ_part2);
	asn1_pop_tag(req);
	asn1_pop_tag(req);
	asn1_pop_tag(req);
	asn1_pop_tag(req);

	asn1_push_tag(req, ASN1_CONTEXT(2));
	asn1_write_GeneralString(req, realm);
	asn1_pop_tag(req);
	asn1_pop_tag(req);

	ret = data_blob(req->data, req->length);
	asn1_free(req);

	free(princ);

	return ret;
}	
Beispiel #13
0
DATA_BLOB spnego_gen_negTokenInit(TALLOC_CTX *ctx,
				  const char *OIDs[],
				  DATA_BLOB *psecblob,
				  const char *principal)
{
	int i;
	ASN1_DATA *data;
	DATA_BLOB ret = data_blob_null;

	data = asn1_init(talloc_tos());
	if (data == NULL) {
		return data_blob_null;
	}

	if (!asn1_push_tag(data,ASN1_APPLICATION(0))) goto err;
	if (!asn1_write_OID(data,OID_SPNEGO)) goto err;
	if (!asn1_push_tag(data,ASN1_CONTEXT(0))) goto err;
	if (!asn1_push_tag(data,ASN1_SEQUENCE(0))) goto err;

	if (!asn1_push_tag(data,ASN1_CONTEXT(0))) goto err;
	if (!asn1_push_tag(data,ASN1_SEQUENCE(0))) goto err;
	for (i=0; OIDs[i]; i++) {
		if (!asn1_write_OID(data,OIDs[i])) goto err;
	}
	if (!asn1_pop_tag(data)) goto err;
	if (!asn1_pop_tag(data)) goto err;

	if (psecblob && psecblob->length && psecblob->data) {
		if (!asn1_push_tag(data, ASN1_CONTEXT(2))) goto err;
		if (!asn1_write_OctetString(data,psecblob->data,
			psecblob->length)) goto err;
		if (!asn1_pop_tag(data)) goto err;
	}

	if (principal) {
		if (!asn1_push_tag(data, ASN1_CONTEXT(3))) goto err;
		if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
		if (!asn1_push_tag(data, ASN1_CONTEXT(0))) goto err;
		if (!asn1_write_GeneralString(data,principal)) goto err;
		if (!asn1_pop_tag(data)) goto err;
		if (!asn1_pop_tag(data)) goto err;
		if (!asn1_pop_tag(data)) goto err;
	}

	if (!asn1_pop_tag(data)) goto err;
	if (!asn1_pop_tag(data)) goto err;

	if (!asn1_pop_tag(data)) goto err;

	if (!asn1_extract_blob(data, ctx, &ret)) {
		goto err;
	}

  err:

	if (asn1_has_error(data)) {
		DEBUG(1, ("Failed to build negTokenInit at offset %d\n",
			  (int)asn1_current_ofs(data)));
	}

	asn1_free(data);

	return ret;
}