1/* 2 * Copyright (c) 2003-2004 Apple Computer, 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.h" 28#include "keychain_utilities.h" 29#include "security.h" 30 31#include <pwd.h> 32#include <stdio.h> 33#include <stdlib.h> 34#include <string.h> 35#include <unistd.h> 36 37static int 38do_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 ? strlen(password) : 0, password, use_password); 54 if (result) 55 { 56 sec_error("SecKeychainUnlock %s: %s", keychainName ? keychainName : "<NULL>", sec_errstr(result)); 57 } 58 59loser: 60 if (keychain) 61 CFRelease(keychain); 62 63 return result; 64} 65 66int 67keychain_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 2; /* @@@ Return 2 triggers 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 2; 105 106 if (!password && use_password) 107 { 108 const char *fmt = "password to unlock %s: "; 109 const char *name = keychainName ? keychainName : "default"; 110 char *prompt = malloc(strlen(fmt) + strlen(name)); 111 sprintf(prompt, fmt, name); 112 password = getpass(prompt); 113 free(prompt); 114 if (!password) 115 { 116 result = -1; 117 goto loser; 118 } 119 zero_password = 1; 120 } 121 122 result = do_unlock(keychainName, password, use_password); 123 if (result) 124 goto loser; 125 126loser: 127 if (zero_password) 128 memset(password, 0, strlen(password)); 129 130 return result; 131} 132