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