keychain_unlock.c
1 /* 2 * Copyright (c) 2003-2004,2012,2014 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 * keychain_unlock.c 24 */ 25 26 #include "keychain_unlock.h" 27 #include "readline_cssm.h" 28 #include "keychain_utilities.h" 29 #include "security_tool.h" 30 31 #include <pwd.h> 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <string.h> 35 #include <unistd.h> 36 37 static int 38 do_unlock(const char *keychainName, char *password, Boolean use_password) 39 { 40 SecKeychainRef keychain = NULL; 41 OSStatus result; 42 43 if (keychainName) 44 { 45 keychain = keychain_open(keychainName); 46 if (!keychain) 47 { 48 result = 1; 49 goto loser; 50 } 51 } 52 53 result = SecKeychainUnlock(keychain, password ? (UInt32) strlen(password) : 0, password, use_password); 54 if (result) 55 { 56 sec_error("SecKeychainUnlock %s: %s", keychainName ? keychainName : "<NULL>", sec_errstr(result)); 57 } 58 59 loser: 60 if (keychain) 61 CFRelease(keychain); 62 63 return result; 64 } 65 66 int 67 keychain_unlock(int argc, char * const *argv) 68 { 69 int zero_password = 0; 70 char *password = NULL; 71 int ch, result = 0; 72 Boolean use_password = TRUE; 73 const char *keychainName = NULL; 74 75 while ((ch = getopt(argc, argv, "hp:u")) != -1) 76 { 77 switch (ch) 78 { 79 case 'p': 80 password = optarg; 81 break; 82 case 'u': 83 use_password = FALSE; 84 break; 85 case '?': 86 default: 87 return SHOW_USAGE_MESSAGE; 88 } 89 } 90 91 argc -= optind; 92 argv += optind; 93 94 if (argc == 1) 95 { 96 keychainName = argv[0]; 97 if (*keychainName == '\0') 98 { 99 result = 2; 100 goto loser; 101 } 102 } 103 else if (argc != 0) 104 return SHOW_USAGE_MESSAGE; 105 106 if (!password && use_password) 107 { 108 password = prompt_password(keychainName); 109 if (!password) 110 { 111 result = -1; 112 goto loser; 113 } 114 zero_password = 1; 115 } 116 117 result = do_unlock(keychainName, password, use_password); 118 if (result) 119 goto loser; 120 121 loser: 122 if (zero_password) 123 memset(password, 0, strlen(password)); 124 125 return result; 126 }