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