hcrypto: Fix more warnings (rsa-ltm)
[metze/heimdal/wip.git] / kuser / kvno.c
1 /*
2  * Copyright (C) 1998 by the FundsXpress, INC.
3  *
4  * All rights reserved.
5  *
6  * Export of this software from the United States of America may require
7  * a specific license from the United States Government.  It is the
8  * responsibility of any person or organization contemplating export to
9  * obtain such a license before exporting.
10  *
11  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
12  * distribute this software and its documentation for any purpose and
13  * without fee is hereby granted, provided that the above copyright
14  * notice appear in all copies and that both that copyright notice and
15  * this permission notice appear in supporting documentation, and that
16  * the name of FundsXpress. not be used in advertising or publicity pertaining
17  * to distribution of the software without specific, written prior
18  * permission.  FundsXpress makes no representations about the suitability of
19  * this software for any purpose.  It is provided "as is" without express
20  * or implied warranty.
21  *
22  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
24  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
25  */
26
27 #include "kuser_locl.h"
28
29 static char *etype_str = NULL;
30 static char *ccache_name = NULL;
31 static char *keytab_name = NULL;
32 static char *sname = NULL;
33
34 static int  version_flag = 0;
35 static int  help_flag = 0;
36 static int  quiet_flag = 0;
37
38 static void do_v5_kvno (int argc, char *argv[],
39                         char *ccache_name, char *etype_str, char *keytab_name,
40                         char *sname);
41
42 struct getargs args[] = {
43     { "enctype",        'e', arg_string, &etype_str,
44       NP_("Encryption type to use", ""), "enctype" },
45     { "cache",          'c', arg_string, &ccache_name,
46       NP_("Credentials cache", ""), "cachename" },
47     { "keytab",         'k', arg_string, &keytab_name,
48       NP_("Keytab to use", ""), "keytabname" },
49     { "server",         'S', arg_string, &sname,
50       NP_("Server to get ticket for", ""), "principal" },
51     { "quiet",          'q', arg_flag, &quiet_flag,
52       NP_("Quiet", "") },
53     { "version",        0, arg_flag, &version_flag },
54     { "help",           0, arg_flag, &help_flag }
55 };
56
57 static void
58 usage(int ret)
59 {
60     arg_printusage_i18n (args, sizeof(args)/sizeof(*args),
61                          N_("Usage: ", ""), NULL,
62                          "principal1 [principal2 ...]",
63                          getarg_i18n);
64     exit (ret);
65 }
66
67 int main(int argc, char *argv[])
68 {
69     int optidx = 0;
70
71     setprogname (argv[0]);
72
73     setlocale(LC_ALL, "");
74     bindtextdomain ("heimdal_kuser", HEIMDAL_LOCALEDIR);
75     textdomain("heimdal_kuser");
76
77     if (getarg(args, sizeof(args)/sizeof(args[0]), argc, argv, &optidx))
78         usage(1);
79
80     if (help_flag)
81         usage (0);
82
83     if (version_flag) {
84         print_version(NULL);
85         exit (0);
86     }
87
88     argc -= optidx;
89     argv += optidx;
90
91     do_v5_kvno(argc, argv, ccache_name, etype_str, keytab_name, sname);
92
93     return 0;
94 }
95
96 static void do_v5_kvno (int count, char *names[],
97                         char * ccache_name, char *etype_str, char *keytab_name,
98                         char *sname)
99 {
100     krb5_error_code ret;
101     krb5_context context = 0;
102     int i, errors;
103     krb5_enctype etype;
104     krb5_ccache ccache;
105     krb5_principal me;
106     krb5_creds in_creds, *out_creds = NULL;
107     Ticket ticket;
108     size_t len;
109     char *princ = NULL;
110     krb5_keytab keytab = NULL;
111
112     ret = krb5_init_context(&context);
113     if (ret)
114         errx(1, "krb5_init_context failed: %d", ret);
115
116     if (etype_str) {
117         ret = krb5_string_to_enctype(context, etype_str, &etype);
118         if (ret)
119             krb5_err(context, 1, ret, "Failed to convert encryption type %s", etype_str);
120     } else {
121         etype = 0;
122     }
123
124     if (ccache_name)
125         ret = krb5_cc_resolve(context, ccache_name, &ccache);
126     else
127         ret = krb5_cc_default(context, &ccache);
128     if (ret)
129         krb5_err(context, 1, ret, "Failed to open credentials cache %s",
130                  (ccache_name) ? ccache_name : "(Default)");
131
132     if (keytab_name) {
133         ret = krb5_kt_resolve(context, keytab_name, &keytab);
134         if (ret)
135             krb5_err(context, 1, ret, "Can't resolve keytab %s", keytab_name);
136     }
137
138     ret = krb5_cc_get_principal(context, ccache, &me);
139     if (ret)
140         krb5_err(context, 1, ret, "krb5_cc_get_principal");
141
142     errors = 0;
143
144     for (i = 0; i < count; i++) {
145         memset(&in_creds, 0, sizeof(in_creds));
146         memset(&ticket, 0, sizeof(ticket));
147
148         in_creds.client = me;
149
150         if (sname != NULL) {
151             ret = krb5_sname_to_principal(context, names[i],
152                                           sname, KRB5_NT_SRV_HST,
153                                           &in_creds.server);
154         } else {
155             ret = krb5_parse_name(context, names[i], &in_creds.server);
156         }
157         if (ret) {
158             if (!quiet_flag)
159                 krb5_warn(context, ret, "Couldn't parse principal name %s", names[i]);
160             errors++;
161             continue;
162         }
163
164         ret = krb5_unparse_name(context, in_creds.server, &princ);
165         if (ret) {
166             krb5_warn(context, ret, "Couldn't format parsed principal name for '%s'",
167                       names[i]);
168             errors++;
169             goto next;
170         }
171
172         in_creds.session.keytype = etype;
173
174         ret = krb5_get_credentials(context, 0, ccache, &in_creds, &out_creds);
175
176         if (ret) {
177             krb5_warn(context, ret, "Couldn't get credentials for %s", princ);
178             errors++;
179             goto next;
180         }
181
182         ret = decode_Ticket(out_creds->ticket.data, out_creds->ticket.length,
183                             &ticket, &len);
184         if (ret) {
185             krb5_err(context, 1, ret, "Can't decode ticket for %s", princ);
186             errors++;
187             goto next;
188             continue;
189         }
190
191         if (keytab) {
192             krb5_keytab_entry   kte;
193             krb5_crypto         crypto;
194             krb5_data           dec_data;
195             EncTicketPart       decr_part;
196
197             ret = krb5_kt_get_entry(context, keytab, in_creds.server,
198                                     (ticket.enc_part.kvno != NULL)?
199                                     *ticket.enc_part.kvno : 0,
200                                     ticket.enc_part.etype,
201                                     &kte);
202             if (ret) {
203                 krb5_warn(context, ret, "Can't decrypt ticket for %s", princ);
204                 if (!quiet_flag)
205                     printf("%s: kvno = %d, keytab entry invalid", princ,
206                            (ticket.enc_part.kvno != NULL)?
207                            *ticket.enc_part.kvno : 0);
208                 errors ++;
209                 goto next;
210             }
211
212             ret = krb5_crypto_init(context, &kte.keyblock, 0, &crypto);
213             if (ret) {
214                 krb5_warn(context, ret, "krb5_crypto_init");
215                 errors ++;
216                 krb5_kt_free_entry(context, &kte);
217                 goto next;
218             }
219
220             ret = krb5_decrypt_EncryptedData (context, crypto, KRB5_KU_TICKET,
221                                               &ticket.enc_part, &dec_data);
222             krb5_crypto_destroy(context, crypto);
223             krb5_kt_free_entry(context, &kte);
224
225             if (ret) {
226                 krb5_warn(context, ret, "krb5_decrypt_EncryptedData");
227                 errors ++;
228                 goto next;
229             }
230
231             ret = decode_EncTicketPart(dec_data.data, dec_data.length,
232                                        &decr_part, &len);
233             krb5_data_free(&dec_data);
234             if (ret) {
235                 krb5_warn(context, ret, "decode_EncTicketPart");
236                 errors ++;
237                 goto next;
238             }
239
240             if (!quiet_flag)
241                 printf("%s: kvno = %d, keytab entry valid\n", princ,
242                        (ticket.enc_part.kvno != NULL)?
243                        *ticket.enc_part.kvno : 0);
244
245             free_EncTicketPart(&decr_part);
246         } else {
247             if (!quiet_flag)
248                 printf("%s: kvno = %d\n", princ,
249                        (ticket.enc_part.kvno != NULL)? *ticket.enc_part.kvno : 0);
250         }
251
252     next:
253         if (out_creds) {
254             krb5_free_creds(context, out_creds);
255             out_creds = NULL;
256         }
257
258         if (princ) {
259             krb5_free_unparsed_name(context, princ);
260             princ = NULL;
261         }
262
263         krb5_free_principal(context, in_creds.server);
264
265         free_Ticket(&ticket);
266     }
267
268     if (keytab)
269         krb5_kt_close(context, keytab);
270     krb5_free_principal(context, me);
271     krb5_cc_close(context, ccache);
272     krb5_free_context(context);
273
274     if (errors)
275         exit(1);
276
277     exit(0);
278 }