gssapi_client.c revision 57419
1121986Sjhb/*
2121986Sjhb * Copyright (c) 1997 - 2000 Kungliga Tekniska H�gskolan
3121986Sjhb * (Royal Institute of Technology, Stockholm, Sweden).
4121986Sjhb * All rights reserved.
5121986Sjhb *
6121986Sjhb * Redistribution and use in source and binary forms, with or without
7121986Sjhb * modification, are permitted provided that the following conditions
8121986Sjhb * are met:
9121986Sjhb *
10121986Sjhb * 1. Redistributions of source code must retain the above copyright
11121986Sjhb *    notice, this list of conditions and the following disclaimer.
12121986Sjhb *
13121986Sjhb * 2. Redistributions in binary form must reproduce the above copyright
14121986Sjhb *    notice, this list of conditions and the following disclaimer in the
15121986Sjhb *    documentation and/or other materials provided with the distribution.
16121986Sjhb *
17121986Sjhb * 3. Neither the name of the Institute nor the names of its contributors
18121986Sjhb *    may be used to endorse or promote products derived from this software
19121986Sjhb *    without specific prior written permission.
20121986Sjhb *
21121986Sjhb * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22121986Sjhb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23121986Sjhb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24121986Sjhb * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25121986Sjhb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26121986Sjhb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27121986Sjhb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28121986Sjhb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29121986Sjhb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30121986Sjhb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31121986Sjhb * SUCH DAMAGE.
32121986Sjhb */
33121986Sjhb
34121986Sjhb#include "test_locl.h"
35121986Sjhb#include <gssapi.h>
36121986Sjhb#include "gss_common.h"
37121986SjhbRCSID("$Id: gssapi_client.c,v 1.12 2000/02/12 21:33:17 assar Exp $");
38121986Sjhb
39121986Sjhbstatic int
40122710Speterdo_trans (int sock, gss_ctx_id_t context_hdl)
41121986Sjhb{
42139240Sjhb    OM_uint32 maj_stat, min_stat;
43121986Sjhb    gss_buffer_desc real_input_token, real_output_token;
44122690Sjhb    gss_buffer_t input_token = &real_input_token,
45121986Sjhb	output_token = &real_output_token;
46122690Sjhb
47121986Sjhb    /* get_mic */
48121986Sjhb
49121986Sjhb    input_token->length = 3;
50121986Sjhb    input_token->value  = strdup("hej");
51121986Sjhb
52121986Sjhb    maj_stat = gss_get_mic(&min_stat,
53121986Sjhb			   context_hdl,
54121986Sjhb			   GSS_C_QOP_DEFAULT,
55121986Sjhb			   input_token,
56121986Sjhb			   output_token);
57121986Sjhb    if (GSS_ERROR(maj_stat))
58121986Sjhb	gss_err (1, min_stat, "gss_get_mic");
59121986Sjhb
60121986Sjhb    write_token (sock, input_token);
61121986Sjhb    write_token (sock, output_token);
62121986Sjhb
63121986Sjhb    /* wrap */
64121986Sjhb
65121986Sjhb    input_token->length = 7;
66122690Sjhb    input_token->value  = "hemligt";
67121986Sjhb
68121986Sjhb
69121986Sjhb    maj_stat = gss_wrap (&min_stat,
70121986Sjhb			 context_hdl,
71121986Sjhb			 1,
72121986Sjhb			 GSS_C_QOP_DEFAULT,
73121986Sjhb			 input_token,
74121986Sjhb			 NULL,
75121986Sjhb			 output_token);
76121986Sjhb    if (GSS_ERROR(maj_stat))
77169395Sjhb	gss_err (1, min_stat, "gss_wrap");
78121986Sjhb
79139240Sjhb    write_token (sock, output_token);
80139240Sjhb
81122690Sjhb    return 0;
82139240Sjhb}
83121986Sjhb
84139240Sjhbstatic int
85139240Sjhbproto (int sock, const char *hostname, const char *service)
86139240Sjhb{
87138528Sups    struct sockaddr_in remote, local;
88138528Sups    int addrlen;
89138528Sups
90138528Sups    int context_established = 0;
91138528Sups    gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT;
92138528Sups    gss_buffer_desc real_input_token, real_output_token;
93138528Sups    gss_buffer_t input_token = &real_input_token,
94138528Sups	output_token = &real_output_token;
95138528Sups    OM_uint32 maj_stat, min_stat;
96138528Sups    gss_name_t server;
97138528Sups    gss_buffer_desc name_token;
98138528Sups
99138528Sups    name_token.length = asprintf ((char **)&name_token.value,
100138528Sups				  "%s@%s", service, hostname);
101138528Sups
102139240Sjhb    maj_stat = gss_import_name (&min_stat,
103122690Sjhb				&name_token,
104139240Sjhb				GSS_C_NT_HOSTBASED_SERVICE,
105139240Sjhb				&server);
106208507Sjhb    if (GSS_ERROR(maj_stat))
107208507Sjhb	gss_err (1, min_stat,
108121986Sjhb		 "Error importing name `%s@%s':\n", service, hostname);
109138528Sups
110121986Sjhb    addrlen = sizeof(local);
111121986Sjhb    if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0
112121986Sjhb	|| addrlen != sizeof(local))
113158236Sjhb	err (1, "getsockname(%s)", hostname);
114158236Sjhb
115138528Sups    addrlen = sizeof(remote);
116158236Sjhb    if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0
117121986Sjhb	|| addrlen != sizeof(remote))
118138528Sups	err (1, "getpeername(%s)", hostname);
119138528Sups
120147181Sups    input_token->length = 0;
121191745Smav    output_token->length = 0;
122212541Smav
123138528Sups    while(!context_established) {
124138528Sups	maj_stat =
125158236Sjhb	    gss_init_sec_context(&min_stat,
126235622Siwasaki				 GSS_C_NO_CREDENTIAL,
127235622Siwasaki				 &context_hdl,
128138528Sups				 server,
129139240Sjhb				 GSS_C_NO_OID,
130139240Sjhb				 GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG,
131138528Sups				 0,
132138528Sups				 GSS_C_NO_CHANNEL_BINDINGS,
133121986Sjhb				 input_token,
134121986Sjhb				 NULL,
135121986Sjhb				 output_token,
136121986Sjhb				 NULL,
137121986Sjhb				 NULL);
138121986Sjhb	if (GSS_ERROR(maj_stat))
139121986Sjhb	    gss_err (1, min_stat, "gss_init_sec_context");
140121986Sjhb	if (output_token->length != 0)
141130980Sjhb	    write_token (sock, output_token);
142130980Sjhb	if (GSS_ERROR(maj_stat)) {
143130980Sjhb	    if (context_hdl != GSS_C_NO_CONTEXT)
144130980Sjhb		gss_delete_sec_context (&min_stat,
145130980Sjhb					&context_hdl,
146130980Sjhb					GSS_C_NO_BUFFER);
147121986Sjhb	    break;
148121986Sjhb	}
149121986Sjhb	if (maj_stat & GSS_S_CONTINUE_NEEDED) {
150121986Sjhb	    read_token (sock, input_token);
151121986Sjhb	} else {
152121986Sjhb	    context_established = 1;
153121986Sjhb	}
154121986Sjhb
155121986Sjhb    }
156121986Sjhb    if (fork_flag) {
157121986Sjhb	pid_t pid;
158121986Sjhb	int pipefd[2];
159121986Sjhb
160121986Sjhb	if (pipe (pipefd) < 0)
161121986Sjhb	    err (1, "pipe");
162122690Sjhb
163208507Sjhb	pid = fork ();
164208507Sjhb	if (pid < 0)
165121986Sjhb	    err (1, "fork");
166167747Sjhb	if (pid != 0) {
167187880Sjeff	    gss_buffer_desc buf;
168167747Sjhb
169187880Sjeff	    maj_stat = gss_export_sec_context (&min_stat,
170187880Sjeff					       &context_hdl,
171187880Sjeff					       &buf);
172187880Sjeff	    if (GSS_ERROR(maj_stat))
173187880Sjeff		gss_err (1, min_stat, "gss_export_sec_context");
174187880Sjeff	    write_token (pipefd[1], &buf);
175187880Sjeff	    exit (0);
176121986Sjhb	} else {
177187880Sjeff	    gss_ctx_id_t context_hdl;
178167247Sjhb	    gss_buffer_desc buf;
179121986Sjhb
180121986Sjhb	    close (pipefd[1]);
181121986Sjhb	    read_token (pipefd[0], &buf);
182121986Sjhb	    close (pipefd[0]);
183130980Sjhb	    maj_stat = gss_import_sec_context (&min_stat, &buf, &context_hdl);
184121986Sjhb	    if (GSS_ERROR(maj_stat))
185121986Sjhb		gss_err (1, min_stat, "gss_import_sec_context");
186128930Sjhb	    gss_release_buffer (&min_stat, &buf);
187128930Sjhb	    return do_trans (sock, context_hdl);
188128930Sjhb	}
189121986Sjhb    } else {
190121986Sjhb	return do_trans (sock, context_hdl);
191121986Sjhb    }
192196224Sjhb}
193121986Sjhb
194208507Sjhbint
195196224Sjhbmain(int argc, char **argv)
196122572Sjhb{
197121986Sjhb    krb5_context context; /* XXX */
198167247Sjhb    int port = client_setup(&context, &argc, argv);
199121986Sjhb    return client_doit (argv[argc], port, service, proto);
200121986Sjhb}
201121986Sjhb