Пример #1
0
krb5_error_code
krb5_ldap_parse_principal_name(char *i_princ_name, char **o_princ_name)
{
    const char *at_rlm_name, *p;
    struct k5buf buf;

    at_rlm_name = strrchr(i_princ_name, '@');
    if (!at_rlm_name) {
        *o_princ_name = strdup(i_princ_name);
        if (!*o_princ_name)
            return ENOMEM;
    } else {
        k5_buf_init_dynamic(&buf);
        for (p = i_princ_name; p < at_rlm_name; p++) {
            if (*p == '@')
                k5_buf_add(&buf, "\\");
            k5_buf_add_len(&buf, p, 1);
        }
        k5_buf_add(&buf, at_rlm_name);
        *o_princ_name = k5_buf_data(&buf);
        if (!*o_princ_name)
            return ENOMEM;
    }
    return 0;
}
Пример #2
0
static krb5_error_code
make_proxy_request(struct conn_state *state, const krb5_data *realm,
                   const krb5_data *message, char **req_out, size_t *len_out)
{
    krb5_kkdcp_message pm;
    krb5_data *encoded_pm = NULL;
    struct k5buf buf;
    const char *uri_path;
    krb5_error_code ret;

    *req_out = NULL;
    *len_out = 0;

    /*
     * Stuff the message length in at the front of the kerb_message field
     * before encoding.  The proxied messages are actually the payload we'd
     * be sending and receiving if we were using plain TCP.
     */
    memset(&pm, 0, sizeof(pm));
    ret = alloc_data(&pm.kerb_message, message->length + 4);
    if (ret != 0)
        goto cleanup;
    store_32_be(message->length, pm.kerb_message.data);
    memcpy(pm.kerb_message.data + 4, message->data, message->length);
    pm.target_domain = *realm;
    ret = encode_krb5_kkdcp_message(&pm, &encoded_pm);
    if (ret != 0)
        goto cleanup;

    /* Build the request to transmit: the headers + the proxy message. */
    k5_buf_init_dynamic(&buf);
    uri_path = (state->http.uri_path != NULL) ? state->http.uri_path : "";
    k5_buf_add_fmt(&buf, "POST /%s HTTP/1.0\r\n", uri_path);
    k5_buf_add(&buf, "Cache-Control: no-cache\r\n");
    k5_buf_add(&buf, "Pragma: no-cache\r\n");
    k5_buf_add(&buf, "User-Agent: kerberos/1.0\r\n");
    k5_buf_add(&buf, "Content-type: application/kerberos\r\n");
    k5_buf_add_fmt(&buf, "Content-Length: %d\r\n\r\n", encoded_pm->length);
    k5_buf_add_len(&buf, encoded_pm->data, encoded_pm->length);
    if (k5_buf_status(&buf) != 0) {
        ret = ENOMEM;
        goto cleanup;
    }

    *req_out = buf.data;
    *len_out = buf.len;

cleanup:
    krb5_free_data_contents(NULL, &pm.kerb_message);
    krb5_free_data(NULL, encoded_pm);
    return ret;
}
Пример #3
0
/* Get any auth indicator values from LDAP and update the "require_auth"
 * string. */
static krb5_error_code
get_ldap_auth_ind(krb5_context context, LDAP *ld, LDAPMessage *ldap_ent,
                  krb5_db_entry *entry, unsigned int *mask)
{
    krb5_error_code ret;
    int i;
    char **auth_inds = NULL;
    struct k5buf buf = EMPTY_K5BUF;

    auth_inds = ldap_get_values(ld, ldap_ent, "krbPrincipalAuthInd");
    if (auth_inds == NULL)
        return 0;

    k5_buf_init_dynamic(&buf);

    /* Make a space seperated list of indicators. */
    for (i = 0; auth_inds[i] != NULL; i++) {
        k5_buf_add(&buf, auth_inds[i]);
        if (auth_inds[i + 1] != NULL)
            k5_buf_add(&buf, " ");
    }

    ret = k5_buf_status(&buf);
    if (ret)
        goto cleanup;

    ret = krb5_dbe_set_string(context, entry, KRB5_KDB_SK_REQUIRE_AUTH,
                              buf.data);
    if (!ret)
        *mask |= KDB_AUTH_IND_ATTR;

cleanup:
    k5_buf_free(&buf);
    ldap_value_free(auth_inds);
    return ret;
}
Пример #4
0
static krb5_error_code
decode_ad_policy_info(const krb5_data *data, char **msg_out)
{
    struct ad_policy_info policy;
    uint64_t password_days;
    const char *p;
    struct k5buf buf;

    *msg_out = NULL;
    if (data->length != AD_POLICY_INFO_LENGTH)
        return 0;

    p = data->data;
    policy.zero_bytes = load_16_be(p);
    p += 2;

    /* first two bytes are zeros */
    if (policy.zero_bytes != 0)
        return 0;

    /* Read in the rest of structure */
    policy.min_length_password = load_32_be(p);
    p += 4;
    policy.password_history = load_32_be(p);
    p += 4;
    policy.password_properties = load_32_be(p);
    p += 4;
    policy.expire = load_64_be(p);
    p += 8;
    policy.min_passwordage = load_64_be(p);
    p += 8;

    /* Check that we processed exactly the expected number of bytes. */
    assert(p == data->data + AD_POLICY_INFO_LENGTH);

    k5_buf_init_dynamic(&buf);

    /*
     * Update src/tests/misc/test_chpw_message.c if changing these strings!
     */

    if (policy.password_properties & AD_POLICY_COMPLEX) {
        k5_buf_add(&buf, _("The password must include numbers or symbols.  "
                           "Don't include any part of your name in the "
                           "password."));
    }
    if (policy.min_length_password > 0) {
        add_spaces(&buf);
        k5_buf_add_fmt(&buf, ngettext("The password must contain at least %d "
                                      "character.",
                                      "The password must contain at least %d "
                                      "characters.",
                                      policy.min_length_password),
                       policy.min_length_password);
    }
    if (policy.password_history) {
        add_spaces(&buf);
        k5_buf_add_fmt(&buf, ngettext("The password must be different from "
                                      "the previous password.",
                                      "The password must be different from "
                                      "the previous %d passwords.",
                                      policy.password_history),
                       policy.password_history);
    }
    if (policy.min_passwordage) {
        password_days = policy.min_passwordage / AD_POLICY_TIME_TO_DAYS;
        if (password_days == 0)
            password_days = 1;
        add_spaces(&buf);
        k5_buf_add_fmt(&buf, ngettext("The password can only be changed once "
                                      "a day.",
                                      "The password can only be changed every "
                                      "%d days.", (int)password_days),
                       (int)password_days);
    }

    if (k5_buf_status(&buf) != 0)
        return ENOMEM;

    if (buf.len > 0)
        *msg_out = buf.data;
    else
        k5_buf_free(&buf);
    return 0;
}
Пример #5
0
/* If buf already contains one or more sentences, add spaces to separate them
 * from the next sentence. */
static void
add_spaces(struct k5buf *buf)
{
    if (buf->len > 0)
        k5_buf_add(buf, "  ");
}
Пример #6
0
static void test_hmac()
{
    krb5_keyblock key;
    krb5_data in, out;
    char outbuf[20];
    char stroutbuf[80];
    krb5_error_code err;
    unsigned int i, j;
    int lose = 0;
    struct k5buf buf;

    /* RFC 2202 test vector.  */
    static const struct hmac_test md5tests[] = {
        {
            16, {
                0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb,
                0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb,
            },
            8, "Hi There",
            "0x9294727a3638bb1c13f48ef8158bfc9d"
        },

        {
            4, "Jefe",
            28, "what do ya want for nothing?",
            "0x750c783e6ab0b503eaa86e310a5db738"
        },

        {
            16, {
                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
            },
            50, {
                0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
                0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
                0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
                0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
                0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
            },
            "0x56be34521d144c88dbb8c733f0e8b3f6"
        },

        {
            25, {
                0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
                0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
                0x15, 0x16, 0x17, 0x18, 0x19
            },
            50, {
                0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
                0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
                0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
                0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
                0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
            },
            "0x697eaf0aca3a3aea3a75164746ffaa79"
        },

        {
            16, {
                0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
                0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c
            },
            20, "Test With Truncation",
            "0x56461ef2342edc00f9bab995690efd4c"
        },

        {
            80, {
                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
            },
            54, "Test Using Larger Than Block-Size Key - Hash Key First",
            "0x6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd"
        },

        {
            80, {
                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
            },
            73,
            "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data",
            "0x6f630fad67cda0ee1fb1f562db3aa53e"
        },
    };

    for (i = 0; i < sizeof(md5tests)/sizeof(md5tests[0]); i++) {
        key.contents = md5tests[i].key;
        key.length = md5tests[i].key_len;
        in.data = md5tests[i].data;
        in.length = md5tests[i].data_len;

        out.data = outbuf;
        out.length = 20;
        printf("\nTest #%d:\n", i+1);
        err = hmac1(&krb5int_hash_md5, &key, &in, &out);
        if (err) {
            com_err(whoami, err, "computing hmac");
            exit(1);
        }

        k5_buf_init_fixed(&buf, stroutbuf, sizeof(stroutbuf));
        k5_buf_add(&buf, "0x");
        for (j = 0; j < out.length; j++)
            k5_buf_add_fmt(&buf, "%02x", 0xff & outbuf[j]);
        if (k5_buf_data(&buf) == NULL)
            abort();
        if (strcmp(stroutbuf, md5tests[i].hexdigest)) {
            printf("*** CHECK FAILED!\n"
                   "\tReturned: %s.\n"
                   "\tExpected: %s.\n", stroutbuf, md5tests[i].hexdigest);
            lose++;
        } else
            printf("Matches expected result.\n");
    }

    /* Do again with SHA-1 tests....  */

    if (lose) {
        printf("%d failures; exiting.\n", lose);
        exit(1);
    }
}