gssapi_client.c revision 72445
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"
3772445SassarRCSID("$Id: gssapi_client.c,v 1.16 2000/08/09 20:53:06 assar Exp $");
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
6857419Smarkm
6957419Smarkm    maj_stat = gss_wrap (&min_stat,
7057419Smarkm			 context_hdl,
7157419Smarkm			 1,
7257419Smarkm			 GSS_C_QOP_DEFAULT,
7357419Smarkm			 input_token,
7457419Smarkm			 NULL,
7557419Smarkm			 output_token);
7657419Smarkm    if (GSS_ERROR(maj_stat))
7757419Smarkm	gss_err (1, min_stat, "gss_wrap");
7857419Smarkm
7957419Smarkm    write_token (sock, output_token);
8057419Smarkm
8157419Smarkm    return 0;
8257419Smarkm}
8357419Smarkm
8457419Smarkmstatic int
8555682Smarkmproto (int sock, const char *hostname, const char *service)
8655682Smarkm{
8755682Smarkm    struct sockaddr_in remote, local;
8872445Sassar    socklen_t addrlen;
8955682Smarkm
9055682Smarkm    int context_established = 0;
9155682Smarkm    gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT;
9255682Smarkm    gss_buffer_desc real_input_token, real_output_token;
9357419Smarkm    gss_buffer_t input_token = &real_input_token,
9457419Smarkm	output_token = &real_output_token;
9555682Smarkm    OM_uint32 maj_stat, min_stat;
9655682Smarkm    gss_name_t server;
9755682Smarkm    gss_buffer_desc name_token;
9872445Sassar    struct gss_channel_bindings_struct input_chan_bindings;
9972445Sassar    u_char init_buf[4];
10072445Sassar    u_char acct_buf[4];
10155682Smarkm
10255682Smarkm    name_token.length = asprintf ((char **)&name_token.value,
10355682Smarkm				  "%s@%s", service, hostname);
10455682Smarkm
10555682Smarkm    maj_stat = gss_import_name (&min_stat,
10655682Smarkm				&name_token,
10755682Smarkm				GSS_C_NT_HOSTBASED_SERVICE,
10855682Smarkm				&server);
10955682Smarkm    if (GSS_ERROR(maj_stat))
11055682Smarkm	gss_err (1, min_stat,
11155682Smarkm		 "Error importing name `%s@%s':\n", service, hostname);
11255682Smarkm
11355682Smarkm    addrlen = sizeof(local);
11455682Smarkm    if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0
11555682Smarkm	|| addrlen != sizeof(local))
11655682Smarkm	err (1, "getsockname(%s)", hostname);
11755682Smarkm
11855682Smarkm    addrlen = sizeof(remote);
11955682Smarkm    if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0
12055682Smarkm	|| addrlen != sizeof(remote))
12155682Smarkm	err (1, "getpeername(%s)", hostname);
12255682Smarkm
12355682Smarkm    input_token->length = 0;
12455682Smarkm    output_token->length = 0;
12555682Smarkm
12672445Sassar    input_chan_bindings.initiator_addrtype = GSS_C_AF_INET;
12772445Sassar    input_chan_bindings.initiator_address.length = 4;
12872445Sassar    init_buf[0] = (local.sin_addr.s_addr >> 24) & 0xFF;
12972445Sassar    init_buf[1] = (local.sin_addr.s_addr >> 16) & 0xFF;
13072445Sassar    init_buf[2] = (local.sin_addr.s_addr >>  8) & 0xFF;
13172445Sassar    init_buf[3] = (local.sin_addr.s_addr >>  0) & 0xFF;
13272445Sassar    input_chan_bindings.initiator_address.value = init_buf;
13372445Sassar
13472445Sassar    input_chan_bindings.acceptor_addrtype = GSS_C_AF_INET;
13572445Sassar    input_chan_bindings.acceptor_address.length = 4;
13672445Sassar    acct_buf[0] = (remote.sin_addr.s_addr >> 24) & 0xFF;
13772445Sassar    acct_buf[1] = (remote.sin_addr.s_addr >> 16) & 0xFF;
13872445Sassar    acct_buf[2] = (remote.sin_addr.s_addr >>  8) & 0xFF;
13972445Sassar    acct_buf[3] = (remote.sin_addr.s_addr >>  0) & 0xFF;
14072445Sassar    input_chan_bindings.acceptor_address.value = acct_buf;
14172445Sassar
14272445Sassar#if 0
14372445Sassar    input_chan_bindings.application_data.value = emalloc(4);
14472445Sassar    * (unsigned short*)input_chan_bindings.application_data.value = local.sin_port;
14572445Sassar    * ((unsigned short *)input_chan_bindings.application_data.value + 1) = remote.sin_port;
14672445Sassar    input_chan_bindings.application_data.length = 4;
14772445Sassar#else
14872445Sassar    input_chan_bindings.application_data.length = 0;
14972445Sassar    input_chan_bindings.application_data.value = NULL;
15072445Sassar#endif
15172445Sassar
15255682Smarkm    while(!context_established) {
15355682Smarkm	maj_stat =
15455682Smarkm	    gss_init_sec_context(&min_stat,
15555682Smarkm				 GSS_C_NO_CREDENTIAL,
15655682Smarkm				 &context_hdl,
15755682Smarkm				 server,
15855682Smarkm				 GSS_C_NO_OID,
15972445Sassar				 GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG
16072445Sassar				 | GSS_C_DELEG_FLAG,
16155682Smarkm				 0,
16272445Sassar				 &input_chan_bindings,
16355682Smarkm				 input_token,
16455682Smarkm				 NULL,
16555682Smarkm				 output_token,
16655682Smarkm				 NULL,
16755682Smarkm				 NULL);
16855682Smarkm	if (GSS_ERROR(maj_stat))
16955682Smarkm	    gss_err (1, min_stat, "gss_init_sec_context");
17055682Smarkm	if (output_token->length != 0)
17155682Smarkm	    write_token (sock, output_token);
17255682Smarkm	if (GSS_ERROR(maj_stat)) {
17355682Smarkm	    if (context_hdl != GSS_C_NO_CONTEXT)
17455682Smarkm		gss_delete_sec_context (&min_stat,
17555682Smarkm					&context_hdl,
17655682Smarkm					GSS_C_NO_BUFFER);
17755682Smarkm	    break;
17855682Smarkm	}
17955682Smarkm	if (maj_stat & GSS_S_CONTINUE_NEEDED) {
18055682Smarkm	    read_token (sock, input_token);
18155682Smarkm	} else {
18255682Smarkm	    context_established = 1;
18355682Smarkm	}
18455682Smarkm
18555682Smarkm    }
18657419Smarkm    if (fork_flag) {
18757419Smarkm	pid_t pid;
18857419Smarkm	int pipefd[2];
18955682Smarkm
19057419Smarkm	if (pipe (pipefd) < 0)
19157419Smarkm	    err (1, "pipe");
19255682Smarkm
19357419Smarkm	pid = fork ();
19457419Smarkm	if (pid < 0)
19557419Smarkm	    err (1, "fork");
19657419Smarkm	if (pid != 0) {
19757419Smarkm	    gss_buffer_desc buf;
19855682Smarkm
19957419Smarkm	    maj_stat = gss_export_sec_context (&min_stat,
20057419Smarkm					       &context_hdl,
20157419Smarkm					       &buf);
20257419Smarkm	    if (GSS_ERROR(maj_stat))
20357419Smarkm		gss_err (1, min_stat, "gss_export_sec_context");
20457419Smarkm	    write_token (pipefd[1], &buf);
20557419Smarkm	    exit (0);
20657419Smarkm	} else {
20757419Smarkm	    gss_ctx_id_t context_hdl;
20857419Smarkm	    gss_buffer_desc buf;
20955682Smarkm
21057419Smarkm	    close (pipefd[1]);
21157419Smarkm	    read_token (pipefd[0], &buf);
21257419Smarkm	    close (pipefd[0]);
21357419Smarkm	    maj_stat = gss_import_sec_context (&min_stat, &buf, &context_hdl);
21457419Smarkm	    if (GSS_ERROR(maj_stat))
21557419Smarkm		gss_err (1, min_stat, "gss_import_sec_context");
21657419Smarkm	    gss_release_buffer (&min_stat, &buf);
21757419Smarkm	    return do_trans (sock, context_hdl);
21857419Smarkm	}
21957419Smarkm    } else {
22057419Smarkm	return do_trans (sock, context_hdl);
22157419Smarkm    }
22255682Smarkm}
22355682Smarkm
22455682Smarkmint
22555682Smarkmmain(int argc, char **argv)
22655682Smarkm{
22755682Smarkm    krb5_context context; /* XXX */
22855682Smarkm    int port = client_setup(&context, &argc, argv);
22955682Smarkm    return client_doit (argv[argc], port, service, proto);
23055682Smarkm}
231