2 // add_internet_password.c
5 // Created by Mitch Adler on 1/9/13.
13 #include <Security/SecItem.h>
14 #include <CoreFoundation/CFString.h>
15 #include <CoreFoundation/CFNumber.h>
17 #include <SecurityTool/tool_errors.h>
19 #include "SecurityCommands.h"
21 typedef uint32_t SecProtocolType
;
22 typedef uint32_t SecAuthenticationType
;
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
)
31 CFDictionaryRef attributes
= NULL
;
32 const void *keys
[9], *values
[9];
36 values
[ix
++] = kSecClassInternetPassword
;
39 keys
[ix
] = kSecAttrServer
;
40 values
[ix
++] = CFStringCreateWithCStringNoCopy(NULL
, serverName
,
41 kCFStringEncodingUTF8
, kCFAllocatorNull
);
44 keys
[ix
] = kSecAttrSecurityDomain
;
45 values
[ix
++] = CFStringCreateWithCStringNoCopy(NULL
, securityDomain
,
46 kCFStringEncodingUTF8
, kCFAllocatorNull
);
49 keys
[ix
] = kSecAttrAccount
;
50 values
[ix
++] = CFStringCreateWithCStringNoCopy(NULL
, accountName
,
51 kCFStringEncodingUTF8
, kCFAllocatorNull
);
54 keys
[ix
] = kSecAttrPath
;
55 values
[ix
++] = CFStringCreateWithCStringNoCopy(NULL
, path
,
56 kCFStringEncodingUTF8
, kCFAllocatorNull
);
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
);
68 keys
[ix
] = kSecValueData
;
69 values
[ix
++] = CFDataCreateWithBytesNoCopy(NULL
, passwordData
,
70 strlen(passwordData
), kCFAllocatorNull
);
73 attributes
= CFDictionaryCreate(NULL
, keys
, values
, ix
,
74 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
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
81 CFRelease(values
[ix
]);
83 result
= SecItemAdd(attributes
, NULL
);
86 CFRelease(attributes
);
90 sec_perror("SecItemAdd", result
);
97 int keychain_add_internet_password(int argc
, char * const *argv
)
99 char *serverName
= NULL
, *securityDomain
= NULL
, *accountName
= NULL
, *path
= NULL
, *passwordData
= NULL
;
101 SecProtocolType protocol
= 0;
102 SecAuthenticationType authenticationType
= 0;
104 const char *keychainName
= NULL
;
107 " -e Use securitydomain\n"
108 " -a Use accountname\n"
111 " -r Use protocol \n"
112 " -c Use SecAuthenticationType \n"
113 " -w Use passwordData \n"
115 while ((ch
= getopt(argc
, argv
, "s:d:a:p:P:r:t:w:h")) != -1)
123 securityDomain
= optarg
;
126 accountName
= optarg
;
135 memcpy(&protocol
,optarg
,4);
136 //protocol = (SecProtocolType)optarg;
139 memcpy(&authenticationType
,optarg
,4);
142 passwordData
= optarg
;
146 return 2; /* @@@ Return 2 triggers usage message. */
155 keychainName
= argv
[0];
156 if (*keychainName
== '\0')
165 result
= do_addinternetpassword(keychainName
, serverName
, securityDomain
,
166 accountName
, path
, port
, protocol
,authenticationType
, passwordData
);