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$"); 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 char *str; 59 60 name_token.length = asprintf (&str, 61 "%s@%s", service, hostname); 62 if (str == NULL) 63 errx(1, "out of memory"); 64 name_token.value = str; 65 66 maj_stat = gss_import_name (&min_stat, 67 &name_token, 68 GSS_C_NT_HOSTBASED_SERVICE, 69 &server); 70 if (GSS_ERROR(maj_stat)) 71 gss_err (1, min_stat, 72 "Error importing name `%s@%s':\n", service, hostname); 73 74 addrlen = sizeof(local); 75 if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0 76 || addrlen != sizeof(local)) 77 err (1, "getsockname(%s)", hostname); 78 79 addrlen = sizeof(remote); 80 if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0 81 || addrlen != sizeof(remote)) 82 err (1, "getpeername(%s)", hostname); 83 84 input_token = &real_input_token; 85 output_token = &real_output_token; 86 87 input_token->length = 0; 88 output_token->length = 0; 89 90 while(!context_established) { 91 maj_stat = 92 gss_init_sec_context(&min_stat, 93 GSS_C_NO_CREDENTIAL, 94 &context_hdl, 95 server, 96 GSS_C_NO_OID, 97 GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG, 98 0, 99 GSS_C_NO_CHANNEL_BINDINGS, 100 input_token, 101 NULL, 102 output_token, 103 NULL, 104 NULL); 105 if (GSS_ERROR(maj_stat)) 106 gss_err (1, min_stat, "gss_init_sec_context"); 107 if (output_token->length != 0) 108 nt_write_token (sock, output_token); 109 if (GSS_ERROR(maj_stat)) { 110 if (context_hdl != GSS_C_NO_CONTEXT) 111 gss_delete_sec_context (&min_stat, 112 &context_hdl, 113 GSS_C_NO_BUFFER); 114 break; 115 } 116 if (maj_stat & GSS_S_CONTINUE_NEEDED) { 117 nt_read_token (sock, input_token); 118 } else { 119 context_established = 1; 120 } 121 122 } 123 124 /* get_mic */ 125 126 input_token->length = 3; 127 input_token->value = strdup("hej"); 128 129 maj_stat = gss_get_mic(&min_stat, 130 context_hdl, 131 GSS_C_QOP_DEFAULT, 132 input_token, 133 output_token); 134 if (GSS_ERROR(maj_stat)) 135 gss_err (1, min_stat, "gss_get_mic"); 136 137 nt_write_token (sock, input_token); 138 nt_write_token (sock, output_token); 139 140 /* wrap */ 141 142 input_token->length = 7; 143 input_token->value = "hemligt"; 144 145 146 maj_stat = gss_wrap (&min_stat, 147 context_hdl, 148 1, 149 GSS_C_QOP_DEFAULT, 150 input_token, 151 NULL, 152 output_token); 153 if (GSS_ERROR(maj_stat)) 154 gss_err (1, min_stat, "gss_wrap"); 155 156 nt_write_token (sock, output_token); 157 158 return 0; 159 } 160 161 int 162 main(int argc, char **argv) 163 { 164 krb5_context context; /* XXX */ 165 int port = client_setup(&context, &argc, argv); 166 return client_doit (argv[argc], port, service, proto); 167 } 168