]> git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/krbtool/krbtool.cpp
Security-57336.1.9.tar.gz
[apple/security.git] / SecurityTests / clxutils / krbtool / krbtool.cpp
1 /*
2 * Copyright (c) 2004,2006,2008 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23 /*
24 * krbtool.cpp - basic PKINIT tool
25 *
26 * Created 20 May 2004 by Doug Mitchell.
27 */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32 #include <sys/types.h>
33 #include <pwd.h>
34 #include "identPicker.h"
35 #include "asnUtils.h"
36 #include <Kerberos/KerberosLogin.h>
37 #include <Kerberos/pkinit_cert_store.h>
38
39 static void usage(char **argv)
40 {
41 printf("Usage: op [option..]\n");
42 printf("Ops:\n");
43 printf(" l login\n");
44 printf(" s select PKINIT client cert\n");
45 printf(" d display PKINIT client cert\n");
46 printf(" D delete PKINIT client cert setting\n");
47 printf("Options:\n");
48 printf(" -p principal -- default is current user for login\n");
49 printf(" -l -- loop (for malloc debug)\n");
50 printf(" TBD\n");
51 exit(1);
52 }
53
54 typedef enum {
55 KTO_Login = 0,
56 KTO_Select,
57 KTO_Display,
58 KTO_DeleteCert
59 } KrbToolOp;
60
61 typedef struct {
62 const char *principal;
63 /* I'm sure others */
64 } KrbToolArgs;
65
66 static int pkinitLogin(
67 const KrbToolArgs *args)
68 {
69 /* Get a principal string one way or the other */
70 const char *principalStr = args->principal;
71 bool freeStr = false;
72 int ourRtn = 0;
73 KLLoginOptions klOpts = NULL;
74
75 if(principalStr == NULL) {
76 struct passwd *pw = getpwuid(getuid ());
77 if(pw == NULL) {
78 printf("***Sorry, can't find current user info. Aborting.\n");
79 return -1;
80 }
81 principalStr = strdup(pw->pw_name);
82 freeStr = true;
83 }
84
85 KLPrincipal principal = NULL;
86 KLStatus klrtn;
87
88 klrtn = KLCreatePrincipalFromString(principalStr, kerberosVersion_V5, &principal);
89 if(klrtn) {
90 printf("***KLCreatePrincipalFromString returned %d. Aborting.\n", (int)klrtn);
91 ourRtn = -1;
92 goto errOut;
93 }
94
95 /* Options, later maybe */
96 /* FIXME - don't know if the login options arg is optional */
97
98 /* By convention we use a non-NULL string as password; this may change later */
99 printf("...attempting TGT acquisition\n");
100 klrtn = KLAcquireNewInitialTicketsWithPassword(principal, klOpts, " ", NULL);
101 if(klrtn) {
102 printf("***KLAcquireInitialTicketsWithPassword returned %d\n", (int)klrtn);
103 }
104 else {
105 printf("...TGT acquisition successful.\n");
106 }
107 errOut:
108 if(freeStr && (principalStr != NULL)) {
109 free((void *)principalStr);
110 }
111 if(klOpts != NULL) {
112 KLDisposeLoginOptions(klOpts);
113 }
114 if(principal != NULL) {
115 KLDisposePrincipal(principal);
116 }
117 return ourRtn;
118 }
119
120 static int pkinitSelect(
121 const KrbToolArgs *args)
122 {
123 OSStatus ortn;
124 SecIdentityRef idRef = NULL;
125
126 if(args->principal == NULL) {
127 printf("***You must supply a principal name for this operation.\n");
128 return -1;
129 }
130 ortn = simpleIdentPicker(NULL, &idRef);
131 switch(ortn) {
132 case CSSMERR_CSSM_USER_CANCELED:
133 printf("...operation terminated with no change to your settings.\n");
134 return 0;
135 case noErr:
136 break;
137 default:
138 printf("***Operation aborted.\n");
139 return -1;
140 }
141
142 krb5_error_code krtn = krb5_pkinit_set_client_cert(args->principal,
143 (krb5_pkinit_signing_cert_t)idRef);
144 if(krtn) {
145 cssmPerror("krb5_pkinit_set_client_cert", krtn);
146 }
147 else {
148 printf("...PKINIT client cert selection successful.\n\n");
149 }
150 if(idRef) {
151 CFRelease(idRef);
152 }
153 return 0;
154 }
155
156 static int pkinitDisplay(
157 const KrbToolArgs *args)
158 {
159 krb5_pkinit_signing_cert_t idRef = NULL;
160 krb5_error_code krtn;
161
162 if(args->principal == NULL) {
163 printf("***You must supply a principal name for this operation.\n");
164 return -1;
165 }
166 krtn = krb5_pkinit_get_client_cert(args->principal, &idRef);
167 switch(krtn) {
168 case errSecItemNotFound:
169 printf("...No PKINIT client cert configured for %s.\n",
170 args->principal ? args->principal : "Default");
171 break;
172 case noErr:
173 {
174 SecCertificateRef certRef = NULL;
175 OSStatus ortn;
176 CSSM_DATA cdata;
177
178 ortn = SecIdentityCopyCertificate((SecIdentityRef)idRef, &certRef);
179 if(ortn) {
180 cssmPerror("SecIdentityCopyCertificate", ortn);
181 break;
182 }
183 ortn = SecCertificateGetData(certRef, &cdata);
184 if(ortn) {
185 cssmPerror("SecCertificateGetData", ortn);
186 break;
187 }
188 printf("--------- PKINIT Client Certificate ---------\n");
189 printCertName(cdata.Data, cdata.Length, NameBoth);
190 printf("---------------------------------------------\n\n");
191
192 char *cert_hash = NULL;
193 krb5_data kcert = {0, cdata.Length, (char *)cdata.Data};
194 cert_hash = krb5_pkinit_cert_hash_str(&kcert);
195 if(cert_hash == NULL) {
196 printf("***Error obtaining cert hash\n");
197 }
198 else {
199 printf("Cert hash string : %s\n\n", cert_hash);
200 free(cert_hash);
201 }
202 CFRelease(certRef);
203 break;
204 }
205 default:
206 cssmPerror("krb5_pkinit_get_client_cert", krtn);
207 printf("***Error obtaining client cert\n");
208 break;
209 }
210 if(idRef) {
211 krb5_pkinit_release_cert(idRef);
212 }
213
214 return 0;
215 }
216
217 static int pkinitDeleteCert(
218 const KrbToolArgs *args)
219 {
220 krb5_error_code krtn;
221
222 krtn = krb5_pkinit_set_client_cert(args->principal, NULL);
223 if(krtn) {
224 cssmPerror("krb5_pkinit_set_client_cert(NULL)", krtn);
225 printf("***Error deleting client cert entry\n");
226 }
227 else {
228 printf("...client cert setting for %s deleted\n", args->principal ?
229 args->principal : "Default principal");
230 }
231 return krtn;
232 }
233
234 int main(int argc, char **argv)
235 {
236 if(argc < 2) {
237 usage(argv);
238 }
239
240 KrbToolOp op = KTO_Login;
241 switch(argv[1][0]) {
242 case 'l':
243 op = KTO_Login;
244 break;
245 case 's':
246 op = KTO_Select;
247 break;
248 case 'd':
249 op = KTO_Display;
250 break;
251 case 'D':
252 op = KTO_DeleteCert;
253 break;
254 default:
255 usage(argv);
256 }
257
258 extern int optind;
259 extern char *optarg;
260 int arg;
261 int ourRtn = 0;
262 KrbToolArgs args;
263 bool doLoop = false;
264
265 memset(&args, 0, sizeof(args));
266 optind = 2;
267 while ((arg = getopt(argc, argv, "p:lh")) != -1) {
268 switch (arg) {
269 case 'p':
270 args.principal = optarg;
271 break;
272 case 'l':
273 doLoop = true;
274 break;
275 case 'h':
276 default:
277 usage(argv);
278 }
279 }
280
281 do {
282 switch(op) {
283 case KTO_Login:
284 ourRtn = pkinitLogin(&args);
285 break;
286 case KTO_Select:
287 ourRtn = pkinitSelect(&args);
288 break;
289 case KTO_Display:
290 ourRtn = pkinitDisplay(&args);
291 break;
292 case KTO_DeleteCert:
293 ourRtn = pkinitDeleteCert(&args);
294 break;
295 default:
296 printf("***BRRZAP! Internal error.\n");
297 exit(1);
298 }
299 if(doLoop) {
300 char resp;
301
302 fpurge(stdin);
303 printf("q to quit, anything else to loop: ");
304 resp = getchar();
305 if(resp == 'q') {
306 break;
307 }
308 }
309 } while(doLoop);
310 /* cleanup */
311 return ourRtn;
312
313 }