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