Path: blob/main/crypto/heimdal/appl/test/gssapi_server.c
34870 views
/*1* Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan2* (Royal Institute of Technology, Stockholm, Sweden).3* All rights reserved.4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8*9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11*12* 2. Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in the14* documentation and/or other materials provided with the distribution.15*16* 3. Neither the name of the Institute nor the names of its contributors17* may be used to endorse or promote products derived from this software18* without specific prior written permission.19*20* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND21* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE22* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE23* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE24* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL25* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS26* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)27* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT28* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY29* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF30* SUCH DAMAGE.31*/3233#include "test_locl.h"34#include <gssapi/gssapi.h>35#include <gssapi/gssapi_krb5.h>36#include <gssapi/gssapi_spnego.h>37#include "gss_common.h"38RCSID("$Id$");3940static int41process_it(int sock,42gss_ctx_id_t context_hdl,43gss_name_t client_name44)45{46OM_uint32 maj_stat, min_stat;47gss_buffer_desc real_input_token, real_output_token;48gss_buffer_t input_token = &real_input_token,49output_token = &real_output_token;50gss_name_t server_name;51int conf_flag;5253print_gss_name("User is", client_name);5455maj_stat = gss_inquire_context(&min_stat,56context_hdl,57NULL,58&server_name,59NULL,60NULL,61NULL,62NULL,63NULL);64if (GSS_ERROR(maj_stat))65gss_err (1, min_stat, "gss_inquire_context");6667print_gss_name("Server is", server_name);6869maj_stat = gss_release_name(&min_stat, &server_name);70if (GSS_ERROR(maj_stat))71gss_err (1, min_stat, "gss_release_name");7273/* gss_verify_mic */7475read_token (sock, input_token);76read_token (sock, output_token);7778maj_stat = gss_verify_mic (&min_stat,79context_hdl,80input_token,81output_token,82NULL);83if (GSS_ERROR(maj_stat))84gss_err (1, min_stat, "gss_verify_mic");8586fprintf (stderr, "gss_verify_mic: %.*s\n", (int)input_token->length,87(char *)input_token->value);8889gss_release_buffer (&min_stat, input_token);90gss_release_buffer (&min_stat, output_token);9192/* gss_unwrap */9394read_token (sock, input_token);9596maj_stat = gss_unwrap (&min_stat,97context_hdl,98input_token,99output_token,100&conf_flag,101NULL);102if(GSS_ERROR(maj_stat))103gss_err (1, min_stat, "gss_unwrap");104105fprintf (stderr, "gss_unwrap: %.*s %s\n", (int)output_token->length,106(char *)output_token->value,107conf_flag ? "CONF" : "INT");108109gss_release_buffer (&min_stat, input_token);110gss_release_buffer (&min_stat, output_token);111112read_token (sock, input_token);113114maj_stat = gss_unwrap (&min_stat,115context_hdl,116input_token,117output_token,118&conf_flag,119NULL);120if(GSS_ERROR(maj_stat))121gss_err (1, min_stat, "gss_unwrap");122123fprintf (stderr, "gss_unwrap: %.*s %s\n", (int)output_token->length,124(char *)output_token->value,125conf_flag ? "CONF" : "INT");126127gss_release_buffer (&min_stat, input_token);128gss_release_buffer (&min_stat, output_token);129130return 0;131}132133static int134proto (int sock, const char *service)135{136struct sockaddr_in remote, local;137socklen_t addrlen;138gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT;139gss_buffer_desc real_input_token, real_output_token;140gss_buffer_t input_token = &real_input_token,141output_token = &real_output_token;142OM_uint32 maj_stat, min_stat;143gss_name_t client_name;144struct gss_channel_bindings_struct input_chan_bindings;145gss_cred_id_t delegated_cred_handle = NULL;146krb5_ccache ccache;147u_char init_buf[4];148u_char acct_buf[4];149gss_OID mech_oid;150char *mech, *p;151152addrlen = sizeof(local);153if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0154|| addrlen != sizeof(local))155err (1, "getsockname)");156157addrlen = sizeof(remote);158if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0159|| addrlen != sizeof(remote))160err (1, "getpeername");161162input_chan_bindings.initiator_addrtype = GSS_C_AF_INET;163input_chan_bindings.initiator_address.length = 4;164init_buf[0] = (remote.sin_addr.s_addr >> 24) & 0xFF;165init_buf[1] = (remote.sin_addr.s_addr >> 16) & 0xFF;166init_buf[2] = (remote.sin_addr.s_addr >> 8) & 0xFF;167init_buf[3] = (remote.sin_addr.s_addr >> 0) & 0xFF;168169input_chan_bindings.initiator_address.value = init_buf;170input_chan_bindings.acceptor_addrtype = GSS_C_AF_INET;171172input_chan_bindings.acceptor_address.length = 4;173acct_buf[0] = (local.sin_addr.s_addr >> 24) & 0xFF;174acct_buf[1] = (local.sin_addr.s_addr >> 16) & 0xFF;175acct_buf[2] = (local.sin_addr.s_addr >> 8) & 0xFF;176acct_buf[3] = (local.sin_addr.s_addr >> 0) & 0xFF;177input_chan_bindings.acceptor_address.value = acct_buf;178input_chan_bindings.application_data.value = emalloc(4);179#if 0180* (unsigned short *)input_chan_bindings.application_data.value =181remote.sin_port;182* ((unsigned short *)input_chan_bindings.application_data.value + 1) =183local.sin_port;184input_chan_bindings.application_data.length = 4;185#else186input_chan_bindings.application_data.length = 0;187input_chan_bindings.application_data.value = NULL;188#endif189190delegated_cred_handle = GSS_C_NO_CREDENTIAL;191192do {193read_token (sock, input_token);194maj_stat =195gss_accept_sec_context (&min_stat,196&context_hdl,197GSS_C_NO_CREDENTIAL,198input_token,199&input_chan_bindings,200&client_name,201&mech_oid,202output_token,203NULL,204NULL,205&delegated_cred_handle);206if(GSS_ERROR(maj_stat))207gss_err (1, min_stat, "gss_accept_sec_context");208if (output_token->length != 0)209write_token (sock, output_token);210if (GSS_ERROR(maj_stat)) {211if (context_hdl != GSS_C_NO_CONTEXT)212gss_delete_sec_context (&min_stat,213&context_hdl,214GSS_C_NO_BUFFER);215break;216}217} while(maj_stat & GSS_S_CONTINUE_NEEDED);218219p = (char *)mech_oid->elements;220if (mech_oid->length == GSS_KRB5_MECHANISM->length221&& memcmp(p, GSS_KRB5_MECHANISM->elements, mech_oid->length) == 0)222mech = "Kerberos 5";223else if (mech_oid->length == GSS_SPNEGO_MECHANISM->length224&& memcmp(p, GSS_SPNEGO_MECHANISM->elements, mech_oid->length) == 0)225mech = "SPNEGO"; /* XXX Silly, wont show up */226else227mech = "Unknown";228229printf("Using mech: %s\n", mech);230231if (delegated_cred_handle != GSS_C_NO_CREDENTIAL) {232krb5_context context;233234printf("Delegated cred found\n");235236maj_stat = krb5_init_context(&context);237maj_stat = krb5_cc_resolve(context, "FILE:/tmp/krb5cc_test", &ccache);238maj_stat = gss_krb5_copy_ccache(&min_stat,239delegated_cred_handle,240ccache);241if (maj_stat == 0) {242krb5_principal p;243maj_stat = krb5_cc_get_principal(context, ccache, &p);244if (maj_stat == 0) {245char *name;246maj_stat = krb5_unparse_name(context, p, &name);247if (maj_stat == 0) {248printf("Delegated user is: `%s'\n", name);249free(name);250}251krb5_free_principal(context, p);252}253}254krb5_cc_close(context, ccache);255gss_release_cred(&min_stat, &delegated_cred_handle);256}257258if (fork_flag) {259pid_t pid;260int pipefd[2];261262if (pipe (pipefd) < 0)263err (1, "pipe");264265pid = fork ();266if (pid < 0)267err (1, "fork");268if (pid != 0) {269gss_buffer_desc buf;270271maj_stat = gss_export_sec_context (&min_stat,272&context_hdl,273&buf);274if (GSS_ERROR(maj_stat))275gss_err (1, min_stat, "gss_export_sec_context");276write_token (pipefd[1], &buf);277exit (0);278} else {279gss_ctx_id_t context_hdl;280gss_buffer_desc buf;281282close (pipefd[1]);283read_token (pipefd[0], &buf);284close (pipefd[0]);285maj_stat = gss_import_sec_context (&min_stat, &buf, &context_hdl);286if (GSS_ERROR(maj_stat))287gss_err (1, min_stat, "gss_import_sec_context");288gss_release_buffer (&min_stat, &buf);289return process_it (sock, context_hdl, client_name);290}291} else {292return process_it (sock, context_hdl, client_name);293}294}295296static int297doit (int port, const char *service)298{299int sock, sock2;300struct sockaddr_in my_addr;301int one = 1;302int ret;303304sock = socket (AF_INET, SOCK_STREAM, 0);305if (sock < 0)306err (1, "socket");307308memset (&my_addr, 0, sizeof(my_addr));309my_addr.sin_family = AF_INET;310my_addr.sin_port = port;311my_addr.sin_addr.s_addr = INADDR_ANY;312313if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,314(void *)&one, sizeof(one)) < 0)315warn ("setsockopt SO_REUSEADDR");316317if (bind (sock, (struct sockaddr *)&my_addr, sizeof(my_addr)) < 0)318err (1, "bind");319320while (1) {321if (listen (sock, 1) < 0)322err (1, "listen");323324sock2 = accept (sock, NULL, NULL);325if (sock2 < 0)326err (1, "accept");327328ret = proto (sock2, service);329}330return ret;331}332333int334main(int argc, char **argv)335{336krb5_context context = NULL; /* XXX */337int port = server_setup(&context, argc, argv);338return doit (port, service);339}340341342343