list.c revision 78527
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
36RCSID("$Id: list.c,v 1.8 2001/05/11 00:54:01 assar Exp $");
37
38static int help_flag;
39static int list_keys;
40static int list_timestamp;
41
42static 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
48static int num_args = sizeof(args) / sizeof(args[0]);
49
50struct key_info {
51    char *version;
52    char *etype;
53    char *principal;
54    char *timestamp;
55    char *key;
56    struct key_info *next;
57};
58
59static int
60do_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    }
165out:
166    krb5_kt_close(context, keytab);
167    return 0;
168}
169
170int
171kt_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