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