xref: /freebsd/crypto/krb5/src/lib/krb5/krb/t_in_ccache.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* t_in_ccache.c: get creds while using input and/or armor ccaches */
3 /*
4  * Copyright (C) 2012 by the Massachusetts Institute of Technology.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  *   notice, this list of conditions and the following disclaimer.
13  *
14  * * Redistributions in binary form must reproduce the above copyright
15  *   notice, this list of conditions and the following disclaimer in
16  *   the documentation and/or other materials provided with the
17  *   distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30  * OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*
34  * A test helper that exercises the input-ccache option, potentially in
35  * combination with armor-ccache options.
36  */
37 
38 #include "k5-int.h"
39 
40 static void
bail_on_err(krb5_context context,const char * msg,krb5_error_code code)41 bail_on_err(krb5_context context, const char *msg, krb5_error_code code)
42 {
43     const char *errmsg;
44 
45     if (code) {
46         errmsg = krb5_get_error_message(context, code);
47         printf("%s: %s\n", msg, errmsg);
48         krb5_free_error_message(context, errmsg);
49         exit(1);
50     }
51 }
52 
53 static krb5_error_code
prompter_cb(krb5_context ctx,void * data,const char * name,const char * banner,int num_prompts,krb5_prompt prompts[])54 prompter_cb(krb5_context ctx, void *data, const char *name,
55             const char *banner, int num_prompts, krb5_prompt prompts[])
56 {
57     /* Not expecting any actual prompts. */
58     if (num_prompts != 0) {
59         printf("too many prompts passed to prompter callback (%d), failing\n",
60                num_prompts);
61         exit(1);
62     }
63     return 0;
64 }
65 
66 int
main(int argc,char ** argv)67 main(int argc, char **argv)
68 {
69     krb5_context ctx;
70     krb5_ccache in_ccache, out_ccache, armor_ccache;
71     krb5_get_init_creds_opt *opt;
72     char *user, *password, *armor_ccname = NULL, *in_ccname = NULL, *perr;
73     const char *err;
74     krb5_principal client;
75     krb5_creds creds;
76     krb5_flags fast_flags;
77     krb5_error_code ret;
78     int c;
79 
80     while ((c = getopt(argc, argv, "I:A:")) != -1) {
81         switch (c) {
82         case 'A':
83             armor_ccname = optarg;
84             break;
85         case 'I':
86             in_ccname = optarg;
87             break;
88         }
89     }
90     if (argc - optind < 2) {
91         fprintf(stderr, "Usage: %s [-A armor_ccache] [-I in_ccache] "
92                 "username password\n", argv[0]);
93         return 1;
94     }
95     user = argv[optind];
96     password = argv[optind + 1];
97 
98     bail_on_err(NULL, "Error initializing Kerberos", krb5_init_context(&ctx));
99     bail_on_err(ctx, "Error allocating space for get_init_creds options",
100                 krb5_get_init_creds_opt_alloc(ctx, &opt));
101     if (in_ccname != NULL) {
102         bail_on_err(ctx, "Error resolving input ccache",
103                     krb5_cc_resolve(ctx, in_ccname, &in_ccache));
104         bail_on_err(ctx, "Error setting input_ccache option",
105                     krb5_get_init_creds_opt_set_in_ccache(ctx, opt,
106                                                           in_ccache));
107     } else {
108         in_ccache = NULL;
109     }
110     if (armor_ccname != NULL) {
111         bail_on_err(ctx, "Error resolving armor ccache",
112                     krb5_cc_resolve(ctx, armor_ccname, &armor_ccache));
113         bail_on_err(ctx, "Error setting fast_ccache option",
114                     krb5_get_init_creds_opt_set_fast_ccache(ctx, opt,
115                                                             armor_ccache));
116         fast_flags = KRB5_FAST_REQUIRED;
117         bail_on_err(ctx, "Error setting option to force use of FAST",
118                     krb5_get_init_creds_opt_set_fast_flags(ctx, opt,
119                                                            fast_flags));
120     } else {
121         armor_ccache = NULL;
122     }
123     bail_on_err(ctx, "Error resolving output (default) ccache",
124                 krb5_cc_default(ctx, &out_ccache));
125     bail_on_err(ctx, "Error setting output ccache option",
126                 krb5_get_init_creds_opt_set_out_ccache(ctx, opt, out_ccache));
127     if (asprintf(&perr, "Error parsing principal name \"%s\"", user) < 0)
128         abort();
129     bail_on_err(ctx, perr, krb5_parse_name(ctx, user, &client));
130     ret = krb5_get_init_creds_password(ctx, &creds, client, password,
131                                        prompter_cb, NULL, 0, NULL, opt);
132     if (ret) {
133         err = krb5_get_error_message(ctx, ret);
134         printf("%s\n", err);
135         krb5_free_error_message(ctx, err);
136     } else {
137         krb5_free_cred_contents(ctx, &creds);
138     }
139     krb5_get_init_creds_opt_free(ctx, opt);
140     krb5_free_principal(ctx, client);
141     krb5_cc_close(ctx, out_ccache);
142     if (armor_ccache != NULL)
143         krb5_cc_close(ctx, armor_ccache);
144     if (in_ccache != NULL)
145         krb5_cc_close(ctx, in_ccache);
146     krb5_free_context(ctx);
147     free(perr);
148     return ret ? (ret - KRB5KDC_ERR_NONE) : 0;
149 }
150