]> git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/kcTool/kcTool.cpp
Security-57337.20.44.tar.gz
[apple/security.git] / SecurityTests / clxutils / kcTool / kcTool.cpp
1 #include <Security/SecKeychainItem.h>
2 #include <Security/SecKeychain.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <strings.h>
6 #include <sys/param.h>
7
8 #define KC_DB_PATH "Library/Keychains" /* relative to home */
9
10 static void usage(char **argv)
11 {
12 printf("usage: %s keychainName command [options]\n", argv[0]);
13 printf("Commands:\n");
14 printf(" c create\n");
15 printf(" s get status\n");
16 printf(" l lock\n");
17 printf(" u unlock\n");
18 printf(" a add genericPassword\n");
19 printf(" g get (lookup) genericPassword\n");
20 printf(" d delete genericPassword\n");
21 printf("Options:\n");
22 printf(" p=keychainPassword\n");
23 printf(" g=genericPassword\n");
24 printf("Options (for create only):\n");
25 printf(" l=lockIntervalInSeconds\n");
26 printf(" L (no lockOnSleep)\n");
27 printf(" n(o user prompt)\n");
28 printf(" h(elp)\n");
29 exit(1);
30 }
31
32 /*
33 * For add/search generic password
34 */
35 #define GP_SERVICE_NAME "kctool"
36 #define GP_SERVICE_NAME_LEN ((UInt32)strlen(GP_SERVICE_NAME))
37 #define GP_ACCOUNT_NAME "John Galt"
38 #define GP_ACCOUNT_NAME_LEN ((UInt32)strlen(GP_ACCOUNT_NAME))
39
40 typedef enum {
41 KC_Nop,
42 KC_CreateKC,
43 KC_GetStatus,
44 KC_LockKC,
45 KC_UnlockKC,
46 KC_AddPasswd,
47 KC_LookupPasswd,
48 KC_DeletePasswd
49 } KcOp;
50
51 static void showError(
52 OSStatus ortn,
53 const char *msg)
54 {
55 printf("***Error %d on %s.\n", (int)ortn, msg);
56 }
57
58 static void safePrint(
59 char *buf,
60 UInt32 len)
61 {
62 UInt32 i;
63 char c;
64
65 for(i=0; i<len; i++) {
66 c = *buf++;
67 if(c == '\0') {
68 break;
69 }
70 putchar(c);
71 }
72 }
73
74 int main(int argc, char **argv)
75 {
76 SecKeychainRef kcRef = nil;
77 char kcPath[MAXPATHLEN + 1];
78 OSStatus ortn;
79 int arg;
80 char *argp;
81
82 /* command line arguments */
83 KcOp op = KC_Nop;
84 char *kcPwd = NULL;
85 UInt32 kcPwdLen = 0;
86 char *genericPwd = NULL;
87 UInt32 genericPwdLen = 0;
88 int lockInterval = 0;
89 Boolean noLockOnSleep = false;
90 Boolean userPrompt = true;
91
92 if(argc < 3) {
93 usage(argv);
94 }
95
96 switch(argv[2][0]) {
97 case 'c':
98 op = KC_CreateKC;
99 break;
100 case 's':
101 op = KC_GetStatus;
102 break;
103 case 'l':
104 op = KC_LockKC;
105 break;
106 case 'u':
107 op = KC_UnlockKC;
108 break;
109 case 'a':
110 op = KC_AddPasswd;
111 break;
112 case 'g':
113 op = KC_LookupPasswd;
114 break;
115 case 'd':
116 op = KC_DeletePasswd;
117 break;
118 default:
119 usage(argv);
120 }
121 for(arg=3; arg<argc; arg++) {
122 argp = argv[arg];
123 switch(argp[0]) {
124 case 'p':
125 kcPwd = &argp[2];
126 kcPwdLen = strlen(kcPwd);
127 break;
128 case 'g':
129 genericPwd = &argp[2];
130 genericPwdLen = strlen(genericPwd);
131 break;
132 case 'l':
133 lockInterval = atoi(&argp[2]);
134 break;
135 case 'L':
136 noLockOnSleep = true;
137 break;
138 case 'n':
139 userPrompt = false;
140 break;
141 default:
142 usage(argv);
143 }
144 }
145 /* cook up KC path */
146 if(argv[1][0] == '/') {
147 /* absolute path already given */
148 strcpy(kcPath, argv[1]);
149 }
150 else {
151 char *userHome = getenv("HOME");
152 if(userHome == NULL) {
153 /* well, this is probably not going to work */
154 userHome = (char *)"";
155 }
156 sprintf(kcPath, "%s/%s/%s", userHome, KC_DB_PATH, argv[1]);
157 }
158
159 /* all commands except KC_CreateKC: open specified keychain */
160 if(op != KC_CreateKC) {
161 ortn = SecKeychainOpen(kcPath, &kcRef);
162 if(ortn) {
163 showError(ortn, "SecKeychainOpen");
164 printf("Cannot open keychain at %s. Aborting.\n", kcPath);
165 exit(1);
166 }
167 }
168
169 /* execute */
170 switch(op) {
171 case KC_CreateKC:
172 {
173 ortn = SecKeychainCreate(kcPath,
174 kcPwdLen, // may be 0
175 kcPwd, // may be NULL
176 userPrompt,
177 nil, // initialAccess
178 &kcRef);
179 if(ortn) {
180 showError(ortn, "SecKeychainCreateNew");
181 exit(1);
182 }
183 else {
184 printf("...keychain %s created.\n", argv[1]);
185 }
186 break;
187 }
188 case KC_GetStatus:
189 {
190 SecKeychainStatus kcStat;
191 ortn = SecKeychainGetStatus(kcRef, &kcStat);
192 if(ortn) {
193 showError(ortn, "SecKeychainGetStatus");
194 exit(1);
195 }
196 printf("...SecKeychainStatus = %u ( ", (unsigned)kcStat);
197 if(kcStat & kSecUnlockStateStatus) {
198 printf("UnlockState ");
199 }
200 if(kcStat & kSecReadPermStatus) {
201 printf("RdPerm ");
202 }
203 if(kcStat & kSecWritePermStatus) {
204 printf("WrPerm ");
205 }
206 printf(")\n");
207 break;
208 }
209 case KC_LockKC:
210 {
211 ortn = SecKeychainLock(kcRef);
212 if(ortn) {
213 showError(ortn, "SecKeychainLock");
214 exit(1);
215 }
216 else {
217 printf("...keychain %s locked.\n", argv[1]);
218 }
219 break;
220 }
221 case KC_UnlockKC:
222 {
223 ortn = SecKeychainUnlock(kcRef,
224 kcPwdLen,
225 kcPwd,
226 kcPwd ? true : false);
227 if(ortn) {
228 showError(ortn, "SecKeychainUnlock");
229 exit(1);
230 }
231 else {
232 printf("...keychain %s unlocked.\n", argv[1]);
233 }
234 break;
235 }
236 case KC_AddPasswd:
237 {
238 SecKeychainItemRef itemRef = nil;
239 if(genericPwd == NULL) {
240 printf("***Must supply a genericPassword argument.\n");
241 exit(1);
242 }
243 ortn = SecKeychainAddGenericPassword(kcRef,
244 GP_SERVICE_NAME_LEN, GP_SERVICE_NAME,
245 GP_ACCOUNT_NAME_LEN, GP_ACCOUNT_NAME,
246 genericPwdLen, genericPwd,
247 &itemRef);
248 if(ortn) {
249 showError(ortn, "SecKeychainAddGenericPassword");
250 exit(1);
251 }
252 else {
253 printf("...password added to keychain %s.\n", argv[1]);
254 }
255 break;
256 }
257 case KC_LookupPasswd:
258 case KC_DeletePasswd:
259 {
260 char *foundPassword;
261 UInt32 pwdLen;
262 SecKeychainItemRef itemRef = nil;
263 ortn = SecKeychainFindGenericPassword(kcRef,
264 GP_SERVICE_NAME_LEN, GP_SERVICE_NAME,
265 GP_ACCOUNT_NAME_LEN, GP_ACCOUNT_NAME,
266 &pwdLen, (void **)&foundPassword,
267 &itemRef);
268 if(ortn) {
269 showError(ortn, "SecKeychainFindGenericPassword");
270 exit(1);
271 }
272 else if(op == KC_DeletePasswd) {
273 /* found it, now delete it */
274 ortn = SecKeychainItemDelete(itemRef);
275 if(ortn) {
276 showError(ortn, "SecKeychainItemDelete");
277 exit(1);
278 }
279 else {
280 printf("...generic password deleted.\n");
281 }
282 }
283 else {
284 printf("...password found: ");
285 safePrint(foundPassword, pwdLen);
286 printf("\n");
287 }
288 break;
289 }
290 default:
291 usage(argv);
292 }
293 /* CLEANUP */
294 return 0;
295 }
296
297