155682Smarkm/* 2233294Sstas * Copyright (c) 1997 - 2000 Kungliga Tekniska H��gskolan 3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4233294Sstas * All rights reserved. 555682Smarkm * 6233294Sstas * Redistribution and use in source and binary forms, with or without 7233294Sstas * modification, are permitted provided that the following conditions 8233294Sstas * are met: 955682Smarkm * 10233294Sstas * 1. Redistributions of source code must retain the above copyright 11233294Sstas * notice, this list of conditions and the following disclaimer. 1255682Smarkm * 13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 14233294Sstas * notice, this list of conditions and the following disclaimer in the 15233294Sstas * documentation and/or other materials provided with the distribution. 1655682Smarkm * 17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors 18233294Sstas * may be used to endorse or promote products derived from this software 19233294Sstas * without specific prior written permission. 2055682Smarkm * 21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31233294Sstas * SUCH DAMAGE. 3255682Smarkm */ 3355682Smarkm 3455682Smarkm#include "test_locl.h" 35233294Sstas#include <gssapi/gssapi.h> 36233294Sstas#include <gssapi/gssapi_krb5.h> 37233294Sstas#include <gssapi/gssapi_spnego.h> 3855682Smarkm#include "gss_common.h" 39233294SstasRCSID("$Id$"); 4055682Smarkm 4155682Smarkmstatic int 4257419Smarkmdo_trans (int sock, gss_ctx_id_t context_hdl) 4357419Smarkm{ 4457419Smarkm OM_uint32 maj_stat, min_stat; 4557419Smarkm gss_buffer_desc real_input_token, real_output_token; 4657419Smarkm gss_buffer_t input_token = &real_input_token, 4757419Smarkm output_token = &real_output_token; 4857419Smarkm 4957419Smarkm /* get_mic */ 5057419Smarkm 5157419Smarkm input_token->length = 3; 5257419Smarkm input_token->value = strdup("hej"); 5357419Smarkm 5457419Smarkm maj_stat = gss_get_mic(&min_stat, 5557419Smarkm context_hdl, 5657419Smarkm GSS_C_QOP_DEFAULT, 5757419Smarkm input_token, 5857419Smarkm output_token); 5957419Smarkm if (GSS_ERROR(maj_stat)) 6057419Smarkm gss_err (1, min_stat, "gss_get_mic"); 6157419Smarkm 6257419Smarkm write_token (sock, input_token); 6357419Smarkm write_token (sock, output_token); 6457419Smarkm 6557419Smarkm /* wrap */ 6657419Smarkm 6757419Smarkm input_token->length = 7; 6857419Smarkm input_token->value = "hemligt"; 6957419Smarkm 70178825Sdfr maj_stat = gss_wrap (&min_stat, 71178825Sdfr context_hdl, 72178825Sdfr 0, 73178825Sdfr GSS_C_QOP_DEFAULT, 74178825Sdfr input_token, 75178825Sdfr NULL, 76178825Sdfr output_token); 77178825Sdfr if (GSS_ERROR(maj_stat)) 78178825Sdfr gss_err (1, min_stat, "gss_wrap"); 7957419Smarkm 80178825Sdfr write_token (sock, output_token); 81178825Sdfr 8257419Smarkm maj_stat = gss_wrap (&min_stat, 8357419Smarkm context_hdl, 8457419Smarkm 1, 8557419Smarkm GSS_C_QOP_DEFAULT, 8657419Smarkm input_token, 8757419Smarkm NULL, 8857419Smarkm output_token); 8957419Smarkm if (GSS_ERROR(maj_stat)) 9057419Smarkm gss_err (1, min_stat, "gss_wrap"); 9157419Smarkm 9257419Smarkm write_token (sock, output_token); 9357419Smarkm 9457419Smarkm return 0; 9557419Smarkm} 9657419Smarkm 97233294Sstasextern char *password; 98233294Sstas 9957419Smarkmstatic int 10055682Smarkmproto (int sock, const char *hostname, const char *service) 10155682Smarkm{ 102233294Sstas struct sockaddr_storage remote, local; 10372445Sassar socklen_t addrlen; 10455682Smarkm 10555682Smarkm int context_established = 0; 10655682Smarkm gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT; 107233294Sstas gss_cred_id_t cred = GSS_C_NO_CREDENTIAL; 10855682Smarkm gss_buffer_desc real_input_token, real_output_token; 10957419Smarkm gss_buffer_t input_token = &real_input_token, 11057419Smarkm output_token = &real_output_token; 11155682Smarkm OM_uint32 maj_stat, min_stat; 11255682Smarkm gss_name_t server; 11355682Smarkm gss_buffer_desc name_token; 11472445Sassar u_char init_buf[4]; 11572445Sassar u_char acct_buf[4]; 116178825Sdfr gss_OID mech_oid; 117178825Sdfr char *str; 11855682Smarkm 119178825Sdfr mech_oid = select_mech(mech); 120178825Sdfr 121178825Sdfr name_token.length = asprintf (&str, 12255682Smarkm "%s@%s", service, hostname); 123178825Sdfr if (str == NULL) 124178825Sdfr errx(1, "malloc - out of memory"); 125178825Sdfr name_token.value = str; 126233294Sstas 12755682Smarkm maj_stat = gss_import_name (&min_stat, 12855682Smarkm &name_token, 12955682Smarkm GSS_C_NT_HOSTBASED_SERVICE, 13055682Smarkm &server); 13155682Smarkm if (GSS_ERROR(maj_stat)) 13255682Smarkm gss_err (1, min_stat, 13355682Smarkm "Error importing name `%s@%s':\n", service, hostname); 13455682Smarkm 135233294Sstas if (password) { 136233294Sstas gss_buffer_desc pw; 137233294Sstas 138233294Sstas pw.value = password; 139233294Sstas pw.length = strlen(password); 140233294Sstas 141233294Sstas maj_stat = gss_acquire_cred_with_password(&min_stat, 142233294Sstas GSS_C_NO_NAME, 143233294Sstas &pw, 144233294Sstas GSS_C_INDEFINITE, 145233294Sstas GSS_C_NO_OID_SET, 146233294Sstas GSS_C_INITIATE, 147233294Sstas &cred, 148233294Sstas NULL, 149233294Sstas NULL); 150233294Sstas if (GSS_ERROR(maj_stat)) 151233294Sstas gss_err (1, min_stat, 152233294Sstas "Error acquiring default initiator credentials"); 153233294Sstas } 154233294Sstas 15555682Smarkm addrlen = sizeof(local); 15655682Smarkm if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0 157233294Sstas || addrlen > sizeof(local)) 15855682Smarkm err (1, "getsockname(%s)", hostname); 15955682Smarkm 16055682Smarkm addrlen = sizeof(remote); 16155682Smarkm if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0 162233294Sstas || addrlen > sizeof(remote)) 16355682Smarkm err (1, "getpeername(%s)", hostname); 16455682Smarkm 16555682Smarkm input_token->length = 0; 16655682Smarkm output_token->length = 0; 16755682Smarkm 168233294Sstas#if 0 169233294Sstas struct gss_channel_bindings_struct input_chan_bindings; 170233294Sstas 17172445Sassar input_chan_bindings.initiator_addrtype = GSS_C_AF_INET; 17272445Sassar input_chan_bindings.initiator_address.length = 4; 17372445Sassar init_buf[0] = (local.sin_addr.s_addr >> 24) & 0xFF; 17472445Sassar init_buf[1] = (local.sin_addr.s_addr >> 16) & 0xFF; 17572445Sassar init_buf[2] = (local.sin_addr.s_addr >> 8) & 0xFF; 17672445Sassar init_buf[3] = (local.sin_addr.s_addr >> 0) & 0xFF; 17772445Sassar input_chan_bindings.initiator_address.value = init_buf; 17872445Sassar 17972445Sassar input_chan_bindings.acceptor_addrtype = GSS_C_AF_INET; 18072445Sassar input_chan_bindings.acceptor_address.length = 4; 18172445Sassar acct_buf[0] = (remote.sin_addr.s_addr >> 24) & 0xFF; 18272445Sassar acct_buf[1] = (remote.sin_addr.s_addr >> 16) & 0xFF; 18372445Sassar acct_buf[2] = (remote.sin_addr.s_addr >> 8) & 0xFF; 18472445Sassar acct_buf[3] = (remote.sin_addr.s_addr >> 0) & 0xFF; 18572445Sassar input_chan_bindings.acceptor_address.value = acct_buf; 186233294Sstas 18772445Sassar input_chan_bindings.application_data.value = emalloc(4); 18872445Sassar * (unsigned short*)input_chan_bindings.application_data.value = local.sin_port; 18972445Sassar * ((unsigned short *)input_chan_bindings.application_data.value + 1) = remote.sin_port; 19072445Sassar input_chan_bindings.application_data.length = 4; 191233294Sstas 19272445Sassar input_chan_bindings.application_data.length = 0; 19372445Sassar input_chan_bindings.application_data.value = NULL; 19472445Sassar#endif 19572445Sassar 19655682Smarkm while(!context_established) { 19755682Smarkm maj_stat = 19855682Smarkm gss_init_sec_context(&min_stat, 199233294Sstas cred, 20055682Smarkm &context_hdl, 20155682Smarkm server, 202178825Sdfr mech_oid, 203233294Sstas GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG, 20455682Smarkm 0, 205233294Sstas NULL, 20655682Smarkm input_token, 20755682Smarkm NULL, 20855682Smarkm output_token, 20955682Smarkm NULL, 21055682Smarkm NULL); 21155682Smarkm if (GSS_ERROR(maj_stat)) 21255682Smarkm gss_err (1, min_stat, "gss_init_sec_context"); 21355682Smarkm if (output_token->length != 0) 21455682Smarkm write_token (sock, output_token); 21555682Smarkm if (GSS_ERROR(maj_stat)) { 21655682Smarkm if (context_hdl != GSS_C_NO_CONTEXT) 21755682Smarkm gss_delete_sec_context (&min_stat, 21855682Smarkm &context_hdl, 21955682Smarkm GSS_C_NO_BUFFER); 22055682Smarkm break; 22155682Smarkm } 22255682Smarkm if (maj_stat & GSS_S_CONTINUE_NEEDED) { 22355682Smarkm read_token (sock, input_token); 22455682Smarkm } else { 22555682Smarkm context_established = 1; 22655682Smarkm } 22755682Smarkm 22855682Smarkm } 22957419Smarkm if (fork_flag) { 23057419Smarkm pid_t pid; 23157419Smarkm int pipefd[2]; 23255682Smarkm 23357419Smarkm if (pipe (pipefd) < 0) 23457419Smarkm err (1, "pipe"); 23555682Smarkm 23657419Smarkm pid = fork (); 23757419Smarkm if (pid < 0) 23857419Smarkm err (1, "fork"); 23957419Smarkm if (pid != 0) { 24057419Smarkm gss_buffer_desc buf; 24155682Smarkm 24257419Smarkm maj_stat = gss_export_sec_context (&min_stat, 24357419Smarkm &context_hdl, 24457419Smarkm &buf); 24557419Smarkm if (GSS_ERROR(maj_stat)) 24657419Smarkm gss_err (1, min_stat, "gss_export_sec_context"); 24757419Smarkm write_token (pipefd[1], &buf); 24857419Smarkm exit (0); 24957419Smarkm } else { 25057419Smarkm gss_ctx_id_t context_hdl; 25157419Smarkm gss_buffer_desc buf; 25255682Smarkm 25357419Smarkm close (pipefd[1]); 25457419Smarkm read_token (pipefd[0], &buf); 25557419Smarkm close (pipefd[0]); 25657419Smarkm maj_stat = gss_import_sec_context (&min_stat, &buf, &context_hdl); 25757419Smarkm if (GSS_ERROR(maj_stat)) 25857419Smarkm gss_err (1, min_stat, "gss_import_sec_context"); 25957419Smarkm gss_release_buffer (&min_stat, &buf); 26057419Smarkm return do_trans (sock, context_hdl); 26157419Smarkm } 26257419Smarkm } else { 26357419Smarkm return do_trans (sock, context_hdl); 26457419Smarkm } 26555682Smarkm} 26655682Smarkm 26755682Smarkmint 26855682Smarkmmain(int argc, char **argv) 26955682Smarkm{ 27055682Smarkm krb5_context context; /* XXX */ 27155682Smarkm int port = client_setup(&context, &argc, argv); 27255682Smarkm return client_doit (argv[argc], port, service, proto); 27355682Smarkm} 274