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"
37 * The format seems to be:
41 * KRB5_SENDAUTH_V1.0 (including zero)
43 * protocol string (with terminating zero)
46 * 1 byte - (0 = OK, else some kind of error)
53 * 4 bytes - length (0 = OK, else length of error)
63 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
64 krb5_sendauth(krb5_context context
,
65 krb5_auth_context
*auth_context
,
67 const char *appl_version
,
68 krb5_principal client
,
69 krb5_principal server
,
70 krb5_flags ap_req_options
,
74 krb5_error
**ret_error
,
75 krb5_ap_rep_enc_part
**rep_result
,
76 krb5_creds
**out_creds
)
79 uint32_t len
, net_len
;
80 const char *version
= KRB5_SENDAUTH_VERSION
;
82 krb5_data ap_req
, error_data
;
84 krb5_principal this_client
= NULL
;
87 krb5_boolean my_ccache
= FALSE
;
89 len
= strlen(version
) + 1;
91 if (krb5_net_write (context
, p_fd
, &net_len
, 4) != 4
92 || krb5_net_write (context
, p_fd
, version
, len
) != len
) {
94 krb5_set_error_message (context
, ret
, "write: %s", strerror(ret
));
98 len
= strlen(appl_version
) + 1;
100 if (krb5_net_write (context
, p_fd
, &net_len
, 4) != 4
101 || krb5_net_write (context
, p_fd
, appl_version
, len
) != len
) {
103 krb5_set_error_message (context
, ret
, "write: %s", strerror(ret
));
107 sret
= krb5_net_read (context
, p_fd
, &repl
, sizeof(repl
));
110 krb5_set_error_message (context
, ret
, "read: %s", strerror(ret
));
112 } else if (sret
!= sizeof(repl
)) {
113 krb5_clear_error_message (context
);
114 return KRB5_SENDAUTH_BADRESPONSE
;
118 krb5_clear_error_message (context
);
119 return KRB5_SENDAUTH_REJECTED
;
122 if (in_creds
== NULL
) {
123 if (ccache
== NULL
) {
124 ret
= krb5_cc_default (context
, &ccache
);
130 if (client
== NULL
) {
131 ret
= krb5_cc_get_principal (context
, ccache
, &this_client
);
134 krb5_cc_close(context
, ccache
);
137 client
= this_client
;
139 memset(&this_cred
, 0, sizeof(this_cred
));
140 this_cred
.client
= client
;
141 this_cred
.server
= server
;
142 this_cred
.times
.endtime
= 0;
143 this_cred
.ticket
.length
= 0;
144 in_creds
= &this_cred
;
146 if (in_creds
->ticket
.length
== 0) {
147 ret
= krb5_get_credentials (context
, 0, ccache
, in_creds
, &creds
);
150 krb5_cc_close(context
, ccache
);
157 krb5_cc_close(context
, ccache
);
158 ret
= krb5_mk_req_extended (context
,
168 krb5_free_creds(context
, creds
);
170 krb5_free_principal(context
, this_client
);
175 ret
= krb5_write_message (context
,
181 krb5_data_free (&ap_req
);
183 ret
= krb5_read_message (context
, p_fd
, &error_data
);
187 if (error_data
.length
!= 0) {
190 ret
= krb5_rd_error (context
, &error_data
, &error
);
191 krb5_data_free (&error_data
);
193 ret
= krb5_error_from_rd_error(context
, &error
, NULL
);
194 if (ret_error
!= NULL
) {
195 *ret_error
= malloc (sizeof(krb5_error
));
196 if (*ret_error
== NULL
) {
197 krb5_free_error_contents (context
, &error
);
202 krb5_free_error_contents (context
, &error
);
206 krb5_clear_error_message(context
);
210 krb5_data_free (&error_data
);
212 if (ap_req_options
& AP_OPTS_MUTUAL_REQUIRED
) {
214 krb5_ap_rep_enc_part
*ignore
= NULL
;
216 krb5_data_zero (&ap_rep
);
217 ret
= krb5_read_message (context
,
223 ret
= krb5_rd_rep (context
, *auth_context
, &ap_rep
,
224 rep_result
? rep_result
: &ignore
);
225 krb5_data_free (&ap_rep
);
228 if (rep_result
== NULL
)
229 krb5_free_ap_rep_enc_part (context
, ignore
);