1 #include <Security/SecKeychainItem.h>
2 #include <Security/SecKeychain.h>
8 #define KC_DB_PATH "Library/Keychains" /* relative to home */
10 static void usage(char **argv
)
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");
17 printf(" u unlock\n");
18 printf(" a add genericPassword\n");
19 printf(" g get (lookup) genericPassword\n");
20 printf(" d delete genericPassword\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");
33 * For add/search generic password
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))
51 static void showError(
55 printf("***Error %d on %s.\n", (int)ortn
, msg
);
58 static void safePrint(
65 for(i
=0; i
<len
; i
++) {
74 int main(int argc
, char **argv
)
76 SecKeychainRef kcRef
= nil
;
77 char kcPath
[MAXPATHLEN
+ 1];
82 /* command line arguments */
86 char *genericPwd
= NULL
;
87 UInt32 genericPwdLen
= 0;
89 Boolean noLockOnSleep
= false;
90 Boolean userPrompt
= true;
113 op
= KC_LookupPasswd
;
116 op
= KC_DeletePasswd
;
121 for(arg
=3; arg
<argc
; arg
++) {
126 kcPwdLen
= strlen(kcPwd
);
129 genericPwd
= &argp
[2];
130 genericPwdLen
= strlen(genericPwd
);
133 lockInterval
= atoi(&argp
[2]);
136 noLockOnSleep
= true;
145 /* cook up KC path */
146 if(argv
[1][0] == '/') {
147 /* absolute path already given */
148 strcpy(kcPath
, argv
[1]);
151 char *userHome
= getenv("HOME");
152 if(userHome
== NULL
) {
153 /* well, this is probably not going to work */
154 userHome
= (char *)"";
156 sprintf(kcPath
, "%s/%s/%s", userHome
, KC_DB_PATH
, argv
[1]);
159 /* all commands except KC_CreateKC: open specified keychain */
160 if(op
!= KC_CreateKC
) {
161 ortn
= SecKeychainOpen(kcPath
, &kcRef
);
163 showError(ortn
, "SecKeychainOpen");
164 printf("Cannot open keychain at %s. Aborting.\n", kcPath
);
173 ortn
= SecKeychainCreate(kcPath
,
174 kcPwdLen
, // may be 0
175 kcPwd
, // may be NULL
177 nil
, // initialAccess
180 showError(ortn
, "SecKeychainCreateNew");
184 printf("...keychain %s created.\n", argv
[1]);
190 SecKeychainStatus kcStat
;
191 ortn
= SecKeychainGetStatus(kcRef
, &kcStat
);
193 showError(ortn
, "SecKeychainGetStatus");
196 printf("...SecKeychainStatus = %u ( ", (unsigned)kcStat
);
197 if(kcStat
& kSecUnlockStateStatus
) {
198 printf("UnlockState ");
200 if(kcStat
& kSecReadPermStatus
) {
203 if(kcStat
& kSecWritePermStatus
) {
211 ortn
= SecKeychainLock(kcRef
);
213 showError(ortn
, "SecKeychainLock");
217 printf("...keychain %s locked.\n", argv
[1]);
223 ortn
= SecKeychainUnlock(kcRef
,
226 kcPwd
? true : false);
228 showError(ortn
, "SecKeychainUnlock");
232 printf("...keychain %s unlocked.\n", argv
[1]);
238 SecKeychainItemRef itemRef
= nil
;
239 if(genericPwd
== NULL
) {
240 printf("***Must supply a genericPassword argument.\n");
243 ortn
= SecKeychainAddGenericPassword(kcRef
,
244 GP_SERVICE_NAME_LEN
, GP_SERVICE_NAME
,
245 GP_ACCOUNT_NAME_LEN
, GP_ACCOUNT_NAME
,
246 genericPwdLen
, genericPwd
,
249 showError(ortn
, "SecKeychainAddGenericPassword");
253 printf("...password added to keychain %s.\n", argv
[1]);
257 case KC_LookupPasswd
:
258 case KC_DeletePasswd
:
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
,
269 showError(ortn
, "SecKeychainFindGenericPassword");
272 else if(op
== KC_DeletePasswd
) {
273 /* found it, now delete it */
274 ortn
= SecKeychainItemDelete(itemRef
);
276 showError(ortn
, "SecKeychainItemDelete");
280 printf("...generic password deleted.\n");
284 printf("...password found: ");
285 safePrint(foundPassword
, pwdLen
);