diff options
Diffstat (limited to 'third_party/heimdal/kuser/kvno.c')
-rw-r--r-- | third_party/heimdal/kuser/kvno.c | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/third_party/heimdal/kuser/kvno.c b/third_party/heimdal/kuser/kvno.c new file mode 100644 index 0000000..7ddf2a2 --- /dev/null +++ b/third_party/heimdal/kuser/kvno.c @@ -0,0 +1,278 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "kuser_locl.h" + +static char *etype_str = NULL; +static char *ccache_name = NULL; +static char *keytab_name = NULL; +static char *sname = NULL; + +static int version_flag = 0; +static int help_flag = 0; +static int quiet_flag = 0; + +static void do_v5_kvno (int argc, char *argv[], + char *ccache_name, char *etype_str, char *keytab_name, + char *sname); + +struct getargs args[] = { + { "enctype", 'e', arg_string, &etype_str, + NP_("Encryption type to use", ""), "enctype" }, + { "cache", 'c', arg_string, &ccache_name, + NP_("Credentials cache", ""), "cachename" }, + { "keytab", 'k', arg_string, &keytab_name, + NP_("Keytab to use", ""), "keytabname" }, + { "server", 'S', arg_string, &sname, + NP_("Server to get ticket for", ""), "principal" }, + { "quiet", 'q', arg_flag, &quiet_flag, + NP_("Quiet", "") }, + { "version", 0, arg_flag, &version_flag }, + { "help", 0, arg_flag, &help_flag } +}; + +static void +usage(int ret) +{ + arg_printusage_i18n (args, sizeof(args)/sizeof(*args), + N_("Usage: ", ""), NULL, + "principal1 [principal2 ...]", + getarg_i18n); + exit (ret); +} + +int main(int argc, char *argv[]) +{ + int optidx = 0; + + setprogname (argv[0]); + + setlocale(LC_ALL, ""); + bindtextdomain ("heimdal_kuser", HEIMDAL_LOCALEDIR); + textdomain("heimdal_kuser"); + + if (getarg(args, sizeof(args)/sizeof(args[0]), argc, argv, &optidx)) + usage(1); + + if (help_flag) + usage (0); + + if (version_flag) { + print_version(NULL); + exit (0); + } + + argc -= optidx; + argv += optidx; + + do_v5_kvno(argc, argv, ccache_name, etype_str, keytab_name, sname); + + return 0; +} + +static void do_v5_kvno (int count, char *names[], + char * ccache_name, char *etype_str, char *keytab_name, + char *sname) +{ + krb5_error_code ret; + krb5_context context = 0; + int i, errors; + krb5_enctype etype; + krb5_ccache ccache; + krb5_principal me; + krb5_creds in_creds, *out_creds = NULL; + Ticket ticket; + size_t len; + char *princ = NULL; + krb5_keytab keytab = NULL; + + ret = krb5_init_context(&context); + if (ret) + errx(1, "krb5_init_context failed: %d", ret); + + if (etype_str) { + ret = krb5_string_to_enctype(context, etype_str, &etype); + if (ret) + krb5_err(context, 1, ret, "Failed to convert encryption type %s", etype_str); + } else { + etype = 0; + } + + if (ccache_name) + ret = krb5_cc_resolve(context, ccache_name, &ccache); + else + ret = krb5_cc_default(context, &ccache); + if (ret) + krb5_err(context, 1, ret, "Failed to open credentials cache %s", + (ccache_name) ? ccache_name : "(Default)"); + + if (keytab_name) { + ret = krb5_kt_resolve(context, keytab_name, &keytab); + if (ret) + krb5_err(context, 1, ret, "Can't resolve keytab %s", keytab_name); + } + + ret = krb5_cc_get_principal(context, ccache, &me); + if (ret) + krb5_err(context, 1, ret, "krb5_cc_get_principal"); + + errors = 0; + + for (i = 0; i < count; i++) { + memset(&in_creds, 0, sizeof(in_creds)); + memset(&ticket, 0, sizeof(ticket)); + + in_creds.client = me; + + if (sname != NULL) { + ret = krb5_sname_to_principal(context, names[i], + sname, KRB5_NT_SRV_HST, + &in_creds.server); + } else { + ret = krb5_parse_name(context, names[i], &in_creds.server); + } + if (ret) { + if (!quiet_flag) + krb5_warn(context, ret, "Couldn't parse principal name %s", names[i]); + errors++; + continue; + } + + ret = krb5_unparse_name(context, in_creds.server, &princ); + if (ret) { + krb5_warn(context, ret, "Couldn't format parsed principal name for '%s'", + names[i]); + errors++; + goto next; + } + + in_creds.session.keytype = etype; + + ret = krb5_get_credentials(context, 0, ccache, &in_creds, &out_creds); + + if (ret) { + krb5_warn(context, ret, "Couldn't get credentials for %s", princ); + errors++; + goto next; + } + + ret = decode_Ticket(out_creds->ticket.data, out_creds->ticket.length, + &ticket, &len); + if (ret) { + krb5_err(context, 1, ret, "Can't decode ticket for %s", princ); + errors++; + goto next; + continue; + } + + if (keytab) { + krb5_keytab_entry kte; + krb5_crypto crypto; + krb5_data dec_data; + EncTicketPart decr_part; + + ret = krb5_kt_get_entry(context, keytab, in_creds.server, + (ticket.enc_part.kvno != NULL)? + *ticket.enc_part.kvno : 0, + ticket.enc_part.etype, + &kte); + if (ret) { + krb5_warn(context, ret, "Can't decrypt ticket for %s", princ); + if (!quiet_flag) + printf("%s: kvno = %d, keytab entry invalid", princ, + (ticket.enc_part.kvno != NULL)? + *ticket.enc_part.kvno : 0); + errors ++; + goto next; + } + + ret = krb5_crypto_init(context, &kte.keyblock, 0, &crypto); + if (ret) { + krb5_warn(context, ret, "krb5_crypto_init"); + errors ++; + krb5_kt_free_entry(context, &kte); + goto next; + } + + ret = krb5_decrypt_EncryptedData (context, crypto, KRB5_KU_TICKET, + &ticket.enc_part, &dec_data); + krb5_crypto_destroy(context, crypto); + krb5_kt_free_entry(context, &kte); + + if (ret) { + krb5_warn(context, ret, "krb5_decrypt_EncryptedData"); + errors ++; + goto next; + } + + ret = decode_EncTicketPart(dec_data.data, dec_data.length, + &decr_part, &len); + krb5_data_free(&dec_data); + if (ret) { + krb5_warn(context, ret, "decode_EncTicketPart"); + errors ++; + goto next; + } + + if (!quiet_flag) + printf("%s: kvno = %d, keytab entry valid\n", princ, + (ticket.enc_part.kvno != NULL)? + *ticket.enc_part.kvno : 0); + + free_EncTicketPart(&decr_part); + } else { + if (!quiet_flag) + printf("%s: kvno = %d\n", princ, + (ticket.enc_part.kvno != NULL)? *ticket.enc_part.kvno : 0); + } + + next: + if (out_creds) { + krb5_free_creds(context, out_creds); + out_creds = NULL; + } + + if (princ) { + krb5_free_unparsed_name(context, princ); + princ = NULL; + } + + krb5_free_principal(context, in_creds.server); + + free_Ticket(&ticket); + } + + if (keytab) + krb5_kt_close(context, keytab); + krb5_free_principal(context, me); + krb5_cc_close(context, ccache); + krb5_free_context(context); + + if (errors) + exit(1); + + exit(0); +} |