2 * Copyright (c) 2013-2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
29 #include <Security/SecItem.h>
30 #include <CoreFoundation/CFString.h>
31 #include <CoreFoundation/CFNumber.h>
33 #include "SecurityTool/sharedTool/tool_errors.h"
35 #include "SecurityCommands.h"
37 typedef uint32_t SecProtocolType
;
38 typedef uint32_t SecAuthenticationType
;
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
)
47 CFDictionaryRef attributes
= NULL
;
48 const void *keys
[9], *values
[9];
52 values
[ix
++] = kSecClassInternetPassword
;
55 keys
[ix
] = kSecAttrServer
;
56 values
[ix
++] = CFStringCreateWithCStringNoCopy(NULL
, serverName
,
57 kCFStringEncodingUTF8
, kCFAllocatorNull
);
60 keys
[ix
] = kSecAttrSecurityDomain
;
61 values
[ix
++] = CFStringCreateWithCStringNoCopy(NULL
, securityDomain
,
62 kCFStringEncodingUTF8
, kCFAllocatorNull
);
65 keys
[ix
] = kSecAttrAccount
;
66 values
[ix
++] = CFStringCreateWithCStringNoCopy(NULL
, accountName
,
67 kCFStringEncodingUTF8
, kCFAllocatorNull
);
70 keys
[ix
] = kSecAttrPath
;
71 values
[ix
++] = CFStringCreateWithCStringNoCopy(NULL
, path
,
72 kCFStringEncodingUTF8
, kCFAllocatorNull
);
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
);
84 keys
[ix
] = kSecValueData
;
85 values
[ix
++] = CFDataCreateWithBytesNoCopy(NULL
, passwordData
,
86 strlen(passwordData
), kCFAllocatorNull
);
89 attributes
= CFDictionaryCreate(NULL
, keys
, values
, ix
,
90 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
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
97 CFRelease(values
[ix
]);
100 result
= SecItemAdd(attributes
, NULL
);
103 CFRelease(attributes
);
108 sec_perror("SecItemAdd", result
);
115 int keychain_add_internet_password(int argc
, char * const *argv
)
117 char *serverName
= NULL
, *securityDomain
= NULL
, *accountName
= NULL
, *path
= NULL
, *passwordData
= NULL
;
119 SecProtocolType protocol
= 0;
120 SecAuthenticationType authenticationType
= 0;
122 const char *keychainName
= NULL
;
125 " -e Use securitydomain\n"
126 " -a Use accountname\n"
129 " -r Use protocol \n"
130 " -c Use SecAuthenticationType \n"
131 " -w Use passwordData \n"
133 while ((ch
= getopt(argc
, argv
, "s:d:a:p:P:r:t:w:h")) != -1)
141 securityDomain
= optarg
;
144 accountName
= optarg
;
153 memcpy(&protocol
,optarg
,4);
154 //protocol = (SecProtocolType)optarg;
157 memcpy(&authenticationType
,optarg
,4);
160 passwordData
= optarg
;
164 return SHOW_USAGE_MESSAGE
;
173 keychainName
= argv
[0];
174 if (*keychainName
== '\0')
181 return SHOW_USAGE_MESSAGE
;
183 result
= do_addinternetpassword(keychainName
, serverName
, securityDomain
,
184 accountName
, path
, port
, protocol
,authenticationType
, passwordData
);