2 * Copyright (c) 2003-2009,2012,2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
23 * keychain_set_settings.c
26 #include "keychain_set_settings.h"
27 #include "keychain_utilities.h"
36 #include <Security/SecKeychain.h>
37 #include <Security/SecKeychainPriv.h>
39 #define PW_BUF_SIZE 512 /* size of buffer to alloc for password */
43 do_keychain_set_settings(const char *keychainName
, SecKeychainSettings newKeychainSettings
)
45 SecKeychainRef keychain
= NULL
;
50 keychain
= keychain_open(keychainName
);
57 result
= SecKeychainSetSettings(keychain
, &newKeychainSettings
);
60 sec_error("SecKeychainSetSettings %s: %s", keychainName
? keychainName
: "<NULL>", sec_errstr(result
));
72 do_keychain_set_password(const char *keychainName
, const char* oldPassword
, const char* newPassword
)
74 SecKeychainRef keychain
= NULL
;
76 UInt32 oldLen
= (oldPassword
) ? strlen(oldPassword
) : 0;
77 UInt32 newLen
= (newPassword
) ? strlen(newPassword
) : 0;
78 char *oldPass
= (oldPassword
) ? (char*)oldPassword
: NULL
;
79 char *newPass
= (newPassword
) ? (char*)newPassword
: NULL
;
85 keychain
= keychain_open(keychainName
);
94 /* prompt for old password */
95 char *pBuf
= getpass("Old Password: ");
97 oldBuf
= (char*) calloc(PW_BUF_SIZE
, 1);
98 oldLen
= strlen(pBuf
);
99 memcpy(oldBuf
, pBuf
, oldLen
);
106 /* prompt for new password */
107 char *pBuf
= getpass("New Password: ");
109 newBuf
= (char*) calloc(PW_BUF_SIZE
, 1);
110 newLen
= strlen(pBuf
);
111 memcpy(newBuf
, pBuf
, newLen
);
114 /* confirm new password */
115 pBuf
= getpass("Retype New Password: ");
117 UInt32 confirmLen
= strlen(pBuf
);
118 if (confirmLen
== newLen
&& newBuf
&&
119 !memcmp(pBuf
, newBuf
, newLen
)) {
122 bzero(pBuf
, confirmLen
);
126 if (!oldPass
|| !newPass
) {
127 sec_error("try again");
131 /* lock keychain first to remove existing credentials */
132 (void)SecKeychainLock(keychain
);
134 /* change the password */
135 result
= SecKeychainChangePassword(keychain
, oldLen
, oldPass
, newLen
, newPass
);
138 sec_error("error changing password for \"%s\": %s",
139 keychainName
? keychainName
: "<NULL>", sec_errstr(result
));
143 /* if we allocated password buffers, zero and free them */
145 bzero(oldBuf
, PW_BUF_SIZE
);
149 bzero(newBuf
, PW_BUF_SIZE
);
160 keychain_set_settings(int argc
, char * const *argv
)
162 char *keychainName
= NULL
;
164 SecKeychainSettings newKeychainSettings
=
165 { SEC_KEYCHAIN_SETTINGS_VERS1
, FALSE
, FALSE
, INT_MAX
};
167 while ((ch
= getopt(argc
, argv
, "hlt:u")) != -1)
172 newKeychainSettings
.lockOnSleep
= TRUE
;
175 newKeychainSettings
.lockInterval
= atoi(optarg
);
178 newKeychainSettings
.useLockInterval
= TRUE
;
182 result
= 2; /* @@@ Return 2 triggers usage message. */
187 if (newKeychainSettings
.lockInterval
!= INT_MAX
) {
188 // -t was specified, which implies -u
189 newKeychainSettings
.useLockInterval
= TRUE
;
191 // -t was unspecified, so revert to no timeout
192 newKeychainSettings
.useLockInterval
= FALSE
;
200 keychainName
= argv
[0];
201 if (*keychainName
== '\0')
213 result
= do_keychain_set_settings(keychainName
, newKeychainSettings
);
221 keychain_set_password(int argc
, char * const *argv
)
223 char *keychainName
= NULL
;
224 char *oldPassword
= NULL
;
225 char *newPassword
= NULL
;
228 while ((ch
= getopt(argc
, argv
, "ho:p:")) != -1)
233 oldPassword
= optarg
;
236 newPassword
= optarg
;
240 result
= 2; /* @@@ Return 2 triggers usage message. */
250 keychainName
= argv
[0];
251 if (*keychainName
== '\0')
263 result
= do_keychain_set_password(keychainName
, oldPassword
, newPassword
);