gssapi_server.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_server.c,v 1.15 2000/08/09 20:53:07 assar Exp $");
3855682Smarkm
3955682Smarkmstatic int
4057419Smarkmprocess_it(int sock,
4157419Smarkm	   gss_ctx_id_t context_hdl,
4257419Smarkm	   gss_name_t client_name
4357419Smarkm	   )
4457419Smarkm{
4557419Smarkm    OM_uint32 maj_stat, min_stat;
4657419Smarkm    gss_buffer_desc name_token;
4757419Smarkm    gss_buffer_desc real_input_token, real_output_token;
4857419Smarkm    gss_buffer_t input_token = &real_input_token,
4957419Smarkm	output_token = &real_output_token;
5057419Smarkm
5157419Smarkm    maj_stat = gss_display_name (&min_stat,
5257419Smarkm				 client_name,
5357419Smarkm				 &name_token,
5457419Smarkm				 NULL);
5557419Smarkm    if (GSS_ERROR(maj_stat))
5657419Smarkm	gss_err (1, min_stat, "gss_display_name");
5757419Smarkm
5857419Smarkm    fprintf (stderr, "User is `%.*s'\n", (int)name_token.length,
5957419Smarkm	    (char *)name_token.value);
6057419Smarkm
6157419Smarkm    gss_release_buffer (&min_stat, &name_token);
6257419Smarkm
6357419Smarkm    /* gss_verify_mic */
6457419Smarkm
6557419Smarkm    read_token (sock, input_token);
6657419Smarkm    read_token (sock, output_token);
6757419Smarkm
6857419Smarkm    maj_stat = gss_verify_mic (&min_stat,
6957419Smarkm			       context_hdl,
7057419Smarkm			       input_token,
7157419Smarkm			       output_token,
7257419Smarkm			       NULL);
7357419Smarkm    if (GSS_ERROR(maj_stat))
7457419Smarkm	gss_err (1, min_stat, "gss_verify_mic");
7557419Smarkm
7657419Smarkm    fprintf (stderr, "gss_verify_mic: %.*s\n", (int)input_token->length,
7757419Smarkm	    (char *)input_token->value);
7857419Smarkm
7957419Smarkm    gss_release_buffer (&min_stat, input_token);
8057419Smarkm    gss_release_buffer (&min_stat, output_token);
8157419Smarkm
8257419Smarkm    /* gss_unwrap */
8357419Smarkm
8457419Smarkm    read_token (sock, input_token);
8557419Smarkm
8657419Smarkm    maj_stat = gss_unwrap (&min_stat,
8757419Smarkm			   context_hdl,
8857419Smarkm			   input_token,
8957419Smarkm			   output_token,
9057419Smarkm			   NULL,
9157419Smarkm			   NULL);
9257419Smarkm    if(GSS_ERROR(maj_stat))
9357419Smarkm	gss_err (1, min_stat, "gss_unwrap");
9457419Smarkm
9557419Smarkm    fprintf (stderr, "gss_unwrap: %.*s\n", (int)output_token->length,
9657419Smarkm	    (char *)output_token->value);
9757419Smarkm
9857419Smarkm    gss_release_buffer (&min_stat, input_token);
9957419Smarkm    gss_release_buffer (&min_stat, output_token);
10057419Smarkm
10157419Smarkm    return 0;
10257419Smarkm}
10357419Smarkm
10457419Smarkmstatic int
10555682Smarkmproto (int sock, const char *service)
10655682Smarkm{
10755682Smarkm    struct sockaddr_in remote, local;
10872445Sassar    socklen_t addrlen;
10955682Smarkm    gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT;
11055682Smarkm    gss_buffer_desc real_input_token, real_output_token;
11157419Smarkm    gss_buffer_t input_token = &real_input_token,
11257419Smarkm	output_token = &real_output_token;
11355682Smarkm    OM_uint32 maj_stat, min_stat;
11455682Smarkm    gss_name_t client_name;
11572445Sassar    struct gss_channel_bindings_struct input_chan_bindings;
11672445Sassar    gss_cred_id_t delegated_cred_handle = NULL;
11772445Sassar    krb5_ccache ccache;
11872445Sassar    u_char init_buf[4];
11972445Sassar    u_char acct_buf[4];
12055682Smarkm
12155682Smarkm    addrlen = sizeof(local);
12255682Smarkm    if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0
12355682Smarkm	|| addrlen != sizeof(local))
12455682Smarkm	err (1, "getsockname)");
12555682Smarkm
12655682Smarkm    addrlen = sizeof(remote);
12755682Smarkm    if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0
12855682Smarkm	|| addrlen != sizeof(remote))
12955682Smarkm	err (1, "getpeername");
13055682Smarkm
13172445Sassar    input_chan_bindings.initiator_addrtype = GSS_C_AF_INET;
13272445Sassar    input_chan_bindings.initiator_address.length = 4;
13372445Sassar    init_buf[0] = (remote.sin_addr.s_addr >> 24) & 0xFF;
13472445Sassar    init_buf[1] = (remote.sin_addr.s_addr >> 16) & 0xFF;
13572445Sassar    init_buf[2] = (remote.sin_addr.s_addr >>  8) & 0xFF;
13672445Sassar    init_buf[3] = (remote.sin_addr.s_addr >>  0) & 0xFF;
13772445Sassar
13872445Sassar    input_chan_bindings.initiator_address.value = init_buf;
13972445Sassar    input_chan_bindings.acceptor_addrtype = GSS_C_AF_INET;
14072445Sassar
14172445Sassar    input_chan_bindings.acceptor_address.length = 4;
14272445Sassar    acct_buf[0] = (local.sin_addr.s_addr >> 24) & 0xFF;
14372445Sassar    acct_buf[1] = (local.sin_addr.s_addr >> 16) & 0xFF;
14472445Sassar    acct_buf[2] = (local.sin_addr.s_addr >>  8) & 0xFF;
14572445Sassar    acct_buf[3] = (local.sin_addr.s_addr >>  0) & 0xFF;
14672445Sassar    input_chan_bindings.acceptor_address.value = acct_buf;
14772445Sassar    input_chan_bindings.application_data.value = emalloc(4);
14872445Sassar#if 0
14972445Sassar    * (unsigned short *)input_chan_bindings.application_data.value =
15072445Sassar                          remote.sin_port;
15172445Sassar    * ((unsigned short *)input_chan_bindings.application_data.value + 1) =
15272445Sassar                          local.sin_port;
15372445Sassar    input_chan_bindings.application_data.length = 4;
15472445Sassar#else
15572445Sassar    input_chan_bindings.application_data.length = 0;
15672445Sassar    input_chan_bindings.application_data.value = NULL;
15772445Sassar#endif
15872445Sassar
15972445Sassar    delegated_cred_handle = emalloc(sizeof(*delegated_cred_handle));
16072445Sassar    memset((char*)delegated_cred_handle, 0, sizeof(*delegated_cred_handle));
16172445Sassar
16255682Smarkm    do {
16355682Smarkm	read_token (sock, input_token);
16455682Smarkm	maj_stat =
16555682Smarkm	    gss_accept_sec_context (&min_stat,
16655682Smarkm				    &context_hdl,
16755682Smarkm				    GSS_C_NO_CREDENTIAL,
16855682Smarkm				    input_token,
16972445Sassar				    &input_chan_bindings,
17055682Smarkm				    &client_name,
17155682Smarkm				    NULL,
17255682Smarkm				    output_token,
17355682Smarkm				    NULL,
17455682Smarkm				    NULL,
17572445Sassar				    /*&delegated_cred_handle*/ NULL);
17655682Smarkm	if(GSS_ERROR(maj_stat))
17755682Smarkm	    gss_err (1, min_stat, "gss_accept_sec_context");
17855682Smarkm	if (output_token->length != 0)
17955682Smarkm	    write_token (sock, output_token);
18055682Smarkm	if (GSS_ERROR(maj_stat)) {
18155682Smarkm	    if (context_hdl != GSS_C_NO_CONTEXT)
18255682Smarkm		gss_delete_sec_context (&min_stat,
18355682Smarkm					&context_hdl,
18455682Smarkm					GSS_C_NO_BUFFER);
18555682Smarkm	    break;
18655682Smarkm	}
18755682Smarkm    } while(maj_stat & GSS_S_CONTINUE_NEEDED);
18872445Sassar
18972445Sassar    if (delegated_cred_handle->ccache) {
19072445Sassar       krb5_context context;
19155682Smarkm
19272445Sassar       maj_stat = krb5_init_context(&context);
19372445Sassar       maj_stat = krb5_cc_resolve(context, "FILE:/tmp/krb5cc_test", &ccache);
19472445Sassar       maj_stat = krb5_cc_copy_cache(context,
19572445Sassar                                      delegated_cred_handle->ccache, ccache);
19672445Sassar       krb5_cc_close(context, ccache);
19772445Sassar       krb5_cc_destroy(context, delegated_cred_handle->ccache);
19872445Sassar    }
19972445Sassar
20057419Smarkm    if (fork_flag) {
20157419Smarkm	pid_t pid;
20257419Smarkm	int pipefd[2];
20355682Smarkm
20457419Smarkm	if (pipe (pipefd) < 0)
20557419Smarkm	    err (1, "pipe");
20655682Smarkm
20757419Smarkm	pid = fork ();
20857419Smarkm	if (pid < 0)
20957419Smarkm	    err (1, "fork");
21057419Smarkm	if (pid != 0) {
21157419Smarkm	    gss_buffer_desc buf;
21255682Smarkm
21357419Smarkm	    maj_stat = gss_export_sec_context (&min_stat,
21457419Smarkm					       &context_hdl,
21557419Smarkm					       &buf);
21657419Smarkm	    if (GSS_ERROR(maj_stat))
21757419Smarkm		gss_err (1, min_stat, "gss_export_sec_context");
21857419Smarkm	    write_token (pipefd[1], &buf);
21957419Smarkm	    exit (0);
22057419Smarkm	} else {
22157419Smarkm	    gss_ctx_id_t context_hdl;
22257419Smarkm	    gss_buffer_desc buf;
22355682Smarkm
22457419Smarkm	    close (pipefd[1]);
22557419Smarkm	    read_token (pipefd[0], &buf);
22657419Smarkm	    close (pipefd[0]);
22757419Smarkm	    maj_stat = gss_import_sec_context (&min_stat, &buf, &context_hdl);
22857419Smarkm	    if (GSS_ERROR(maj_stat))
22957419Smarkm		gss_err (1, min_stat, "gss_import_sec_context");
23057419Smarkm	    gss_release_buffer (&min_stat, &buf);
23157419Smarkm	    return process_it (sock, context_hdl, client_name);
23257419Smarkm	}
23357419Smarkm    } else {
23457419Smarkm	return process_it (sock, context_hdl, client_name);
23557419Smarkm    }
23655682Smarkm}
23755682Smarkm
23855682Smarkmstatic int
23955682Smarkmdoit (int port, const char *service)
24055682Smarkm{
24155682Smarkm    int sock, sock2;
24255682Smarkm    struct sockaddr_in my_addr;
24355682Smarkm    int one = 1;
24455682Smarkm
24555682Smarkm    sock = socket (AF_INET, SOCK_STREAM, 0);
24655682Smarkm    if (sock < 0)
24755682Smarkm	err (1, "socket");
24855682Smarkm
24955682Smarkm    memset (&my_addr, 0, sizeof(my_addr));
25055682Smarkm    my_addr.sin_family      = AF_INET;
25155682Smarkm    my_addr.sin_port        = port;
25255682Smarkm    my_addr.sin_addr.s_addr = INADDR_ANY;
25355682Smarkm
25455682Smarkm    if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
25555682Smarkm		    (void *)&one, sizeof(one)) < 0)
25655682Smarkm	warn ("setsockopt SO_REUSEADDR");
25755682Smarkm
25855682Smarkm    if (bind (sock, (struct sockaddr *)&my_addr, sizeof(my_addr)) < 0)
25955682Smarkm	err (1, "bind");
26055682Smarkm
26155682Smarkm    if (listen (sock, 1) < 0)
26255682Smarkm	err (1, "listen");
26355682Smarkm
26455682Smarkm    sock2 = accept (sock, NULL, NULL);
26555682Smarkm    if (sock2 < 0)
26655682Smarkm	err (1, "accept");
26755682Smarkm
26855682Smarkm    return proto (sock2, service);
26955682Smarkm}
27055682Smarkm
27155682Smarkmint
27255682Smarkmmain(int argc, char **argv)
27355682Smarkm{
27455682Smarkm    krb5_context context = NULL; /* XXX */
27555682Smarkm    int port = server_setup(&context, argc, argv);
27655682Smarkm    return doit (port, service);
27755682Smarkm}
278