2 * Copyright (c) 1997 - 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 __RCSID("$Heimdal: sendauth.c 17442 2006-05-05 09:31:15Z lha $"
40 * The format seems to be:
44 * KRB5_SENDAUTH_V1.0 (including zero)
46 * protocol string (with terminating zero)
49 * 1 byte - (0 = OK, else some kind of error)
56 * 4 bytes - length (0 = OK, else length of error)
66 krb5_error_code KRB5_LIB_FUNCTION
67 krb5_sendauth(krb5_context context
,
68 krb5_auth_context
*auth_context
,
70 const char *appl_version
,
71 krb5_principal client
,
72 krb5_principal server
,
73 krb5_flags ap_req_options
,
77 krb5_error
**ret_error
,
78 krb5_ap_rep_enc_part
**rep_result
,
79 krb5_creds
**out_creds
)
82 uint32_t len
, net_len
;
83 const char *version
= KRB5_SENDAUTH_VERSION
;
85 krb5_data ap_req
, error_data
;
87 krb5_principal this_client
= NULL
;
90 krb5_boolean my_ccache
= FALSE
;
92 len
= strlen(version
) + 1;
94 if (krb5_net_write (context
, p_fd
, &net_len
, 4) != 4
95 || krb5_net_write (context
, p_fd
, version
, len
) != len
) {
97 krb5_set_error_string (context
, "write: %s", strerror(ret
));
101 len
= strlen(appl_version
) + 1;
102 net_len
= htonl(len
);
103 if (krb5_net_write (context
, p_fd
, &net_len
, 4) != 4
104 || krb5_net_write (context
, p_fd
, appl_version
, len
) != len
) {
106 krb5_set_error_string (context
, "write: %s", strerror(ret
));
110 sret
= krb5_net_read (context
, p_fd
, &repl
, sizeof(repl
));
113 krb5_set_error_string (context
, "read: %s", strerror(ret
));
115 } else if (sret
!= sizeof(repl
)) {
116 krb5_clear_error_string (context
);
117 return KRB5_SENDAUTH_BADRESPONSE
;
121 krb5_clear_error_string (context
);
122 return KRB5_SENDAUTH_REJECTED
;
125 if (in_creds
== NULL
) {
126 if (ccache
== NULL
) {
127 ret
= krb5_cc_default (context
, &ccache
);
133 if (client
== NULL
) {
134 ret
= krb5_cc_get_principal (context
, ccache
, &this_client
);
137 krb5_cc_close(context
, ccache
);
140 client
= this_client
;
142 memset(&this_cred
, 0, sizeof(this_cred
));
143 this_cred
.client
= client
;
144 this_cred
.server
= server
;
145 this_cred
.times
.endtime
= 0;
146 this_cred
.ticket
.length
= 0;
147 in_creds
= &this_cred
;
149 if (in_creds
->ticket
.length
== 0) {
150 ret
= krb5_get_credentials (context
, 0, ccache
, in_creds
, &creds
);
153 krb5_cc_close(context
, ccache
);
160 krb5_cc_close(context
, ccache
);
161 ret
= krb5_mk_req_extended (context
,
171 krb5_free_creds(context
, creds
);
173 krb5_free_principal(context
, this_client
);
178 ret
= krb5_write_message (context
,
184 krb5_data_free (&ap_req
);
186 ret
= krb5_read_message (context
, p_fd
, &error_data
);
190 if (error_data
.length
!= 0) {
193 ret
= krb5_rd_error (context
, &error_data
, &error
);
194 krb5_data_free (&error_data
);
196 ret
= krb5_error_from_rd_error(context
, &error
, NULL
);
197 if (ret_error
!= NULL
) {
198 *ret_error
= malloc (sizeof(krb5_error
));
199 if (*ret_error
== NULL
) {
200 krb5_free_error_contents (context
, &error
);
205 krb5_free_error_contents (context
, &error
);
209 krb5_clear_error_string(context
);
214 if (ap_req_options
& AP_OPTS_MUTUAL_REQUIRED
) {
216 krb5_ap_rep_enc_part
*ignore
;
218 krb5_data_zero (&ap_rep
);
219 ret
= krb5_read_message (context
,
225 ret
= krb5_rd_rep (context
, *auth_context
, &ap_rep
,
226 rep_result
? rep_result
: &ignore
);
227 krb5_data_free (&ap_rep
);
230 if (rep_result
== NULL
)
231 krb5_free_ap_rep_enc_part (context
, ignore
);