X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/c38e3ce98599a410a47dc10253faa4d5830f13b2..427c49bcad63d042b29ada2ac27e3dfc4845c779:/sec/Security/Tool/add_internet_password.c diff --git a/sec/Security/Tool/add_internet_password.c b/sec/Security/Tool/add_internet_password.c new file mode 100644 index 00000000..9c36c11b --- /dev/null +++ b/sec/Security/Tool/add_internet_password.c @@ -0,0 +1,170 @@ +// +// add_internet_password.c +// sec +// +// Created by Mitch Adler on 1/9/13. +// +// + +#include +#include +#include + +#include +#include +#include + +#include + +#include "SecurityCommands.h" + +typedef uint32_t SecProtocolType; +typedef uint32_t SecAuthenticationType; + +static int +do_addinternetpassword(const char *keychainName, const char *serverName, + const char *securityDomain, const char *accountName, const char *path, + UInt16 port, SecProtocolType protocol, + SecAuthenticationType authenticationType, const void *passwordData) +{ + OSStatus result; + CFDictionaryRef attributes = NULL; + const void *keys[9], *values[9]; + CFIndex ix = 0; + + keys[ix] = kSecClass; + values[ix++] = kSecClassInternetPassword; + + if (serverName) { + keys[ix] = kSecAttrServer; + values[ix++] = CFStringCreateWithCStringNoCopy(NULL, serverName, + kCFStringEncodingUTF8, kCFAllocatorNull); + } + if (securityDomain) { + keys[ix] = kSecAttrSecurityDomain; + values[ix++] = CFStringCreateWithCStringNoCopy(NULL, securityDomain, + kCFStringEncodingUTF8, kCFAllocatorNull); + } + if (accountName) { + keys[ix] = kSecAttrAccount; + values[ix++] = CFStringCreateWithCStringNoCopy(NULL, accountName, + kCFStringEncodingUTF8, kCFAllocatorNull); + } + if (path) { + keys[ix] = kSecAttrPath; + values[ix++] = CFStringCreateWithCStringNoCopy(NULL, path, + kCFStringEncodingUTF8, kCFAllocatorNull); + } + keys[ix] = kSecAttrPort; + values[ix++] = CFNumberCreate(NULL, kCFNumberSInt16Type, &port); + /* Protocol is a 4 char code, perhaps we should use a string rep instead. */ + keys[ix] = kSecAttrProtocol; + values[ix++] = CFNumberCreate(NULL, kCFNumberSInt32Type, &protocol); + keys[ix] = kSecAttrAuthenticationType; + values[ix++] = CFNumberCreate(NULL, kCFNumberSInt32Type, &authenticationType); + + if (passwordData) + { + keys[ix] = kSecValueData; + values[ix++] = CFDataCreateWithBytesNoCopy(NULL, passwordData, + strlen(passwordData), kCFAllocatorNull); + } + + attributes = CFDictionaryCreate(NULL, keys, values, ix, + &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + /* Release the values we just added to the dictionary. */ + /* @@@ For performance reasons we could choose to make the dictionaries + CFRetain callback a no op and let the dictionary deal with the + releasing. */ + for (; ix-- > 0;) + CFRelease(values[ix]); + + result = SecItemAdd(attributes, NULL); + + if (attributes) + CFRelease(attributes); + + if (result) + { + sec_perror("SecItemAdd", result); + } + + return result; +} + + +int keychain_add_internet_password(int argc, char * const *argv) +{ + char *serverName = NULL, *securityDomain = NULL, *accountName = NULL, *path = NULL, *passwordData = NULL; + UInt16 port = 0; + SecProtocolType protocol = 0; + SecAuthenticationType authenticationType = 0; + int ch, result = 0; + const char *keychainName = NULL; + /* + -s Use servername\n" + " -e Use securitydomain\n" + " -a Use accountname\n" + " -p Use path\n" + " -o Use port \n" + " -r Use protocol \n" + " -c Use SecAuthenticationType \n" + " -w Use passwordData \n" + */ + while ((ch = getopt(argc, argv, "s:d:a:p:P:r:t:w:h")) != -1) + { + switch (ch) + { + case 's': + serverName = optarg; + break; + case 'd': + securityDomain = optarg; + break; + case 'a': + accountName = optarg; + break; + case 'p': + path = optarg; + break; + case 'P': + port = atoi(optarg); + break; + case 'r': + memcpy(&protocol,optarg,4); + //protocol = (SecProtocolType)optarg; + break; + case 't': + memcpy(&authenticationType,optarg,4); + break; + case 'w': + passwordData = optarg; + break; + case '?': + default: + return 2; /* @@@ Return 2 triggers usage message. */ + } + } + + argc -= optind; + argv += optind; + + if (argc == 1) + { + keychainName = argv[0]; + if (*keychainName == '\0') + { + result = 2; + goto loser; + } + } + else if (argc != 0) + return 2; + + result = do_addinternetpassword(keychainName, serverName, securityDomain, + accountName, path, port, protocol,authenticationType, passwordData); + +loser: + return result; +}