]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - crypto/heimdal/lib/hdb/print.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / crypto / heimdal / lib / hdb / print.c
1 /*
2  * Copyright (c) 1999-2005 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 <hex.h>
35 #include <ctype.h>
36
37 RCSID("$Id: print.c 16378 2005-12-12 12:40:12Z lha $");
38
39 /* 
40    This is the present contents of a dump line. This might change at
41    any time. Fields are separated by white space.
42
43   principal
44   keyblock
45         kvno
46         keys...
47                 mkvno
48                 enctype
49                 keyvalue
50                 salt (- means use normal salt)
51   creation date and principal
52   modification date and principal
53   principal valid from date (not used)
54   principal valid end date (not used)
55   principal key expires (not used)
56   max ticket life
57   max renewable life
58   flags
59   generation number
60   */
61
62 static krb5_error_code
63 append_string(krb5_context context, krb5_storage *sp, const char *fmt, ...)
64 {
65     krb5_error_code ret;
66     char *s;
67     va_list ap;
68     va_start(ap, fmt);
69     vasprintf(&s, fmt, ap);
70     va_end(ap);
71     if(s == NULL) {
72         krb5_set_error_string(context, "malloc: out of memory");
73         return ENOMEM;
74     }
75     ret = krb5_storage_write(sp, s, strlen(s));
76     free(s);
77     return ret;
78 }
79
80 static krb5_error_code
81 append_hex(krb5_context context, krb5_storage *sp, krb5_data *data)
82 {
83     int i, printable = 1;
84     char *p;
85
86     p = data->data;
87     for(i = 0; i < data->length; i++)
88         if(!isalnum((unsigned char)p[i]) && p[i] != '.'){
89             printable = 0;
90             break;
91         }
92     if(printable)
93         return append_string(context, sp, "\"%.*s\"",
94                              data->length, data->data);
95     hex_encode(data->data, data->length, &p);
96     append_string(context, sp, "%s", p);
97     free(p);
98     return 0;
99 }
100
101 static char *
102 time2str(time_t t)
103 {
104     static char buf[128];
105     strftime(buf, sizeof(buf), "%Y%m%d%H%M%S", gmtime(&t));
106     return buf;
107 }
108
109 static krb5_error_code
110 append_event(krb5_context context, krb5_storage *sp, Event *ev)
111 {
112     char *pr = NULL;
113     krb5_error_code ret;
114     if(ev == NULL)
115         return append_string(context, sp, "- ");
116     if (ev->principal != NULL) {
117        ret = krb5_unparse_name(context, ev->principal, &pr);
118        if(ret)
119            return ret;
120     }
121     ret = append_string(context, sp, "%s:%s ",
122                         time2str(ev->time), pr ? pr : "UNKNOWN");
123     free(pr);
124     return ret;
125 }
126
127 static krb5_error_code
128 entry2string_int (krb5_context context, krb5_storage *sp, hdb_entry *ent)
129 {
130     char *p;
131     int i;
132     krb5_error_code ret;
133
134     /* --- principal */
135     ret = krb5_unparse_name(context, ent->principal, &p);
136     if(ret)
137         return ret;
138     append_string(context, sp, "%s ", p);
139     free(p);
140     /* --- kvno */
141     append_string(context, sp, "%d", ent->kvno);
142     /* --- keys */
143     for(i = 0; i < ent->keys.len; i++){
144         /* --- mkvno, keytype */
145         if(ent->keys.val[i].mkvno)
146             append_string(context, sp, ":%d:%d:", 
147                           *ent->keys.val[i].mkvno, 
148                           ent->keys.val[i].key.keytype);
149         else
150             append_string(context, sp, "::%d:", 
151                           ent->keys.val[i].key.keytype);
152         /* --- keydata */
153         append_hex(context, sp, &ent->keys.val[i].key.keyvalue);
154         append_string(context, sp, ":");
155         /* --- salt */
156         if(ent->keys.val[i].salt){
157             append_string(context, sp, "%u/", ent->keys.val[i].salt->type);
158             append_hex(context, sp, &ent->keys.val[i].salt->salt);
159         }else
160             append_string(context, sp, "-");
161     }
162     append_string(context, sp, " ");
163     /* --- created by */
164     append_event(context, sp, &ent->created_by);
165     /* --- modified by */
166     append_event(context, sp, ent->modified_by);
167
168     /* --- valid start */
169     if(ent->valid_start)
170         append_string(context, sp, "%s ", time2str(*ent->valid_start));
171     else
172         append_string(context, sp, "- ");
173
174     /* --- valid end */
175     if(ent->valid_end)
176         append_string(context, sp, "%s ", time2str(*ent->valid_end));
177     else
178         append_string(context, sp, "- ");
179     
180     /* --- password ends */
181     if(ent->pw_end)
182         append_string(context, sp, "%s ", time2str(*ent->pw_end));
183     else
184         append_string(context, sp, "- ");
185
186     /* --- max life */
187     if(ent->max_life)
188         append_string(context, sp, "%d ", *ent->max_life);
189     else
190         append_string(context, sp, "- ");
191
192     /* --- max renewable life */
193     if(ent->max_renew)
194         append_string(context, sp, "%d ", *ent->max_renew);
195     else
196         append_string(context, sp, "- ");
197     
198     /* --- flags */
199     append_string(context, sp, "%d ", HDBFlags2int(ent->flags));
200
201     /* --- generation number */
202     if(ent->generation) {
203         append_string(context, sp, "%s:%d:%d ", time2str(ent->generation->time),
204                       ent->generation->usec,
205                       ent->generation->gen);
206     } else
207         append_string(context, sp, "- ");
208
209     /* --- extensions */
210     if(ent->extensions && ent->extensions->len > 0) {
211         for(i = 0; i < ent->extensions->len; i++) {
212             void *d;
213             size_t size, sz;
214
215             ASN1_MALLOC_ENCODE(HDB_extension, d, size,
216                                &ent->extensions->val[i], &sz, ret);
217             if (ret) {
218                 krb5_clear_error_string(context);
219                 return ret;
220             }
221             if(size != sz)
222                 krb5_abortx(context, "internal asn.1 encoder error");
223
224             if (hex_encode(d, size, &p) < 0) {
225                 free(d);
226                 krb5_set_error_string(context, "malloc: out of memory");
227                 return ENOMEM;
228             }
229
230             free(d);
231             append_string(context, sp, "%s%s", p, 
232                           ent->extensions->len - 1 != i ? ":" : "");
233             free(p);
234         }
235     } else
236         append_string(context, sp, "-");
237
238     
239     return 0;
240 }
241
242 krb5_error_code
243 hdb_entry2string (krb5_context context, hdb_entry *ent, char **str)
244 {
245     krb5_error_code ret;
246     krb5_data data;
247     krb5_storage *sp;
248
249     sp = krb5_storage_emem();
250     if(sp == NULL) {
251         krb5_set_error_string(context, "malloc: out of memory");
252         return ENOMEM;
253     }
254     
255     ret = entry2string_int(context, sp, ent);
256     if(ret) {
257         krb5_storage_free(sp);
258         return ret;
259     }
260
261     krb5_storage_write(sp, "\0", 1);
262     krb5_storage_to_data(sp, &data);
263     krb5_storage_free(sp);
264     *str = data.data;
265     return 0;
266 }
267
268 /* print a hdb_entry to (FILE*)data; suitable for hdb_foreach */
269
270 krb5_error_code
271 hdb_print_entry(krb5_context context, HDB *db, hdb_entry_ex *entry, void *data)
272 {
273     krb5_error_code ret;
274     krb5_storage *sp;
275
276     FILE *f = data;
277
278     fflush(f);
279     sp = krb5_storage_from_fd(fileno(f));
280     if(sp == NULL) {
281         krb5_set_error_string(context, "malloc: out of memory");
282         return ENOMEM;
283     }
284     
285     ret = entry2string_int(context, sp, &entry->entry);
286     if(ret) {
287         krb5_storage_free(sp);
288         return ret;
289     }
290
291     krb5_storage_write(sp, "\n", 1);
292     krb5_storage_free(sp);
293     return 0;
294 }