]> git.saurik.com Git - apple/security.git/blob - sec/Security/Tool/add_internet_password.c
Security-55471.14.18.tar.gz
[apple/security.git] / sec / Security / Tool / add_internet_password.c
1 //
2 // add_internet_password.c
3 // sec
4 //
5 // Created by Mitch Adler on 1/9/13.
6 //
7 //
8
9 #include <string.h>
10 #include <getopt.h>
11 #include <stdlib.h>
12
13 #include <Security/SecItem.h>
14 #include <CoreFoundation/CFString.h>
15 #include <CoreFoundation/CFNumber.h>
16
17 #include <SecurityTool/tool_errors.h>
18
19 #include "SecurityCommands.h"
20
21 typedef uint32_t SecProtocolType;
22 typedef uint32_t SecAuthenticationType;
23
24 static int
25 do_addinternetpassword(const char *keychainName, const char *serverName,
26 const char *securityDomain, const char *accountName, const char *path,
27 UInt16 port, SecProtocolType protocol,
28 SecAuthenticationType authenticationType, const void *passwordData)
29 {
30 OSStatus result;
31 CFDictionaryRef attributes = NULL;
32 const void *keys[9], *values[9];
33 CFIndex ix = 0;
34
35 keys[ix] = kSecClass;
36 values[ix++] = kSecClassInternetPassword;
37
38 if (serverName) {
39 keys[ix] = kSecAttrServer;
40 values[ix++] = CFStringCreateWithCStringNoCopy(NULL, serverName,
41 kCFStringEncodingUTF8, kCFAllocatorNull);
42 }
43 if (securityDomain) {
44 keys[ix] = kSecAttrSecurityDomain;
45 values[ix++] = CFStringCreateWithCStringNoCopy(NULL, securityDomain,
46 kCFStringEncodingUTF8, kCFAllocatorNull);
47 }
48 if (accountName) {
49 keys[ix] = kSecAttrAccount;
50 values[ix++] = CFStringCreateWithCStringNoCopy(NULL, accountName,
51 kCFStringEncodingUTF8, kCFAllocatorNull);
52 }
53 if (path) {
54 keys[ix] = kSecAttrPath;
55 values[ix++] = CFStringCreateWithCStringNoCopy(NULL, path,
56 kCFStringEncodingUTF8, kCFAllocatorNull);
57 }
58 keys[ix] = kSecAttrPort;
59 values[ix++] = CFNumberCreate(NULL, kCFNumberSInt16Type, &port);
60 /* Protocol is a 4 char code, perhaps we should use a string rep instead. */
61 keys[ix] = kSecAttrProtocol;
62 values[ix++] = CFNumberCreate(NULL, kCFNumberSInt32Type, &protocol);
63 keys[ix] = kSecAttrAuthenticationType;
64 values[ix++] = CFNumberCreate(NULL, kCFNumberSInt32Type, &authenticationType);
65
66 if (passwordData)
67 {
68 keys[ix] = kSecValueData;
69 values[ix++] = CFDataCreateWithBytesNoCopy(NULL, passwordData,
70 strlen(passwordData), kCFAllocatorNull);
71 }
72
73 attributes = CFDictionaryCreate(NULL, keys, values, ix,
74 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
75
76 /* Release the values we just added to the dictionary. */
77 /* @@@ For performance reasons we could choose to make the dictionaries
78 CFRetain callback a no op and let the dictionary deal with the
79 releasing. */
80 for (; ix-- > 0;)
81 CFRelease(values[ix]);
82
83 result = SecItemAdd(attributes, NULL);
84
85 if (attributes)
86 CFRelease(attributes);
87
88 if (result)
89 {
90 sec_perror("SecItemAdd", result);
91 }
92
93 return result;
94 }
95
96
97 int keychain_add_internet_password(int argc, char * const *argv)
98 {
99 char *serverName = NULL, *securityDomain = NULL, *accountName = NULL, *path = NULL, *passwordData = NULL;
100 UInt16 port = 0;
101 SecProtocolType protocol = 0;
102 SecAuthenticationType authenticationType = 0;
103 int ch, result = 0;
104 const char *keychainName = NULL;
105 /*
106 -s Use servername\n"
107 " -e Use securitydomain\n"
108 " -a Use accountname\n"
109 " -p Use path\n"
110 " -o Use port \n"
111 " -r Use protocol \n"
112 " -c Use SecAuthenticationType \n"
113 " -w Use passwordData \n"
114 */
115 while ((ch = getopt(argc, argv, "s:d:a:p:P:r:t:w:h")) != -1)
116 {
117 switch (ch)
118 {
119 case 's':
120 serverName = optarg;
121 break;
122 case 'd':
123 securityDomain = optarg;
124 break;
125 case 'a':
126 accountName = optarg;
127 break;
128 case 'p':
129 path = optarg;
130 break;
131 case 'P':
132 port = atoi(optarg);
133 break;
134 case 'r':
135 memcpy(&protocol,optarg,4);
136 //protocol = (SecProtocolType)optarg;
137 break;
138 case 't':
139 memcpy(&authenticationType,optarg,4);
140 break;
141 case 'w':
142 passwordData = optarg;
143 break;
144 case '?':
145 default:
146 return 2; /* @@@ Return 2 triggers usage message. */
147 }
148 }
149
150 argc -= optind;
151 argv += optind;
152
153 if (argc == 1)
154 {
155 keychainName = argv[0];
156 if (*keychainName == '\0')
157 {
158 result = 2;
159 goto loser;
160 }
161 }
162 else if (argc != 0)
163 return 2;
164
165 result = do_addinternetpassword(keychainName, serverName, securityDomain,
166 accountName, path, port, protocol,authenticationType, passwordData);
167
168 loser:
169 return result;
170 }