1 /* $NetBSD: sendauth.c,v 1.1.1.2 2014/04/24 12:45:51 pettai Exp $ */
4 * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 #include "krb5_locl.h"
39 * The format seems to be:
43 * KRB5_SENDAUTH_V1.0 (including zero)
45 * protocol string (with terminating zero)
48 * 1 byte - (0 = OK, else some kind of error)
55 * 4 bytes - length (0 = OK, else length of error)
65 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
66 krb5_sendauth(krb5_context context
,
67 krb5_auth_context
*auth_context
,
69 const char *appl_version
,
70 krb5_principal client
,
71 krb5_principal server
,
72 krb5_flags ap_req_options
,
76 krb5_error
**ret_error
,
77 krb5_ap_rep_enc_part
**rep_result
,
78 krb5_creds
**out_creds
)
81 uint32_t len
, net_len
;
82 const char *version
= KRB5_SENDAUTH_VERSION
;
84 krb5_data ap_req
, error_data
;
86 krb5_principal this_client
= NULL
;
89 krb5_boolean my_ccache
= FALSE
;
91 len
= strlen(version
) + 1;
93 if (krb5_net_write (context
, p_fd
, &net_len
, 4) != 4
94 || krb5_net_write (context
, p_fd
, version
, len
) != len
) {
96 krb5_set_error_message (context
, ret
, "write: %s", strerror(ret
));
100 len
= strlen(appl_version
) + 1;
101 net_len
= htonl(len
);
102 if (krb5_net_write (context
, p_fd
, &net_len
, 4) != 4
103 || krb5_net_write (context
, p_fd
, appl_version
, len
) != len
) {
105 krb5_set_error_message (context
, ret
, "write: %s", strerror(ret
));
109 sret
= krb5_net_read (context
, p_fd
, &repl
, sizeof(repl
));
112 krb5_set_error_message (context
, ret
, "read: %s", strerror(ret
));
114 } else if (sret
!= sizeof(repl
)) {
115 krb5_clear_error_message (context
);
116 return KRB5_SENDAUTH_BADRESPONSE
;
120 krb5_clear_error_message (context
);
121 return KRB5_SENDAUTH_REJECTED
;
124 if (in_creds
== NULL
) {
125 if (ccache
== NULL
) {
126 ret
= krb5_cc_default (context
, &ccache
);
132 if (client
== NULL
) {
133 ret
= krb5_cc_get_principal (context
, ccache
, &this_client
);
136 krb5_cc_close(context
, ccache
);
139 client
= this_client
;
141 memset(&this_cred
, 0, sizeof(this_cred
));
142 this_cred
.client
= client
;
143 this_cred
.server
= server
;
144 this_cred
.times
.endtime
= 0;
145 this_cred
.ticket
.length
= 0;
146 in_creds
= &this_cred
;
148 if (in_creds
->ticket
.length
== 0) {
149 ret
= krb5_get_credentials (context
, 0, ccache
, in_creds
, &creds
);
152 krb5_cc_close(context
, ccache
);
159 krb5_cc_close(context
, ccache
);
160 ret
= krb5_mk_req_extended (context
,
170 krb5_free_creds(context
, creds
);
172 krb5_free_principal(context
, this_client
);
177 ret
= krb5_write_message (context
,
183 krb5_data_free (&ap_req
);
185 ret
= krb5_read_message (context
, p_fd
, &error_data
);
189 if (error_data
.length
!= 0) {
192 ret
= krb5_rd_error (context
, &error_data
, &error
);
193 krb5_data_free (&error_data
);
195 ret
= krb5_error_from_rd_error(context
, &error
, NULL
);
196 if (ret_error
!= NULL
) {
197 *ret_error
= malloc (sizeof(krb5_error
));
198 if (*ret_error
== NULL
) {
199 krb5_free_error_contents (context
, &error
);
204 krb5_free_error_contents (context
, &error
);
208 krb5_clear_error_message(context
);
212 krb5_data_free (&error_data
);
214 if (ap_req_options
& AP_OPTS_MUTUAL_REQUIRED
) {
216 krb5_ap_rep_enc_part
*ignore
= NULL
;
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
);