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
);