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