xref: /freebsd/crypto/heimdal/lib/hdb/print.c (revision f0adf7f5cdd241db2f2c817683191a6ef64a4e95)
1 /*
2  * Copyright (c) 1999-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 KTH nor the names of its contributors may be
18  *    used to endorse or promote products derived from this software without
19  *    specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
22  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
32 
33 #include "hdb_locl.h"
34 #include <ctype.h>
35 
36 RCSID("$Id: print.c,v 1.8 2002/05/24 15:18:02 joda Exp $");
37 
38 /*
39    This is the present contents of a dump line. This might change at
40    any time. Fields are separated by white space.
41 
42   principal
43   keyblock
44   	kvno
45 	keys...
46 		mkvno
47 		enctype
48 		keyvalue
49 		salt (- means use normal salt)
50   creation date and principal
51   modification date and principal
52   principal valid from date (not used)
53   principal valid end date (not used)
54   principal key expires (not used)
55   max ticket life
56   max renewable life
57   flags
58   generation number
59   */
60 
61 static krb5_error_code
62 append_string(krb5_context context, krb5_storage *sp, const char *fmt, ...)
63 {
64     krb5_error_code ret;
65     char *s;
66     va_list ap;
67     va_start(ap, fmt);
68     vasprintf(&s, fmt, ap);
69     va_end(ap);
70     if(s == NULL) {
71 	krb5_set_error_string(context, "malloc: out of memory");
72 	return ENOMEM;
73     }
74     ret = krb5_storage_write(sp, s, strlen(s));
75     free(s);
76     return ret;
77 }
78 
79 static krb5_error_code
80 append_hex(krb5_context context, krb5_storage *sp, krb5_data *data)
81 {
82     int i, printable = 1;
83     char *p;
84 
85     p = data->data;
86     for(i = 0; i < data->length; i++)
87 	if(!isalnum((unsigned char)p[i]) && p[i] != '.'){
88 	    printable = 0;
89 	    break;
90 	}
91     if(printable)
92 	return append_string(context, sp, "\"%.*s\"",
93 			     data->length, data->data);
94     for(i = 0; i < data->length; i++)
95 	append_string(context, sp, "%02x", ((unsigned char*)data->data)[i]);
96     return 0;
97 }
98 
99 static char *
100 time2str(time_t t)
101 {
102     static char buf[128];
103     strftime(buf, sizeof(buf), "%Y%m%d%H%M%S", gmtime(&t));
104     return buf;
105 }
106 
107 static krb5_error_code
108 append_event(krb5_context context, krb5_storage *sp, Event *ev)
109 {
110     char *pr = NULL;
111     krb5_error_code ret;
112     if(ev == NULL)
113 	return append_string(context, sp, "- ");
114     if (ev->principal != NULL) {
115        ret = krb5_unparse_name(context, ev->principal, &pr);
116        if(ret)
117            return ret;
118     }
119     ret = append_string(context, sp, "%s:%s ",
120 			time2str(ev->time), pr ? pr : "UNKNOWN");
121     free(pr);
122     return ret;
123 }
124 
125 static krb5_error_code
126 entry2string_int (krb5_context context, krb5_storage *sp, hdb_entry *ent)
127 {
128     char *p;
129     int i;
130     krb5_error_code ret;
131 
132     /* --- principal */
133     ret = krb5_unparse_name(context, ent->principal, &p);
134     if(ret)
135 	return ret;
136     append_string(context, sp, "%s ", p);
137     free(p);
138     /* --- kvno */
139     append_string(context, sp, "%d", ent->kvno);
140     /* --- keys */
141     for(i = 0; i < ent->keys.len; i++){
142 	/* --- mkvno, keytype */
143 	if(ent->keys.val[i].mkvno)
144 	    append_string(context, sp, ":%d:%d:",
145 			  *ent->keys.val[i].mkvno,
146 			  ent->keys.val[i].key.keytype);
147 	else
148 	    append_string(context, sp, "::%d:",
149 			  ent->keys.val[i].key.keytype);
150 	/* --- keydata */
151 	append_hex(context, sp, &ent->keys.val[i].key.keyvalue);
152 	append_string(context, sp, ":");
153 	/* --- salt */
154 	if(ent->keys.val[i].salt){
155 	    append_string(context, sp, "%u/", ent->keys.val[i].salt->type);
156 	    append_hex(context, sp, &ent->keys.val[i].salt->salt);
157 	}else
158 	    append_string(context, sp, "-");
159     }
160     append_string(context, sp, " ");
161     /* --- created by */
162     append_event(context, sp, &ent->created_by);
163     /* --- modified by */
164     append_event(context, sp, ent->modified_by);
165 
166     /* --- valid start */
167     if(ent->valid_start)
168 	append_string(context, sp, "%s ", time2str(*ent->valid_start));
169     else
170 	append_string(context, sp, "- ");
171 
172     /* --- valid end */
173     if(ent->valid_end)
174 	append_string(context, sp, "%s ", time2str(*ent->valid_end));
175     else
176 	append_string(context, sp, "- ");
177 
178     /* --- password ends */
179     if(ent->pw_end)
180 	append_string(context, sp, "%s ", time2str(*ent->pw_end));
181     else
182 	append_string(context, sp, "- ");
183 
184     /* --- max life */
185     if(ent->max_life)
186 	append_string(context, sp, "%d ", *ent->max_life);
187     else
188 	append_string(context, sp, "- ");
189 
190     /* --- max renewable life */
191     if(ent->max_renew)
192 	append_string(context, sp, "%d ", *ent->max_renew);
193     else
194 	append_string(context, sp, "- ");
195 
196     /* --- flags */
197     append_string(context, sp, "%d ", HDBFlags2int(ent->flags));
198 
199     /* --- generation number */
200     if(ent->generation) {
201 	append_string(context, sp, "%s:%d:%d", time2str(ent->generation->time),
202 		      ent->generation->usec,
203 		      ent->generation->gen);
204     } else
205 	append_string(context, sp, "-");
206 
207     return 0;
208 }
209 
210 krb5_error_code
211 hdb_entry2string (krb5_context context, hdb_entry *ent, char **str)
212 {
213     krb5_error_code ret;
214     krb5_data data;
215     krb5_storage *sp;
216 
217     sp = krb5_storage_emem();
218     if(sp == NULL) {
219 	krb5_set_error_string(context, "malloc: out of memory");
220 	return ENOMEM;
221     }
222 
223     ret = entry2string_int(context, sp, ent);
224     if(ret) {
225 	krb5_storage_free(sp);
226 	return ret;
227     }
228 
229     krb5_storage_write(sp, "\0", 1);
230     krb5_storage_to_data(sp, &data);
231     krb5_storage_free(sp);
232     *str = data.data;
233     return 0;
234 }
235 
236 /* print a hdb_entry to (FILE*)data; suitable for hdb_foreach */
237 
238 krb5_error_code
239 hdb_print_entry(krb5_context context, HDB *db, hdb_entry *entry, void *data)
240 {
241     krb5_error_code ret;
242     krb5_storage *sp;
243 
244     FILE *f = data;
245 
246     fflush(f);
247     sp = krb5_storage_from_fd(fileno(f));
248     if(sp == NULL) {
249 	krb5_set_error_string(context, "malloc: out of memory");
250 	return ENOMEM;
251     }
252 
253     ret = entry2string_int(context, sp, entry);
254     if(ret) {
255 	krb5_storage_free(sp);
256 	return ret;
257     }
258 
259     krb5_storage_write(sp, "\n", 1);
260     krb5_storage_free(sp);
261     return 0;
262 }
263