1 1.1 elric /* $NetBSD: kvno.c,v 1.2 2017/01/28 21:31:45 christos Exp $ */ 2 1.1 elric 3 1.1 elric /* 4 1.1 elric * Copyright (C) 1998 by the FundsXpress, INC. 5 1.2 christos * 6 1.1 elric * All rights reserved. 7 1.2 christos * 8 1.1 elric * Export of this software from the United States of America may require 9 1.1 elric * a specific license from the United States Government. It is the 10 1.1 elric * responsibility of any person or organization contemplating export to 11 1.1 elric * obtain such a license before exporting. 12 1.2 christos * 13 1.1 elric * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 14 1.1 elric * distribute this software and its documentation for any purpose and 15 1.1 elric * without fee is hereby granted, provided that the above copyright 16 1.1 elric * notice appear in all copies and that both that copyright notice and 17 1.1 elric * this permission notice appear in supporting documentation, and that 18 1.1 elric * the name of FundsXpress. not be used in advertising or publicity pertaining 19 1.1 elric * to distribution of the software without specific, written prior 20 1.1 elric * permission. FundsXpress makes no representations about the suitability of 21 1.1 elric * this software for any purpose. It is provided "as is" without express 22 1.1 elric * or implied warranty. 23 1.2 christos * 24 1.1 elric * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 25 1.1 elric * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 26 1.1 elric * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 27 1.1 elric */ 28 1.1 elric 29 1.1 elric #include "kuser_locl.h" 30 1.1 elric 31 1.1 elric static char *etype_str = NULL; 32 1.1 elric static char *ccache_name = NULL; 33 1.1 elric static char *keytab_name = NULL; 34 1.1 elric static char *sname = NULL; 35 1.1 elric 36 1.1 elric static int version_flag = 0; 37 1.1 elric static int help_flag = 0; 38 1.1 elric static int quiet_flag = 0; 39 1.1 elric 40 1.2 christos static void do_v5_kvno (int argc, char *argv[], 41 1.1 elric char *ccache_name, char *etype_str, char *keytab_name, 42 1.1 elric char *sname); 43 1.1 elric 44 1.1 elric struct getargs args[] = { 45 1.1 elric { "enctype", 'e', arg_string, &etype_str, 46 1.1 elric NP_("Encryption type to use", ""), "enctype" }, 47 1.1 elric { "cache", 'c', arg_string, &ccache_name, 48 1.1 elric NP_("Credentials cache", ""), "cachename" }, 49 1.1 elric { "keytab", 'k', arg_string, &keytab_name, 50 1.1 elric NP_("Keytab to use", ""), "keytabname" }, 51 1.1 elric { "server", 'S', arg_string, &sname, 52 1.1 elric NP_("Server to get ticket for", ""), "principal" }, 53 1.1 elric { "quiet", 'q', arg_flag, &quiet_flag, 54 1.1 elric NP_("Quiet", "") }, 55 1.1 elric { "version", 0, arg_flag, &version_flag }, 56 1.1 elric { "help", 0, arg_flag, &help_flag } 57 1.1 elric }; 58 1.1 elric 59 1.1 elric static void 60 1.1 elric usage(int ret) 61 1.1 elric { 62 1.1 elric arg_printusage_i18n (args, sizeof(args)/sizeof(*args), 63 1.1 elric N_("Usage: ", ""), NULL, 64 1.1 elric "principal1 [principal2 ...]", 65 1.1 elric getarg_i18n); 66 1.1 elric exit (ret); 67 1.1 elric } 68 1.1 elric 69 1.1 elric int main(int argc, char *argv[]) 70 1.1 elric { 71 1.1 elric int optidx = 0; 72 1.1 elric 73 1.1 elric setprogname (argv[0]); 74 1.1 elric 75 1.1 elric setlocale(LC_ALL, ""); 76 1.1 elric bindtextdomain ("heimdal_kuser", HEIMDAL_LOCALEDIR); 77 1.1 elric textdomain("heimdal_kuser"); 78 1.1 elric 79 1.1 elric if (getarg(args, sizeof(args)/sizeof(args[0]), argc, argv, &optidx)) 80 1.1 elric usage(1); 81 1.1 elric 82 1.1 elric if (help_flag) 83 1.1 elric usage (0); 84 1.1 elric 85 1.1 elric if (version_flag) { 86 1.1 elric print_version(NULL); 87 1.1 elric exit (0); 88 1.1 elric } 89 1.1 elric 90 1.1 elric argc -= optidx; 91 1.1 elric argv += optidx; 92 1.1 elric 93 1.1 elric do_v5_kvno(argc, argv, ccache_name, etype_str, keytab_name, sname); 94 1.1 elric 95 1.1 elric return 0; 96 1.1 elric } 97 1.1 elric 98 1.2 christos static void do_v5_kvno (int count, char *names[], 99 1.1 elric char * ccache_name, char *etype_str, char *keytab_name, 100 1.1 elric char *sname) 101 1.1 elric { 102 1.1 elric krb5_error_code ret; 103 1.1 elric krb5_context context = 0; 104 1.1 elric int i, errors; 105 1.1 elric krb5_enctype etype; 106 1.1 elric krb5_ccache ccache; 107 1.1 elric krb5_principal me; 108 1.1 elric krb5_creds in_creds, *out_creds = NULL; 109 1.1 elric Ticket ticket; 110 1.1 elric size_t len; 111 1.1 elric char *princ = NULL; 112 1.1 elric krb5_keytab keytab = NULL; 113 1.1 elric 114 1.1 elric ret = krb5_init_context(&context); 115 1.1 elric if (ret) 116 1.1 elric errx(1, "krb5_init_context failed: %d", ret); 117 1.1 elric 118 1.1 elric if (etype_str) { 119 1.1 elric ret = krb5_string_to_enctype(context, etype_str, &etype); 120 1.1 elric if (ret) 121 1.1 elric krb5_err(context, 1, ret, "Failed to convert encryption type %s", etype_str); 122 1.1 elric } else { 123 1.1 elric etype = 0; 124 1.1 elric } 125 1.1 elric 126 1.1 elric if (ccache_name) 127 1.1 elric ret = krb5_cc_resolve(context, ccache_name, &ccache); 128 1.1 elric else 129 1.1 elric ret = krb5_cc_default(context, &ccache); 130 1.1 elric if (ret) 131 1.1 elric krb5_err(context, 1, ret, "Failed to open credentials cache %s", 132 1.1 elric (ccache_name) ? ccache_name : "(Default)"); 133 1.1 elric 134 1.1 elric if (keytab_name) { 135 1.1 elric ret = krb5_kt_resolve(context, keytab_name, &keytab); 136 1.1 elric if (ret) 137 1.1 elric krb5_err(context, 1, ret, "Can't resolve keytab %s", keytab_name); 138 1.1 elric } 139 1.1 elric 140 1.1 elric ret = krb5_cc_get_principal(context, ccache, &me); 141 1.1 elric if (ret) 142 1.1 elric krb5_err(context, 1, ret, "krb5_cc_get_principal"); 143 1.1 elric 144 1.1 elric errors = 0; 145 1.1 elric 146 1.1 elric for (i = 0; i < count; i++) { 147 1.1 elric memset(&in_creds, 0, sizeof(in_creds)); 148 1.1 elric memset(&ticket, 0, sizeof(ticket)); 149 1.1 elric 150 1.1 elric in_creds.client = me; 151 1.1 elric 152 1.1 elric if (sname != NULL) { 153 1.1 elric ret = krb5_sname_to_principal(context, names[i], 154 1.1 elric sname, KRB5_NT_SRV_HST, 155 1.1 elric &in_creds.server); 156 1.1 elric } else { 157 1.1 elric ret = krb5_parse_name(context, names[i], &in_creds.server); 158 1.1 elric } 159 1.1 elric if (ret) { 160 1.1 elric if (!quiet_flag) 161 1.1 elric krb5_warn(context, ret, "Couldn't parse principal name %s", names[i]); 162 1.1 elric errors++; 163 1.1 elric continue; 164 1.1 elric } 165 1.1 elric 166 1.1 elric ret = krb5_unparse_name(context, in_creds.server, &princ); 167 1.1 elric if (ret) { 168 1.1 elric krb5_warn(context, ret, "Couldn't format parsed principal name for '%s'", 169 1.1 elric names[i]); 170 1.1 elric errors++; 171 1.1 elric goto next; 172 1.1 elric } 173 1.1 elric 174 1.1 elric in_creds.session.keytype = etype; 175 1.1 elric 176 1.1 elric ret = krb5_get_credentials(context, 0, ccache, &in_creds, &out_creds); 177 1.1 elric 178 1.1 elric if (ret) { 179 1.1 elric krb5_warn(context, ret, "Couldn't get credentials for %s", princ); 180 1.1 elric errors++; 181 1.1 elric goto next; 182 1.1 elric } 183 1.1 elric 184 1.1 elric ret = decode_Ticket(out_creds->ticket.data, out_creds->ticket.length, 185 1.1 elric &ticket, &len); 186 1.1 elric if (ret) { 187 1.1 elric krb5_err(context, 1, ret, "Can't decode ticket for %s", princ); 188 1.1 elric errors++; 189 1.1 elric goto next; 190 1.1 elric continue; 191 1.1 elric } 192 1.1 elric 193 1.1 elric if (keytab) { 194 1.1 elric krb5_keytab_entry kte; 195 1.1 elric krb5_crypto crypto; 196 1.1 elric krb5_data dec_data; 197 1.1 elric EncTicketPart decr_part; 198 1.1 elric 199 1.1 elric ret = krb5_kt_get_entry(context, keytab, in_creds.server, 200 1.1 elric (ticket.enc_part.kvno != NULL)? 201 1.1 elric *ticket.enc_part.kvno : 0, 202 1.1 elric ticket.enc_part.etype, 203 1.1 elric &kte); 204 1.1 elric if (ret) { 205 1.1 elric krb5_warn(context, ret, "Can't decrypt ticket for %s", princ); 206 1.1 elric if (!quiet_flag) 207 1.1 elric printf("%s: kvno = %d, keytab entry invalid", princ, 208 1.1 elric (ticket.enc_part.kvno != NULL)? 209 1.1 elric *ticket.enc_part.kvno : 0); 210 1.1 elric errors ++; 211 1.1 elric goto next; 212 1.1 elric } 213 1.1 elric 214 1.1 elric ret = krb5_crypto_init(context, &kte.keyblock, 0, &crypto); 215 1.1 elric if (ret) { 216 1.1 elric krb5_warn(context, ret, "krb5_crypto_init"); 217 1.1 elric errors ++; 218 1.1 elric krb5_kt_free_entry(context, &kte); 219 1.1 elric goto next; 220 1.1 elric } 221 1.1 elric 222 1.1 elric ret = krb5_decrypt_EncryptedData (context, crypto, KRB5_KU_TICKET, 223 1.1 elric &ticket.enc_part, &dec_data); 224 1.1 elric krb5_crypto_destroy(context, crypto); 225 1.1 elric krb5_kt_free_entry(context, &kte); 226 1.1 elric 227 1.1 elric if (ret) { 228 1.1 elric krb5_warn(context, ret, "krb5_decrypt_EncryptedData"); 229 1.1 elric errors ++; 230 1.1 elric goto next; 231 1.1 elric } 232 1.1 elric 233 1.1 elric ret = decode_EncTicketPart(dec_data.data, dec_data.length, 234 1.1 elric &decr_part, &len); 235 1.1 elric krb5_data_free(&dec_data); 236 1.1 elric if (ret) { 237 1.1 elric krb5_warn(context, ret, "decode_EncTicketPart"); 238 1.1 elric errors ++; 239 1.1 elric goto next; 240 1.1 elric } 241 1.1 elric 242 1.1 elric if (!quiet_flag) 243 1.1 elric printf("%s: kvno = %d, keytab entry valid\n", princ, 244 1.1 elric (ticket.enc_part.kvno != NULL)? 245 1.1 elric *ticket.enc_part.kvno : 0); 246 1.1 elric 247 1.1 elric free_EncTicketPart(&decr_part); 248 1.1 elric } else { 249 1.1 elric if (!quiet_flag) 250 1.1 elric printf("%s: kvno = %d\n", princ, 251 1.1 elric (ticket.enc_part.kvno != NULL)? *ticket.enc_part.kvno : 0); 252 1.1 elric } 253 1.1 elric 254 1.1 elric next: 255 1.1 elric if (out_creds) { 256 1.1 elric krb5_free_creds(context, out_creds); 257 1.1 elric out_creds = NULL; 258 1.1 elric } 259 1.1 elric 260 1.1 elric if (princ) { 261 1.1 elric krb5_free_unparsed_name(context, princ); 262 1.1 elric princ = NULL; 263 1.1 elric } 264 1.1 elric 265 1.1 elric krb5_free_principal(context, in_creds.server); 266 1.1 elric 267 1.1 elric free_Ticket(&ticket); 268 1.1 elric } 269 1.1 elric 270 1.1 elric if (keytab) 271 1.1 elric krb5_kt_close(context, keytab); 272 1.1 elric krb5_free_principal(context, me); 273 1.1 elric krb5_cc_close(context, ccache); 274 1.1 elric krb5_free_context(context); 275 1.1 elric 276 1.1 elric if (errors) 277 1.1 elric exit(1); 278 1.1 elric 279 1.1 elric exit(0); 280 1.1 elric } 281