#include "keychain_unlock.h"
#include "readline_cssm.h"
#include "keychain_utilities.h"
#include "security_tool.h"
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static int
do_unlock(const char *keychainName, char *password, Boolean use_password)
{
SecKeychainRef keychain = NULL;
OSStatus result;
if (keychainName)
{
keychain = keychain_open(keychainName);
if (!keychain)
{
result = 1;
goto loser;
}
}
result = SecKeychainUnlock(keychain, password ? (UInt32) strlen(password) : 0, password, use_password);
if (result)
{
sec_error("SecKeychainUnlock %s: %s", keychainName ? keychainName : "<NULL>", sec_errstr(result));
}
loser:
if (keychain)
CFRelease(keychain);
return result;
}
int
keychain_unlock(int argc, char * const *argv)
{
int zero_password = 0;
char *password = NULL;
int ch, result = 0;
Boolean use_password = TRUE;
const char *keychainName = NULL;
while ((ch = getopt(argc, argv, "hp:u")) != -1)
{
switch (ch)
{
case 'p':
password = optarg;
break;
case 'u':
use_password = FALSE;
break;
case '?':
default:
return SHOW_USAGE_MESSAGE;
}
}
argc -= optind;
argv += optind;
if (argc == 1)
{
keychainName = argv[0];
if (*keychainName == '\0')
{
result = 2;
goto loser;
}
}
else if (argc != 0)
return SHOW_USAGE_MESSAGE;
if (!password && use_password)
{
password = prompt_password(keychainName);
if (!password)
{
result = -1;
goto loser;
}
zero_password = 1;
}
result = do_unlock(keychainName, password, use_password);
if (result)
goto loser;
loser:
if (zero_password)
memset(password, 0, strlen(password));
return result;
}