gssapi_client.c revision 178825
155682Smarkm/*
257419Smarkm * Copyright (c) 1997 - 2000 Kungliga Tekniska H�gskolan
355682Smarkm * (Royal Institute of Technology, Stockholm, Sweden).
455682Smarkm * All rights reserved.
555682Smarkm *
655682Smarkm * Redistribution and use in source and binary forms, with or without
755682Smarkm * modification, are permitted provided that the following conditions
855682Smarkm * are met:
955682Smarkm *
1055682Smarkm * 1. Redistributions of source code must retain the above copyright
1155682Smarkm *    notice, this list of conditions and the following disclaimer.
1255682Smarkm *
1355682Smarkm * 2. Redistributions in binary form must reproduce the above copyright
1455682Smarkm *    notice, this list of conditions and the following disclaimer in the
1555682Smarkm *    documentation and/or other materials provided with the distribution.
1655682Smarkm *
1755682Smarkm * 3. Neither the name of the Institute nor the names of its contributors
1855682Smarkm *    may be used to endorse or promote products derived from this software
1955682Smarkm *    without specific prior written permission.
2055682Smarkm *
2155682Smarkm * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
2255682Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2355682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2455682Smarkm * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
2555682Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2655682Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2755682Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2855682Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2955682Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3055682Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3155682Smarkm * SUCH DAMAGE.
3255682Smarkm */
3355682Smarkm
3455682Smarkm#include "test_locl.h"
3555682Smarkm#include <gssapi.h>
3655682Smarkm#include "gss_common.h"
37178825SdfrRCSID("$Id: gssapi_client.c 21521 2007-07-12 13:13:40Z lha $");
3855682Smarkm
3955682Smarkmstatic int
4057419Smarkmdo_trans (int sock, gss_ctx_id_t context_hdl)
4157419Smarkm{
4257419Smarkm    OM_uint32 maj_stat, min_stat;
4357419Smarkm    gss_buffer_desc real_input_token, real_output_token;
4457419Smarkm    gss_buffer_t input_token = &real_input_token,
4557419Smarkm	output_token = &real_output_token;
4657419Smarkm
4757419Smarkm    /* get_mic */
4857419Smarkm
4957419Smarkm    input_token->length = 3;
5057419Smarkm    input_token->value  = strdup("hej");
5157419Smarkm
5257419Smarkm    maj_stat = gss_get_mic(&min_stat,
5357419Smarkm			   context_hdl,
5457419Smarkm			   GSS_C_QOP_DEFAULT,
5557419Smarkm			   input_token,
5657419Smarkm			   output_token);
5757419Smarkm    if (GSS_ERROR(maj_stat))
5857419Smarkm	gss_err (1, min_stat, "gss_get_mic");
5957419Smarkm
6057419Smarkm    write_token (sock, input_token);
6157419Smarkm    write_token (sock, output_token);
6257419Smarkm
6357419Smarkm    /* wrap */
6457419Smarkm
6557419Smarkm    input_token->length = 7;
6657419Smarkm    input_token->value  = "hemligt";
6757419Smarkm
68178825Sdfr    maj_stat = gss_wrap (&min_stat,
69178825Sdfr			 context_hdl,
70178825Sdfr			 0,
71178825Sdfr			 GSS_C_QOP_DEFAULT,
72178825Sdfr			 input_token,
73178825Sdfr			 NULL,
74178825Sdfr			 output_token);
75178825Sdfr    if (GSS_ERROR(maj_stat))
76178825Sdfr	gss_err (1, min_stat, "gss_wrap");
7757419Smarkm
78178825Sdfr    write_token (sock, output_token);
79178825Sdfr
8057419Smarkm    maj_stat = gss_wrap (&min_stat,
8157419Smarkm			 context_hdl,
8257419Smarkm			 1,
8357419Smarkm			 GSS_C_QOP_DEFAULT,
8457419Smarkm			 input_token,
8557419Smarkm			 NULL,
8657419Smarkm			 output_token);
8757419Smarkm    if (GSS_ERROR(maj_stat))
8857419Smarkm	gss_err (1, min_stat, "gss_wrap");
8957419Smarkm
9057419Smarkm    write_token (sock, output_token);
9157419Smarkm
9257419Smarkm    return 0;
9357419Smarkm}
9457419Smarkm
9557419Smarkmstatic int
9655682Smarkmproto (int sock, const char *hostname, const char *service)
9755682Smarkm{
9855682Smarkm    struct sockaddr_in remote, local;
9972445Sassar    socklen_t addrlen;
10055682Smarkm
10155682Smarkm    int context_established = 0;
10255682Smarkm    gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT;
10355682Smarkm    gss_buffer_desc real_input_token, real_output_token;
10457419Smarkm    gss_buffer_t input_token = &real_input_token,
10557419Smarkm	output_token = &real_output_token;
10655682Smarkm    OM_uint32 maj_stat, min_stat;
10755682Smarkm    gss_name_t server;
10855682Smarkm    gss_buffer_desc name_token;
10972445Sassar    struct gss_channel_bindings_struct input_chan_bindings;
11072445Sassar    u_char init_buf[4];
11172445Sassar    u_char acct_buf[4];
112178825Sdfr    gss_OID mech_oid;
113178825Sdfr    char *str;
11455682Smarkm
115178825Sdfr    mech_oid = select_mech(mech);
116178825Sdfr
117178825Sdfr    name_token.length = asprintf (&str,
11855682Smarkm				  "%s@%s", service, hostname);
119178825Sdfr    if (str == NULL)
120178825Sdfr	errx(1, "malloc - out of memory");
121178825Sdfr    name_token.value = str;
122178825Sdfr
12355682Smarkm    maj_stat = gss_import_name (&min_stat,
12455682Smarkm				&name_token,
12555682Smarkm				GSS_C_NT_HOSTBASED_SERVICE,
12655682Smarkm				&server);
12755682Smarkm    if (GSS_ERROR(maj_stat))
12855682Smarkm	gss_err (1, min_stat,
12955682Smarkm		 "Error importing name `%s@%s':\n", service, hostname);
13055682Smarkm
13155682Smarkm    addrlen = sizeof(local);
13255682Smarkm    if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0
13355682Smarkm	|| addrlen != sizeof(local))
13455682Smarkm	err (1, "getsockname(%s)", hostname);
13555682Smarkm
13655682Smarkm    addrlen = sizeof(remote);
13755682Smarkm    if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0
13855682Smarkm	|| addrlen != sizeof(remote))
13955682Smarkm	err (1, "getpeername(%s)", hostname);
14055682Smarkm
14155682Smarkm    input_token->length = 0;
14255682Smarkm    output_token->length = 0;
14355682Smarkm
14472445Sassar    input_chan_bindings.initiator_addrtype = GSS_C_AF_INET;
14572445Sassar    input_chan_bindings.initiator_address.length = 4;
14672445Sassar    init_buf[0] = (local.sin_addr.s_addr >> 24) & 0xFF;
14772445Sassar    init_buf[1] = (local.sin_addr.s_addr >> 16) & 0xFF;
14872445Sassar    init_buf[2] = (local.sin_addr.s_addr >>  8) & 0xFF;
14972445Sassar    init_buf[3] = (local.sin_addr.s_addr >>  0) & 0xFF;
15072445Sassar    input_chan_bindings.initiator_address.value = init_buf;
15172445Sassar
15272445Sassar    input_chan_bindings.acceptor_addrtype = GSS_C_AF_INET;
15372445Sassar    input_chan_bindings.acceptor_address.length = 4;
15472445Sassar    acct_buf[0] = (remote.sin_addr.s_addr >> 24) & 0xFF;
15572445Sassar    acct_buf[1] = (remote.sin_addr.s_addr >> 16) & 0xFF;
15672445Sassar    acct_buf[2] = (remote.sin_addr.s_addr >>  8) & 0xFF;
15772445Sassar    acct_buf[3] = (remote.sin_addr.s_addr >>  0) & 0xFF;
15872445Sassar    input_chan_bindings.acceptor_address.value = acct_buf;
15972445Sassar
16072445Sassar#if 0
16172445Sassar    input_chan_bindings.application_data.value = emalloc(4);
16272445Sassar    * (unsigned short*)input_chan_bindings.application_data.value = local.sin_port;
16372445Sassar    * ((unsigned short *)input_chan_bindings.application_data.value + 1) = remote.sin_port;
16472445Sassar    input_chan_bindings.application_data.length = 4;
16572445Sassar#else
16672445Sassar    input_chan_bindings.application_data.length = 0;
16772445Sassar    input_chan_bindings.application_data.value = NULL;
16872445Sassar#endif
16972445Sassar
17055682Smarkm    while(!context_established) {
17155682Smarkm	maj_stat =
17255682Smarkm	    gss_init_sec_context(&min_stat,
17355682Smarkm				 GSS_C_NO_CREDENTIAL,
17455682Smarkm				 &context_hdl,
17555682Smarkm				 server,
176178825Sdfr				 mech_oid,
17772445Sassar				 GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG
17872445Sassar				 | GSS_C_DELEG_FLAG,
17955682Smarkm				 0,
18072445Sassar				 &input_chan_bindings,
18155682Smarkm				 input_token,
18255682Smarkm				 NULL,
18355682Smarkm				 output_token,
18455682Smarkm				 NULL,
18555682Smarkm				 NULL);
18655682Smarkm	if (GSS_ERROR(maj_stat))
18755682Smarkm	    gss_err (1, min_stat, "gss_init_sec_context");
18855682Smarkm	if (output_token->length != 0)
18955682Smarkm	    write_token (sock, output_token);
19055682Smarkm	if (GSS_ERROR(maj_stat)) {
19155682Smarkm	    if (context_hdl != GSS_C_NO_CONTEXT)
19255682Smarkm		gss_delete_sec_context (&min_stat,
19355682Smarkm					&context_hdl,
19455682Smarkm					GSS_C_NO_BUFFER);
19555682Smarkm	    break;
19655682Smarkm	}
19755682Smarkm	if (maj_stat & GSS_S_CONTINUE_NEEDED) {
19855682Smarkm	    read_token (sock, input_token);
19955682Smarkm	} else {
20055682Smarkm	    context_established = 1;
20155682Smarkm	}
20255682Smarkm
20355682Smarkm    }
20457419Smarkm    if (fork_flag) {
20557419Smarkm	pid_t pid;
20657419Smarkm	int pipefd[2];
20755682Smarkm
20857419Smarkm	if (pipe (pipefd) < 0)
20957419Smarkm	    err (1, "pipe");
21055682Smarkm
21157419Smarkm	pid = fork ();
21257419Smarkm	if (pid < 0)
21357419Smarkm	    err (1, "fork");
21457419Smarkm	if (pid != 0) {
21557419Smarkm	    gss_buffer_desc buf;
21655682Smarkm
21757419Smarkm	    maj_stat = gss_export_sec_context (&min_stat,
21857419Smarkm					       &context_hdl,
21957419Smarkm					       &buf);
22057419Smarkm	    if (GSS_ERROR(maj_stat))
22157419Smarkm		gss_err (1, min_stat, "gss_export_sec_context");
22257419Smarkm	    write_token (pipefd[1], &buf);
22357419Smarkm	    exit (0);
22457419Smarkm	} else {
22557419Smarkm	    gss_ctx_id_t context_hdl;
22657419Smarkm	    gss_buffer_desc buf;
22755682Smarkm
22857419Smarkm	    close (pipefd[1]);
22957419Smarkm	    read_token (pipefd[0], &buf);
23057419Smarkm	    close (pipefd[0]);
23157419Smarkm	    maj_stat = gss_import_sec_context (&min_stat, &buf, &context_hdl);
23257419Smarkm	    if (GSS_ERROR(maj_stat))
23357419Smarkm		gss_err (1, min_stat, "gss_import_sec_context");
23457419Smarkm	    gss_release_buffer (&min_stat, &buf);
23557419Smarkm	    return do_trans (sock, context_hdl);
23657419Smarkm	}
23757419Smarkm    } else {
23857419Smarkm	return do_trans (sock, context_hdl);
23957419Smarkm    }
24055682Smarkm}
24155682Smarkm
24255682Smarkmint
24355682Smarkmmain(int argc, char **argv)
24455682Smarkm{
24555682Smarkm    krb5_context context; /* XXX */
24655682Smarkm    int port = client_setup(&context, &argc, argv);
24755682Smarkm    return client_doit (argv[argc], port, service, proto);
24855682Smarkm}
249