Exemplo n.º 1
0
static bool
getAttributeId(const gss_buffer_t desc,
               gss_eap_attrid *attrid)
{
    char *strAttr, *s;
    int canon, code;

    if (desc->length == 0)
        return false;

    canon = isdigit(*(char *)desc->value);

    /* need to duplicate because attr may not be NUL terminated */
    strAttr = (char *)GSSEAP_MALLOC((canon ? 5 : 0) + desc->length + 1);
    if (strAttr == NULL)
        throw new std::bad_alloc();

    s = strAttr;

    if (canon) {
        memcpy(s, "Attr-", 5);
        s += 5;
    }

    memcpy(s, desc->value, desc->length);
    s += desc->length;
    *s = '\0';

    code = rs_attr_parse_name(strAttr, &attrid->second, &attrid->first);

    GSSEAP_FREE(strAttr);

    return (code == RSE_OK);
}
Exemplo n.º 2
0
int
gssEapDecrypt(krb5_context context,
              int dce_style,
              size_t ec,
              size_t rrc,
#ifdef HAVE_HEIMDAL_VERSION
              krb5_crypto crypto,
#else
              krb5_keyblock *crypto,
#endif
              int usage,
              gss_iov_buffer_desc *iov,
              int iov_count)
{
    krb5_error_code code;
    size_t kiov_count;
    krb5_crypto_iov *kiov;

    code = mapIov(context, dce_style, ec, rrc, crypto,
                  iov, iov_count, &kiov, &kiov_count);
    if (code != 0)
        goto cleanup;

#ifdef HAVE_HEIMDAL_VERSION
    code = krb5_decrypt_iov_ivec(context, crypto, usage, kiov, kiov_count, NULL);
#else
    code = krb5_c_decrypt_iov(context, crypto, usage, NULL, kiov, kiov_count);
#endif

cleanup:
    if (kiov != NULL)
        GSSEAP_FREE(kiov);

    return code;
}
Exemplo n.º 3
0
OM_uint32
gssEapReleaseCred(OM_uint32 *minor, gss_cred_id_t *pCred)
{
    OM_uint32 tmpMinor;
    gss_cred_id_t cred = *pCred;

    if (cred == GSS_C_NO_CREDENTIAL) {
        return GSS_S_COMPLETE;
    }

    gssEapReleaseName(&tmpMinor, &cred->name);
    gssEapReleaseName(&tmpMinor, &cred->target);

    zeroAndReleasePassword(&cred->password);
#ifndef MECH_EAP
    zeroAndReleasePassword(&cred->deleg_assertions);
#endif

    gss_release_buffer(&tmpMinor, &cred->radiusConfigFile);
    gss_release_buffer(&tmpMinor, &cred->radiusConfigStanza);
    gss_release_buffer(&tmpMinor, &cred->caCertificate);
    gss_release_buffer(&tmpMinor, &cred->subjectNameConstraint);
    gss_release_buffer(&tmpMinor, &cred->subjectAltNameConstraint);

    GSSEAP_MUTEX_DESTROY(&cred->mutex);
    memset(cred, 0, sizeof(*cred));
    GSSEAP_FREE(cred);
    *pCred = NULL;

    *minor = 0;
    return GSS_S_COMPLETE;
}
Exemplo n.º 4
0
static void
zeroAndReleasePassword(gss_buffer_t password)
{
    if (password->value != NULL) {
        memset(password->value, 0, password->length);
        GSSEAP_FREE(password->value);
    }

    password->value = NULL;
    password->length = 0;
}
Exemplo n.º 5
0
static JSONObject
avpToJson(rs_const_avp *vp)
{
    JSONObject obj;
    gss_eap_attrid attrid;

    GSSEAP_ASSERT(rs_avp_length(vp) <= RS_MAX_STRING_LEN);

    switch (rs_avp_typeof(vp)) {
    case RS_TYPE_INTEGER:
        obj.set("value", rs_avp_integer_value(vp));
        break;
    case RS_TYPE_DATE:
        obj.set("value", rs_avp_date_value(vp));
        break;
    case RS_TYPE_STRING:
        obj.set("value", rs_avp_string_value(vp));
        break;
    default: {
        char *b64;

        if (base64Encode(rs_avp_octets_value_const_ptr(vp),
                         rs_avp_length(vp), &b64) < 0)
            throw std::bad_alloc();

        obj.set("value", b64);
        GSSEAP_FREE(b64);
        break;
    }
    }

    attrid = avpToAttrId(vp);

    obj.set("type", attrid.second);
    if (attrid.first != 0)
        obj.set("vendor", attrid.first);

    return obj;
}
Exemplo n.º 6
0
OM_uint32
gssEapDecodeInnerTokens(OM_uint32 *minor,
                        const gss_buffer_t buffer,
                        struct gss_eap_token_buffer_set *tokens)
{
    OM_uint32 major, tmpMinor;
    unsigned char *p;
    size_t count = 0;
    size_t remain;

    tokens->buffers.count = 0;
    tokens->buffers.elements = NULL;
    tokens->types = NULL;

    if (buffer->length == 0) {
        major = GSS_S_COMPLETE;
        goto cleanup;
    }

    p = (unsigned char *)buffer->value;
    remain = buffer->length;

    do {
        OM_uint32 *ntypes;
        gss_buffer_desc tokenBuffer, *newTokenBuffers;

        if (remain < 8) {
            major = GSS_S_DEFECTIVE_TOKEN;
            *minor = GSSEAP_TOK_TRUNC;
            goto cleanup;
        }

        if (tokens->buffers.count <= count) {
            if (count == 0)
                count = 1;
            else
                count *= 2;

            ntypes = GSSEAP_MALLOC(count * sizeof(OM_uint32));
            if (ntypes == NULL) {
                major = GSS_S_FAILURE;
                *minor = ENOMEM;
                goto cleanup;
            }
            if (tokens->types != NULL) {
                memcpy(ntypes, tokens->types, tokens->buffers.count * sizeof(OM_uint32));
                GSSEAP_FREE(tokens->types);
            }
            tokens->types = ntypes;

            newTokenBuffers = GSSEAP_MALLOC(count * sizeof(gss_buffer_desc));
            if (newTokenBuffers == NULL) {
                major = GSS_S_FAILURE;
                *minor = ENOMEM;
                goto cleanup;
            }
            if (tokens->buffers.elements != NULL) {
                memcpy(newTokenBuffers, tokens->buffers.elements,
                       tokens->buffers.count * sizeof(gss_buffer_desc));
                GSSEAP_FREE(tokens->buffers.elements);
            }
            tokens->buffers.elements = newTokenBuffers;
        }

        tokens->types[tokens->buffers.count] = load_uint32_be(&p[0]);
        tokenBuffer.length = load_uint32_be(&p[4]);

        if (remain < 8 + tokenBuffer.length) {
            major = GSS_S_DEFECTIVE_TOKEN;
            *minor = GSSEAP_TOK_TRUNC;
            goto cleanup;
        }
        tokenBuffer.value = &p[8];

        tokens->buffers.elements[tokens->buffers.count] = tokenBuffer;
        tokens->buffers.count++;

        p      += 8 + tokenBuffer.length;
        remain -= 8 + tokenBuffer.length;
    } while (remain != 0);

    major = GSS_S_COMPLETE;
    *minor = 0;

cleanup:
    if (GSS_ERROR(major))
        gssEapReleaseInnerTokens(&tmpMinor, tokens, 0);

    return major;
}
Exemplo n.º 7
0
OM_uint32
gssEapPseudoRandom(OM_uint32 *minor,
                   gss_const_ctx_id_t ctx,
                   int prf_key,
                   const gss_buffer_t prf_in,
                   gss_buffer_t prf_out)
{
    krb5_error_code code;
    int i;
    OM_uint32 tmpMinor;
    size_t prflen;
    krb5_data t, ns;
    unsigned char *p;
    krb5_context krbContext;
    ssize_t desired_output_len = prf_out->length;
#ifdef HAVE_HEIMDAL_VERSION
    krb5_crypto krbCrypto = NULL;
#endif

    *minor = 0;

    GSSEAP_KRB_INIT(&krbContext);

    KRB_DATA_INIT(&t);
    KRB_DATA_INIT(&ns);

    if (prf_key != GSS_C_PRF_KEY_PARTIAL &&
        prf_key != GSS_C_PRF_KEY_FULL) {
        code = GSSEAP_BAD_PRF_KEY;
        goto cleanup;
    }

#ifdef HAVE_HEIMDAL_VERSION
    code = krb5_crypto_prf_length(krbContext, ctx->encryptionType, &prflen);
#else
    code = krb5_c_prf_length(krbContext, ctx->encryptionType, &prflen);
#endif
    if (code != 0)
        goto cleanup;

    ns.length = 4 + prf_in->length;
    ns.data = GSSEAP_MALLOC(ns.length);
    if (ns.data == NULL) {
        code = ENOMEM;
        goto cleanup;
    }

#ifdef HAVE_HEIMDAL_VERSION
    code = krb5_crypto_init(krbContext, &ctx->rfc3961Key, 0, &krbCrypto);
    if (code != 0)
        goto cleanup;
#else
    t.length = prflen;
    t.data = GSSEAP_MALLOC(t.length);
    if (t.data == NULL) {
        code = ENOMEM;
        goto cleanup;
    }
#endif

    memcpy((unsigned char *)ns.data + 4, prf_in->value, prf_in->length);
    i = 0;
    p = (unsigned char *)prf_out->value;
    while (desired_output_len > 0) {
        store_uint32_be(i, ns.data);

#ifdef HAVE_HEIMDAL_VERSION
        code = krb5_crypto_prf(krbContext, krbCrypto, &ns, &t);
#else
        code = krb5_c_prf(krbContext, &ctx->rfc3961Key, &ns, &t);
#endif
        if (code != 0)
            goto cleanup;

        memcpy(p, t.data, MIN(t.length, desired_output_len));

        p += t.length;
        desired_output_len -= t.length;
        i++;
    }

cleanup:
    if (code != 0)
        gss_release_buffer(&tmpMinor, prf_out);
    if (ns.data != NULL) {
        memset(ns.data, 0, ns.length);
        GSSEAP_FREE(ns.data);
    }
#ifdef HAVE_HEIMDAL_VERSION
    krb5_crypto_destroy(krbContext, krbCrypto);
    krb5_data_free(&t);
#else
    if (t.data != NULL) {
        memset(t.data, 0, t.length);
        GSSEAP_FREE(t.data);
    }
#endif

    *minor = code;

    return (code == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE;
}