/ SecurityTool / macOS / keychain_unlock.c
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  }