xref: /freebsd/crypto/heimdal/appl/test/gssapi_server.c (revision 5e9cd1ae3e10592ed70e7575551cba1bbab04d84)
1b528cefcSMark Murray /*
2283d988cSMark Murray  * Copyright (c) 1997 - 2000 Kungliga Tekniska H�gskolan
3b528cefcSMark Murray  * (Royal Institute of Technology, Stockholm, Sweden).
4b528cefcSMark Murray  * All rights reserved.
5b528cefcSMark Murray  *
6b528cefcSMark Murray  * Redistribution and use in source and binary forms, with or without
7b528cefcSMark Murray  * modification, are permitted provided that the following conditions
8b528cefcSMark Murray  * are met:
9b528cefcSMark Murray  *
10b528cefcSMark Murray  * 1. Redistributions of source code must retain the above copyright
11b528cefcSMark Murray  *    notice, this list of conditions and the following disclaimer.
12b528cefcSMark Murray  *
13b528cefcSMark Murray  * 2. Redistributions in binary form must reproduce the above copyright
14b528cefcSMark Murray  *    notice, this list of conditions and the following disclaimer in the
15b528cefcSMark Murray  *    documentation and/or other materials provided with the distribution.
16b528cefcSMark Murray  *
17b528cefcSMark Murray  * 3. Neither the name of the Institute nor the names of its contributors
18b528cefcSMark Murray  *    may be used to endorse or promote products derived from this software
19b528cefcSMark Murray  *    without specific prior written permission.
20b528cefcSMark Murray  *
21b528cefcSMark Murray  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22b528cefcSMark Murray  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23b528cefcSMark Murray  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24b528cefcSMark Murray  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25b528cefcSMark Murray  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26b528cefcSMark Murray  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27b528cefcSMark Murray  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28b528cefcSMark Murray  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29b528cefcSMark Murray  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30b528cefcSMark Murray  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31b528cefcSMark Murray  * SUCH DAMAGE.
32b528cefcSMark Murray  */
33b528cefcSMark Murray 
34b528cefcSMark Murray #include "test_locl.h"
35b528cefcSMark Murray #include <gssapi.h>
36b528cefcSMark Murray #include "gss_common.h"
375e9cd1aeSAssar Westerlund RCSID("$Id: gssapi_server.c,v 1.15 2000/08/09 20:53:07 assar Exp $");
38283d988cSMark Murray 
39283d988cSMark Murray static int
40283d988cSMark Murray process_it(int sock,
41283d988cSMark Murray 	   gss_ctx_id_t context_hdl,
42283d988cSMark Murray 	   gss_name_t client_name
43283d988cSMark Murray 	   )
44283d988cSMark Murray {
45283d988cSMark Murray     OM_uint32 maj_stat, min_stat;
46283d988cSMark Murray     gss_buffer_desc name_token;
47283d988cSMark Murray     gss_buffer_desc real_input_token, real_output_token;
48283d988cSMark Murray     gss_buffer_t input_token = &real_input_token,
49283d988cSMark Murray 	output_token = &real_output_token;
50283d988cSMark Murray 
51283d988cSMark Murray     maj_stat = gss_display_name (&min_stat,
52283d988cSMark Murray 				 client_name,
53283d988cSMark Murray 				 &name_token,
54283d988cSMark Murray 				 NULL);
55283d988cSMark Murray     if (GSS_ERROR(maj_stat))
56283d988cSMark Murray 	gss_err (1, min_stat, "gss_display_name");
57283d988cSMark Murray 
58283d988cSMark Murray     fprintf (stderr, "User is `%.*s'\n", (int)name_token.length,
59283d988cSMark Murray 	    (char *)name_token.value);
60283d988cSMark Murray 
61283d988cSMark Murray     gss_release_buffer (&min_stat, &name_token);
62283d988cSMark Murray 
63283d988cSMark Murray     /* gss_verify_mic */
64283d988cSMark Murray 
65283d988cSMark Murray     read_token (sock, input_token);
66283d988cSMark Murray     read_token (sock, output_token);
67283d988cSMark Murray 
68283d988cSMark Murray     maj_stat = gss_verify_mic (&min_stat,
69283d988cSMark Murray 			       context_hdl,
70283d988cSMark Murray 			       input_token,
71283d988cSMark Murray 			       output_token,
72283d988cSMark Murray 			       NULL);
73283d988cSMark Murray     if (GSS_ERROR(maj_stat))
74283d988cSMark Murray 	gss_err (1, min_stat, "gss_verify_mic");
75283d988cSMark Murray 
76283d988cSMark Murray     fprintf (stderr, "gss_verify_mic: %.*s\n", (int)input_token->length,
77283d988cSMark Murray 	    (char *)input_token->value);
78283d988cSMark Murray 
79283d988cSMark Murray     gss_release_buffer (&min_stat, input_token);
80283d988cSMark Murray     gss_release_buffer (&min_stat, output_token);
81283d988cSMark Murray 
82283d988cSMark Murray     /* gss_unwrap */
83283d988cSMark Murray 
84283d988cSMark Murray     read_token (sock, input_token);
85283d988cSMark Murray 
86283d988cSMark Murray     maj_stat = gss_unwrap (&min_stat,
87283d988cSMark Murray 			   context_hdl,
88283d988cSMark Murray 			   input_token,
89283d988cSMark Murray 			   output_token,
90283d988cSMark Murray 			   NULL,
91283d988cSMark Murray 			   NULL);
92283d988cSMark Murray     if(GSS_ERROR(maj_stat))
93283d988cSMark Murray 	gss_err (1, min_stat, "gss_unwrap");
94283d988cSMark Murray 
95283d988cSMark Murray     fprintf (stderr, "gss_unwrap: %.*s\n", (int)output_token->length,
96283d988cSMark Murray 	    (char *)output_token->value);
97283d988cSMark Murray 
98283d988cSMark Murray     gss_release_buffer (&min_stat, input_token);
99283d988cSMark Murray     gss_release_buffer (&min_stat, output_token);
100283d988cSMark Murray 
101283d988cSMark Murray     return 0;
102283d988cSMark Murray }
103b528cefcSMark Murray 
104b528cefcSMark Murray static int
105b528cefcSMark Murray proto (int sock, const char *service)
106b528cefcSMark Murray {
107b528cefcSMark Murray     struct sockaddr_in remote, local;
1085e9cd1aeSAssar Westerlund     socklen_t addrlen;
109b528cefcSMark Murray     gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT;
110b528cefcSMark Murray     gss_buffer_desc real_input_token, real_output_token;
111283d988cSMark Murray     gss_buffer_t input_token = &real_input_token,
112283d988cSMark Murray 	output_token = &real_output_token;
113b528cefcSMark Murray     OM_uint32 maj_stat, min_stat;
114b528cefcSMark Murray     gss_name_t client_name;
1155e9cd1aeSAssar Westerlund     struct gss_channel_bindings_struct input_chan_bindings;
1165e9cd1aeSAssar Westerlund     gss_cred_id_t delegated_cred_handle = NULL;
1175e9cd1aeSAssar Westerlund     krb5_ccache ccache;
1185e9cd1aeSAssar Westerlund     u_char init_buf[4];
1195e9cd1aeSAssar Westerlund     u_char acct_buf[4];
120b528cefcSMark Murray 
121b528cefcSMark Murray     addrlen = sizeof(local);
122b528cefcSMark Murray     if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0
123b528cefcSMark Murray 	|| addrlen != sizeof(local))
124b528cefcSMark Murray 	err (1, "getsockname)");
125b528cefcSMark Murray 
126b528cefcSMark Murray     addrlen = sizeof(remote);
127b528cefcSMark Murray     if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0
128b528cefcSMark Murray 	|| addrlen != sizeof(remote))
129b528cefcSMark Murray 	err (1, "getpeername");
130b528cefcSMark Murray 
1315e9cd1aeSAssar Westerlund     input_chan_bindings.initiator_addrtype = GSS_C_AF_INET;
1325e9cd1aeSAssar Westerlund     input_chan_bindings.initiator_address.length = 4;
1335e9cd1aeSAssar Westerlund     init_buf[0] = (remote.sin_addr.s_addr >> 24) & 0xFF;
1345e9cd1aeSAssar Westerlund     init_buf[1] = (remote.sin_addr.s_addr >> 16) & 0xFF;
1355e9cd1aeSAssar Westerlund     init_buf[2] = (remote.sin_addr.s_addr >>  8) & 0xFF;
1365e9cd1aeSAssar Westerlund     init_buf[3] = (remote.sin_addr.s_addr >>  0) & 0xFF;
1375e9cd1aeSAssar Westerlund 
1385e9cd1aeSAssar Westerlund     input_chan_bindings.initiator_address.value = init_buf;
1395e9cd1aeSAssar Westerlund     input_chan_bindings.acceptor_addrtype = GSS_C_AF_INET;
1405e9cd1aeSAssar Westerlund 
1415e9cd1aeSAssar Westerlund     input_chan_bindings.acceptor_address.length = 4;
1425e9cd1aeSAssar Westerlund     acct_buf[0] = (local.sin_addr.s_addr >> 24) & 0xFF;
1435e9cd1aeSAssar Westerlund     acct_buf[1] = (local.sin_addr.s_addr >> 16) & 0xFF;
1445e9cd1aeSAssar Westerlund     acct_buf[2] = (local.sin_addr.s_addr >>  8) & 0xFF;
1455e9cd1aeSAssar Westerlund     acct_buf[3] = (local.sin_addr.s_addr >>  0) & 0xFF;
1465e9cd1aeSAssar Westerlund     input_chan_bindings.acceptor_address.value = acct_buf;
1475e9cd1aeSAssar Westerlund     input_chan_bindings.application_data.value = emalloc(4);
1485e9cd1aeSAssar Westerlund #if 0
1495e9cd1aeSAssar Westerlund     * (unsigned short *)input_chan_bindings.application_data.value =
1505e9cd1aeSAssar Westerlund                           remote.sin_port;
1515e9cd1aeSAssar Westerlund     * ((unsigned short *)input_chan_bindings.application_data.value + 1) =
1525e9cd1aeSAssar Westerlund                           local.sin_port;
1535e9cd1aeSAssar Westerlund     input_chan_bindings.application_data.length = 4;
1545e9cd1aeSAssar Westerlund #else
1555e9cd1aeSAssar Westerlund     input_chan_bindings.application_data.length = 0;
1565e9cd1aeSAssar Westerlund     input_chan_bindings.application_data.value = NULL;
1575e9cd1aeSAssar Westerlund #endif
1585e9cd1aeSAssar Westerlund 
1595e9cd1aeSAssar Westerlund     delegated_cred_handle = emalloc(sizeof(*delegated_cred_handle));
1605e9cd1aeSAssar Westerlund     memset((char*)delegated_cred_handle, 0, sizeof(*delegated_cred_handle));
1615e9cd1aeSAssar Westerlund 
162b528cefcSMark Murray     do {
163b528cefcSMark Murray 	read_token (sock, input_token);
164b528cefcSMark Murray 	maj_stat =
165b528cefcSMark Murray 	    gss_accept_sec_context (&min_stat,
166b528cefcSMark Murray 				    &context_hdl,
167b528cefcSMark Murray 				    GSS_C_NO_CREDENTIAL,
168b528cefcSMark Murray 				    input_token,
1695e9cd1aeSAssar Westerlund 				    &input_chan_bindings,
170b528cefcSMark Murray 				    &client_name,
171b528cefcSMark Murray 				    NULL,
172b528cefcSMark Murray 				    output_token,
173b528cefcSMark Murray 				    NULL,
174b528cefcSMark Murray 				    NULL,
1755e9cd1aeSAssar Westerlund 				    /*&delegated_cred_handle*/ NULL);
176b528cefcSMark Murray 	if(GSS_ERROR(maj_stat))
177b528cefcSMark Murray 	    gss_err (1, min_stat, "gss_accept_sec_context");
178b528cefcSMark Murray 	if (output_token->length != 0)
179b528cefcSMark Murray 	    write_token (sock, output_token);
180b528cefcSMark Murray 	if (GSS_ERROR(maj_stat)) {
181b528cefcSMark Murray 	    if (context_hdl != GSS_C_NO_CONTEXT)
182b528cefcSMark Murray 		gss_delete_sec_context (&min_stat,
183b528cefcSMark Murray 					&context_hdl,
184b528cefcSMark Murray 					GSS_C_NO_BUFFER);
185b528cefcSMark Murray 	    break;
186b528cefcSMark Murray 	}
187b528cefcSMark Murray     } while(maj_stat & GSS_S_CONTINUE_NEEDED);
188b528cefcSMark Murray 
1895e9cd1aeSAssar Westerlund     if (delegated_cred_handle->ccache) {
1905e9cd1aeSAssar Westerlund        krb5_context context;
1915e9cd1aeSAssar Westerlund 
1925e9cd1aeSAssar Westerlund        maj_stat = krb5_init_context(&context);
1935e9cd1aeSAssar Westerlund        maj_stat = krb5_cc_resolve(context, "FILE:/tmp/krb5cc_test", &ccache);
1945e9cd1aeSAssar Westerlund        maj_stat = krb5_cc_copy_cache(context,
1955e9cd1aeSAssar Westerlund                                       delegated_cred_handle->ccache, ccache);
1965e9cd1aeSAssar Westerlund        krb5_cc_close(context, ccache);
1975e9cd1aeSAssar Westerlund        krb5_cc_destroy(context, delegated_cred_handle->ccache);
1985e9cd1aeSAssar Westerlund     }
1995e9cd1aeSAssar Westerlund 
200283d988cSMark Murray     if (fork_flag) {
201283d988cSMark Murray 	pid_t pid;
202283d988cSMark Murray 	int pipefd[2];
203283d988cSMark Murray 
204283d988cSMark Murray 	if (pipe (pipefd) < 0)
205283d988cSMark Murray 	    err (1, "pipe");
206283d988cSMark Murray 
207283d988cSMark Murray 	pid = fork ();
208283d988cSMark Murray 	if (pid < 0)
209283d988cSMark Murray 	    err (1, "fork");
210283d988cSMark Murray 	if (pid != 0) {
211283d988cSMark Murray 	    gss_buffer_desc buf;
212283d988cSMark Murray 
213283d988cSMark Murray 	    maj_stat = gss_export_sec_context (&min_stat,
214283d988cSMark Murray 					       &context_hdl,
215283d988cSMark Murray 					       &buf);
216b528cefcSMark Murray 	    if (GSS_ERROR(maj_stat))
217283d988cSMark Murray 		gss_err (1, min_stat, "gss_export_sec_context");
218283d988cSMark Murray 	    write_token (pipefd[1], &buf);
219283d988cSMark Murray 	    exit (0);
220283d988cSMark Murray 	} else {
221283d988cSMark Murray 	    gss_ctx_id_t context_hdl;
222283d988cSMark Murray 	    gss_buffer_desc buf;
223b528cefcSMark Murray 
224283d988cSMark Murray 	    close (pipefd[1]);
225283d988cSMark Murray 	    read_token (pipefd[0], &buf);
226283d988cSMark Murray 	    close (pipefd[0]);
227283d988cSMark Murray 	    maj_stat = gss_import_sec_context (&min_stat, &buf, &context_hdl);
228b528cefcSMark Murray 	    if (GSS_ERROR(maj_stat))
229283d988cSMark Murray 		gss_err (1, min_stat, "gss_import_sec_context");
230283d988cSMark Murray 	    gss_release_buffer (&min_stat, &buf);
231283d988cSMark Murray 	    return process_it (sock, context_hdl, client_name);
232283d988cSMark Murray 	}
233283d988cSMark Murray     } else {
234283d988cSMark Murray 	return process_it (sock, context_hdl, client_name);
235283d988cSMark Murray     }
236b528cefcSMark Murray }
237b528cefcSMark Murray 
238b528cefcSMark Murray static int
239b528cefcSMark Murray doit (int port, const char *service)
240b528cefcSMark Murray {
241b528cefcSMark Murray     int sock, sock2;
242b528cefcSMark Murray     struct sockaddr_in my_addr;
243b528cefcSMark Murray     int one = 1;
244b528cefcSMark Murray 
245b528cefcSMark Murray     sock = socket (AF_INET, SOCK_STREAM, 0);
246b528cefcSMark Murray     if (sock < 0)
247b528cefcSMark Murray 	err (1, "socket");
248b528cefcSMark Murray 
249b528cefcSMark Murray     memset (&my_addr, 0, sizeof(my_addr));
250b528cefcSMark Murray     my_addr.sin_family      = AF_INET;
251b528cefcSMark Murray     my_addr.sin_port        = port;
252b528cefcSMark Murray     my_addr.sin_addr.s_addr = INADDR_ANY;
253b528cefcSMark Murray 
254b528cefcSMark Murray     if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
255b528cefcSMark Murray 		    (void *)&one, sizeof(one)) < 0)
256b528cefcSMark Murray 	warn ("setsockopt SO_REUSEADDR");
257b528cefcSMark Murray 
258b528cefcSMark Murray     if (bind (sock, (struct sockaddr *)&my_addr, sizeof(my_addr)) < 0)
259b528cefcSMark Murray 	err (1, "bind");
260b528cefcSMark Murray 
261b528cefcSMark Murray     if (listen (sock, 1) < 0)
262b528cefcSMark Murray 	err (1, "listen");
263b528cefcSMark Murray 
264b528cefcSMark Murray     sock2 = accept (sock, NULL, NULL);
265b528cefcSMark Murray     if (sock2 < 0)
266b528cefcSMark Murray 	err (1, "accept");
267b528cefcSMark Murray 
268b528cefcSMark Murray     return proto (sock2, service);
269b528cefcSMark Murray }
270b528cefcSMark Murray 
271b528cefcSMark Murray int
272b528cefcSMark Murray main(int argc, char **argv)
273b528cefcSMark Murray {
274b528cefcSMark Murray     krb5_context context = NULL; /* XXX */
275b528cefcSMark Murray     int port = server_setup(&context, argc, argv);
276b528cefcSMark Murray     return doit (port, service);
277b528cefcSMark Murray }
278