2 * Copyright (c) 2006 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include "krb5_locl.h"
35 #include "digest_asn1.h"
37 #ifndef HEIMDAL_SMALLER
39 struct krb5_digest_data
{
44 DigestInitReply initReply
;
45 DigestRequest request
;
46 DigestResponse response
;
50 krb5_digest_alloc(krb5_context context
, krb5_digest
*digest
)
54 d
= calloc(1, sizeof(*d
));
57 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
66 krb5_digest_free(krb5_digest digest
)
70 free_DigestInit(&digest
->init
);
71 free_DigestInitReply(&digest
->initReply
);
72 free_DigestRequest(&digest
->request
);
73 free_DigestResponse(&digest
->response
);
74 memset(digest
, 0, sizeof(*digest
));
80 krb5_digest_set_server_cb(krb5_context context
,
85 if (digest
->init
.channel
) {
86 krb5_set_error_message(context
, EINVAL
,
87 N_("server channel binding already set", ""));
90 digest
->init
.channel
= calloc(1, sizeof(*digest
->init
.channel
));
91 if (digest
->init
.channel
== NULL
)
94 digest
->init
.channel
->cb_type
= strdup(type
);
95 if (digest
->init
.channel
->cb_type
== NULL
)
98 digest
->init
.channel
->cb_binding
= strdup(binding
);
99 if (digest
->init
.channel
->cb_binding
== NULL
)
103 if (digest
->init
.channel
) {
104 free(digest
->init
.channel
->cb_type
);
105 free(digest
->init
.channel
->cb_binding
);
106 free(digest
->init
.channel
);
107 digest
->init
.channel
= NULL
;
109 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
114 krb5_digest_set_type(krb5_context context
,
118 if (digest
->init
.type
) {
119 krb5_set_error_message(context
, EINVAL
, "client type already set");
122 digest
->init
.type
= strdup(type
);
123 if (digest
->init
.type
== NULL
) {
124 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
131 krb5_digest_set_hostname(krb5_context context
,
133 const char *hostname
)
135 if (digest
->init
.hostname
) {
136 krb5_set_error_message(context
, EINVAL
, "server hostname already set");
139 digest
->init
.hostname
= malloc(sizeof(*digest
->init
.hostname
));
140 if (digest
->init
.hostname
== NULL
) {
141 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
144 *digest
->init
.hostname
= strdup(hostname
);
145 if (*digest
->init
.hostname
== NULL
) {
146 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
147 free(digest
->init
.hostname
);
148 digest
->init
.hostname
= NULL
;
155 krb5_digest_get_server_nonce(krb5_context context
,
158 return digest
->initReply
.nonce
;
162 krb5_digest_set_server_nonce(krb5_context context
,
166 if (digest
->request
.serverNonce
) {
167 krb5_set_error_message(context
, EINVAL
, N_("nonce already set", ""));
170 digest
->request
.serverNonce
= strdup(nonce
);
171 if (digest
->request
.serverNonce
== NULL
) {
172 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
179 krb5_digest_get_opaque(krb5_context context
,
182 return digest
->initReply
.opaque
;
186 krb5_digest_set_opaque(krb5_context context
,
190 if (digest
->request
.opaque
) {
191 krb5_set_error_message(context
, EINVAL
, "opaque already set");
194 digest
->request
.opaque
= strdup(opaque
);
195 if (digest
->request
.opaque
== NULL
) {
196 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
203 krb5_digest_get_identifier(krb5_context context
,
206 if (digest
->initReply
.identifier
== NULL
)
208 return *digest
->initReply
.identifier
;
212 krb5_digest_set_identifier(krb5_context context
,
216 if (digest
->request
.identifier
) {
217 krb5_set_error_message(context
, EINVAL
, N_("identifier already set", ""));
220 digest
->request
.identifier
= calloc(1, sizeof(*digest
->request
.identifier
));
221 if (digest
->request
.identifier
== NULL
) {
222 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
225 *digest
->request
.identifier
= strdup(id
);
226 if (*digest
->request
.identifier
== NULL
) {
227 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
228 free(digest
->request
.identifier
);
229 digest
->request
.identifier
= NULL
;
235 static krb5_error_code
236 digest_request(krb5_context context
,
239 krb5_key_usage usage
,
240 const DigestReqInner
*ireq
,
241 DigestRepInner
*irep
)
246 krb5_data data
, data2
;
248 krb5_crypto crypto
= NULL
;
249 krb5_auth_context ac
= NULL
;
250 krb5_principal principal
= NULL
;
251 krb5_ccache id
= NULL
;
254 krb5_data_zero(&data
);
255 krb5_data_zero(&data2
);
256 memset(&req
, 0, sizeof(req
));
257 memset(&rep
, 0, sizeof(rep
));
259 if (ccache
== NULL
) {
260 ret
= krb5_cc_default(context
, &id
);
267 ret
= krb5_get_default_realm(context
, &r
);
277 ret
= krb5_make_principal(context
, &principal
,
278 r
, KRB5_DIGEST_NAME
, r
, NULL
);
282 ASN1_MALLOC_ENCODE(DigestReqInner
, data
.data
, data
.length
,
285 krb5_set_error_message(context
, ret
,
286 N_("Failed to encode digest inner request", ""));
289 if (size
!= data
.length
)
290 krb5_abortx(context
, "ASN.1 internal encoder error");
292 ret
= krb5_mk_req_exact(context
, &ac
,
293 AP_OPTS_USE_SUBKEY
|AP_OPTS_MUTUAL_REQUIRED
,
294 principal
, NULL
, id
, &req
.apReq
);
301 ret
= krb5_auth_con_getlocalsubkey(context
, ac
, &key
);
306 krb5_set_error_message(context
, ret
,
307 N_("Digest failed to get local subkey", ""));
311 ret
= krb5_crypto_init(context
, key
, 0, &crypto
);
312 krb5_free_keyblock (context
, key
);
317 ret
= krb5_encrypt_EncryptedData(context
, crypto
, usage
,
318 data
.data
, data
.length
, 0,
323 krb5_data_free(&data
);
325 ASN1_MALLOC_ENCODE(DigestREQ
, data
.data
, data
.length
,
328 krb5_set_error_message(context
, ret
,
329 N_("Failed to encode DigestREQest", ""));
332 if (size
!= data
.length
)
333 krb5_abortx(context
, "ASN.1 internal encoder error");
335 ret
= krb5_sendto_kdc(context
, &data
, &r
, &data2
);
339 ret
= decode_DigestREP(data2
.data
, data2
.length
, &rep
, NULL
);
341 krb5_set_error_message(context
, ret
,
342 N_("Failed to parse digest response", ""));
347 krb5_ap_rep_enc_part
*repl
;
349 ret
= krb5_rd_rep(context
, ac
, &rep
.apRep
, &repl
);
353 krb5_free_ap_rep_enc_part(context
, repl
);
358 ret
= krb5_auth_con_getremotesubkey(context
, ac
, &key
);
363 krb5_set_error_message(context
, ret
,
364 N_("Digest reply have no remote subkey", ""));
368 krb5_crypto_destroy(context
, crypto
);
369 ret
= krb5_crypto_init(context
, key
, 0, &crypto
);
370 krb5_free_keyblock (context
, key
);
375 krb5_data_free(&data
);
376 ret
= krb5_decrypt_EncryptedData(context
, crypto
, usage
,
377 &rep
.innerRep
, &data
);
381 ret
= decode_DigestRepInner(data
.data
, data
.length
, irep
, NULL
);
383 krb5_set_error_message(context
, ret
,
384 N_("Failed to decode digest inner reply", ""));
389 if (ccache
== NULL
&& id
)
390 krb5_cc_close(context
, id
);
391 if (realm
== NULL
&& r
)
394 krb5_crypto_destroy(context
, crypto
);
396 krb5_auth_con_free(context
, ac
);
398 krb5_free_principal(context
, principal
);
400 krb5_data_free(&data
);
401 krb5_data_free(&data2
);
403 free_DigestREQ(&req
);
404 free_DigestREP(&rep
);
410 krb5_digest_init_request(krb5_context context
,
419 memset(&ireq
, 0, sizeof(ireq
));
420 memset(&irep
, 0, sizeof(irep
));
422 if (digest
->init
.type
== NULL
) {
423 krb5_set_error_message(context
, EINVAL
,
424 N_("Type missing from init req", ""));
428 ireq
.element
= choice_DigestReqInner_init
;
429 ireq
.u
.init
= digest
->init
;
431 ret
= digest_request(context
, realm
, ccache
,
432 KRB5_KU_DIGEST_ENCRYPT
, &ireq
, &irep
);
436 if (irep
.element
== choice_DigestRepInner_error
) {
437 ret
= irep
.u
.error
.code
;
438 krb5_set_error_message(context
, ret
, N_("Digest init error: %s", ""),
439 irep
.u
.error
.reason
);
443 if (irep
.element
!= choice_DigestRepInner_initReply
) {
445 krb5_set_error_message(context
, ret
,
446 N_("digest reply not an initReply", ""));
450 ret
= copy_DigestInitReply(&irep
.u
.initReply
, &digest
->initReply
);
452 krb5_set_error_message(context
, ret
,
453 N_("Failed to copy initReply", ""));
458 free_DigestRepInner(&irep
);
465 krb5_digest_set_client_nonce(krb5_context context
,
469 if (digest
->request
.clientNonce
) {
470 krb5_set_error_message(context
, EINVAL
,
471 N_("clientNonce already set", ""));
474 digest
->request
.clientNonce
=
475 calloc(1, sizeof(*digest
->request
.clientNonce
));
476 if (digest
->request
.clientNonce
== NULL
) {
477 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
480 *digest
->request
.clientNonce
= strdup(nonce
);
481 if (*digest
->request
.clientNonce
== NULL
) {
482 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
483 free(digest
->request
.clientNonce
);
484 digest
->request
.clientNonce
= NULL
;
491 krb5_digest_set_digest(krb5_context context
,
495 if (digest
->request
.digest
) {
496 krb5_set_error_message(context
, EINVAL
,
497 N_("digest already set", ""));
500 digest
->request
.digest
= strdup(dgst
);
501 if (digest
->request
.digest
== NULL
) {
502 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
509 krb5_digest_set_username(krb5_context context
,
511 const char *username
)
513 if (digest
->request
.username
) {
514 krb5_set_error_message(context
, EINVAL
, "username already set");
517 digest
->request
.username
= strdup(username
);
518 if (digest
->request
.username
== NULL
) {
519 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
526 krb5_digest_set_authid(krb5_context context
,
530 if (digest
->request
.authid
) {
531 krb5_set_error_message(context
, EINVAL
, "authid already set");
534 digest
->request
.authid
= malloc(sizeof(*digest
->request
.authid
));
535 if (digest
->request
.authid
== NULL
) {
536 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
539 *digest
->request
.authid
= strdup(authid
);
540 if (*digest
->request
.authid
== NULL
) {
541 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
542 free(digest
->request
.authid
);
543 digest
->request
.authid
= NULL
;
550 krb5_digest_set_authentication_user(krb5_context context
,
552 krb5_principal authentication_user
)
556 if (digest
->request
.authentication_user
) {
557 krb5_set_error_message(context
, EINVAL
,
558 N_("authentication_user already set", ""));
561 ret
= krb5_copy_principal(context
,
563 &digest
->request
.authentication_user
);
570 krb5_digest_set_realm(krb5_context context
,
574 if (digest
->request
.realm
) {
575 krb5_set_error_message(context
, EINVAL
, "realm already set");
578 digest
->request
.realm
= malloc(sizeof(*digest
->request
.realm
));
579 if (digest
->request
.realm
== NULL
) {
580 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
583 *digest
->request
.realm
= strdup(realm
);
584 if (*digest
->request
.realm
== NULL
) {
585 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
586 free(digest
->request
.realm
);
587 digest
->request
.realm
= NULL
;
594 krb5_digest_set_method(krb5_context context
,
598 if (digest
->request
.method
) {
599 krb5_set_error_message(context
, EINVAL
,
600 N_("method already set", ""));
603 digest
->request
.method
= malloc(sizeof(*digest
->request
.method
));
604 if (digest
->request
.method
== NULL
) {
605 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
608 *digest
->request
.method
= strdup(method
);
609 if (*digest
->request
.method
== NULL
) {
610 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
611 free(digest
->request
.method
);
612 digest
->request
.method
= NULL
;
619 krb5_digest_set_uri(krb5_context context
,
623 if (digest
->request
.uri
) {
624 krb5_set_error_message(context
, EINVAL
, N_("uri already set", ""));
627 digest
->request
.uri
= malloc(sizeof(*digest
->request
.uri
));
628 if (digest
->request
.uri
== NULL
) {
629 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
632 *digest
->request
.uri
= strdup(uri
);
633 if (*digest
->request
.uri
== NULL
) {
634 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
635 free(digest
->request
.uri
);
636 digest
->request
.uri
= NULL
;
643 krb5_digest_set_nonceCount(krb5_context context
,
645 const char *nonce_count
)
647 if (digest
->request
.nonceCount
) {
648 krb5_set_error_message(context
, EINVAL
,
649 N_("nonceCount already set", ""));
652 digest
->request
.nonceCount
=
653 malloc(sizeof(*digest
->request
.nonceCount
));
654 if (digest
->request
.nonceCount
== NULL
) {
655 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
658 *digest
->request
.nonceCount
= strdup(nonce_count
);
659 if (*digest
->request
.nonceCount
== NULL
) {
660 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
661 free(digest
->request
.nonceCount
);
662 digest
->request
.nonceCount
= NULL
;
669 krb5_digest_set_qop(krb5_context context
,
673 if (digest
->request
.qop
) {
674 krb5_set_error_message(context
, EINVAL
, "qop already set");
677 digest
->request
.qop
= malloc(sizeof(*digest
->request
.qop
));
678 if (digest
->request
.qop
== NULL
) {
679 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
682 *digest
->request
.qop
= strdup(qop
);
683 if (*digest
->request
.qop
== NULL
) {
684 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
685 free(digest
->request
.qop
);
686 digest
->request
.qop
= NULL
;
693 krb5_digest_set_responseData(krb5_context context
,
695 const char *response
)
697 digest
->request
.responseData
= strdup(response
);
698 if (digest
->request
.responseData
== NULL
) {
699 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
706 krb5_digest_request(krb5_context context
,
715 memset(&ireq
, 0, sizeof(ireq
));
716 memset(&irep
, 0, sizeof(irep
));
718 ireq
.element
= choice_DigestReqInner_digestRequest
;
719 ireq
.u
.digestRequest
= digest
->request
;
721 if (digest
->request
.type
== NULL
) {
722 if (digest
->init
.type
== NULL
) {
723 krb5_set_error_message(context
, EINVAL
,
724 N_("Type missing from req", ""));
727 ireq
.u
.digestRequest
.type
= digest
->init
.type
;
730 if (ireq
.u
.digestRequest
.digest
== NULL
)
731 ireq
.u
.digestRequest
.digest
= "md5";
733 ret
= digest_request(context
, realm
, ccache
,
734 KRB5_KU_DIGEST_ENCRYPT
, &ireq
, &irep
);
738 if (irep
.element
== choice_DigestRepInner_error
) {
739 ret
= irep
.u
.error
.code
;
740 krb5_set_error_message(context
, ret
,
741 N_("Digest response error: %s", ""),
742 irep
.u
.error
.reason
);
746 if (irep
.element
!= choice_DigestRepInner_response
) {
747 krb5_set_error_message(context
, EINVAL
,
748 N_("digest reply not an DigestResponse", ""));
753 ret
= copy_DigestResponse(&irep
.u
.response
, &digest
->response
);
755 krb5_set_error_message(context
, ret
,
756 N_("Failed to copy initReply,", ""));
761 free_DigestRepInner(&irep
);
767 krb5_digest_rep_get_status(krb5_context context
,
770 return digest
->response
.success
? TRUE
: FALSE
;
774 krb5_digest_get_rsp(krb5_context context
,
777 if (digest
->response
.rsp
== NULL
)
779 return *digest
->response
.rsp
;
783 krb5_digest_get_tickets(krb5_context context
,
793 krb5_digest_get_client_binding(krb5_context context
,
798 if (digest
->response
.channel
) {
799 *type
= strdup(digest
->response
.channel
->cb_type
);
800 *binding
= strdup(digest
->response
.channel
->cb_binding
);
801 if (*type
== NULL
|| *binding
== NULL
) {
804 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
815 krb5_digest_get_session_key(krb5_context context
,
821 krb5_data_zero(data
);
822 if (digest
->response
.session_key
== NULL
)
824 ret
= der_copy_octet_string(digest
->response
.session_key
, data
);
826 krb5_clear_error_message(context
);
831 struct krb5_ntlm_data
{
833 NTLMInitReply initReply
;
835 NTLMResponse response
;
839 krb5_ntlm_alloc(krb5_context context
,
842 *ntlm
= calloc(1, sizeof(**ntlm
));
844 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
851 krb5_ntlm_free(krb5_context context
, krb5_ntlm ntlm
)
853 free_NTLMInit(&ntlm
->init
);
854 free_NTLMInitReply(&ntlm
->initReply
);
855 free_NTLMRequest(&ntlm
->request
);
856 free_NTLMResponse(&ntlm
->response
);
857 memset(ntlm
, 0, sizeof(*ntlm
));
864 krb5_ntlm_init_request(krb5_context context
,
869 const char *hostname
,
870 const char *domainname
)
876 memset(&ireq
, 0, sizeof(ireq
));
877 memset(&irep
, 0, sizeof(irep
));
879 ntlm
->init
.flags
= flags
;
881 ALLOC(ntlm
->init
.hostname
, 1);
882 *ntlm
->init
.hostname
= strdup(hostname
);
885 ALLOC(ntlm
->init
.domain
, 1);
886 *ntlm
->init
.domain
= strdup(domainname
);
889 ireq
.element
= choice_DigestReqInner_ntlmInit
;
890 ireq
.u
.ntlmInit
= ntlm
->init
;
892 ret
= digest_request(context
, realm
, ccache
,
893 KRB5_KU_DIGEST_ENCRYPT
, &ireq
, &irep
);
897 if (irep
.element
== choice_DigestRepInner_error
) {
898 ret
= irep
.u
.error
.code
;
899 krb5_set_error_message(context
, ret
, N_("Digest init error: %s", ""),
900 irep
.u
.error
.reason
);
904 if (irep
.element
!= choice_DigestRepInner_ntlmInitReply
) {
906 krb5_set_error_message(context
, ret
,
907 N_("ntlm reply not an initReply", ""));
911 ret
= copy_NTLMInitReply(&irep
.u
.ntlmInitReply
, &ntlm
->initReply
);
913 krb5_set_error_message(context
, ret
,
914 N_("Failed to copy initReply", ""));
919 free_DigestRepInner(&irep
);
925 krb5_ntlm_init_get_flags(krb5_context context
,
929 *flags
= ntlm
->initReply
.flags
;
934 krb5_ntlm_init_get_challange(krb5_context context
,
936 krb5_data
*challange
)
940 ret
= der_copy_octet_string(&ntlm
->initReply
.challange
, challange
);
942 krb5_clear_error_message(context
);
948 krb5_ntlm_init_get_opaque(krb5_context context
,
954 ret
= der_copy_octet_string(&ntlm
->initReply
.opaque
, opaque
);
956 krb5_clear_error_message(context
);
962 krb5_ntlm_init_get_targetname(krb5_context context
,
966 *name
= strdup(ntlm
->initReply
.targetname
);
968 krb5_clear_error_message(context
);
975 krb5_ntlm_init_get_targetinfo(krb5_context context
,
981 if (ntlm
->initReply
.targetinfo
== NULL
) {
982 krb5_data_zero(data
);
986 ret
= krb5_data_copy(data
,
987 ntlm
->initReply
.targetinfo
->data
,
988 ntlm
->initReply
.targetinfo
->length
);
990 krb5_clear_error_message(context
);
998 krb5_ntlm_request(krb5_context context
,
1003 DigestReqInner ireq
;
1004 DigestRepInner irep
;
1005 krb5_error_code ret
;
1007 memset(&ireq
, 0, sizeof(ireq
));
1008 memset(&irep
, 0, sizeof(irep
));
1010 ireq
.element
= choice_DigestReqInner_ntlmRequest
;
1011 ireq
.u
.ntlmRequest
= ntlm
->request
;
1013 ret
= digest_request(context
, realm
, ccache
,
1014 KRB5_KU_DIGEST_ENCRYPT
, &ireq
, &irep
);
1018 if (irep
.element
== choice_DigestRepInner_error
) {
1019 ret
= irep
.u
.error
.code
;
1020 krb5_set_error_message(context
, ret
,
1021 N_("NTLM response error: %s", ""),
1022 irep
.u
.error
.reason
);
1026 if (irep
.element
!= choice_DigestRepInner_ntlmResponse
) {
1028 krb5_set_error_message(context
, ret
,
1029 N_("NTLM reply not an NTLMResponse", ""));
1033 ret
= copy_NTLMResponse(&irep
.u
.ntlmResponse
, &ntlm
->response
);
1035 krb5_set_error_message(context
, ret
,
1036 N_("Failed to copy NTLMResponse", ""));
1041 free_DigestRepInner(&irep
);
1047 krb5_ntlm_req_set_flags(krb5_context context
,
1051 ntlm
->request
.flags
= flags
;
1056 krb5_ntlm_req_set_username(krb5_context context
,
1058 const char *username
)
1060 ntlm
->request
.username
= strdup(username
);
1061 if (ntlm
->request
.username
== NULL
) {
1062 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
1069 krb5_ntlm_req_set_targetname(krb5_context context
,
1071 const char *targetname
)
1073 ntlm
->request
.targetname
= strdup(targetname
);
1074 if (ntlm
->request
.targetname
== NULL
) {
1075 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
1082 krb5_ntlm_req_set_lm(krb5_context context
,
1084 void *hash
, size_t len
)
1086 ntlm
->request
.lm
.data
= malloc(len
);
1087 if (ntlm
->request
.lm
.data
== NULL
&& len
!= 0) {
1088 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
1091 ntlm
->request
.lm
.length
= len
;
1092 memcpy(ntlm
->request
.lm
.data
, hash
, len
);
1097 krb5_ntlm_req_set_ntlm(krb5_context context
,
1099 void *hash
, size_t len
)
1101 ntlm
->request
.ntlm
.data
= malloc(len
);
1102 if (ntlm
->request
.ntlm
.data
== NULL
&& len
!= 0) {
1103 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
1106 ntlm
->request
.ntlm
.length
= len
;
1107 memcpy(ntlm
->request
.ntlm
.data
, hash
, len
);
1112 krb5_ntlm_req_set_opaque(krb5_context context
,
1116 ntlm
->request
.opaque
.data
= malloc(opaque
->length
);
1117 if (ntlm
->request
.opaque
.data
== NULL
&& opaque
->length
!= 0) {
1118 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
1121 ntlm
->request
.opaque
.length
= opaque
->length
;
1122 memcpy(ntlm
->request
.opaque
.data
, opaque
->data
, opaque
->length
);
1127 krb5_ntlm_req_set_session(krb5_context context
,
1129 void *sessionkey
, size_t length
)
1131 ntlm
->request
.sessionkey
= calloc(1, sizeof(*ntlm
->request
.sessionkey
));
1132 if (ntlm
->request
.sessionkey
== NULL
) {
1133 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
1136 ntlm
->request
.sessionkey
->data
= malloc(length
);
1137 if (ntlm
->request
.sessionkey
->data
== NULL
&& length
!= 0) {
1138 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
1141 memcpy(ntlm
->request
.sessionkey
->data
, sessionkey
, length
);
1142 ntlm
->request
.sessionkey
->length
= length
;
1147 krb5_ntlm_rep_get_status(krb5_context context
,
1150 return ntlm
->response
.success
? TRUE
: FALSE
;
1154 krb5_ntlm_rep_get_sessionkey(krb5_context context
,
1158 if (ntlm
->response
.sessionkey
== NULL
) {
1159 krb5_set_error_message(context
, EINVAL
,
1160 N_("no ntlm session key", ""));
1163 krb5_clear_error_message(context
);
1164 return krb5_data_copy(data
,
1165 ntlm
->response
.sessionkey
->data
,
1166 ntlm
->response
.sessionkey
->length
);
1170 * Get the supported/allowed mechanism for this principal.
1172 * @param context A Keberos context.
1173 * @param realm The realm of the KDC.
1174 * @param ccache The credential cache to use when talking to the KDC.
1175 * @param flags The supported mechanism.
1177 * @return Return an error code or 0.
1179 * @ingroup krb5_digest
1183 krb5_digest_probe(krb5_context context
,
1188 DigestReqInner ireq
;
1189 DigestRepInner irep
;
1190 krb5_error_code ret
;
1192 memset(&ireq
, 0, sizeof(ireq
));
1193 memset(&irep
, 0, sizeof(irep
));
1195 ireq
.element
= choice_DigestReqInner_supportedMechs
;
1197 ret
= digest_request(context
, realm
, ccache
,
1198 KRB5_KU_DIGEST_ENCRYPT
, &ireq
, &irep
);
1202 if (irep
.element
== choice_DigestRepInner_error
) {
1203 ret
= irep
.u
.error
.code
;
1204 krb5_set_error_message(context
, ret
, "Digest probe error: %s",
1205 irep
.u
.error
.reason
);
1209 if (irep
.element
!= choice_DigestRepInner_supportedMechs
) {
1211 krb5_set_error_message(context
, ret
, "Digest reply not an probe");
1215 *flags
= DigestTypes2int(irep
.u
.supportedMechs
);
1218 free_DigestRepInner(&irep
);
1223 #endif /* HEIMDAL_SMALLER */