003 File Manager
Current Path:
/usr/src/crypto/heimdal/lib/krb5
usr
/
src
/
crypto
/
heimdal
/
lib
/
krb5
/
π
..
π
Makefile.am
(7.68 KB)
π
Makefile.in
(224.98 KB)
π
acache.c
(26.87 KB)
π
acl.c
(7.58 KB)
π
add_et_list.c
(2.2 KB)
π
addr_families.c
(38.89 KB)
π
aes-test.c
(22.56 KB)
π
aname_to_localname.c
(2.83 KB)
π
appdefault.c
(4.41 KB)
π
asn1_glue.c
(2.37 KB)
π
auth_context.c
(14.97 KB)
π
build_ap_req.c
(2.77 KB)
π
build_auth.c
(5.5 KB)
π
cache.c
(41.88 KB)
π
ccache_plugin.h
(1.67 KB)
π
changepw.c
(20.59 KB)
π
codec.c
(6.1 KB)
π
config_file.c
(31.7 KB)
π
constants.c
(2.51 KB)
π
context.c
(37.71 KB)
π
convert_creds.c
(3.46 KB)
π
copy_host_realm.c
(2.66 KB)
π
crc.c
(2.19 KB)
π
creds.c
(8.75 KB)
π
crypto-aes.c
(4.62 KB)
π
crypto-algs.c
(3.04 KB)
π
crypto-arcfour.c
(8.78 KB)
π
crypto-des-common.c
(4.37 KB)
π
crypto-des.c
(8.8 KB)
π
crypto-des3.c
(5.36 KB)
π
crypto-evp.c
(5.45 KB)
π
crypto-null.c
(2.55 KB)
π
crypto-pk.c
(8.4 KB)
π
crypto-rand.c
(3.43 KB)
π
crypto-stubs.c
(3.1 KB)
π
crypto.c
(66.51 KB)
π
crypto.h
(6.5 KB)
π
data.c
(5.66 KB)
π
deprecated.c
(14.72 KB)
π
derived-key-test.c
(6.48 KB)
π
digest.c
(31.6 KB)
π
doxygen.c
(25.72 KB)
π
eai_to_heim_errno.c
(3.46 KB)
π
error_string.c
(8.93 KB)
π
expand_hostname.c
(5.59 KB)
π
expand_path.c
(12.35 KB)
π
fcache.c
(25.36 KB)
π
free.c
(2.01 KB)
π
free_host_realm.c
(2.1 KB)
π
generate_seq_number.c
(2.03 KB)
π
generate_subkey.c
(2.6 KB)
π
get_addrs.c
(8.2 KB)
π
get_cred.c
(38.45 KB)
π
get_default_principal.c
(4.47 KB)
π
get_default_realm.c
(2.74 KB)
π
get_for_creds.c
(13.48 KB)
π
get_host_realm.c
(7.06 KB)
π
get_in_tkt.c
(14.45 KB)
π
get_port.c
(2.04 KB)
π
heim_err.et
(1.7 KB)
π
init_creds.c
(12.11 KB)
π
init_creds_pw.c
(52.57 KB)
π
k524_err.et
(577 B)
π
kcm.c
(26.55 KB)
π
kcm.h
(2.83 KB)
π
kerberos.8
(4.14 KB)
π
keyblock.c
(5.31 KB)
π
keytab.c
(23.88 KB)
π
keytab_any.c
(6.48 KB)
π
keytab_file.c
(19.7 KB)
π
keytab_keyfile.c
(10.74 KB)
π
keytab_memory.c
(6.29 KB)
π
krb5-private.h
(12.91 KB)
π
krb5-protos.h
(113.43 KB)
π
krb5-v4compat.h
(4.44 KB)
π
krb5.conf.5
(18.31 KB)
π
krb5.h
(29.75 KB)
π
krb5.moduli
(1.11 KB)
π
krb524_convert_creds_kdc.3
(3.12 KB)
π
krb5_425_conv_principal.3
(7.02 KB)
π
krb5_acl_match_file.3
(3.49 KB)
π
krb5_aname_to_localname.3
(2.87 KB)
π
krb5_appdefault.3
(3.08 KB)
π
krb5_auth_context.3
(10.8 KB)
π
krb5_c_make_checksum.3
(6.92 KB)
π
krb5_ccapi.h
(7.52 KB)
π
krb5_check_transited.3
(3.28 KB)
π
krb5_create_checksum.3
(6.02 KB)
π
krb5_creds.3
(3.31 KB)
π
krb5_digest.3
(6.57 KB)
π
krb5_eai_to_heim_errno.3
(2.4 KB)
π
krb5_encrypt.3
(7 KB)
π
krb5_err.et
(12.86 KB)
π
krb5_find_padata.3
(2.53 KB)
π
krb5_generate_random_block.3
(2.1 KB)
π
krb5_get_all_client_addrs.3
(2.83 KB)
π
krb5_get_credentials.3
(5.03 KB)
π
krb5_get_creds.3
(5.28 KB)
π
krb5_get_forwarded_creds.3
(2.74 KB)
π
krb5_get_in_cred.3
(7.46 KB)
π
krb5_get_init_creds.3
(11.03 KB)
π
krb5_get_krbhst.3
(3.26 KB)
π
krb5_getportbyname.3
(2.32 KB)
π
krb5_init_context.3
(7.88 KB)
π
krb5_is_thread_safe.3
(2.24 KB)
π
krb5_krbhst_init.3
(5.67 KB)
π
krb5_locl.h
(8.47 KB)
π
krb5_mk_req.3
(5.18 KB)
π
krb5_mk_safe.3
(2.78 KB)
π
krb5_openlog.3
(7.96 KB)
π
krb5_parse_name.3
(2.57 KB)
π
krb5_principal.3
(11.85 KB)
π
krb5_rcache.3
(4.21 KB)
π
krb5_rd_error.3
(3.33 KB)
π
krb5_rd_safe.3
(2.77 KB)
π
krb5_set_default_realm.3
(4.29 KB)
π
krb5_set_password.3
(4.11 KB)
π
krb5_string_to_key.3
(4.39 KB)
π
krb5_timeofday.3
(3.33 KB)
π
krb5_verify_init_creds.3
(3.51 KB)
π
krb5_verify_user.3
(6.71 KB)
π
krb_err.et
(2.55 KB)
π
krbhst-test.c
(3.02 KB)
π
krbhst.c
(26.94 KB)
π
kuserok.c
(8.14 KB)
π
locate_plugin.h
(2.36 KB)
π
log.c
(11.94 KB)
π
mcache.c
(11.54 KB)
π
misc.c
(3.9 KB)
π
mit_glue.c
(11.14 KB)
π
mk_error.c
(3.23 KB)
π
mk_priv.c
(4.54 KB)
π
mk_rep.c
(3.99 KB)
π
mk_req.c
(3.58 KB)
π
mk_req_ext.c
(4.78 KB)
π
mk_safe.c
(4.36 KB)
π
n-fold-test.c
(4.14 KB)
π
n-fold.c
(3.8 KB)
π
net_read.c
(1.86 KB)
π
net_write.c
(3.05 KB)
π
pac.c
(28.37 KB)
π
padata.c
(2.35 KB)
π
parse-name-test.c
(5.81 KB)
π
pcache.c
(2.33 KB)
π
pkinit.c
(63.8 KB)
π
plugin.c
(13.71 KB)
π
principal.c
(28.4 KB)
π
prog_setup.c
(2.34 KB)
π
prompter_posix.c
(2.45 KB)
π
rd_cred.c
(9.44 KB)
π
rd_error.c
(3.83 KB)
π
rd_priv.c
(5.38 KB)
π
rd_rep.c
(3.72 KB)
π
rd_req.c
(25.6 KB)
π
rd_safe.c
(6.34 KB)
π
read_message.c
(3.22 KB)
π
recvauth.c
(6.16 KB)
π
replay.c
(8.24 KB)
π
salt-aes.c
(3.34 KB)
π
salt-arcfour.c
(3.24 KB)
π
salt-des.c
(6.68 KB)
π
salt-des3.c
(4.36 KB)
π
salt.c
(9 KB)
π
scache.c
(32.86 KB)
π
send_to_kdc.c
(16.06 KB)
π
send_to_kdc_plugin.h
(2.22 KB)
π
sendauth.c
(6.12 KB)
π
set_default_realm.c
(3.01 KB)
π
sock_principal.c
(2.52 KB)
π
store-int.c
(2.14 KB)
π
store-int.h
(2.07 KB)
π
store-test.c
(3.63 KB)
π
store.c
(35.77 KB)
π
store_emem.c
(5.06 KB)
π
store_fd.c
(3.4 KB)
π
store_mem.c
(5.42 KB)
π
string-to-key-test.c
(5.75 KB)
π
test_acl.c
(4.56 KB)
π
test_addr.c
(7.27 KB)
π
test_alname.c
(4.28 KB)
π
test_cc.c
(19.39 KB)
π
test_config.c
(7.92 KB)
π
test_crypto.c
(5.68 KB)
π
test_crypto_wrapping.c
(4.48 KB)
π
test_forward.c
(3.64 KB)
π
test_get_addrs.c
(3.21 KB)
π
test_hostname.c
(3.82 KB)
π
test_keytab.c
(7.42 KB)
π
test_kuserok.c
(2.9 KB)
π
test_mem.c
(2.21 KB)
π
test_pac.c
(15.1 KB)
π
test_pkinit_dh2key.c
(6.9 KB)
π
test_plugin.c
(3.4 KB)
π
test_prf.c
(3.21 KB)
π
test_princ.c
(10.44 KB)
π
test_renew.c
(3.22 KB)
π
test_store.c
(7.96 KB)
π
test_time.c
(2.57 KB)
π
ticket.c
(21.91 KB)
π
time.c
(3.84 KB)
π
transited.c
(11.11 KB)
π
verify_init.c
(6.47 KB)
π
verify_krb5_conf.8
(3.41 KB)
π
verify_krb5_conf.c
(20.63 KB)
π
verify_user.c
(7 KB)
π
version-script.map
(18.82 KB)
π
version.c
(1.71 KB)
π
warn.c
(8.98 KB)
π
write_message.c
(2.87 KB)
Editing: digest.c
/* * Copyright (c) 2006 Kungliga Tekniska HΓΆgskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "krb5_locl.h" #include "digest_asn1.h" #ifndef HEIMDAL_SMALLER struct krb5_digest_data { char *cbtype; char *cbbinding; DigestInit init; DigestInitReply initReply; DigestRequest request; DigestResponse response; }; KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_digest_alloc(krb5_context context, krb5_digest *digest) { krb5_digest d; d = calloc(1, sizeof(*d)); if (d == NULL) { *digest = NULL; krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } *digest = d; return 0; } KRB5_LIB_FUNCTION void KRB5_LIB_CALL krb5_digest_free(krb5_digest digest) { if (digest == NULL) return; free_DigestInit(&digest->init); free_DigestInitReply(&digest->initReply); free_DigestRequest(&digest->request); free_DigestResponse(&digest->response); memset(digest, 0, sizeof(*digest)); free(digest); return; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_digest_set_server_cb(krb5_context context, krb5_digest digest, const char *type, const char *binding) { if (digest->init.channel) { krb5_set_error_message(context, EINVAL, N_("server channel binding already set", "")); return EINVAL; } digest->init.channel = calloc(1, sizeof(*digest->init.channel)); if (digest->init.channel == NULL) goto error; digest->init.channel->cb_type = strdup(type); if (digest->init.channel->cb_type == NULL) goto error; digest->init.channel->cb_binding = strdup(binding); if (digest->init.channel->cb_binding == NULL) goto error; return 0; error: if (digest->init.channel) { free(digest->init.channel->cb_type); free(digest->init.channel->cb_binding); free(digest->init.channel); digest->init.channel = NULL; } krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_digest_set_type(krb5_context context, krb5_digest digest, const char *type) { if (digest->init.type) { krb5_set_error_message(context, EINVAL, "client type already set"); return EINVAL; } digest->init.type = strdup(type); if (digest->init.type == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } return 0; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_digest_set_hostname(krb5_context context, krb5_digest digest, const char *hostname) { if (digest->init.hostname) { krb5_set_error_message(context, EINVAL, "server hostname already set"); return EINVAL; } digest->init.hostname = malloc(sizeof(*digest->init.hostname)); if (digest->init.hostname == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } *digest->init.hostname = strdup(hostname); if (*digest->init.hostname == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); free(digest->init.hostname); digest->init.hostname = NULL; return ENOMEM; } return 0; } KRB5_LIB_FUNCTION const char * KRB5_LIB_CALL krb5_digest_get_server_nonce(krb5_context context, krb5_digest digest) { return digest->initReply.nonce; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_digest_set_server_nonce(krb5_context context, krb5_digest digest, const char *nonce) { if (digest->request.serverNonce) { krb5_set_error_message(context, EINVAL, N_("nonce already set", "")); return EINVAL; } digest->request.serverNonce = strdup(nonce); if (digest->request.serverNonce == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } return 0; } KRB5_LIB_FUNCTION const char * KRB5_LIB_CALL krb5_digest_get_opaque(krb5_context context, krb5_digest digest) { return digest->initReply.opaque; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_digest_set_opaque(krb5_context context, krb5_digest digest, const char *opaque) { if (digest->request.opaque) { krb5_set_error_message(context, EINVAL, "opaque already set"); return EINVAL; } digest->request.opaque = strdup(opaque); if (digest->request.opaque == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } return 0; } KRB5_LIB_FUNCTION const char * KRB5_LIB_CALL krb5_digest_get_identifier(krb5_context context, krb5_digest digest) { if (digest->initReply.identifier == NULL) return NULL; return *digest->initReply.identifier; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_digest_set_identifier(krb5_context context, krb5_digest digest, const char *id) { if (digest->request.identifier) { krb5_set_error_message(context, EINVAL, N_("identifier already set", "")); return EINVAL; } digest->request.identifier = calloc(1, sizeof(*digest->request.identifier)); if (digest->request.identifier == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } *digest->request.identifier = strdup(id); if (*digest->request.identifier == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); free(digest->request.identifier); digest->request.identifier = NULL; return ENOMEM; } return 0; } static krb5_error_code digest_request(krb5_context context, krb5_realm realm, krb5_ccache ccache, krb5_key_usage usage, const DigestReqInner *ireq, DigestRepInner *irep) { DigestREQ req; DigestREP rep; krb5_error_code ret; krb5_data data, data2; size_t size = 0; krb5_crypto crypto = NULL; krb5_auth_context ac = NULL; krb5_principal principal = NULL; krb5_ccache id = NULL; krb5_realm r = NULL; krb5_data_zero(&data); krb5_data_zero(&data2); memset(&req, 0, sizeof(req)); memset(&rep, 0, sizeof(rep)); if (ccache == NULL) { ret = krb5_cc_default(context, &id); if (ret) goto out; } else id = ccache; if (realm == NULL) { ret = krb5_get_default_realm(context, &r); if (ret) goto out; } else r = realm; /* * */ ret = krb5_make_principal(context, &principal, r, KRB5_DIGEST_NAME, r, NULL); if (ret) goto out; ASN1_MALLOC_ENCODE(DigestReqInner, data.data, data.length, ireq, &size, ret); if (ret) { krb5_set_error_message(context, ret, N_("Failed to encode digest inner request", "")); goto out; } if (size != data.length) krb5_abortx(context, "ASN.1 internal encoder error"); ret = krb5_mk_req_exact(context, &ac, AP_OPTS_USE_SUBKEY|AP_OPTS_MUTUAL_REQUIRED, principal, NULL, id, &req.apReq); if (ret) goto out; { krb5_keyblock *key; ret = krb5_auth_con_getlocalsubkey(context, ac, &key); if (ret) goto out; if (key == NULL) { ret = EINVAL; krb5_set_error_message(context, ret, N_("Digest failed to get local subkey", "")); goto out; } ret = krb5_crypto_init(context, key, 0, &crypto); krb5_free_keyblock (context, key); if (ret) goto out; } ret = krb5_encrypt_EncryptedData(context, crypto, usage, data.data, data.length, 0, &req.innerReq); if (ret) goto out; krb5_data_free(&data); ASN1_MALLOC_ENCODE(DigestREQ, data.data, data.length, &req, &size, ret); if (ret) { krb5_set_error_message(context, ret, N_("Failed to encode DigestREQest", "")); goto out; } if (size != data.length) krb5_abortx(context, "ASN.1 internal encoder error"); ret = krb5_sendto_kdc(context, &data, &r, &data2); if (ret) goto out; ret = decode_DigestREP(data2.data, data2.length, &rep, NULL); if (ret) { krb5_set_error_message(context, ret, N_("Failed to parse digest response", "")); goto out; } { krb5_ap_rep_enc_part *repl; ret = krb5_rd_rep(context, ac, &rep.apRep, &repl); if (ret) goto out; krb5_free_ap_rep_enc_part(context, repl); } { krb5_keyblock *key; ret = krb5_auth_con_getremotesubkey(context, ac, &key); if (ret) goto out; if (key == NULL) { ret = EINVAL; krb5_set_error_message(context, ret, N_("Digest reply have no remote subkey", "")); goto out; } krb5_crypto_destroy(context, crypto); ret = krb5_crypto_init(context, key, 0, &crypto); krb5_free_keyblock (context, key); if (ret) goto out; } krb5_data_free(&data); ret = krb5_decrypt_EncryptedData(context, crypto, usage, &rep.innerRep, &data); if (ret) goto out; ret = decode_DigestRepInner(data.data, data.length, irep, NULL); if (ret) { krb5_set_error_message(context, ret, N_("Failed to decode digest inner reply", "")); goto out; } out: if (ccache == NULL && id) krb5_cc_close(context, id); if (realm == NULL && r) free(r); if (crypto) krb5_crypto_destroy(context, crypto); if (ac) krb5_auth_con_free(context, ac); if (principal) krb5_free_principal(context, principal); krb5_data_free(&data); krb5_data_free(&data2); free_DigestREQ(&req); free_DigestREP(&rep); return ret; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_digest_init_request(krb5_context context, krb5_digest digest, krb5_realm realm, krb5_ccache ccache) { DigestReqInner ireq; DigestRepInner irep; krb5_error_code ret; memset(&ireq, 0, sizeof(ireq)); memset(&irep, 0, sizeof(irep)); if (digest->init.type == NULL) { krb5_set_error_message(context, EINVAL, N_("Type missing from init req", "")); return EINVAL; } ireq.element = choice_DigestReqInner_init; ireq.u.init = digest->init; ret = digest_request(context, realm, ccache, KRB5_KU_DIGEST_ENCRYPT, &ireq, &irep); if (ret) goto out; if (irep.element == choice_DigestRepInner_error) { ret = irep.u.error.code; krb5_set_error_message(context, ret, N_("Digest init error: %s", ""), irep.u.error.reason); goto out; } if (irep.element != choice_DigestRepInner_initReply) { ret = EINVAL; krb5_set_error_message(context, ret, N_("digest reply not an initReply", "")); goto out; } ret = copy_DigestInitReply(&irep.u.initReply, &digest->initReply); if (ret) { krb5_set_error_message(context, ret, N_("Failed to copy initReply", "")); goto out; } out: free_DigestRepInner(&irep); return ret; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_digest_set_client_nonce(krb5_context context, krb5_digest digest, const char *nonce) { if (digest->request.clientNonce) { krb5_set_error_message(context, EINVAL, N_("clientNonce already set", "")); return EINVAL; } digest->request.clientNonce = calloc(1, sizeof(*digest->request.clientNonce)); if (digest->request.clientNonce == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } *digest->request.clientNonce = strdup(nonce); if (*digest->request.clientNonce == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); free(digest->request.clientNonce); digest->request.clientNonce = NULL; return ENOMEM; } return 0; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_digest_set_digest(krb5_context context, krb5_digest digest, const char *dgst) { if (digest->request.digest) { krb5_set_error_message(context, EINVAL, N_("digest already set", "")); return EINVAL; } digest->request.digest = strdup(dgst); if (digest->request.digest == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } return 0; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_digest_set_username(krb5_context context, krb5_digest digest, const char *username) { if (digest->request.username) { krb5_set_error_message(context, EINVAL, "username already set"); return EINVAL; } digest->request.username = strdup(username); if (digest->request.username == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } return 0; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_digest_set_authid(krb5_context context, krb5_digest digest, const char *authid) { if (digest->request.authid) { krb5_set_error_message(context, EINVAL, "authid already set"); return EINVAL; } digest->request.authid = malloc(sizeof(*digest->request.authid)); if (digest->request.authid == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } *digest->request.authid = strdup(authid); if (*digest->request.authid == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); free(digest->request.authid); digest->request.authid = NULL; return ENOMEM; } return 0; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_digest_set_authentication_user(krb5_context context, krb5_digest digest, krb5_principal authentication_user) { krb5_error_code ret; if (digest->request.authentication_user) { krb5_set_error_message(context, EINVAL, N_("authentication_user already set", "")); return EINVAL; } ret = krb5_copy_principal(context, authentication_user, &digest->request.authentication_user); if (ret) return ret; return 0; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_digest_set_realm(krb5_context context, krb5_digest digest, const char *realm) { if (digest->request.realm) { krb5_set_error_message(context, EINVAL, "realm already set"); return EINVAL; } digest->request.realm = malloc(sizeof(*digest->request.realm)); if (digest->request.realm == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } *digest->request.realm = strdup(realm); if (*digest->request.realm == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); free(digest->request.realm); digest->request.realm = NULL; return ENOMEM; } return 0; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_digest_set_method(krb5_context context, krb5_digest digest, const char *method) { if (digest->request.method) { krb5_set_error_message(context, EINVAL, N_("method already set", "")); return EINVAL; } digest->request.method = malloc(sizeof(*digest->request.method)); if (digest->request.method == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } *digest->request.method = strdup(method); if (*digest->request.method == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); free(digest->request.method); digest->request.method = NULL; return ENOMEM; } return 0; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_digest_set_uri(krb5_context context, krb5_digest digest, const char *uri) { if (digest->request.uri) { krb5_set_error_message(context, EINVAL, N_("uri already set", "")); return EINVAL; } digest->request.uri = malloc(sizeof(*digest->request.uri)); if (digest->request.uri == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } *digest->request.uri = strdup(uri); if (*digest->request.uri == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); free(digest->request.uri); digest->request.uri = NULL; return ENOMEM; } return 0; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_digest_set_nonceCount(krb5_context context, krb5_digest digest, const char *nonce_count) { if (digest->request.nonceCount) { krb5_set_error_message(context, EINVAL, N_("nonceCount already set", "")); return EINVAL; } digest->request.nonceCount = malloc(sizeof(*digest->request.nonceCount)); if (digest->request.nonceCount == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } *digest->request.nonceCount = strdup(nonce_count); if (*digest->request.nonceCount == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); free(digest->request.nonceCount); digest->request.nonceCount = NULL; return ENOMEM; } return 0; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_digest_set_qop(krb5_context context, krb5_digest digest, const char *qop) { if (digest->request.qop) { krb5_set_error_message(context, EINVAL, "qop already set"); return EINVAL; } digest->request.qop = malloc(sizeof(*digest->request.qop)); if (digest->request.qop == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } *digest->request.qop = strdup(qop); if (*digest->request.qop == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); free(digest->request.qop); digest->request.qop = NULL; return ENOMEM; } return 0; } KRB5_LIB_FUNCTION int KRB5_LIB_CALL krb5_digest_set_responseData(krb5_context context, krb5_digest digest, const char *response) { digest->request.responseData = strdup(response); if (digest->request.responseData == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } return 0; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_digest_request(krb5_context context, krb5_digest digest, krb5_realm realm, krb5_ccache ccache) { DigestReqInner ireq; DigestRepInner irep; krb5_error_code ret; memset(&ireq, 0, sizeof(ireq)); memset(&irep, 0, sizeof(irep)); ireq.element = choice_DigestReqInner_digestRequest; ireq.u.digestRequest = digest->request; if (digest->request.type == NULL) { if (digest->init.type == NULL) { krb5_set_error_message(context, EINVAL, N_("Type missing from req", "")); return EINVAL; } ireq.u.digestRequest.type = digest->init.type; } if (ireq.u.digestRequest.digest == NULL) { static char md5[] = "md5"; ireq.u.digestRequest.digest = md5; } ret = digest_request(context, realm, ccache, KRB5_KU_DIGEST_ENCRYPT, &ireq, &irep); if (ret) return ret; if (irep.element == choice_DigestRepInner_error) { ret = irep.u.error.code; krb5_set_error_message(context, ret, N_("Digest response error: %s", ""), irep.u.error.reason); goto out; } if (irep.element != choice_DigestRepInner_response) { krb5_set_error_message(context, EINVAL, N_("digest reply not an DigestResponse", "")); ret = EINVAL; goto out; } ret = copy_DigestResponse(&irep.u.response, &digest->response); if (ret) { krb5_set_error_message(context, ret, N_("Failed to copy initReply,", "")); goto out; } out: free_DigestRepInner(&irep); return ret; } KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL krb5_digest_rep_get_status(krb5_context context, krb5_digest digest) { return digest->response.success ? TRUE : FALSE; } KRB5_LIB_FUNCTION const char * KRB5_LIB_CALL krb5_digest_get_rsp(krb5_context context, krb5_digest digest) { if (digest->response.rsp == NULL) return NULL; return *digest->response.rsp; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_digest_get_tickets(krb5_context context, krb5_digest digest, Ticket **tickets) { *tickets = NULL; return 0; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_digest_get_client_binding(krb5_context context, krb5_digest digest, char **type, char **binding) { if (digest->response.channel) { *type = strdup(digest->response.channel->cb_type); *binding = strdup(digest->response.channel->cb_binding); if (*type == NULL || *binding == NULL) { free(*type); free(*binding); krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } } else { *type = NULL; *binding = NULL; } return 0; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_digest_get_session_key(krb5_context context, krb5_digest digest, krb5_data *data) { krb5_error_code ret; krb5_data_zero(data); if (digest->response.session_key == NULL) return 0; ret = der_copy_octet_string(digest->response.session_key, data); if (ret) krb5_clear_error_message(context); return ret; } struct krb5_ntlm_data { NTLMInit init; NTLMInitReply initReply; NTLMRequest request; NTLMResponse response; }; KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_ntlm_alloc(krb5_context context, krb5_ntlm *ntlm) { *ntlm = calloc(1, sizeof(**ntlm)); if (*ntlm == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } return 0; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_ntlm_free(krb5_context context, krb5_ntlm ntlm) { free_NTLMInit(&ntlm->init); free_NTLMInitReply(&ntlm->initReply); free_NTLMRequest(&ntlm->request); free_NTLMResponse(&ntlm->response); memset(ntlm, 0, sizeof(*ntlm)); free(ntlm); return 0; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_ntlm_init_request(krb5_context context, krb5_ntlm ntlm, krb5_realm realm, krb5_ccache ccache, uint32_t flags, const char *hostname, const char *domainname) { DigestReqInner ireq; DigestRepInner irep; krb5_error_code ret; memset(&ireq, 0, sizeof(ireq)); memset(&irep, 0, sizeof(irep)); ntlm->init.flags = flags; if (hostname) { ALLOC(ntlm->init.hostname, 1); *ntlm->init.hostname = strdup(hostname); } if (domainname) { ALLOC(ntlm->init.domain, 1); *ntlm->init.domain = strdup(domainname); } ireq.element = choice_DigestReqInner_ntlmInit; ireq.u.ntlmInit = ntlm->init; ret = digest_request(context, realm, ccache, KRB5_KU_DIGEST_ENCRYPT, &ireq, &irep); if (ret) goto out; if (irep.element == choice_DigestRepInner_error) { ret = irep.u.error.code; krb5_set_error_message(context, ret, N_("Digest init error: %s", ""), irep.u.error.reason); goto out; } if (irep.element != choice_DigestRepInner_ntlmInitReply) { ret = EINVAL; krb5_set_error_message(context, ret, N_("ntlm reply not an initReply", "")); goto out; } ret = copy_NTLMInitReply(&irep.u.ntlmInitReply, &ntlm->initReply); if (ret) { krb5_set_error_message(context, ret, N_("Failed to copy initReply", "")); goto out; } out: free_DigestRepInner(&irep); return ret; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_ntlm_init_get_flags(krb5_context context, krb5_ntlm ntlm, uint32_t *flags) { *flags = ntlm->initReply.flags; return 0; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_ntlm_init_get_challange(krb5_context context, krb5_ntlm ntlm, krb5_data *challange) { krb5_error_code ret; ret = der_copy_octet_string(&ntlm->initReply.challange, challange); if (ret) krb5_clear_error_message(context); return ret; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_ntlm_init_get_opaque(krb5_context context, krb5_ntlm ntlm, krb5_data *opaque) { krb5_error_code ret; ret = der_copy_octet_string(&ntlm->initReply.opaque, opaque); if (ret) krb5_clear_error_message(context); return ret; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_ntlm_init_get_targetname(krb5_context context, krb5_ntlm ntlm, char **name) { *name = strdup(ntlm->initReply.targetname); if (*name == NULL) { krb5_clear_error_message(context); return ENOMEM; } return 0; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_ntlm_init_get_targetinfo(krb5_context context, krb5_ntlm ntlm, krb5_data *data) { krb5_error_code ret; if (ntlm->initReply.targetinfo == NULL) { krb5_data_zero(data); return 0; } ret = krb5_data_copy(data, ntlm->initReply.targetinfo->data, ntlm->initReply.targetinfo->length); if (ret) { krb5_clear_error_message(context); return ret; } return 0; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_ntlm_request(krb5_context context, krb5_ntlm ntlm, krb5_realm realm, krb5_ccache ccache) { DigestReqInner ireq; DigestRepInner irep; krb5_error_code ret; memset(&ireq, 0, sizeof(ireq)); memset(&irep, 0, sizeof(irep)); ireq.element = choice_DigestReqInner_ntlmRequest; ireq.u.ntlmRequest = ntlm->request; ret = digest_request(context, realm, ccache, KRB5_KU_DIGEST_ENCRYPT, &ireq, &irep); if (ret) return ret; if (irep.element == choice_DigestRepInner_error) { ret = irep.u.error.code; krb5_set_error_message(context, ret, N_("NTLM response error: %s", ""), irep.u.error.reason); goto out; } if (irep.element != choice_DigestRepInner_ntlmResponse) { ret = EINVAL; krb5_set_error_message(context, ret, N_("NTLM reply not an NTLMResponse", "")); goto out; } ret = copy_NTLMResponse(&irep.u.ntlmResponse, &ntlm->response); if (ret) { krb5_set_error_message(context, ret, N_("Failed to copy NTLMResponse", "")); goto out; } out: free_DigestRepInner(&irep); return ret; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_ntlm_req_set_flags(krb5_context context, krb5_ntlm ntlm, uint32_t flags) { ntlm->request.flags = flags; return 0; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_ntlm_req_set_username(krb5_context context, krb5_ntlm ntlm, const char *username) { ntlm->request.username = strdup(username); if (ntlm->request.username == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } return 0; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_ntlm_req_set_targetname(krb5_context context, krb5_ntlm ntlm, const char *targetname) { ntlm->request.targetname = strdup(targetname); if (ntlm->request.targetname == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } return 0; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_ntlm_req_set_lm(krb5_context context, krb5_ntlm ntlm, void *hash, size_t len) { ntlm->request.lm.data = malloc(len); if (ntlm->request.lm.data == NULL && len != 0) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } ntlm->request.lm.length = len; memcpy(ntlm->request.lm.data, hash, len); return 0; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_ntlm_req_set_ntlm(krb5_context context, krb5_ntlm ntlm, void *hash, size_t len) { ntlm->request.ntlm.data = malloc(len); if (ntlm->request.ntlm.data == NULL && len != 0) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } ntlm->request.ntlm.length = len; memcpy(ntlm->request.ntlm.data, hash, len); return 0; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_ntlm_req_set_opaque(krb5_context context, krb5_ntlm ntlm, krb5_data *opaque) { ntlm->request.opaque.data = malloc(opaque->length); if (ntlm->request.opaque.data == NULL && opaque->length != 0) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } ntlm->request.opaque.length = opaque->length; memcpy(ntlm->request.opaque.data, opaque->data, opaque->length); return 0; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_ntlm_req_set_session(krb5_context context, krb5_ntlm ntlm, void *sessionkey, size_t length) { ntlm->request.sessionkey = calloc(1, sizeof(*ntlm->request.sessionkey)); if (ntlm->request.sessionkey == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } ntlm->request.sessionkey->data = malloc(length); if (ntlm->request.sessionkey->data == NULL && length != 0) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } memcpy(ntlm->request.sessionkey->data, sessionkey, length); ntlm->request.sessionkey->length = length; return 0; } KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL krb5_ntlm_rep_get_status(krb5_context context, krb5_ntlm ntlm) { return ntlm->response.success ? TRUE : FALSE; } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_ntlm_rep_get_sessionkey(krb5_context context, krb5_ntlm ntlm, krb5_data *data) { if (ntlm->response.sessionkey == NULL) { krb5_set_error_message(context, EINVAL, N_("no ntlm session key", "")); return EINVAL; } krb5_clear_error_message(context); return krb5_data_copy(data, ntlm->response.sessionkey->data, ntlm->response.sessionkey->length); } /** * Get the supported/allowed mechanism for this principal. * * @param context A Keberos context. * @param realm The realm of the KDC. * @param ccache The credential cache to use when talking to the KDC. * @param flags The supported mechanism. * * @return Return an error code or 0. * * @ingroup krb5_digest */ KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_digest_probe(krb5_context context, krb5_realm realm, krb5_ccache ccache, unsigned *flags) { DigestReqInner ireq; DigestRepInner irep; krb5_error_code ret; memset(&ireq, 0, sizeof(ireq)); memset(&irep, 0, sizeof(irep)); ireq.element = choice_DigestReqInner_supportedMechs; ret = digest_request(context, realm, ccache, KRB5_KU_DIGEST_ENCRYPT, &ireq, &irep); if (ret) goto out; if (irep.element == choice_DigestRepInner_error) { ret = irep.u.error.code; krb5_set_error_message(context, ret, "Digest probe error: %s", irep.u.error.reason); goto out; } if (irep.element != choice_DigestRepInner_supportedMechs) { ret = EINVAL; krb5_set_error_message(context, ret, "Digest reply not an probe"); goto out; } *flags = DigestTypes2int(irep.u.supportedMechs); out: free_DigestRepInner(&irep); return ret; } #endif /* HEIMDAL_SMALLER */
Upload File
Create Folder