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"
36 #include "digest_asn1.h"
38 struct krb5_digest_data
{
43 DigestInitReply initReply
;
44 DigestRequest request
;
45 DigestResponse response
;
49 krb5_digest_alloc(krb5_context context
, krb5_digest
*digest
)
53 d
= calloc(1, sizeof(*d
));
56 krb5_set_error_string(context
, "out of memory");
65 krb5_digest_free(krb5_digest digest
)
69 free_DigestInit(&digest
->init
);
70 free_DigestInitReply(&digest
->initReply
);
71 free_DigestRequest(&digest
->request
);
72 free_DigestResponse(&digest
->response
);
73 memset(digest
, 0, sizeof(*digest
));
79 krb5_digest_set_server_cb(krb5_context context
,
84 if (digest
->init
.channel
) {
85 krb5_set_error_string(context
, "server channel binding already set");
88 digest
->init
.channel
= calloc(1, sizeof(*digest
->init
.channel
));
89 if (digest
->init
.channel
== NULL
)
92 digest
->init
.channel
->cb_type
= strdup(type
);
93 if (digest
->init
.channel
->cb_type
== NULL
)
96 digest
->init
.channel
->cb_binding
= strdup(binding
);
97 if (digest
->init
.channel
->cb_binding
== NULL
)
101 if (digest
->init
.channel
) {
102 free(digest
->init
.channel
->cb_type
);
103 free(digest
->init
.channel
->cb_binding
);
104 free(digest
->init
.channel
);
105 digest
->init
.channel
= NULL
;
107 krb5_set_error_string(context
, "out of memory");
112 krb5_digest_set_type(krb5_context context
,
116 if (digest
->init
.type
) {
117 krb5_set_error_string(context
, "client type already set");
120 digest
->init
.type
= strdup(type
);
121 if (digest
->init
.type
== NULL
) {
122 krb5_set_error_string(context
, "out of memory");
129 krb5_digest_set_hostname(krb5_context context
,
131 const char *hostname
)
133 if (digest
->init
.hostname
) {
134 krb5_set_error_string(context
, "server hostname already set");
137 digest
->init
.hostname
= malloc(sizeof(*digest
->init
.hostname
));
138 if (digest
->init
.hostname
== NULL
) {
139 krb5_set_error_string(context
, "out of memory");
142 *digest
->init
.hostname
= strdup(hostname
);
143 if (*digest
->init
.hostname
== NULL
) {
144 krb5_set_error_string(context
, "out of memory");
145 free(digest
->init
.hostname
);
146 digest
->init
.hostname
= NULL
;
153 krb5_digest_get_server_nonce(krb5_context context
,
156 return digest
->initReply
.nonce
;
160 krb5_digest_set_server_nonce(krb5_context context
,
164 if (digest
->request
.serverNonce
) {
165 krb5_set_error_string(context
, "nonce already set");
168 digest
->request
.serverNonce
= strdup(nonce
);
169 if (digest
->request
.serverNonce
== NULL
) {
170 krb5_set_error_string(context
, "out of memory");
177 krb5_digest_get_opaque(krb5_context context
,
180 return digest
->initReply
.opaque
;
184 krb5_digest_set_opaque(krb5_context context
,
188 if (digest
->request
.opaque
) {
189 krb5_set_error_string(context
, "opaque already set");
192 digest
->request
.opaque
= strdup(opaque
);
193 if (digest
->request
.opaque
== NULL
) {
194 krb5_set_error_string(context
, "out of memory");
201 krb5_digest_get_identifier(krb5_context context
,
204 if (digest
->initReply
.identifier
== NULL
)
206 return *digest
->initReply
.identifier
;
210 krb5_digest_set_identifier(krb5_context context
,
214 if (digest
->request
.identifier
) {
215 krb5_set_error_string(context
, "identifier already set");
218 digest
->request
.identifier
= calloc(1, sizeof(*digest
->request
.identifier
));
219 if (digest
->request
.identifier
== NULL
) {
220 krb5_set_error_string(context
, "out of memory");
223 *digest
->request
.identifier
= strdup(id
);
224 if (*digest
->request
.identifier
== NULL
) {
225 krb5_set_error_string(context
, "out of memory");
226 free(digest
->request
.identifier
);
227 digest
->request
.identifier
= NULL
;
233 static krb5_error_code
234 digest_request(krb5_context context
,
237 krb5_key_usage usage
,
238 const DigestReqInner
*ireq
,
239 DigestRepInner
*irep
)
244 krb5_data data
, data2
;
246 krb5_crypto crypto
= NULL
;
247 krb5_auth_context ac
= NULL
;
248 krb5_principal principal
= NULL
;
249 krb5_ccache id
= NULL
;
252 krb5_data_zero(&data
);
253 krb5_data_zero(&data2
);
254 memset(&req
, 0, sizeof(req
));
255 memset(&rep
, 0, sizeof(rep
));
257 if (ccache
== NULL
) {
258 ret
= krb5_cc_default(context
, &id
);
265 ret
= krb5_get_default_realm(context
, &r
);
275 ret
= krb5_make_principal(context
, &principal
,
276 r
, KRB5_DIGEST_NAME
, r
, NULL
);
280 ASN1_MALLOC_ENCODE(DigestReqInner
, data
.data
, data
.length
,
283 krb5_set_error_string(context
,
284 "Failed to encode digest inner request");
287 if (size
!= data
.length
)
288 krb5_abortx(context
, "ASN.1 internal encoder error");
290 ret
= krb5_mk_req_exact(context
, &ac
,
291 AP_OPTS_USE_SUBKEY
|AP_OPTS_MUTUAL_REQUIRED
,
292 principal
, NULL
, id
, &req
.apReq
);
299 ret
= krb5_auth_con_getlocalsubkey(context
, ac
, &key
);
303 krb5_set_error_string(context
, "Digest failed to get local subkey");
308 ret
= krb5_crypto_init(context
, key
, 0, &crypto
);
309 krb5_free_keyblock (context
, key
);
314 ret
= krb5_encrypt_EncryptedData(context
, crypto
, usage
,
315 data
.data
, data
.length
, 0,
320 krb5_data_free(&data
);
322 ASN1_MALLOC_ENCODE(DigestREQ
, data
.data
, data
.length
,
325 krb5_set_error_string(context
, "Failed to encode DigestREQest");
328 if (size
!= data
.length
)
329 krb5_abortx(context
, "ASN.1 internal encoder error");
331 ret
= krb5_sendto_kdc(context
, &data
, &r
, &data2
);
335 ret
= decode_DigestREP(data2
.data
, data2
.length
, &rep
, NULL
);
337 krb5_set_error_string(context
, "Failed to parse digest response");
342 krb5_ap_rep_enc_part
*repl
;
344 ret
= krb5_rd_rep(context
, ac
, &rep
.apRep
, &repl
);
348 krb5_free_ap_rep_enc_part(context
, repl
);
353 ret
= krb5_auth_con_getremotesubkey(context
, ac
, &key
);
358 krb5_set_error_string(context
,
359 "Digest reply have no remote subkey");
363 krb5_crypto_destroy(context
, crypto
);
364 ret
= krb5_crypto_init(context
, key
, 0, &crypto
);
365 krb5_free_keyblock (context
, key
);
370 krb5_data_free(&data
);
371 ret
= krb5_decrypt_EncryptedData(context
, crypto
, usage
,
372 &rep
.innerRep
, &data
);
376 ret
= decode_DigestRepInner(data
.data
, data
.length
, irep
, NULL
);
378 krb5_set_error_string(context
, "Failed to decode digest inner reply");
383 if (ccache
== NULL
&& id
)
384 krb5_cc_close(context
, id
);
385 if (realm
== NULL
&& r
)
388 krb5_crypto_destroy(context
, crypto
);
390 krb5_auth_con_free(context
, ac
);
392 krb5_free_principal(context
, principal
);
394 krb5_data_free(&data
);
395 krb5_data_free(&data2
);
397 free_DigestREQ(&req
);
398 free_DigestREP(&rep
);
404 krb5_digest_init_request(krb5_context context
,
413 memset(&ireq
, 0, sizeof(ireq
));
414 memset(&irep
, 0, sizeof(irep
));
416 if (digest
->init
.type
== NULL
) {
417 krb5_set_error_string(context
, "Type missing from init req");
421 ireq
.element
= choice_DigestReqInner_init
;
422 ireq
.u
.init
= digest
->init
;
424 ret
= digest_request(context
, realm
, ccache
,
425 KRB5_KU_DIGEST_ENCRYPT
, &ireq
, &irep
);
429 if (irep
.element
== choice_DigestRepInner_error
) {
430 krb5_set_error_string(context
, "Digest init error: %s",
431 irep
.u
.error
.reason
);
432 ret
= irep
.u
.error
.code
;
436 if (irep
.element
!= choice_DigestRepInner_initReply
) {
437 krb5_set_error_string(context
, "digest reply not an initReply");
442 ret
= copy_DigestInitReply(&irep
.u
.initReply
, &digest
->initReply
);
444 krb5_set_error_string(context
, "Failed to copy initReply");
449 free_DigestRepInner(&irep
);
456 krb5_digest_set_client_nonce(krb5_context context
,
460 if (digest
->request
.clientNonce
) {
461 krb5_set_error_string(context
, "clientNonce already set");
464 digest
->request
.clientNonce
=
465 calloc(1, sizeof(*digest
->request
.clientNonce
));
466 if (digest
->request
.clientNonce
== NULL
) {
467 krb5_set_error_string(context
, "out of memory");
470 *digest
->request
.clientNonce
= strdup(nonce
);
471 if (*digest
->request
.clientNonce
== NULL
) {
472 krb5_set_error_string(context
, "out of memory");
473 free(digest
->request
.clientNonce
);
474 digest
->request
.clientNonce
= NULL
;
481 krb5_digest_set_digest(krb5_context context
,
485 if (digest
->request
.digest
) {
486 krb5_set_error_string(context
, "digest already set");
489 digest
->request
.digest
= strdup(dgst
);
490 if (digest
->request
.digest
== NULL
) {
491 krb5_set_error_string(context
, "out of memory");
498 krb5_digest_set_username(krb5_context context
,
500 const char *username
)
502 if (digest
->request
.username
) {
503 krb5_set_error_string(context
, "username already set");
506 digest
->request
.username
= strdup(username
);
507 if (digest
->request
.username
== NULL
) {
508 krb5_set_error_string(context
, "out of memory");
515 krb5_digest_set_authid(krb5_context context
,
519 if (digest
->request
.authid
) {
520 krb5_set_error_string(context
, "authid already set");
523 digest
->request
.authid
= malloc(sizeof(*digest
->request
.authid
));
524 if (digest
->request
.authid
== NULL
) {
525 krb5_set_error_string(context
, "out of memory");
528 *digest
->request
.authid
= strdup(authid
);
529 if (*digest
->request
.authid
== NULL
) {
530 krb5_set_error_string(context
, "out of memory");
531 free(digest
->request
.authid
);
532 digest
->request
.authid
= NULL
;
539 krb5_digest_set_authentication_user(krb5_context context
,
541 krb5_principal authentication_user
)
545 if (digest
->request
.authentication_user
) {
546 krb5_set_error_string(context
, "authentication_user already set");
549 ret
= krb5_copy_principal(context
,
551 &digest
->request
.authentication_user
);
552 if (digest
->request
.authentication_user
== NULL
) {
553 krb5_set_error_string(context
, "out of memory");
560 krb5_digest_set_realm(krb5_context context
,
564 if (digest
->request
.realm
) {
565 krb5_set_error_string(context
, "realm already set");
568 digest
->request
.realm
= malloc(sizeof(*digest
->request
.realm
));
569 if (digest
->request
.realm
== NULL
) {
570 krb5_set_error_string(context
, "out of memory");
573 *digest
->request
.realm
= strdup(realm
);
574 if (*digest
->request
.realm
== NULL
) {
575 krb5_set_error_string(context
, "out of memory");
576 free(digest
->request
.realm
);
577 digest
->request
.realm
= NULL
;
584 krb5_digest_set_method(krb5_context context
,
588 if (digest
->request
.method
) {
589 krb5_set_error_string(context
, "method already set");
592 digest
->request
.method
= malloc(sizeof(*digest
->request
.method
));
593 if (digest
->request
.method
== NULL
) {
594 krb5_set_error_string(context
, "out of memory");
597 *digest
->request
.method
= strdup(method
);
598 if (*digest
->request
.method
== NULL
) {
599 krb5_set_error_string(context
, "out of memory");
600 free(digest
->request
.method
);
601 digest
->request
.method
= NULL
;
608 krb5_digest_set_uri(krb5_context context
,
612 if (digest
->request
.uri
) {
613 krb5_set_error_string(context
, "uri already set");
616 digest
->request
.uri
= malloc(sizeof(*digest
->request
.uri
));
617 if (digest
->request
.uri
== NULL
) {
618 krb5_set_error_string(context
, "out of memory");
621 *digest
->request
.uri
= strdup(uri
);
622 if (*digest
->request
.uri
== NULL
) {
623 krb5_set_error_string(context
, "out of memory");
624 free(digest
->request
.uri
);
625 digest
->request
.uri
= NULL
;
632 krb5_digest_set_nonceCount(krb5_context context
,
634 const char *nonce_count
)
636 if (digest
->request
.nonceCount
) {
637 krb5_set_error_string(context
, "nonceCount already set");
640 digest
->request
.nonceCount
=
641 malloc(sizeof(*digest
->request
.nonceCount
));
642 if (digest
->request
.nonceCount
== NULL
) {
643 krb5_set_error_string(context
, "out of memory");
646 *digest
->request
.nonceCount
= strdup(nonce_count
);
647 if (*digest
->request
.nonceCount
== NULL
) {
648 krb5_set_error_string(context
, "out of memory");
649 free(digest
->request
.nonceCount
);
650 digest
->request
.nonceCount
= NULL
;
657 krb5_digest_set_qop(krb5_context context
,
661 if (digest
->request
.qop
) {
662 krb5_set_error_string(context
, "qop already set");
665 digest
->request
.qop
= malloc(sizeof(*digest
->request
.qop
));
666 if (digest
->request
.qop
== NULL
) {
667 krb5_set_error_string(context
, "out of memory");
670 *digest
->request
.qop
= strdup(qop
);
671 if (*digest
->request
.qop
== NULL
) {
672 krb5_set_error_string(context
, "out of memory");
673 free(digest
->request
.qop
);
674 digest
->request
.qop
= NULL
;
681 krb5_digest_set_responseData(krb5_context context
,
683 const char *response
)
685 digest
->request
.responseData
= strdup(response
);
686 if (digest
->request
.responseData
== NULL
) {
687 krb5_set_error_string(context
, "out of memory");
694 krb5_digest_request(krb5_context context
,
703 memset(&ireq
, 0, sizeof(ireq
));
704 memset(&irep
, 0, sizeof(irep
));
706 ireq
.element
= choice_DigestReqInner_digestRequest
;
707 ireq
.u
.digestRequest
= digest
->request
;
709 if (digest
->request
.type
== NULL
) {
710 if (digest
->init
.type
== NULL
) {
711 krb5_set_error_string(context
, "Type missing from req");
714 ireq
.u
.digestRequest
.type
= digest
->init
.type
;
717 if (ireq
.u
.digestRequest
.digest
== NULL
)
718 ireq
.u
.digestRequest
.digest
= "md5";
720 ret
= digest_request(context
, realm
, ccache
,
721 KRB5_KU_DIGEST_ENCRYPT
, &ireq
, &irep
);
725 if (irep
.element
== choice_DigestRepInner_error
) {
726 krb5_set_error_string(context
, "Digest response error: %s",
727 irep
.u
.error
.reason
);
728 ret
= irep
.u
.error
.code
;
732 if (irep
.element
!= choice_DigestRepInner_response
) {
733 krb5_set_error_string(context
, "digest reply not an DigestResponse");
738 ret
= copy_DigestResponse(&irep
.u
.response
, &digest
->response
);
740 krb5_set_error_string(context
, "Failed to copy initReply");
745 free_DigestRepInner(&irep
);
751 krb5_digest_rep_get_status(krb5_context context
,
754 return digest
->response
.success
? TRUE
: FALSE
;
758 krb5_digest_get_rsp(krb5_context context
,
761 if (digest
->response
.rsp
== NULL
)
763 return *digest
->response
.rsp
;
767 krb5_digest_get_tickets(krb5_context context
,
777 krb5_digest_get_client_binding(krb5_context context
,
782 if (digest
->response
.channel
) {
783 *type
= strdup(digest
->response
.channel
->cb_type
);
784 *binding
= strdup(digest
->response
.channel
->cb_binding
);
785 if (*type
== NULL
|| *binding
== NULL
) {
788 krb5_set_error_string(context
, "out of memory");
799 krb5_digest_get_session_key(krb5_context context
,
805 krb5_data_zero(data
);
806 if (digest
->response
.session_key
== NULL
)
808 ret
= der_copy_octet_string(digest
->response
.session_key
, data
);
810 krb5_clear_error_string(context
);
815 struct krb5_ntlm_data
{
817 NTLMInitReply initReply
;
819 NTLMResponse response
;
823 krb5_ntlm_alloc(krb5_context context
,
826 *ntlm
= calloc(1, sizeof(**ntlm
));
828 krb5_set_error_string(context
, "out of memory");
835 krb5_ntlm_free(krb5_context context
, krb5_ntlm ntlm
)
837 free_NTLMInit(&ntlm
->init
);
838 free_NTLMInitReply(&ntlm
->initReply
);
839 free_NTLMRequest(&ntlm
->request
);
840 free_NTLMResponse(&ntlm
->response
);
841 memset(ntlm
, 0, sizeof(*ntlm
));
848 krb5_ntlm_init_request(krb5_context context
,
853 const char *hostname
,
854 const char *domainname
)
860 memset(&ireq
, 0, sizeof(ireq
));
861 memset(&irep
, 0, sizeof(irep
));
863 ntlm
->init
.flags
= flags
;
865 ALLOC(ntlm
->init
.hostname
, 1);
866 *ntlm
->init
.hostname
= strdup(hostname
);
869 ALLOC(ntlm
->init
.domain
, 1);
870 *ntlm
->init
.domain
= strdup(domainname
);
873 ireq
.element
= choice_DigestReqInner_ntlmInit
;
874 ireq
.u
.ntlmInit
= ntlm
->init
;
876 ret
= digest_request(context
, realm
, ccache
,
877 KRB5_KU_DIGEST_ENCRYPT
, &ireq
, &irep
);
881 if (irep
.element
== choice_DigestRepInner_error
) {
882 krb5_set_error_string(context
, "Digest init error: %s",
883 irep
.u
.error
.reason
);
884 ret
= irep
.u
.error
.code
;
888 if (irep
.element
!= choice_DigestRepInner_ntlmInitReply
) {
889 krb5_set_error_string(context
, "ntlm reply not an initReply");
894 ret
= copy_NTLMInitReply(&irep
.u
.ntlmInitReply
, &ntlm
->initReply
);
896 krb5_set_error_string(context
, "Failed to copy initReply");
901 free_DigestRepInner(&irep
);
907 krb5_ntlm_init_get_flags(krb5_context context
,
911 *flags
= ntlm
->initReply
.flags
;
916 krb5_ntlm_init_get_challange(krb5_context context
,
918 krb5_data
*challange
)
922 ret
= der_copy_octet_string(&ntlm
->initReply
.challange
, challange
);
924 krb5_clear_error_string(context
);
930 krb5_ntlm_init_get_opaque(krb5_context context
,
936 ret
= der_copy_octet_string(&ntlm
->initReply
.opaque
, opaque
);
938 krb5_clear_error_string(context
);
944 krb5_ntlm_init_get_targetname(krb5_context context
,
948 *name
= strdup(ntlm
->initReply
.targetname
);
950 krb5_clear_error_string(context
);
957 krb5_ntlm_init_get_targetinfo(krb5_context context
,
963 if (ntlm
->initReply
.targetinfo
== NULL
) {
964 krb5_data_zero(data
);
968 ret
= krb5_data_copy(data
,
969 ntlm
->initReply
.targetinfo
->data
,
970 ntlm
->initReply
.targetinfo
->length
);
972 krb5_clear_error_string(context
);
980 krb5_ntlm_request(krb5_context context
,
989 memset(&ireq
, 0, sizeof(ireq
));
990 memset(&irep
, 0, sizeof(irep
));
992 ireq
.element
= choice_DigestReqInner_ntlmRequest
;
993 ireq
.u
.ntlmRequest
= ntlm
->request
;
995 ret
= digest_request(context
, realm
, ccache
,
996 KRB5_KU_DIGEST_ENCRYPT
, &ireq
, &irep
);
1000 if (irep
.element
== choice_DigestRepInner_error
) {
1001 krb5_set_error_string(context
, "NTLM response error: %s",
1002 irep
.u
.error
.reason
);
1003 ret
= irep
.u
.error
.code
;
1007 if (irep
.element
!= choice_DigestRepInner_ntlmResponse
) {
1008 krb5_set_error_string(context
, "NTLM reply not an NTLMResponse");
1013 ret
= copy_NTLMResponse(&irep
.u
.ntlmResponse
, &ntlm
->response
);
1015 krb5_set_error_string(context
, "Failed to copy NTLMResponse");
1020 free_DigestRepInner(&irep
);
1026 krb5_ntlm_req_set_flags(krb5_context context
,
1030 ntlm
->request
.flags
= flags
;
1035 krb5_ntlm_req_set_username(krb5_context context
,
1037 const char *username
)
1039 ntlm
->request
.username
= strdup(username
);
1040 if (ntlm
->request
.username
== NULL
) {
1041 krb5_set_error_string(context
, "out of memory");
1048 krb5_ntlm_req_set_targetname(krb5_context context
,
1050 const char *targetname
)
1052 ntlm
->request
.targetname
= strdup(targetname
);
1053 if (ntlm
->request
.targetname
== NULL
) {
1054 krb5_set_error_string(context
, "out of memory");
1061 krb5_ntlm_req_set_lm(krb5_context context
,
1063 void *hash
, size_t len
)
1065 ntlm
->request
.lm
.data
= malloc(len
);
1066 if (ntlm
->request
.lm
.data
== NULL
) {
1067 krb5_set_error_string(context
, "out of memory");
1070 ntlm
->request
.lm
.length
= len
;
1071 memcpy(ntlm
->request
.lm
.data
, hash
, len
);
1076 krb5_ntlm_req_set_ntlm(krb5_context context
,
1078 void *hash
, size_t len
)
1080 ntlm
->request
.ntlm
.data
= malloc(len
);
1081 if (ntlm
->request
.ntlm
.data
== NULL
) {
1082 krb5_set_error_string(context
, "out of memory");
1085 ntlm
->request
.ntlm
.length
= len
;
1086 memcpy(ntlm
->request
.ntlm
.data
, hash
, len
);
1091 krb5_ntlm_req_set_opaque(krb5_context context
,
1095 ntlm
->request
.opaque
.data
= malloc(opaque
->length
);
1096 if (ntlm
->request
.opaque
.data
== NULL
) {
1097 krb5_set_error_string(context
, "out of memory");
1100 ntlm
->request
.opaque
.length
= opaque
->length
;
1101 memcpy(ntlm
->request
.opaque
.data
, opaque
->data
, opaque
->length
);
1106 krb5_ntlm_req_set_session(krb5_context context
,
1108 void *sessionkey
, size_t length
)
1110 ntlm
->request
.sessionkey
= calloc(1, sizeof(*ntlm
->request
.sessionkey
));
1111 if (ntlm
->request
.sessionkey
== NULL
) {
1112 krb5_set_error_string(context
, "out of memory");
1115 ntlm
->request
.sessionkey
->data
= malloc(length
);
1116 if (ntlm
->request
.sessionkey
->data
== NULL
) {
1117 krb5_set_error_string(context
, "out of memory");
1120 memcpy(ntlm
->request
.sessionkey
->data
, sessionkey
, length
);
1121 ntlm
->request
.sessionkey
->length
= length
;
1126 krb5_ntlm_rep_get_status(krb5_context context
,
1129 return ntlm
->response
.success
? TRUE
: FALSE
;
1133 krb5_ntlm_rep_get_sessionkey(krb5_context context
,
1137 if (ntlm
->response
.sessionkey
== NULL
) {
1138 krb5_set_error_string(context
, "no ntlm session key");
1141 krb5_clear_error_string(context
);
1142 return krb5_data_copy(data
,
1143 ntlm
->response
.sessionkey
->data
,
1144 ntlm
->response
.sessionkey
->length
);
1148 * Get the supported/allowed mechanism for this principal.
1150 * @param context A Keberos context.
1151 * @param realm The realm of the KDC.
1152 * @param ccache The credential cache to use when talking to the KDC.
1153 * @param flags The supported mechanism.
1155 * @return Return an error code or 0.
1157 * @ingroup krb5_digest
1161 krb5_digest_probe(krb5_context context
,
1166 DigestReqInner ireq
;
1167 DigestRepInner irep
;
1168 krb5_error_code ret
;
1170 memset(&ireq
, 0, sizeof(ireq
));
1171 memset(&irep
, 0, sizeof(irep
));
1173 ireq
.element
= choice_DigestReqInner_supportedMechs
;
1175 ret
= digest_request(context
, realm
, ccache
,
1176 KRB5_KU_DIGEST_ENCRYPT
, &ireq
, &irep
);
1180 if (irep
.element
== choice_DigestRepInner_error
) {
1181 krb5_set_error_string(context
, "Digest probe error: %s",
1182 irep
.u
.error
.reason
);
1183 ret
= irep
.u
.error
.code
;
1187 if (irep
.element
!= choice_DigestRepInner_supportedMechs
) {
1188 krb5_set_error_string(context
, "Digest reply not an probe");
1193 *flags
= DigestTypes2int(irep
.u
.supportedMechs
);
1196 free_DigestRepInner(&irep
);