cf/largefile.m4: Fix build with autoconf-2.72
[heimdal.git] / appl / test / gssapi_client.c
blob13049c800770eebbb10d8fe09e8a8961a74111a9
1 /*
2 * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
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
31 * SUCH DAMAGE.
34 #include "test_locl.h"
35 #include <gssapi/gssapi.h>
36 #include <gssapi/gssapi_krb5.h>
37 #include <gssapi/gssapi_spnego.h>
38 #include "gss_common.h"
39 RCSID("$Id$");
41 static int
42 do_trans (int sock, gss_ctx_id_t context_hdl)
44 OM_uint32 maj_stat, min_stat;
45 gss_buffer_desc real_input_token, real_output_token;
46 gss_buffer_t input_token = &real_input_token,
47 output_token = &real_output_token;
48 int conf_flag;
50 /* get_mic */
52 input_token->length = 3;
53 input_token->value = strdup("hej");
55 maj_stat = gss_get_mic(&min_stat,
56 context_hdl,
57 GSS_C_QOP_DEFAULT,
58 input_token,
59 output_token);
60 if (GSS_ERROR(maj_stat))
61 gss_err (1, min_stat, "gss_get_mic");
63 write_token (sock, input_token);
64 write_token (sock, output_token);
66 gss_release_buffer(&min_stat, output_token);
68 /* verify mic */
70 read_token (sock, input_token);
71 read_token (sock, output_token);
73 maj_stat = gss_verify_mic(&min_stat,
74 context_hdl,
75 input_token,
76 output_token,
77 NULL);
78 if (GSS_ERROR(maj_stat))
79 gss_err (1, min_stat, "gss_verify_mic");
81 gss_release_buffer (&min_stat, input_token);
82 gss_release_buffer (&min_stat, output_token);
84 /* wrap */
86 input_token->length = 7;
87 input_token->value = "hemligt";
89 maj_stat = gss_wrap (&min_stat,
90 context_hdl,
92 GSS_C_QOP_DEFAULT,
93 input_token,
94 NULL,
95 output_token);
96 if (GSS_ERROR(maj_stat))
97 gss_err (1, min_stat, "gss_wrap");
99 write_token (sock, output_token);
101 maj_stat = gss_wrap (&min_stat,
102 context_hdl,
104 GSS_C_QOP_DEFAULT,
105 input_token,
106 NULL,
107 output_token);
108 if (GSS_ERROR(maj_stat))
109 gss_err (1, min_stat, "gss_wrap");
111 write_token (sock, output_token);
113 read_token (sock, input_token);
115 maj_stat = gss_unwrap (&min_stat,
116 context_hdl,
117 input_token,
118 output_token,
119 &conf_flag,
120 NULL);
121 if(GSS_ERROR(maj_stat))
122 gss_err (1, min_stat, "gss_unwrap");
124 write_token (sock, output_token);
126 gss_release_buffer(&min_stat, output_token);
128 return 0;
131 extern char *password;
133 static int
134 proto (int sock, const char *hostname, const char *service)
136 struct sockaddr_storage remote, local;
137 socklen_t addrlen;
139 int context_established = 0;
140 gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT;
141 gss_cred_id_t cred = GSS_C_NO_CREDENTIAL;
142 gss_buffer_desc real_input_token, real_output_token;
143 gss_buffer_t input_token = &real_input_token,
144 output_token = &real_output_token;
145 OM_uint32 maj_stat, min_stat;
146 gss_name_t server;
147 gss_buffer_desc name_token;
148 gss_OID mech_oid;
149 char *str;
151 mech_oid = select_mech(mech);
153 name_token.length = asprintf (&str,
154 "%s@%s", service, hostname);
155 if (str == NULL)
156 errx(1, "malloc - out of memory");
157 name_token.value = str;
159 maj_stat = gss_import_name (&min_stat,
160 &name_token,
161 GSS_C_NT_HOSTBASED_SERVICE,
162 &server);
163 if (GSS_ERROR(maj_stat))
164 gss_err (1, min_stat,
165 "Error importing name `%s@%s':\n", service, hostname);
167 if (password) {
168 gss_buffer_desc pw;
170 pw.value = password;
171 pw.length = strlen(password);
173 maj_stat = gss_acquire_cred_with_password(&min_stat,
174 GSS_C_NO_NAME,
175 &pw,
176 GSS_C_INDEFINITE,
177 GSS_C_NO_OID_SET,
178 GSS_C_INITIATE,
179 &cred,
180 NULL,
181 NULL);
182 if (GSS_ERROR(maj_stat))
183 gss_err (1, min_stat,
184 "Error acquiring default initiator credentials");
187 addrlen = sizeof(local);
188 if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0
189 || addrlen > sizeof(local))
190 err (1, "getsockname(%s)", hostname);
192 addrlen = sizeof(remote);
193 if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0
194 || addrlen > sizeof(remote))
195 err (1, "getpeername(%s)", hostname);
197 input_token->length = 0;
198 output_token->length = 0;
200 #if 0
201 struct gss_channel_bindings_struct input_chan_bindings;
202 u_char init_buf[4];
203 u_char acct_buf[4];
205 input_chan_bindings.initiator_addrtype = GSS_C_AF_INET;
206 input_chan_bindings.initiator_address.length = 4;
207 init_buf[0] = (local.sin_addr.s_addr >> 24) & 0xFF;
208 init_buf[1] = (local.sin_addr.s_addr >> 16) & 0xFF;
209 init_buf[2] = (local.sin_addr.s_addr >> 8) & 0xFF;
210 init_buf[3] = (local.sin_addr.s_addr >> 0) & 0xFF;
211 input_chan_bindings.initiator_address.value = init_buf;
213 input_chan_bindings.acceptor_addrtype = GSS_C_AF_INET;
214 input_chan_bindings.acceptor_address.length = 4;
215 acct_buf[0] = (remote.sin_addr.s_addr >> 24) & 0xFF;
216 acct_buf[1] = (remote.sin_addr.s_addr >> 16) & 0xFF;
217 acct_buf[2] = (remote.sin_addr.s_addr >> 8) & 0xFF;
218 acct_buf[3] = (remote.sin_addr.s_addr >> 0) & 0xFF;
219 input_chan_bindings.acceptor_address.value = acct_buf;
221 input_chan_bindings.application_data.value = emalloc(4);
222 * (unsigned short*)input_chan_bindings.application_data.value = local.sin_port;
223 * ((unsigned short *)input_chan_bindings.application_data.value + 1) = remote.sin_port;
224 input_chan_bindings.application_data.length = 4;
226 input_chan_bindings.application_data.length = 0;
227 input_chan_bindings.application_data.value = NULL;
228 #endif
230 while(!context_established) {
231 maj_stat =
232 gss_init_sec_context(&min_stat,
233 cred,
234 &context_hdl,
235 server,
236 mech_oid,
237 GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG,
239 NULL,
240 input_token,
241 NULL,
242 output_token,
243 NULL,
244 NULL);
245 if (GSS_ERROR(maj_stat))
246 gss_err (1, min_stat, "gss_init_sec_context");
247 if (output_token->length != 0)
248 write_token (sock, output_token);
249 if (GSS_ERROR(maj_stat)) {
250 if (context_hdl != GSS_C_NO_CONTEXT)
251 gss_delete_sec_context (&min_stat,
252 &context_hdl,
253 GSS_C_NO_BUFFER);
254 break;
256 if (maj_stat & GSS_S_CONTINUE_NEEDED) {
257 read_token (sock, input_token);
258 } else {
259 context_established = 1;
263 if (fork_flag) {
264 pid_t pid;
265 int pipefd[2];
267 if (pipe (pipefd) < 0)
268 err (1, "pipe");
270 pid = fork ();
271 if (pid < 0)
272 err (1, "fork");
273 if (pid != 0) {
274 gss_buffer_desc buf;
276 maj_stat = gss_export_sec_context (&min_stat,
277 &context_hdl,
278 &buf);
279 if (GSS_ERROR(maj_stat))
280 gss_err (1, min_stat, "gss_export_sec_context");
281 write_token (pipefd[1], &buf);
282 exit (0);
283 } else {
284 gss_ctx_id_t context_hdl;
285 gss_buffer_desc buf;
287 close (pipefd[1]);
288 read_token (pipefd[0], &buf);
289 close (pipefd[0]);
290 maj_stat = gss_import_sec_context (&min_stat, &buf, &context_hdl);
291 if (GSS_ERROR(maj_stat))
292 gss_err (1, min_stat, "gss_import_sec_context");
293 gss_release_buffer (&min_stat, &buf);
294 return do_trans (sock, context_hdl);
296 } else {
297 return do_trans (sock, context_hdl);
302 main(int argc, char **argv)
304 krb5_context context; /* XXX */
305 int port = client_setup(&context, &argc, argv);
306 return client_doit (argv[argc], port, service, proto);