2 * Copyright (c) 2015 Cryptonector LLC.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. The name Cryptonector LLC may not be used to endorse or promote
17 * products derived from this software without specific prior written
20 * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
30 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47 print_gss_err(OM_uint32 stat, int status_type, gss_OID mech)
52 OM_uint32 msg_ctx = 0;
56 maj = gss_display_status(&min, stat, status_type, mech, &msg_ctx,
58 if (maj != GSS_S_COMPLETE) {
59 fprintf(stderr, "Error displaying GSS %s error (%lu): %lu, %lu",
60 status_type == GSS_C_GSS_CODE ? "major" : "minor",
61 (unsigned long)stat, (unsigned long)maj,
66 fprintf(stderr, "GSS %s error: %.*s\n",
67 status_type == GSS_C_GSS_CODE ? "major" : "minor",
68 (int)str.length, (char *)str.value);
71 fprintf(stderr, "\t%.*s\n", (int)str.length, (char *)str.value);
73 gss_release_buffer(&min, &str);
74 } while (msg_ctx != 0);
78 print_gss_errs(OM_uint32 major, OM_uint32 minor, gss_OID mech)
80 print_gss_err(major, GSS_C_GSS_CODE, GSS_C_NO_OID);
81 print_gss_err(major, GSS_C_MECH_CODE, mech);
85 gss_err(int exitval, OM_uint32 major, OM_uint32 minor, gss_OID mech,
93 print_gss_errs(major, minor, mech);
97 static int version_flag = 0;
98 static int help_flag = 0;
99 static int env_flag = 0;
100 static int def_flag = 0;
101 static int overwrite_flag = 0;
103 static struct getargs args[] = {
104 {"version", 0, arg_flag, &version_flag, "print version", NULL },
105 {"help", 0, arg_flag, &help_flag, NULL, NULL },
106 {"env", 'e', arg_flag, &env_flag,
107 "output env settings", NULL },
108 {"default", 0, arg_flag, &def_flag,
109 "switch credential store default principal", NULL },
110 {"overwrite", 0, arg_flag, &overwrite_flag,
111 "overwrite matching credential", NULL },
117 arg_printusage(args, sizeof(args)/sizeof(*args),
118 NULL, "from_ccache to_ccache");
123 main(int argc, char **argv)
125 OM_uint32 major, minor;
126 gss_cred_id_t from_cred = GSS_C_NO_CREDENTIAL;
127 gss_cred_id_t to_cred = GSS_C_NO_CREDENTIAL;
128 gss_cred_id_t cred = GSS_C_NO_CREDENTIAL;
129 gss_key_value_element_desc from_elements, to_elements;
130 gss_key_value_set_desc from, to;
131 gss_buffer_set_t env = GSS_C_NO_BUFFER_SET;
132 OM_uint32 store_flags = 0;
135 setprogname(argv[0]);
136 if (getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
148 store_flags |= GSS_C_STORE_CRED_DEFAULT;
150 store_flags |= GSS_C_STORE_CRED_OVERWRITE;
156 errx(1, "required arguments missing");
158 errx(1, "too many arguments");
160 from_elements.key = "ccache";
161 from_elements.value = argv[0];
163 from.elements = &from_elements;
165 to_elements.key = "ccache";
166 to_elements.value = argv[1];
168 to.elements = &to_elements;
170 major = gss_add_cred_from(&minor, GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME,
171 GSS_KRB5_MECHANISM, GSS_C_INITIATE,
172 GSS_C_INDEFINITE, GSS_C_INDEFINITE,
173 &from, &from_cred, NULL, NULL, NULL);
174 if (major != GSS_S_COMPLETE)
175 gss_err(1, major, minor, GSS_KRB5_MECHANISM,
176 "failed to acquire creds from %s", argv[0]);
178 major = gss_store_cred_into2(&minor, from_cred, GSS_C_INITIATE,
179 GSS_KRB5_MECHANISM, store_flags, &to, NULL,
180 NULL, env_flag ? &env : NULL);
181 if (major != GSS_S_COMPLETE)
182 gss_err(1, major, minor, GSS_KRB5_MECHANISM,
183 "failed to store creds into %s", argv[1]);
187 int got_krb5ccname = 0;
189 if (env == GSS_C_NO_BUFFER_SET)
190 warnx("No environment settings");
192 for (i = 0; env != GSS_C_NO_BUFFER_SET && i < env->count; i++) {
193 got_krb5ccname = got_krb5ccname ||
194 (env->elements[i].length > sizeof("KRB5CCNAME=") &&
195 strncmp((const char *)env->elements[i].value, "KRB5CCNAME=",
196 sizeof("KRB5CCNAME=") - 1) == 0);
197 printf("%.*s\n", (int)env->elements[i].length,
198 (const char *)env->elements[i].value);
200 (void) gss_release_buffer_set(&minor, &env);
203 errx(1, "KRB5CCNAME environment variable not set by "
204 "gss_store_cred_into2()");
207 (void) gss_release_cred(&minor, &from_cred);
208 (void) gss_release_cred(&minor, &to_cred);
210 major = gss_add_cred(&minor, GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME,
211 GSS_KRB5_MECHANISM, GSS_C_INITIATE, GSS_C_INDEFINITE,
212 GSS_C_INDEFINITE, &cred, NULL, NULL, NULL);
213 if (major != GSS_S_COMPLETE)
214 gss_err(1, major, minor, GSS_KRB5_MECHANISM,
215 "failed to acquire creds from %s", argv[1]);
216 (void) gss_release_cred(&minor, &cred);