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/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
]);
99 result
= SecItemAdd(attributes
, NULL
);
102 CFRelease(attributes
);
106 sec_perror("SecItemAdd", result
);
113 int keychain_add_internet_password(int argc
, char * const *argv
)
115 char *serverName
= NULL
, *securityDomain
= NULL
, *accountName
= NULL
, *path
= NULL
, *passwordData
= NULL
;
117 SecProtocolType protocol
= 0;
118 SecAuthenticationType authenticationType
= 0;
120 const char *keychainName
= NULL
;
123 " -e Use securitydomain\n"
124 " -a Use accountname\n"
127 " -r Use protocol \n"
128 " -c Use SecAuthenticationType \n"
129 " -w Use passwordData \n"
131 while ((ch
= getopt(argc
, argv
, "s:d:a:p:P:r:t:w:h")) != -1)
139 securityDomain
= optarg
;
142 accountName
= optarg
;
151 memcpy(&protocol
,optarg
,4);
152 //protocol = (SecProtocolType)optarg;
155 memcpy(&authenticationType
,optarg
,4);
158 passwordData
= optarg
;
162 return SHOW_USAGE_MESSAGE
;
171 keychainName
= argv
[0];
172 if (*keychainName
== '\0')
179 return SHOW_USAGE_MESSAGE
;
181 result
= do_addinternetpassword(keychainName
, serverName
, securityDomain
,
182 accountName
, path
, port
, protocol
,authenticationType
, passwordData
);