1 /* 2 * Copyright (c) 1997 - 2001 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 "ktutil_locl.h" 35 36 RCSID("$Id: list.c,v 1.8 2001/05/11 00:54:01 assar Exp $"); 37 38 static int help_flag; 39 static int list_keys; 40 static int list_timestamp; 41 42 static struct getargs args[] = { 43 { "help", 'h', arg_flag, &help_flag }, 44 { "keys", 0, arg_flag, &list_keys, "show key value" }, 45 { "timestamp", 0, arg_flag, &list_timestamp, "show timestamp" }, 46 }; 47 48 static int num_args = sizeof(args) / sizeof(args[0]); 49 50 struct key_info { 51 char *version; 52 char *etype; 53 char *principal; 54 char *timestamp; 55 char *key; 56 struct key_info *next; 57 }; 58 59 static int 60 do_list(const char *keytab_string) 61 { 62 krb5_error_code ret; 63 krb5_keytab keytab; 64 krb5_keytab_entry entry; 65 krb5_kt_cursor cursor; 66 struct key_info *ki, **kie = &ki, *kp; 67 68 int max_version = sizeof("Vno") - 1; 69 int max_etype = sizeof("Type") - 1; 70 int max_principal = sizeof("Principal") - 1; 71 int max_timestamp = sizeof("Date") - 1; 72 int max_key = sizeof("Key") - 1; 73 74 ret = krb5_kt_resolve(context, keytab_string, &keytab); 75 if (ret) { 76 krb5_warn(context, ret, "resolving keytab %s", keytab_string); 77 return 0; 78 } 79 80 ret = krb5_kt_start_seq_get(context, keytab, &cursor); 81 if(ret){ 82 krb5_warn(context, ret, "krb5_kt_start_seq_get %s", keytab_string); 83 goto out; 84 } 85 86 printf ("%s:\n\n", keytab_string); 87 88 while((ret = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0){ 89 #define CHECK_MAX(F) if(max_##F < strlen(kp->F)) max_##F = strlen(kp->F) 90 91 kp = malloc(sizeof(*kp)); 92 if (kp == NULL) { 93 krb5_kt_free_entry(context, &entry); 94 krb5_kt_end_seq_get(context, keytab, &cursor); 95 krb5_warn(context, ret, "malloc failed"); 96 goto out; 97 } 98 99 asprintf(&kp->version, "%d", entry.vno); 100 CHECK_MAX(version); 101 ret = krb5_enctype_to_string(context, 102 entry.keyblock.keytype, &kp->etype); 103 if (ret != 0) 104 asprintf(&kp->etype, "unknown (%d)", entry.keyblock.keytype); 105 CHECK_MAX(etype); 106 krb5_unparse_name(context, entry.principal, &kp->principal); 107 CHECK_MAX(principal); 108 if (list_timestamp) { 109 char tstamp[256]; 110 111 krb5_format_time(context, entry.timestamp, 112 tstamp, sizeof(tstamp), FALSE); 113 114 kp->timestamp = strdup(tstamp); 115 CHECK_MAX(timestamp); 116 } 117 if(list_keys) { 118 int i; 119 kp->key = malloc(2 * entry.keyblock.keyvalue.length + 1); 120 for(i = 0; i < entry.keyblock.keyvalue.length; i++) 121 snprintf(kp->key + 2 * i, 3, "%02x", 122 ((unsigned char*)entry.keyblock.keyvalue.data)[i]); 123 CHECK_MAX(key); 124 } 125 kp->next = NULL; 126 *kie = kp; 127 kie = &kp->next; 128 krb5_kt_free_entry(context, &entry); 129 } 130 ret = krb5_kt_end_seq_get(context, keytab, &cursor); 131 132 printf("%-*s %-*s %-*s", max_version, "Vno", 133 max_etype, "Type", 134 max_principal, "Principal"); 135 if(list_timestamp) 136 printf(" %-*s", max_timestamp, "Date"); 137 if(list_keys) 138 printf(" %s", "Key"); 139 printf("\n"); 140 141 for(kp = ki; kp; ) { 142 printf("%*s %-*s %-*s", max_version, kp->version, 143 max_etype, kp->etype, 144 max_principal, kp->principal); 145 if(list_timestamp) 146 printf(" %-*s", max_timestamp, kp->timestamp); 147 if(list_keys) 148 printf(" %s", kp->key); 149 printf("\n"); 150 151 /* free entries */ 152 free(kp->version); 153 free(kp->etype); 154 free(kp->principal); 155 if(list_timestamp) 156 free(kp->timestamp); 157 if(list_keys) { 158 memset(kp->key, 0, strlen(kp->key)); 159 free(kp->key); 160 } 161 ki = kp; 162 kp = kp->next; 163 free(ki); 164 } 165 out: 166 krb5_kt_close(context, keytab); 167 return 0; 168 } 169 170 int 171 kt_list(int argc, char **argv) 172 { 173 int optind = 0; 174 175 if(verbose_flag) 176 list_timestamp = 1; 177 178 if(getarg(args, num_args, argc, argv, &optind)){ 179 arg_printusage(args, num_args, "ktutil list", ""); 180 return 1; 181 } 182 if(help_flag){ 183 arg_printusage(args, num_args, "ktutil list", ""); 184 return 0; 185 } 186 187 if (keytab_string == NULL) { 188 do_list("FILE:/etc/krb5.keytab"); 189 #ifdef KRB4 190 printf ("\n"); 191 do_list("krb4:/etc/srvtab"); 192 #endif 193 } else { 194 do_list(keytab_string); 195 } 196 return 0; 197 } 198