1 /* 2 * Copyright (c) 1997 - 2002 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.10 2002/01/30 10:12:21 joda 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 /* XXX specialcase the ANY type */ 75 if(strncasecmp(keytab_string, "ANY:", 4) == 0) { 76 int flag = 0; 77 char buf[1024]; 78 keytab_string += 4; 79 while (strsep_copy((const char**)&keytab_string, ",", 80 buf, sizeof(buf)) != -1) { 81 if(flag) 82 printf("\n"); 83 do_list(buf); 84 flag = 1; 85 } 86 return 0; 87 } 88 89 ret = krb5_kt_resolve(context, keytab_string, &keytab); 90 if (ret) { 91 krb5_warn(context, ret, "resolving keytab %s", keytab_string); 92 return 0; 93 } 94 95 ret = krb5_kt_start_seq_get(context, keytab, &cursor); 96 if(ret){ 97 krb5_warn(context, ret, "krb5_kt_start_seq_get %s", keytab_string); 98 goto out; 99 } 100 101 printf ("%s:\n\n", keytab_string); 102 103 while((ret = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0){ 104 #define CHECK_MAX(F) if(max_##F < strlen(kp->F)) max_##F = strlen(kp->F) 105 106 kp = malloc(sizeof(*kp)); 107 if (kp == NULL) { 108 krb5_kt_free_entry(context, &entry); 109 krb5_kt_end_seq_get(context, keytab, &cursor); 110 krb5_warn(context, ret, "malloc failed"); 111 goto out; 112 } 113 114 asprintf(&kp->version, "%d", entry.vno); 115 CHECK_MAX(version); 116 ret = krb5_enctype_to_string(context, 117 entry.keyblock.keytype, &kp->etype); 118 if (ret != 0) 119 asprintf(&kp->etype, "unknown (%d)", entry.keyblock.keytype); 120 CHECK_MAX(etype); 121 krb5_unparse_name(context, entry.principal, &kp->principal); 122 CHECK_MAX(principal); 123 if (list_timestamp) { 124 char tstamp[256]; 125 126 krb5_format_time(context, entry.timestamp, 127 tstamp, sizeof(tstamp), FALSE); 128 129 kp->timestamp = strdup(tstamp); 130 CHECK_MAX(timestamp); 131 } 132 if(list_keys) { 133 int i; 134 kp->key = malloc(2 * entry.keyblock.keyvalue.length + 1); 135 for(i = 0; i < entry.keyblock.keyvalue.length; i++) 136 snprintf(kp->key + 2 * i, 3, "%02x", 137 ((unsigned char*)entry.keyblock.keyvalue.data)[i]); 138 CHECK_MAX(key); 139 } 140 *kie = kp; 141 kie = &kp->next; 142 krb5_kt_free_entry(context, &entry); 143 } 144 *kie = NULL; /* termiate list */ 145 ret = krb5_kt_end_seq_get(context, keytab, &cursor); 146 147 printf("%-*s %-*s %-*s", max_version, "Vno", 148 max_etype, "Type", 149 max_principal, "Principal"); 150 if(list_timestamp) 151 printf(" %-*s", max_timestamp, "Date"); 152 if(list_keys) 153 printf(" %s", "Key"); 154 printf("\n"); 155 156 for(kp = ki; kp; ) { 157 printf("%*s %-*s %-*s", max_version, kp->version, 158 max_etype, kp->etype, 159 max_principal, kp->principal); 160 if(list_timestamp) 161 printf(" %-*s", max_timestamp, kp->timestamp); 162 if(list_keys) 163 printf(" %s", kp->key); 164 printf("\n"); 165 166 /* free entries */ 167 free(kp->version); 168 free(kp->etype); 169 free(kp->principal); 170 if(list_timestamp) 171 free(kp->timestamp); 172 if(list_keys) { 173 memset(kp->key, 0, strlen(kp->key)); 174 free(kp->key); 175 } 176 ki = kp; 177 kp = kp->next; 178 free(ki); 179 } 180 out: 181 krb5_kt_close(context, keytab); 182 return 0; 183 } 184 185 int 186 kt_list(int argc, char **argv) 187 { 188 krb5_error_code ret; 189 int optind = 0; 190 char kt[1024]; 191 192 if(verbose_flag) 193 list_timestamp = 1; 194 195 if(getarg(args, num_args, argc, argv, &optind)){ 196 arg_printusage(args, num_args, "ktutil list", ""); 197 return 1; 198 } 199 if(help_flag){ 200 arg_printusage(args, num_args, "ktutil list", ""); 201 return 0; 202 } 203 204 if (keytab_string == NULL) { 205 if((ret = krb5_kt_default_name(context, kt, sizeof(kt))) != 0) { 206 krb5_warn(context, ret, "getting default keytab name"); 207 return 0; 208 } 209 keytab_string = kt; 210 } 211 do_list(keytab_string); 212 return 0; 213 } 214