]> git.saurik.com Git - apple/security.git/blob - OSX/sec/Security/Tool/add_internet_password.c
Security-57336.1.9.tar.gz
[apple/security.git] / OSX / sec / Security / Tool / 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/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 result = SecItemAdd(attributes, NULL);
100
101 if (attributes)
102 CFRelease(attributes);
103
104 if (result)
105 {
106 sec_perror("SecItemAdd", result);
107 }
108
109 return result;
110 }
111
112
113 int keychain_add_internet_password(int argc, char * const *argv)
114 {
115 char *serverName = NULL, *securityDomain = NULL, *accountName = NULL, *path = NULL, *passwordData = NULL;
116 UInt16 port = 0;
117 SecProtocolType protocol = 0;
118 SecAuthenticationType authenticationType = 0;
119 int ch, result = 0;
120 const char *keychainName = NULL;
121 /*
122 -s Use servername\n"
123 " -e Use securitydomain\n"
124 " -a Use accountname\n"
125 " -p Use path\n"
126 " -o Use port \n"
127 " -r Use protocol \n"
128 " -c Use SecAuthenticationType \n"
129 " -w Use passwordData \n"
130 */
131 while ((ch = getopt(argc, argv, "s:d:a:p:P:r:t:w:h")) != -1)
132 {
133 switch (ch)
134 {
135 case 's':
136 serverName = optarg;
137 break;
138 case 'd':
139 securityDomain = optarg;
140 break;
141 case 'a':
142 accountName = optarg;
143 break;
144 case 'p':
145 path = optarg;
146 break;
147 case 'P':
148 port = atoi(optarg);
149 break;
150 case 'r':
151 memcpy(&protocol,optarg,4);
152 //protocol = (SecProtocolType)optarg;
153 break;
154 case 't':
155 memcpy(&authenticationType,optarg,4);
156 break;
157 case 'w':
158 passwordData = optarg;
159 break;
160 case '?':
161 default:
162 return 2; /* @@@ Return 2 triggers usage message. */
163 }
164 }
165
166 argc -= optind;
167 argv += optind;
168
169 if (argc == 1)
170 {
171 keychainName = argv[0];
172 if (*keychainName == '\0')
173 {
174 result = 2;
175 goto loser;
176 }
177 }
178 else if (argc != 0)
179 return 2;
180
181 result = do_addinternetpassword(keychainName, serverName, securityDomain,
182 accountName, path, port, protocol,authenticationType, passwordData);
183
184 loser:
185 return result;
186 }