Example #1
2
/*
  generate a krb5 GSS-API wrapper packet given a ticket
*/
DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket, const uint8 tok_id[2])
{
	ASN1_DATA data;
	DATA_BLOB ret;

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

	asn1_push_tag(&data, ASN1_APPLICATION(0));
	asn1_write_OID(&data, OID_KERBEROS5);

	asn1_write(&data, tok_id, 2);
	asn1_write(&data, ticket.data, ticket.length);
	asn1_pop_tag(&data);

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

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

	return ret;
}
Example #2
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;
}
Example #3
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;
}
Example #4
0
/*
  generate a krb5 GSS-API wrapper packet given a ticket
*/
DATA_BLOB spnego_gen_krb5_wrap(TALLOC_CTX *ctx, const DATA_BLOB ticket, const uint8 tok_id[2])
{
    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_KERBEROS5);

    asn1_write(data, tok_id, 2);
    asn1_write(data, ticket.data, ticket.length);
    asn1_pop_tag(data);

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

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

    return ret;
}
Example #5
0
ssize_t write_spnego_data(DATA_BLOB *blob, SPNEGO_DATA *spnego)
{
	ASN1_DATA asn1;
	ssize_t ret = -1;

	ZERO_STRUCT(asn1);

	switch (spnego->type) {
	case SPNEGO_NEG_TOKEN_INIT:
		asn1_push_tag(&asn1, ASN1_APPLICATION(0));
		asn1_write_OID(&asn1, OID_SPNEGO);
		write_negTokenInit(&asn1, &spnego->negTokenInit);
		asn1_pop_tag(&asn1);
		break;
	case SPNEGO_NEG_TOKEN_TARG:
		write_negTokenTarg(&asn1, &spnego->negTokenTarg);
		break;
	default:
		asn1.has_error = True;
		break;
	}

	if (!asn1.has_error) {
		*blob = data_blob(asn1.data, asn1.length);
		ret = asn1.ofs;
	}
	asn1_free(&asn1);

	return ret;
}
Example #6
0
/*
  generate a krb5 GSS-API wrapper packet given a ticket
*/
static DATA_BLOB gensec_gssapi_gen_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *ticket, const uint8_t tok_id[2])
{
    struct asn1_data *data;
    DATA_BLOB ret;

    data = asn1_init(mem_ctx);
    if (!data || !ticket->data) {
        return data_blob(NULL,0);
    }

    asn1_push_tag(data, ASN1_APPLICATION(0));
    asn1_write_OID(data, GENSEC_OID_KERBEROS5);

    asn1_write(data, tok_id, 2);
    asn1_write(data, ticket->data, ticket->length);
    asn1_pop_tag(data);

    if (data->has_error) {
        DEBUG(1,("Failed to build krb5 wrapper at offset %d\n", (int)data->ofs));
        asn1_free(data);
        return data_blob(NULL,0);
    }

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

    return ret;
}
Example #7
0
/*
  generate a krb5 GSS-API wrapper packet given a ticket
*/
DATA_BLOB spnego_gen_krb5_wrap(TALLOC_CTX *ctx, const DATA_BLOB ticket, const uint8_t tok_id[2])
{
	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_KERBEROS5)) goto err;

	if (!asn1_write(data, tok_id, 2)) goto err;
	if (!asn1_write(data, ticket.data, ticket.length)) 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 krb5 wrapper at offset %d\n",
			  (int)asn1_current_ofs(data)));
	}

	asn1_free(data);

	return ret;
}
Example #8
0
ssize_t spnego_write_data(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct spnego_data *spnego)
{
    struct asn1_data *asn1 = asn1_init(mem_ctx);
    ssize_t ret = -1;

    if (asn1 == NULL) {
        return -1;
    }

    switch (spnego->type) {
    case SPNEGO_NEG_TOKEN_INIT:
        asn1_push_tag(asn1, ASN1_APPLICATION(0));
        asn1_write_OID(asn1, GENSEC_OID_SPNEGO);
        write_negTokenInit(asn1, &spnego->negTokenInit);
        asn1_pop_tag(asn1);
        break;
    case SPNEGO_NEG_TOKEN_TARG:
        write_negTokenTarg(asn1, &spnego->negTokenTarg);
        break;
    default:
        asn1->has_error = true;
        break;
    }

    if (!asn1->has_error) {
        *blob = data_blob_talloc(mem_ctx, asn1->data, asn1->length);
        ret = asn1->ofs;
    }
    asn1_free(asn1);

    return ret;
}
Example #9
0
bool spnego_write_mech_types(TALLOC_CTX *mem_ctx,
                             const char **mech_types,
                             DATA_BLOB *blob)
{
    struct asn1_data *asn1 = asn1_init(mem_ctx);

    /* Write mechTypes */
    if (mech_types && *mech_types) {
        int i;

        asn1_push_tag(asn1, ASN1_SEQUENCE(0));
        for (i = 0; mech_types[i]; i++) {
            asn1_write_OID(asn1, mech_types[i]);
        }
        asn1_pop_tag(asn1);
    }

    if (asn1->has_error) {
        asn1_free(asn1);
        return false;
    }

    *blob = data_blob_talloc(mem_ctx, asn1->data, asn1->length);
    if (blob->length != asn1->length) {
        asn1_free(asn1);
        return false;
    }

    asn1_free(asn1);

    return true;
}
Example #10
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;
}
Example #11
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;
}
Example #12
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;
}
Example #13
0
/*
  generate a negTokenInit packet given a GUID, a list of supported
  OIDs (the mechanisms) and a principal name string 
*/
DATA_BLOB spnego_gen_negTokenInit(uint8 guid[16], 
				  const char *OIDs[], 
				  const char *principal)
{
	int i;
	ASN1_DATA data;
	DATA_BLOB ret;

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

	asn1_write(&data, guid, 16);
	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(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));
		asn1_free(&data);
	}

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

	return ret;
}
Example #14
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;
}
Example #15
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;
}
Example #16
0
bool spnego_mech_list_blob(TALLOC_CTX *mem_ctx,
                           char **oid_list, DATA_BLOB *raw_data)
{
    ASN1_DATA *data;
    unsigned int idx;

    if (!oid_list || !oid_list[0] || !raw_data) {
        return false;
    }

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

    asn1_push_tag(data, ASN1_SEQUENCE(0));
    for (idx = 0; oid_list[idx]; idx++) {
        asn1_write_OID(data, oid_list[idx]);
    }
    asn1_pop_tag(data);

    if (data->has_error) {
        DEBUG(3, (__location__ " failed at %d\n", (int)data->ofs));
        asn1_free(data);
        return false;
    }

    *raw_data = data_blob_talloc(mem_ctx, data->data, data->length);
    if (!raw_data->data) {
        DEBUG(3, (__location__": data_blob_talloc() failed!\n"));
        asn1_free(data);
        return false;
    }

    asn1_free(data);
    return true;
}
Example #17
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;
}
Example #18
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;
}
Example #19
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;
}	
Example #20
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;
}
Example #21
0
static bool read_negTokenInit(struct asn1_data *asn1, TALLOC_CTX *mem_ctx,
                              struct spnego_negTokenInit *token)
{
    ZERO_STRUCTP(token);

    asn1_start_tag(asn1, ASN1_CONTEXT(0));
    asn1_start_tag(asn1, ASN1_SEQUENCE(0));

    while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) {
        int i;
        uint8_t context;
        if (!asn1_peek_uint8(asn1, &context)) {
            asn1->has_error = true;
            break;
        }

        switch (context) {
        /* Read mechTypes */
        case ASN1_CONTEXT(0):
            asn1_start_tag(asn1, ASN1_CONTEXT(0));
            asn1_start_tag(asn1, ASN1_SEQUENCE(0));

            token->mechTypes = talloc(NULL, const char *);
            for (i = 0; !asn1->has_error &&
                    0 < asn1_tag_remaining(asn1); i++) {
                token->mechTypes = talloc_realloc(NULL,
                                                  token->mechTypes,
                                                  const char *, i+2);
                asn1_read_OID(asn1, token->mechTypes, token->mechTypes + i);
            }
            token->mechTypes[i] = NULL;

            asn1_end_tag(asn1);
            asn1_end_tag(asn1);
            break;
        /* Read reqFlags */
        case ASN1_CONTEXT(1):
            asn1_start_tag(asn1, ASN1_CONTEXT(1));
            asn1_read_Integer(asn1, &token->reqFlags);
            token->reqFlags |= SPNEGO_REQ_FLAG;
            asn1_end_tag(asn1);
            break;
        /* Read mechToken */
        case ASN1_CONTEXT(2):
            asn1_start_tag(asn1, ASN1_CONTEXT(2));
            asn1_read_OctetString(asn1, mem_ctx, &token->mechToken);
            asn1_end_tag(asn1);
            break;
        /* Read mecListMIC */
        case ASN1_CONTEXT(3):
        {
            uint8_t type_peek;
            asn1_start_tag(asn1, ASN1_CONTEXT(3));
            if (!asn1_peek_uint8(asn1, &type_peek)) {
                asn1->has_error = true;
                break;
            }
            if (type_peek == ASN1_OCTET_STRING) {
                asn1_read_OctetString(asn1, mem_ctx,
                                      &token->mechListMIC);
            } else {
                /* RFC 2478 says we have an Octet String here,
                   but W2k sends something different... */
                char *mechListMIC;
                asn1_push_tag(asn1, ASN1_SEQUENCE(0));
                asn1_push_tag(asn1, ASN1_CONTEXT(0));
                asn1_read_GeneralString(asn1, mem_ctx, &mechListMIC);
                asn1_pop_tag(asn1);
                asn1_pop_tag(asn1);

                token->targetPrincipal = mechListMIC;
            }
            asn1_end_tag(asn1);
            break;
        }
        default:
            asn1->has_error = true;
            break;
        }
    }

    asn1_end_tag(asn1);
    asn1_end_tag(asn1);

    return !asn1->has_error;
}
Example #22
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;
}
Example #23
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;
}
Example #24
0
static bool read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token)
{
	ZERO_STRUCTP(token);

	asn1_start_tag(asn1, ASN1_CONTEXT(0));
	asn1_start_tag(asn1, ASN1_SEQUENCE(0));

	while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) {
		int i;

		switch (asn1->data[asn1->ofs]) {
		/* Read mechTypes */
		case ASN1_CONTEXT(0):
			asn1_start_tag(asn1, ASN1_CONTEXT(0));
			asn1_start_tag(asn1, ASN1_SEQUENCE(0));

			token->mechTypes = SMB_MALLOC_P(const char *);
			for (i = 0; !asn1->has_error &&
				     0 < asn1_tag_remaining(asn1); i++) {
				char *p_oid = NULL;
				token->mechTypes = 
					SMB_REALLOC_ARRAY(token->mechTypes, const char *, i + 2);
				if (!token->mechTypes) {
					asn1->has_error = True;
					return False;
				}
				asn1_read_OID(asn1, &p_oid);
				token->mechTypes[i] = p_oid;
			}
			token->mechTypes[i] = NULL;
			
			asn1_end_tag(asn1);
			asn1_end_tag(asn1);
			break;
		/* Read reqFlags */
		case ASN1_CONTEXT(1):
			asn1_start_tag(asn1, ASN1_CONTEXT(1));
			asn1_read_Integer(asn1, &token->reqFlags);
			token->reqFlags |= SPNEGO_REQ_FLAG;
			asn1_end_tag(asn1);
			break;
                /* Read mechToken */
		case ASN1_CONTEXT(2):
			asn1_start_tag(asn1, ASN1_CONTEXT(2));
			asn1_read_OctetString(asn1, &token->mechToken);
			asn1_end_tag(asn1);
			break;
		/* Read mecListMIC */
		case ASN1_CONTEXT(3):
			asn1_start_tag(asn1, ASN1_CONTEXT(3));
			if (asn1->data[asn1->ofs] == ASN1_OCTET_STRING) {
				asn1_read_OctetString(asn1,
						      &token->mechListMIC);
			} else {
				/* RFC 2478 says we have an Octet String here,
				   but W2k sends something different... */
				char *mechListMIC;
				asn1_push_tag(asn1, ASN1_SEQUENCE(0));
				asn1_push_tag(asn1, ASN1_CONTEXT(0));
				asn1_read_GeneralString(asn1, &mechListMIC);
				asn1_pop_tag(asn1);
				asn1_pop_tag(asn1);

				token->mechListMIC =
					data_blob(mechListMIC, strlen(mechListMIC));
				SAFE_FREE(mechListMIC);
			}
			asn1_end_tag(asn1);
			break;
		default:
			asn1->has_error = True;
			break;
		}
	}

	asn1_end_tag(asn1);
	asn1_end_tag(asn1);

	return !asn1->has_error;
}