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; }
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; }
/* 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; }
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; }
/* 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, " "); }
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); } }