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