1 /* 2 * Copyright (c) 1997 - 1999 Kungliga Tekniska H�gskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of the Institute nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include "test_locl.h" 35 #include <gssapi.h> 36 #include "nt_gss_common.h" 37 38 RCSID("$Id: nt_gss_client.c,v 1.4 2000/08/09 20:53:07 assar Exp $"); 39 40 /* 41 * This program tries to act as a client for the sample in `Sample 42 * SSPI Code' in Windows 2000 RC1 SDK. 43 */ 44 45 static int 46 proto (int sock, const char *hostname, const char *service) 47 { 48 struct sockaddr_in remote, local; 49 socklen_t addrlen; 50 51 int context_established = 0; 52 gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT; 53 gss_buffer_t input_token, output_token; 54 gss_buffer_desc real_input_token, real_output_token; 55 OM_uint32 maj_stat, min_stat; 56 gss_name_t server; 57 gss_buffer_desc name_token; 58 59 name_token.length = asprintf ((char **)&name_token.value, 60 "%s@%s", service, hostname); 61 62 maj_stat = gss_import_name (&min_stat, 63 &name_token, 64 GSS_C_NT_HOSTBASED_SERVICE, 65 &server); 66 if (GSS_ERROR(maj_stat)) 67 gss_err (1, min_stat, 68 "Error importing name `%s@%s':\n", service, hostname); 69 70 addrlen = sizeof(local); 71 if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0 72 || addrlen != sizeof(local)) 73 err (1, "getsockname(%s)", hostname); 74 75 addrlen = sizeof(remote); 76 if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0 77 || addrlen != sizeof(remote)) 78 err (1, "getpeername(%s)", hostname); 79 80 input_token = &real_input_token; 81 output_token = &real_output_token; 82 83 input_token->length = 0; 84 output_token->length = 0; 85 86 while(!context_established) { 87 maj_stat = 88 gss_init_sec_context(&min_stat, 89 GSS_C_NO_CREDENTIAL, 90 &context_hdl, 91 server, 92 GSS_C_NO_OID, 93 GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG, 94 0, 95 GSS_C_NO_CHANNEL_BINDINGS, 96 input_token, 97 NULL, 98 output_token, 99 NULL, 100 NULL); 101 if (GSS_ERROR(maj_stat)) 102 gss_err (1, min_stat, "gss_init_sec_context"); 103 if (output_token->length != 0) 104 nt_write_token (sock, output_token); 105 if (GSS_ERROR(maj_stat)) { 106 if (context_hdl != GSS_C_NO_CONTEXT) 107 gss_delete_sec_context (&min_stat, 108 &context_hdl, 109 GSS_C_NO_BUFFER); 110 break; 111 } 112 if (maj_stat & GSS_S_CONTINUE_NEEDED) { 113 nt_read_token (sock, input_token); 114 } else { 115 context_established = 1; 116 } 117 118 } 119 120 /* get_mic */ 121 122 input_token->length = 3; 123 input_token->value = strdup("hej"); 124 125 maj_stat = gss_get_mic(&min_stat, 126 context_hdl, 127 GSS_C_QOP_DEFAULT, 128 input_token, 129 output_token); 130 if (GSS_ERROR(maj_stat)) 131 gss_err (1, min_stat, "gss_get_mic"); 132 133 nt_write_token (sock, input_token); 134 nt_write_token (sock, output_token); 135 136 /* wrap */ 137 138 input_token->length = 7; 139 input_token->value = "hemligt"; 140 141 142 maj_stat = gss_wrap (&min_stat, 143 context_hdl, 144 1, 145 GSS_C_QOP_DEFAULT, 146 input_token, 147 NULL, 148 output_token); 149 if (GSS_ERROR(maj_stat)) 150 gss_err (1, min_stat, "gss_wrap"); 151 152 nt_write_token (sock, output_token); 153 154 return 0; 155 } 156 157 int 158 main(int argc, char **argv) 159 { 160 krb5_context context; /* XXX */ 161 int port = client_setup(&context, &argc, argv); 162 return client_doit (argv[argc], port, service, proto); 163 } 164