1/* 2 * Copyright (c) 2003-2004 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 KTH nor the names of its contributors may be 18 * used to endorse or promote products derived from this software without 19 * specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY 22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE 25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 28 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34#include "gsskrb5_locl.h" 35#include <err.h> 36#include <getarg.h> 37 38static void 39gss_print_errors (int min_stat) 40{ 41 OM_uint32 new_stat; 42 OM_uint32 msg_ctx = 0; 43 gss_buffer_desc status_string; 44 OM_uint32 ret; 45 46 do { 47 ret = gss_display_status (&new_stat, 48 min_stat, 49 GSS_C_MECH_CODE, 50 GSS_C_NO_OID, 51 &msg_ctx, 52 &status_string); 53 fprintf (stderr, "%.*s\n", (int)status_string.length, 54 (char *)status_string.value); 55 gss_release_buffer (&new_stat, &status_string); 56 } while (!GSS_ERROR(ret) && msg_ctx != 0); 57} 58 59static void 60gss_err(int exitval, int status, const char *fmt, ...) 61{ 62 va_list args; 63 64 va_start(args, fmt); 65 vwarnx (fmt, args); 66 gss_print_errors (status); 67 va_end(args); 68 exit (exitval); 69} 70 71static void 72acquire_release_loop(gss_name_t name, int counter, gss_cred_usage_t usage) 73{ 74 OM_uint32 maj_stat, min_stat; 75 gss_cred_id_t cred; 76 int i; 77 78 for (i = 0; i < counter; i++) { 79 maj_stat = gss_acquire_cred(&min_stat, name, 80 GSS_C_INDEFINITE, 81 GSS_C_NO_OID_SET, 82 usage, 83 &cred, 84 NULL, 85 NULL); 86 if (maj_stat != GSS_S_COMPLETE) 87 gss_err(1, min_stat, "aquire %d %d != GSS_S_COMPLETE", 88 i, (int)maj_stat); 89 90 maj_stat = gss_release_cred(&min_stat, &cred); 91 if (maj_stat != GSS_S_COMPLETE) 92 gss_err(1, min_stat, "release %d %d != GSS_S_COMPLETE", 93 i, (int)maj_stat); 94 } 95} 96 97 98static void 99acquire_add_release_add(gss_name_t name, gss_cred_usage_t usage) 100{ 101 OM_uint32 maj_stat, min_stat; 102 gss_cred_id_t cred, cred2, cred3; 103 104 maj_stat = gss_acquire_cred(&min_stat, name, 105 GSS_C_INDEFINITE, 106 GSS_C_NO_OID_SET, 107 usage, 108 &cred, 109 NULL, 110 NULL); 111 if (maj_stat != GSS_S_COMPLETE) 112 gss_err(1, min_stat, "aquire %d != GSS_S_COMPLETE", (int)maj_stat); 113 114 maj_stat = gss_add_cred(&min_stat, 115 cred, 116 GSS_C_NO_NAME, 117 GSS_KRB5_MECHANISM, 118 usage, 119 GSS_C_INDEFINITE, 120 GSS_C_INDEFINITE, 121 &cred2, 122 NULL, 123 NULL, 124 NULL); 125 126 if (maj_stat != GSS_S_COMPLETE) 127 gss_err(1, min_stat, "add_cred %d != GSS_S_COMPLETE", (int)maj_stat); 128 129 maj_stat = gss_release_cred(&min_stat, &cred); 130 if (maj_stat != GSS_S_COMPLETE) 131 gss_err(1, min_stat, "release %d != GSS_S_COMPLETE", (int)maj_stat); 132 133 maj_stat = gss_add_cred(&min_stat, 134 cred2, 135 GSS_C_NO_NAME, 136 GSS_KRB5_MECHANISM, 137 GSS_C_BOTH, 138 GSS_C_INDEFINITE, 139 GSS_C_INDEFINITE, 140 &cred3, 141 NULL, 142 NULL, 143 NULL); 144 145 maj_stat = gss_release_cred(&min_stat, &cred2); 146 if (maj_stat != GSS_S_COMPLETE) 147 gss_err(1, min_stat, "release 2 %d != GSS_S_COMPLETE", (int)maj_stat); 148 149 maj_stat = gss_release_cred(&min_stat, &cred3); 150 if (maj_stat != GSS_S_COMPLETE) 151 gss_err(1, min_stat, "release 2 %d != GSS_S_COMPLETE", (int)maj_stat); 152} 153 154static int version_flag = 0; 155static int help_flag = 0; 156 157static struct getargs args[] = { 158 {"version", 0, arg_flag, &version_flag, "print version", NULL }, 159 {"help", 0, arg_flag, &help_flag, NULL, NULL } 160}; 161 162static void 163usage (int ret) 164{ 165 arg_printusage (args, sizeof(args)/sizeof(*args), 166 NULL, "service@host"); 167 exit (ret); 168} 169 170 171int 172main(int argc, char **argv) 173{ 174 struct gss_buffer_desc_struct name_buffer; 175 OM_uint32 maj_stat, min_stat; 176 gss_name_t name; 177 int optidx = 0; 178 179 setprogname(argv[0]); 180 if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx)) 181 usage(1); 182 183 if (help_flag) 184 usage (0); 185 186 if(version_flag){ 187 print_version(NULL); 188 exit(0); 189 } 190 191 argc -= optidx; 192 argv += optidx; 193 194 if (argc < 1) 195 errx(1, "argc < 1"); 196 197 name_buffer.value = argv[0]; 198 name_buffer.length = strlen(argv[0]); 199 200 maj_stat = gss_import_name(&min_stat, &name_buffer, 201 GSS_C_NT_HOSTBASED_SERVICE, 202 &name); 203 if (maj_stat != GSS_S_COMPLETE) 204 errx(1, "import name error"); 205 206 acquire_release_loop(name, 100, GSS_C_ACCEPT); 207 acquire_release_loop(name, 100, GSS_C_INITIATE); 208 acquire_release_loop(name, 100, GSS_C_BOTH); 209 210 acquire_add_release_add(name, GSS_C_ACCEPT); 211 acquire_add_release_add(name, GSS_C_INITIATE); 212 acquire_add_release_add(name, GSS_C_BOTH); 213 214 gss_release_name(&min_stat, &name); 215 216 return 0; 217} 218