1 /* 2 * Copyright (c) 2006 Kungliga Tekniska Högskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Portions Copyright (c) 2009 - 2010 Apple Inc. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of KTH nor the names of its contributors may be 20 * used to endorse or promote products derived from this software without 21 * specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY 24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE 27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 30 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 32 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 33 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 #include <config.h> 37 #include <roken.h> 38 39 #include <stdio.h> 40 #include <gssapi.h> 41 #include <gssapi_krb5.h> 42 #include <gssapi_spnego.h> 43 #include <gssapi_ntlm.h> 44 #include <err.h> 45 #include <getarg.h> 46 #include <rtbl.h> 47 #include <gss-commands.h> 48 49 50 static int version_flag = 0; 51 static int help_flag = 0; 52 53 static struct getargs args[] = { 54 {"version", 0, arg_flag, &version_flag, "print version", NULL }, 55 {"help", 0, arg_flag, &help_flag, NULL, NULL } 56 }; 57 58 static void 59 usage (int ret) 60 { 61 arg_printusage (args, sizeof(args)/sizeof(*args), 62 NULL, "service@host"); 63 exit (ret); 64 } 65 66 #define COL_OID "OID" 67 #define COL_NAME "Name" 68 #define COL_DESC "Description" 69 #define COL_VALUE "Value" 70 #define COL_MECH "Mech" 71 #define COL_EXPIRE "Expire" 72 #define COL_SASL "SASL" 73 74 int 75 supported_mechanisms(void *argptr, int argc, char **argv) 76 { 77 OM_uint32 maj_stat, min_stat; 78 gss_OID_set mechs; 79 rtbl_t ct; 80 size_t i; 81 82 maj_stat = gss_indicate_mechs(&min_stat, &mechs); 83 if (maj_stat != GSS_S_COMPLETE) 84 errx(1, "gss_indicate_mechs failed"); 85 86 printf("Supported mechanisms:\n"); 87 88 ct = rtbl_create(); 89 if (ct == NULL) 90 errx(1, "rtbl_create"); 91 92 rtbl_set_separator(ct, " "); 93 rtbl_add_column(ct, COL_OID, 0); 94 rtbl_add_column(ct, COL_NAME, 0); 95 rtbl_add_column(ct, COL_DESC, 0); 96 rtbl_add_column(ct, COL_SASL, 0); 97 98 for (i = 0; i < mechs->count; i++) { 99 gss_buffer_desc str, sasl_name, mech_name, mech_desc; 100 101 maj_stat = gss_oid_to_str(&min_stat, &mechs->elements[i], &str); 102 if (maj_stat != GSS_S_COMPLETE) 103 errx(1, "gss_oid_to_str failed"); 104 105 rtbl_add_column_entryv(ct, COL_OID, "%.*s", 106 (int)str.length, (char *)str.value); 107 gss_release_buffer(&min_stat, &str); 108 109 (void)gss_inquire_saslname_for_mech(&min_stat, 110 &mechs->elements[i], 111 &sasl_name, 112 &mech_name, 113 &mech_desc); 114 115 rtbl_add_column_entryv(ct, COL_NAME, "%.*s", 116 (int)mech_name.length, (char *)mech_name.value); 117 rtbl_add_column_entryv(ct, COL_DESC, "%.*s", 118 (int)mech_desc.length, (char *)mech_desc.value); 119 rtbl_add_column_entryv(ct, COL_SASL, "%.*s", 120 (int)sasl_name.length, (char *)sasl_name.value); 121 122 gss_release_buffer(&min_stat, &mech_name); 123 gss_release_buffer(&min_stat, &mech_desc); 124 gss_release_buffer(&min_stat, &sasl_name); 125 126 } 127 gss_release_oid_set(&min_stat, &mechs); 128 129 rtbl_format(ct, stdout); 130 rtbl_destroy(ct); 131 132 return 0; 133 } 134 135 static void 136 print_mech_attr(const char *mechname, gss_const_OID mech, gss_OID_set set) 137 { 138 gss_buffer_desc name, desc; 139 OM_uint32 major, minor; 140 rtbl_t ct; 141 size_t n; 142 143 ct = rtbl_create(); 144 if (ct == NULL) 145 errx(1, "rtbl_create"); 146 147 rtbl_set_separator(ct, " "); 148 rtbl_add_column(ct, COL_OID, 0); 149 rtbl_add_column(ct, COL_DESC, 0); 150 if (mech) 151 rtbl_add_column(ct, COL_VALUE, 0); 152 153 for (n = 0; n < set->count; n++) { 154 major = gss_display_mech_attr(&minor, &set->elements[n], &name, &desc, NULL); 155 if (major) 156 continue; 157 158 rtbl_add_column_entryv(ct, COL_OID, "%.*s", 159 (int)name.length, (char *)name.value); 160 rtbl_add_column_entryv(ct, COL_DESC, "%.*s", 161 (int)desc.length, (char *)desc.value); 162 if (mech) { 163 gss_buffer_desc value; 164 165 if (gss_mo_get(mech, &set->elements[n], &value) != 0) 166 value.length = 0; 167 168 if (value.length) 169 rtbl_add_column_entryv(ct, COL_VALUE, "%.*s", 170 (int)value.length, (char *)value.value); 171 else 172 rtbl_add_column_entryv(ct, COL_VALUE, "<>"); 173 gss_release_buffer(&minor, &value); 174 } 175 176 gss_release_buffer(&minor, &name); 177 gss_release_buffer(&minor, &desc); 178 } 179 180 printf("attributes for: %s\n", mechname); 181 rtbl_format(ct, stdout); 182 rtbl_destroy(ct); 183 } 184 185 186 int 187 attrs_for_mech(struct attrs_for_mech_options *opt, int argc, char **argv) 188 { 189 gss_OID_set mech_attr = NULL, known_mech_attrs = NULL; 190 gss_OID mech = GSS_C_NO_OID; 191 OM_uint32 major, minor; 192 193 if (opt->mech_string) { 194 mech = gss_name_to_oid(opt->mech_string); 195 if (mech == NULL) 196 errx(1, "mech %s is unknown", opt->mech_string); 197 } 198 199 major = gss_inquire_attrs_for_mech(&minor, mech, &mech_attr, &known_mech_attrs); 200 if (major) 201 errx(1, "gss_inquire_attrs_for_mech"); 202 203 if (mech) { 204 print_mech_attr(opt->mech_string, mech, mech_attr); 205 } 206 207 if (opt->all_flag) { 208 print_mech_attr("all mechs", NULL, known_mech_attrs); 209 } 210 211 gss_release_oid_set(&minor, &mech_attr); 212 gss_release_oid_set(&minor, &known_mech_attrs); 213 214 return 0; 215 } 216 217 218 /* 219 * 220 */ 221 222 int 223 help(void *opt, int argc, char **argv) 224 { 225 sl_slc_help(commands, argc, argv); 226 return 0; 227 } 228 229 int 230 main(int argc, char **argv) 231 { 232 int optidx = 0; 233 234 setprogname(argv[0]); 235 if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx)) 236 usage(1); 237 238 if (help_flag) 239 usage (0); 240 241 if(version_flag){ 242 print_version(NULL); 243 exit(0); 244 } 245 246 argc -= optidx; 247 argv += optidx; 248 249 if (argc == 0) { 250 help(NULL, argc, argv); 251 return 1; 252 } 253 254 return sl_command (commands, argc, argv); 255 } 256