gssapi_server.c revision 57419
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"
3757419SmarkmRCSID("$Id: gssapi_server.c,v 1.12 2000/02/12 21:34:11 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;
10855682Smarkm    int 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;
11555682Smarkm
11655682Smarkm    addrlen = sizeof(local);
11755682Smarkm    if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0
11855682Smarkm	|| addrlen != sizeof(local))
11955682Smarkm	err (1, "getsockname)");
12055682Smarkm
12155682Smarkm    addrlen = sizeof(remote);
12255682Smarkm    if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0
12355682Smarkm	|| addrlen != sizeof(remote))
12455682Smarkm	err (1, "getpeername");
12555682Smarkm
12655682Smarkm    do {
12755682Smarkm	read_token (sock, input_token);
12855682Smarkm	maj_stat =
12955682Smarkm	    gss_accept_sec_context (&min_stat,
13055682Smarkm				    &context_hdl,
13155682Smarkm				    GSS_C_NO_CREDENTIAL,
13255682Smarkm				    input_token,
13355682Smarkm				    GSS_C_NO_CHANNEL_BINDINGS,
13455682Smarkm				    &client_name,
13555682Smarkm				    NULL,
13655682Smarkm				    output_token,
13755682Smarkm				    NULL,
13855682Smarkm				    NULL,
13955682Smarkm				    NULL);
14055682Smarkm	if(GSS_ERROR(maj_stat))
14155682Smarkm	    gss_err (1, min_stat, "gss_accept_sec_context");
14255682Smarkm	if (output_token->length != 0)
14355682Smarkm	    write_token (sock, output_token);
14455682Smarkm	if (GSS_ERROR(maj_stat)) {
14555682Smarkm	    if (context_hdl != GSS_C_NO_CONTEXT)
14655682Smarkm		gss_delete_sec_context (&min_stat,
14755682Smarkm					&context_hdl,
14855682Smarkm					GSS_C_NO_BUFFER);
14955682Smarkm	    break;
15055682Smarkm	}
15155682Smarkm    } while(maj_stat & GSS_S_CONTINUE_NEEDED);
15255682Smarkm
15357419Smarkm    if (fork_flag) {
15457419Smarkm	pid_t pid;
15557419Smarkm	int pipefd[2];
15655682Smarkm
15757419Smarkm	if (pipe (pipefd) < 0)
15857419Smarkm	    err (1, "pipe");
15955682Smarkm
16057419Smarkm	pid = fork ();
16157419Smarkm	if (pid < 0)
16257419Smarkm	    err (1, "fork");
16357419Smarkm	if (pid != 0) {
16457419Smarkm	    gss_buffer_desc buf;
16555682Smarkm
16657419Smarkm	    maj_stat = gss_export_sec_context (&min_stat,
16757419Smarkm					       &context_hdl,
16857419Smarkm					       &buf);
16957419Smarkm	    if (GSS_ERROR(maj_stat))
17057419Smarkm		gss_err (1, min_stat, "gss_export_sec_context");
17157419Smarkm	    write_token (pipefd[1], &buf);
17257419Smarkm	    exit (0);
17357419Smarkm	} else {
17457419Smarkm	    gss_ctx_id_t context_hdl;
17557419Smarkm	    gss_buffer_desc buf;
17655682Smarkm
17757419Smarkm	    close (pipefd[1]);
17857419Smarkm	    read_token (pipefd[0], &buf);
17957419Smarkm	    close (pipefd[0]);
18057419Smarkm	    maj_stat = gss_import_sec_context (&min_stat, &buf, &context_hdl);
18157419Smarkm	    if (GSS_ERROR(maj_stat))
18257419Smarkm		gss_err (1, min_stat, "gss_import_sec_context");
18357419Smarkm	    gss_release_buffer (&min_stat, &buf);
18457419Smarkm	    return process_it (sock, context_hdl, client_name);
18557419Smarkm	}
18657419Smarkm    } else {
18757419Smarkm	return process_it (sock, context_hdl, client_name);
18857419Smarkm    }
18955682Smarkm}
19055682Smarkm
19155682Smarkmstatic int
19255682Smarkmdoit (int port, const char *service)
19355682Smarkm{
19455682Smarkm    int sock, sock2;
19555682Smarkm    struct sockaddr_in my_addr;
19655682Smarkm    int one = 1;
19755682Smarkm
19855682Smarkm    sock = socket (AF_INET, SOCK_STREAM, 0);
19955682Smarkm    if (sock < 0)
20055682Smarkm	err (1, "socket");
20155682Smarkm
20255682Smarkm    memset (&my_addr, 0, sizeof(my_addr));
20355682Smarkm    my_addr.sin_family      = AF_INET;
20455682Smarkm    my_addr.sin_port        = port;
20555682Smarkm    my_addr.sin_addr.s_addr = INADDR_ANY;
20655682Smarkm
20755682Smarkm    if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
20855682Smarkm		    (void *)&one, sizeof(one)) < 0)
20955682Smarkm	warn ("setsockopt SO_REUSEADDR");
21055682Smarkm
21155682Smarkm    if (bind (sock, (struct sockaddr *)&my_addr, sizeof(my_addr)) < 0)
21255682Smarkm	err (1, "bind");
21355682Smarkm
21455682Smarkm    if (listen (sock, 1) < 0)
21555682Smarkm	err (1, "listen");
21655682Smarkm
21755682Smarkm    sock2 = accept (sock, NULL, NULL);
21855682Smarkm    if (sock2 < 0)
21955682Smarkm	err (1, "accept");
22055682Smarkm
22155682Smarkm    return proto (sock2, service);
22255682Smarkm}
22355682Smarkm
22455682Smarkmint
22555682Smarkmmain(int argc, char **argv)
22655682Smarkm{
22755682Smarkm    krb5_context context = NULL; /* XXX */
22855682Smarkm    int port = server_setup(&context, argc, argv);
22955682Smarkm    return doit (port, service);
23055682Smarkm}
231