#define kim_os_preference_any_identity "KIM_IDENTITY_ANY"
+#pragma mark -
+
/* ------------------------------------------------------------------------ */
-static kim_error kim_os_preferences_cfstring_for_key (kim_preference_key in_key,
- CFStringRef *out_kim_string_key,
- CFStringRef *out_kll_string_key)
+static CFStringRef kim_os_preferences_cfstring_for_key (kim_preference_key in_key)
{
- kim_error err = KIM_NO_ERROR;
-
- if (!err && !out_kim_string_key) { err = check_error (KIM_NULL_PARAMETER_ERR); }
- if (!err && !out_kll_string_key) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+ if (in_key == kim_preference_key_options) {
+ return CFSTR ("CredentialOptions");
+
+ } else if (in_key == kim_preference_key_lifetime) {
+ return CFSTR ("CredentialLifetime");
+
+ } else if (in_key == kim_preference_key_renewable) {
+ return CFSTR ("RenewableCredentials");
+
+ } else if (in_key == kim_preference_key_renewal_lifetime) {
+ return CFSTR ("CredentialRenewalLifetime");
+
+ } else if (in_key == kim_preference_key_forwardable) {
+ return CFSTR ("ForwardableCredentials");
+
+ } else if (in_key == kim_preference_key_proxiable) {
+ return CFSTR ("ProxiableCredentials");
+
+ } else if (in_key == kim_preference_key_addressless) {
+ return CFSTR ("AddresslessCredentials");
+
+ } else if (in_key == kim_preference_key_remember_options) {
+ return CFSTR ("RememberCredentialAttributes");
+
+ } else if (in_key == kim_preference_key_client_identity) {
+ return CFSTR ("ClientIdentity");
+
+ } else if (in_key == kim_preference_key_remember_client_identity) {
+ return CFSTR ("RememberClientIdentity");
+
+ } else if (in_key == kim_preference_key_favorites) {
+ return CFSTR ("FavoriteIdentities");
+
+ } else if (in_key == kim_preference_key_minimum_lifetime) {
+ return CFSTR ("MinimumLifetime");
+
+ } else if (in_key == kim_preference_key_maximum_lifetime) {
+ return CFSTR ("MaximumLifetime");
+
+ } else if (in_key == kim_preference_key_minimum_renewal_lifetime) {
+ return CFSTR ("MinimumRenewalLifetime");
+
+ } else if (in_key == kim_preference_key_maximum_renewal_lifetime) {
+ return CFSTR ("MaximumRenewalLifetime");
+
+ }
- if (!err) {
- if (in_key == kim_preference_key_lifetime) {
- *out_kim_string_key = CFSTR ("CredentialLifetime");
- *out_kll_string_key = CFSTR ("KLDefaultTicketLifetime");
-
- } else if (in_key == kim_preference_key_renewable) {
- *out_kim_string_key = CFSTR ("RenewableCredentials");
- *out_kll_string_key = CFSTR ("KLGetRenewableTickets");
-
- } else if (in_key == kim_preference_key_renewal_lifetime) {
- *out_kim_string_key = CFSTR ("CredentialRenewalLifetime");
- *out_kll_string_key = CFSTR ("KLDefaultRenewableLifetime");
-
- } else if (in_key == kim_preference_key_forwardable) {
- *out_kim_string_key = CFSTR ("ForwardableCredentials");
- *out_kll_string_key = CFSTR ("KLDefaultForwardableTicket");
-
- } else if (in_key == kim_preference_key_proxiable) {
- *out_kim_string_key = CFSTR ("ProxiableCredentials");
- *out_kll_string_key = CFSTR ("KLGetProxiableTickets");
-
- } else if (in_key == kim_preference_key_addressless) {
- *out_kim_string_key = CFSTR ("AddresslessCredentials");
- *out_kll_string_key = CFSTR ("KLGetAddresslessTickets");
-
- } else if (in_key == kim_preference_key_remember_options) {
- *out_kim_string_key = CFSTR ("RememberCredentialAttributes");
- *out_kll_string_key = CFSTR ("KLRememberExtras");
-
- } else if (in_key == kim_preference_key_client_identity) {
- *out_kim_string_key = CFSTR ("ClientIdentity");
- *out_kll_string_key = CFSTR ("KLName");
-
- } else if (in_key == kim_preference_key_remember_client_identity) {
- *out_kim_string_key = CFSTR ("RememberClientIdentity");
- *out_kll_string_key = CFSTR ("KLRememberPrincipal");
-
- } else if (in_key == kim_preference_key_favorites) {
- *out_kim_string_key = CFSTR ("FavoriteIdentities");
- *out_kll_string_key = CFSTR ("KLFavoriteIdentities");
-
- } else if (in_key == kim_preference_key_minimum_lifetime) {
- *out_kim_string_key = CFSTR ("MinimumLifetime");
- *out_kll_string_key = CFSTR ("KLMinimumTicketLifetime");
-
- } else if (in_key == kim_preference_key_maximum_lifetime) {
- *out_kim_string_key = CFSTR ("MaximumLifetime");
- *out_kll_string_key = CFSTR ("KLMaximumTicketLifetime");
-
- } else if (in_key == kim_preference_key_minimum_renewal_lifetime) {
- *out_kim_string_key = CFSTR ("MinimumRenewalLifetime");
- *out_kll_string_key = CFSTR ("KLMinimumRenewableLifetime");
-
- } else if (in_key == kim_preference_key_maximum_renewal_lifetime) {
- *out_kim_string_key = CFSTR ("MaximumRenewalLifetime");
- *out_kll_string_key = CFSTR ("KLMaximumRenewableLifetime");
-
- } else {
- /* ignore unsupported keys */
- kim_debug_printf ("Unsupported preference key %d", in_key);
- *out_kim_string_key = NULL;
- *out_kll_string_key = NULL;
- }
+ return NULL; /* ignore unsupported keys */
+}
+
+/* ------------------------------------------------------------------------ */
+
+static CFStringRef kim_os_preferences_compat_cfstring_for_key (kim_preference_key in_key)
+{
+ if (in_key == kim_preference_key_lifetime) {
+ return CFSTR ("KLDefaultTicketLifetime");
+
+ } else if (in_key == kim_preference_key_renewable) {
+ return CFSTR ("KLGetRenewableTickets");
+
+ } else if (in_key == kim_preference_key_renewal_lifetime) {
+ return CFSTR ("KLDefaultRenewableLifetime");
+
+ } else if (in_key == kim_preference_key_forwardable) {
+ return CFSTR ("KLDefaultForwardableTicket");
+
+ } else if (in_key == kim_preference_key_proxiable) {
+ return CFSTR ("KLGetProxiableTickets");
+
+ } else if (in_key == kim_preference_key_addressless) {
+ return CFSTR ("KLGetAddresslessTickets");
+
+ } else if (in_key == kim_preference_key_remember_options) {
+ return CFSTR ("KLRememberExtras");
+
+ } else if (in_key == kim_preference_key_client_identity) {
+ return CFSTR ("KLName");
+
+ } else if (in_key == kim_preference_key_remember_client_identity) {
+ return CFSTR ("KLRememberPrincipal");
+
+ } else if (in_key == kim_preference_key_favorites) {
+ return CFSTR ("KLFavoriteIdentities");
+
+ } else if (in_key == kim_preference_key_minimum_lifetime) {
+ return CFSTR ("KLMinimumTicketLifetime");
+
+ } else if (in_key == kim_preference_key_maximum_lifetime) {
+ return CFSTR ("KLMaximumTicketLifetime");
+
+ } else if (in_key == kim_preference_key_minimum_renewal_lifetime) {
+ return CFSTR ("KLMinimumRenewableLifetime");
+
+ } else if (in_key == kim_preference_key_maximum_renewal_lifetime) {
+ return CFSTR ("KLMaximumRenewableLifetime");
+
}
- return check_error (err);
+ return NULL; /* ignore unsupported keys */
}
/* ------------------------------------------------------------------------ */
-static kim_error kim_os_preferences_get_value (kim_preference_key in_key,
- CFTypeID in_type,
- CFPropertyListRef *out_value)
+static kim_error kim_os_preferences_copy_value_for_file (CFStringRef in_key,
+ CFTypeID in_type,
+ CFStringRef in_file,
+ CFPropertyListRef *out_value)
{
kim_error err = KIM_NO_ERROR;
CFPropertyListRef value = NULL;
CFStringRef users[] = { kCFPreferencesCurrentUser, kCFPreferencesAnyUser, NULL };
- CFStringRef files[] = { KIM_PREFERENCES_FILE, KLL_PREFERENCES_FILE, NULL };
CFStringRef hosts[] = { kCFPreferencesCurrentHost, kCFPreferencesAnyHost, NULL };
- CFStringRef keys[] = { NULL, NULL, NULL };
+ if (!err && !in_key ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+ if (!err && !in_file ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
if (!err && !out_value) { err = check_error (KIM_NULL_PARAMETER_ERR); }
if (!err) {
- /* Index must correspond to the appropriate file */
- err = kim_os_preferences_cfstring_for_key (in_key, &keys[0], &keys[1]);
- }
-
- if (!err) {
- kim_count u, f, h;
+ kim_count u, h;
if (!kim_library_allow_home_directory_access()) {
users[0] = kCFPreferencesAnyUser;
}
for (u = 0; !value && users[u]; u++) {
- for (f = 0; !value && files[f] && keys[f]; f++) {
- for (h = 0; !value && hosts[h]; h++) {
- value = CFPreferencesCopyValue (keys[f], files[f], users[u], hosts[h]);
- }
+ for (h = 0; !value && hosts[h]; h++) {
+ value = CFPreferencesCopyValue (in_key, in_file, users[u], hosts[h]);
}
}
return check_error (err);
}
+#pragma mark -
+
+/* ------------------------------------------------------------------------ */
+
+static kim_error kim_os_preferences_copy_value (kim_preference_key in_key,
+ CFTypeID in_type,
+ CFPropertyListRef *out_value)
+{
+ kim_error err = KIM_NO_ERROR;
+ CFStringRef key = kim_os_preferences_cfstring_for_key (in_key);
+
+ err = kim_os_preferences_copy_value_for_file (key, in_type,
+ KIM_PREFERENCES_FILE,
+ out_value);
+
+ return check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static kim_error kim_os_preferences_copy_value_compat (kim_preference_key in_key,
+ CFTypeID in_type,
+ CFPropertyListRef *out_value)
+{
+ kim_error err = KIM_NO_ERROR;
+ CFStringRef key = kim_os_preferences_compat_cfstring_for_key (in_key);
+
+ err = kim_os_preferences_copy_value_for_file (key, in_type,
+ KLL_PREFERENCES_FILE,
+ out_value);
+
+ return check_error (err);
+}
+
/* ------------------------------------------------------------------------ */
static kim_error kim_os_preferences_set_value (kim_preference_key in_key,
- CFPropertyListRef in_value)
+ CFPropertyListRef in_value)
{
kim_error err = KIM_NO_ERROR;
- CFStringRef kim_key = NULL;
- CFStringRef kll_key = NULL;
+ CFStringRef key = NULL;
if (!err && !in_value) { err = check_error (KIM_NULL_PARAMETER_ERR); }
if (!err) {
- err = kim_os_preferences_cfstring_for_key (in_key, &kim_key, &kll_key);
+ key = kim_os_preferences_cfstring_for_key (in_key);
}
- if (!err && kim_key) {
+ if (!err && key) {
kim_boolean homedir_ok = kim_library_allow_home_directory_access();
CFStringRef user = homedir_ok ? kCFPreferencesCurrentUser : kCFPreferencesAnyUser;
CFStringRef host = homedir_ok ? kCFPreferencesAnyHost : kCFPreferencesCurrentHost;
- CFPreferencesSetValue (kim_key, in_value, KIM_PREFERENCES_FILE, user, host);
+ CFPreferencesSetValue (key, in_value, KIM_PREFERENCES_FILE, user, host);
if (!CFPreferencesSynchronize (KIM_PREFERENCES_FILE, user, host)) {
err = check_error (KIM_PREFERENCES_WRITE_ERR);
}
if (!err && !out_identity) { err = check_error (KIM_NULL_PARAMETER_ERR); }
if (!err) {
- err = kim_os_preferences_get_value (in_key, CFStringGetTypeID (),
- (CFPropertyListRef *) &value);
+ err = kim_os_preferences_copy_value (in_key, CFStringGetTypeID (),
+ (CFPropertyListRef *) &value);
+
+ }
+
+ if (!err && !value) {
+ err = kim_os_preferences_copy_value_compat (in_key, CFStringGetTypeID (),
+ (CFPropertyListRef *) &value);
}
if (!err) {
/* ------------------------------------------------------------------------ */
-kim_error kim_os_preferences_get_favorites_for_key (kim_preference_key in_key,
- kim_favorites io_favorites)
+kim_error kim_os_preferences_get_lifetime_for_key (kim_preference_key in_key,
+ kim_lifetime in_hardcoded_default,
+ kim_lifetime *out_lifetime)
{
kim_error err = KIM_NO_ERROR;
- CFArrayRef value = NULL;
+ CFNumberRef value = NULL;
- if (!err && !io_favorites) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+ if (!err && !out_lifetime) { err = check_error (KIM_NULL_PARAMETER_ERR); }
if (!err) {
- err = kim_os_preferences_get_value (in_key, CFArrayGetTypeID (),
- (CFPropertyListRef *) &value);
+ err = kim_os_preferences_copy_value (in_key, CFNumberGetTypeID (),
+ (CFPropertyListRef *) &value);
+ }
+
+ if (!err && !value) {
+ err = kim_os_preferences_copy_value_compat (in_key, CFNumberGetTypeID (),
+ (CFPropertyListRef *) &value);
}
if (!err) {
- if (!value || CFArrayGetCount (value) < 1) {
- err = kim_favorites_remove_all_identities (io_favorites);
-
- } else {
- CFIndex count = CFArrayGetCount (value);
- CFIndex i;
-
- for (i = 0; !err && i < count; i++) {
- CFStringRef cfstring = NULL;
- kim_string string = NULL;
- kim_identity identity = NULL;
-
- cfstring = (CFStringRef) CFArrayGetValueAtIndex (value, i);
- if (!cfstring || CFGetTypeID (cfstring) != CFStringGetTypeID ()) {
- err = check_error (KIM_PREFERENCES_READ_ERR);
- }
-
- if (!err) {
- err = kim_os_string_create_from_cfstring (&string, cfstring);
- }
-
- if (!err) {
- err = kim_identity_create_from_string (&identity, string);
- }
-
- if (!err) {
- err = kim_favorites_add_identity (io_favorites, identity,
- KIM_OPTIONS_DEFAULT);
- }
-
- kim_identity_free (&identity);
- kim_string_free (&string);
+ if (value) {
+ SInt32 number; // CFNumbers are signed so we need to cast
+ if (CFNumberGetValue (value, kCFNumberSInt32Type, &number) != TRUE) {
+ err = KIM_OUT_OF_MEMORY_ERR;
+ } else {
+ *out_lifetime = number;
}
+ } else {
+ *out_lifetime = in_hardcoded_default;
}
}
- if (err) {
- kim_favorites_remove_all_identities (io_favorites);
- }
-
if (value) { CFRelease (value); }
return check_error (err);
}
/* ------------------------------------------------------------------------ */
-kim_error kim_os_preferences_set_favorites_for_key (kim_preference_key in_key,
- kim_favorites in_favorites)
+
+kim_error kim_os_preferences_set_lifetime_for_key (kim_preference_key in_key,
+ kim_lifetime in_lifetime)
{
kim_error err = KIM_NO_ERROR;
- kim_count count = 0;
- CFMutableArrayRef value = NULL;
-
- if (!err && !in_favorites) { err = check_error (KIM_NULL_PARAMETER_ERR); }
-
- if (!err) {
- err = kim_favorites_get_number_of_identities (in_favorites, &count);
- }
+ CFNumberRef value = NULL;
+ SInt32 number = (SInt32) in_lifetime;
if (!err) {
- value = CFArrayCreateMutable (kCFAllocatorDefault, count,
- &kCFTypeArrayCallBacks);
+ value = CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt32Type, &number);
if (!value) { err = KIM_OUT_OF_MEMORY_ERR; }
}
- if (!err) {
- kim_count i;
-
- for (i = 0; !err && i < count; i++) {
- kim_identity identity = NULL;
- kim_options options = NULL;
- kim_string string = NULL;
- CFStringRef cfstring = NULL;
-
- err = kim_favorites_get_identity_at_index (in_favorites, i,
- &identity,
- &options);
-
- if (!err) {
- err = kim_identity_get_string (identity, &string);
- }
-
- if (!err) {
- err = kim_os_string_get_cfstring (string, &cfstring);
- }
-
- if (!err) {
- CFArrayAppendValue (value, cfstring);
- }
-
- if (cfstring) { CFRelease (cfstring); }
- kim_string_free (&string);
- kim_options_free (&options);
- kim_identity_free (&identity);
- }
- }
-
if (!err) {
err = kim_os_preferences_set_value (in_key, value);
}
/* ------------------------------------------------------------------------ */
-kim_error kim_os_preferences_get_time_for_key (kim_preference_key in_key,
- kim_time in_hardcoded_default,
- kim_time *out_time)
+kim_error kim_os_preferences_get_boolean_for_key (kim_preference_key in_key,
+ kim_boolean in_hardcoded_default,
+ kim_boolean *out_boolean)
{
kim_error err = KIM_NO_ERROR;
- CFNumberRef value = NULL;
+ CFBooleanRef value = NULL;
- if (!err && !out_time) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+ if (!err && !out_boolean) { err = check_error (KIM_NULL_PARAMETER_ERR); }
if (!err) {
- err = kim_os_preferences_get_value (in_key, CFNumberGetTypeID (),
- (CFPropertyListRef *) &value);
+ err = kim_os_preferences_copy_value (in_key, CFBooleanGetTypeID (),
+ (CFPropertyListRef *) &value);
+ }
+
+ if (!err && !value) {
+ err = kim_os_preferences_copy_value_compat (in_key, CFBooleanGetTypeID (),
+ (CFPropertyListRef *) &value);
}
if (!err) {
if (value) {
- SInt32 number; // CFNumbers are signed so we need to cast
- if (CFNumberGetValue (value, kCFNumberSInt32Type, &number) != TRUE) {
- err = KIM_OUT_OF_MEMORY_ERR;
- } else {
- *out_time = number;
- }
+ *out_boolean = CFBooleanGetValue (value);
} else {
- *out_time = in_hardcoded_default;
+ *out_boolean = in_hardcoded_default;
}
}
/* ------------------------------------------------------------------------ */
-kim_error kim_os_preferences_set_time_for_key (kim_preference_key in_key,
- kim_time in_time)
+kim_error kim_os_preferences_set_boolean_for_key (kim_preference_key in_key,
+ kim_boolean in_boolean)
{
kim_error err = KIM_NO_ERROR;
- CFNumberRef value = NULL;
- SInt32 number = (SInt32) in_time;
-
- if (!err) {
- value = CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt32Type, &number);
- if (!value) { err = KIM_OUT_OF_MEMORY_ERR; }
- }
+ CFBooleanRef value = in_boolean ? kCFBooleanTrue : kCFBooleanFalse;
if (!err) {
err = kim_os_preferences_set_value (in_key, value);
}
- if (value) { CFRelease (value); }
-
return check_error (err);
}
+#pragma mark -
+
/* ------------------------------------------------------------------------ */
-kim_error kim_os_preferences_get_lifetime_for_key (kim_preference_key in_key,
- kim_lifetime in_hardcoded_default,
- kim_lifetime *out_lifetime)
+static kim_error kim_os_preferences_copy_value_for_dict_key (CFDictionaryRef in_dictionary,
+ kim_preference_key in_key,
+ CFTypeID in_type,
+ CFPropertyListRef *out_value)
{
kim_error err = KIM_NO_ERROR;
- CFNumberRef value = NULL;
+ CFPropertyListRef value = NULL;
- if (!err && !out_lifetime) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+ if (!err && !in_dictionary) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+ if (!err && !out_value ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
if (!err) {
- err = kim_os_preferences_get_value (in_key, CFNumberGetTypeID (),
- (CFPropertyListRef *) &value);
+ CFStringRef key = kim_os_preferences_cfstring_for_key (in_key);
+
+ value = CFDictionaryGetValue (in_dictionary, key);
+ if (value && CFGetTypeID (value) != in_type) {
+ err = check_error (KIM_PREFERENCES_READ_ERR);
+ }
}
if (!err) {
- if (value) {
- SInt32 number; // CFNumbers are signed so we need to cast
- if (CFNumberGetValue (value, kCFNumberSInt32Type, &number) != TRUE) {
- err = KIM_OUT_OF_MEMORY_ERR;
- } else {
- *out_lifetime = number;
- }
- } else {
- *out_lifetime = in_hardcoded_default;
- }
+ *out_value = value;
}
- if (value) { CFRelease (value); }
-
return check_error (err);
}
/* ------------------------------------------------------------------------ */
-kim_error kim_os_preferences_set_lifetime_for_key (kim_preference_key in_key,
- kim_lifetime in_lifetime)
+static kim_error kim_os_preferences_set_value_for_dict_key (CFMutableDictionaryRef in_dictionary,
+ kim_preference_key in_key,
+ CFPropertyListRef in_value)
{
kim_error err = KIM_NO_ERROR;
- CFNumberRef value = NULL;
- SInt32 number = (SInt32) in_lifetime;
- if (!err) {
- value = CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt32Type, &number);
- if (!value) { err = KIM_OUT_OF_MEMORY_ERR; }
- }
+ if (!err && !in_dictionary) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+ if (!err && !in_value ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
if (!err) {
- err = kim_os_preferences_set_value (in_key, value);
+ CFStringRef key = kim_os_preferences_cfstring_for_key (in_key);
+
+ CFDictionarySetValue (in_dictionary, key, in_value);
}
- if (value) { CFRelease (value); }
-
return check_error (err);
}
/* ------------------------------------------------------------------------ */
-kim_error kim_os_preferences_get_boolean_for_key (kim_preference_key in_key,
- kim_boolean in_hardcoded_default,
- kim_boolean *out_boolean)
+static kim_error kim_os_preferences_dictionary_to_options (CFDictionaryRef in_dictionary,
+ kim_options *out_options)
{
kim_error err = KIM_NO_ERROR;
- CFBooleanRef value = NULL;
+ kim_options options = KIM_OPTIONS_DEFAULT;
+ kim_boolean found_options = 0;
- if (!err && !out_boolean) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+ if (!err && !in_dictionary) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+ if (!err && !out_options ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
if (!err) {
- err = kim_os_preferences_get_value (in_key, CFBooleanGetTypeID (),
- (CFPropertyListRef *) &value);
+ err = kim_options_create_empty (&options);
}
if (!err) {
- if (value) {
- *out_boolean = CFBooleanGetValue (value);
- } else {
- *out_boolean = in_hardcoded_default;
+ CFBooleanRef value = NULL;
+
+ err = kim_os_preferences_copy_value_for_dict_key (in_dictionary,
+ kim_preference_key_renewable,
+ CFBooleanGetTypeID (),
+ (CFPropertyListRef *) &value);
+
+ if (!err && value) {
+ found_options = 1;
+ err = kim_options_set_renewable (options, CFBooleanGetValue (value));
}
}
- if (value) { CFRelease (value); }
+ if (!err) {
+ CFNumberRef value = NULL;
+ SInt32 lifetime; // CFNumbers are signed so we need to cast
+
+ err = kim_os_preferences_copy_value_for_dict_key (in_dictionary,
+ kim_preference_key_lifetime,
+ CFNumberGetTypeID (),
+ (CFPropertyListRef *) &value);
+
+ if (!err && value && CFNumberGetValue (value, kCFNumberSInt32Type,
+ &lifetime)) {
+ found_options = 1;
+ err = kim_options_set_lifetime (options, lifetime);
+ }
+ }
- return check_error (err);
-}
+ if (!err) {
+ CFNumberRef value = NULL;
+ SInt32 lifetime; // CFNumbers are signed so we need to cast
+
+ err = kim_os_preferences_copy_value_for_dict_key (in_dictionary,
+ kim_preference_key_renewal_lifetime,
+ CFNumberGetTypeID (),
+ (CFPropertyListRef *) &value);
+
+ if (!err && value && CFNumberGetValue (value, kCFNumberSInt32Type,
+ &lifetime)) {
+ found_options = 1;
+ err = kim_options_set_renewal_lifetime (options, lifetime);
+ } }
+
+ if (!err) {
+ CFBooleanRef value = NULL;
+
+ err = kim_os_preferences_copy_value_for_dict_key (in_dictionary,
+ kim_preference_key_forwardable,
+ CFBooleanGetTypeID (),
+ (CFPropertyListRef *) &value);
+
+ if (!err && value) {
+ found_options = 1;
+ err = kim_options_set_forwardable (options, CFBooleanGetValue (value));
+ }
+ }
+
+ if (!err) {
+ CFBooleanRef value = NULL;
+
+ err = kim_os_preferences_copy_value_for_dict_key (in_dictionary,
+ kim_preference_key_proxiable,
+ CFBooleanGetTypeID (),
+ (CFPropertyListRef *) &value);
+
+ if (!err && value) {
+ found_options = 1;
+ err = kim_options_set_proxiable (options, CFBooleanGetValue (value));
+ }
+ }
+
+ if (!err) {
+ CFBooleanRef value = NULL;
+
+ err = kim_os_preferences_copy_value_for_dict_key (in_dictionary,
+ kim_preference_key_addressless,
+ CFBooleanGetTypeID (),
+ (CFPropertyListRef *) &value);
+
+ if (!err && value) {
+ found_options = 1;
+ err = kim_options_set_addressless (options, CFBooleanGetValue (value));
+ }
+ }
+
+ if (!err && !found_options) {
+ kim_options_free (&options);
+ options = KIM_OPTIONS_DEFAULT;
+ }
+
+ if (!err) {
+ *out_options = options;
+ options = NULL;
+ }
+
+ kim_options_free (&options);
+
+ return check_error (err);
+}
/* ------------------------------------------------------------------------ */
-kim_error kim_os_preferences_set_boolean_for_key (kim_preference_key in_key,
- kim_boolean in_boolean)
+static kim_error kim_os_preferences_options_to_dictionary (kim_options in_options,
+ CFMutableDictionaryRef io_dictionary)
{
kim_error err = KIM_NO_ERROR;
- CFBooleanRef value = in_boolean ? kCFBooleanTrue : kCFBooleanFalse;
+
+ if (!err && !in_options ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+ if (!err && !io_dictionary) { err = check_error (KIM_NULL_PARAMETER_ERR); }
if (!err) {
- err = kim_os_preferences_set_value (in_key, value);
+ CFNumberRef value = NULL;
+ kim_lifetime lifetime;
+
+ err = kim_options_get_lifetime (in_options, &lifetime);
+
+ if (!err) {
+ SInt32 number = (SInt32) lifetime;
+
+ value = CFNumberCreate (kCFAllocatorDefault,
+ kCFNumberSInt32Type, &number);
+ if (!value) { err = KIM_OUT_OF_MEMORY_ERR; }
+ }
+
+ if (!err) {
+ err = kim_os_preferences_set_value_for_dict_key (io_dictionary,
+ kim_preference_key_lifetime,
+ value);
+ }
+
+ if (value) { CFRelease (value); }
+ }
+
+ if (!err) {
+ kim_boolean boolean;
+
+ err = kim_options_get_renewable (in_options, &boolean);
+
+ if (!err) {
+ CFBooleanRef value = boolean ? kCFBooleanTrue : kCFBooleanFalse;
+
+ err = kim_os_preferences_set_value_for_dict_key (io_dictionary,
+ kim_preference_key_renewable,
+ value);
+ }
+ }
+
+ if (!err) {
+ CFNumberRef value = NULL;
+ kim_lifetime lifetime;
+
+ err = kim_options_get_renewal_lifetime (in_options, &lifetime);
+
+ if (!err) {
+ SInt32 number = (SInt32) lifetime;
+
+ value = CFNumberCreate (kCFAllocatorDefault,
+ kCFNumberSInt32Type, &number);
+ if (!value) { err = KIM_OUT_OF_MEMORY_ERR; }
+ }
+
+ if (!err) {
+ err = kim_os_preferences_set_value_for_dict_key (io_dictionary,
+ kim_preference_key_renewal_lifetime,
+ value);
+ }
+
+ if (value) { CFRelease (value); }
+ }
+
+ if (!err) {
+ kim_boolean boolean;
+
+ err = kim_options_get_forwardable (in_options, &boolean);
+
+ if (!err) {
+ CFBooleanRef value = boolean ? kCFBooleanTrue : kCFBooleanFalse;
+
+ err = kim_os_preferences_set_value_for_dict_key (io_dictionary,
+ kim_preference_key_forwardable,
+ value);
+ }
+ }
+
+ if (!err) {
+ kim_boolean boolean;
+
+ err = kim_options_get_proxiable (in_options, &boolean);
+
+ if (!err) {
+ CFBooleanRef value = boolean ? kCFBooleanTrue : kCFBooleanFalse;
+
+ err = kim_os_preferences_set_value_for_dict_key (io_dictionary,
+ kim_preference_key_proxiable,
+ value);
+ }
+ }
+
+ if (!err) {
+ kim_boolean boolean;
+
+ err = kim_options_get_addressless (in_options, &boolean);
+
+ if (!err) {
+ CFBooleanRef value = boolean ? kCFBooleanTrue : kCFBooleanFalse;
+
+ err = kim_os_preferences_set_value_for_dict_key (io_dictionary,
+ kim_preference_key_addressless,
+ value);
+ }
+ }
+
+ return check_error (err);
+}
+
+
+
+#pragma mark -
+
+/* ------------------------------------------------------------------------ */
+
+static kim_error kim_os_preferences_get_options_compat (kim_options *out_options)
+{
+ kim_error err = KIM_NO_ERROR;
+ kim_options options = KIM_OPTIONS_DEFAULT;
+ kim_boolean found_options = 0;
+
+ if (!err && !out_options) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+
+ if (!err) {
+ err = kim_options_create_empty (&options);
+ }
+
+ if (!err) {
+ CFNumberRef value = NULL;
+ SInt32 lifetime; // CFNumbers are signed so we need to cast
+
+ err = kim_os_preferences_copy_value_compat (kim_preference_key_lifetime,
+ CFNumberGetTypeID (),
+ (CFPropertyListRef *) &value);
+
+ if (!err && value && CFNumberGetValue (value, kCFNumberSInt32Type,
+ &lifetime)) {
+ found_options = 1;
+ err = kim_options_set_lifetime (options, lifetime);
+ }
+
+ if (value) { CFRelease (value); }
+ }
+
+ if (!err) {
+ CFBooleanRef value = NULL;
+
+ err = kim_os_preferences_copy_value_compat (kim_preference_key_renewable,
+ CFBooleanGetTypeID (),
+ (CFPropertyListRef *) &value);
+
+ if (!err && value) {
+ found_options = 1;
+ err = kim_options_set_renewable (options, CFBooleanGetValue (value));
+ }
+
+ if (value) { CFRelease (value); }
+ }
+
+ if (!err) {
+ CFNumberRef value = NULL;
+ SInt32 lifetime; // CFNumbers are signed so we need to cast
+
+ err = kim_os_preferences_copy_value_compat (kim_preference_key_renewal_lifetime,
+ CFNumberGetTypeID (),
+ (CFPropertyListRef *) &value);
+
+ if (!err && value && CFNumberGetValue (value, kCFNumberSInt32Type,
+ &lifetime)) {
+ found_options = 1;
+ err = kim_options_set_renewal_lifetime (options, lifetime);
+ }
+
+ if (value) { CFRelease (value); }
+ }
+
+ if (!err) {
+ CFBooleanRef value = NULL;
+
+ err = kim_os_preferences_copy_value_compat (kim_preference_key_forwardable,
+ CFBooleanGetTypeID (),
+ (CFPropertyListRef *) &value);
+
+ if (!err && value) {
+ found_options = 1;
+ err = kim_options_set_forwardable (options, CFBooleanGetValue (value));
+ }
+
+ if (value) { CFRelease (value); }
+ }
+
+ if (!err) {
+ CFBooleanRef value = NULL;
+
+ err = kim_os_preferences_copy_value_compat (kim_preference_key_proxiable,
+ CFBooleanGetTypeID (),
+ (CFPropertyListRef *) &value);
+
+ if (!err && value) {
+ found_options = 1;
+ err = kim_options_set_proxiable (options, CFBooleanGetValue (value));
+ }
+
+ if (value) { CFRelease (value); }
+ }
+
+ if (!err) {
+ CFBooleanRef value = NULL;
+
+ err = kim_os_preferences_copy_value_compat (kim_preference_key_addressless,
+ CFBooleanGetTypeID (),
+ (CFPropertyListRef *) &value);
+
+ if (!err && value) {
+ found_options = 1;
+ err = kim_options_set_addressless (options, CFBooleanGetValue (value));
+ }
+
+ if (value) { CFRelease (value); }
+ }
+
+ if (!err && !found_options) {
+ kim_options_free (&options);
+ options = KIM_OPTIONS_DEFAULT;
+ }
+
+ if (!err) {
+ *out_options = options;
+ }
+
+ return check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_os_preferences_get_options_for_key (kim_preference_key in_key,
+ kim_options *out_options)
+{
+ kim_error err = KIM_NO_ERROR;
+ CFDictionaryRef dictionary = NULL;
+ kim_options options = KIM_OPTIONS_DEFAULT;
+
+ if (!err && !out_options) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+
+ if (!err) {
+ err = kim_os_preferences_copy_value (in_key, CFDictionaryGetTypeID (),
+ (CFPropertyListRef *) &dictionary);
+
+ if (!err && dictionary) {
+ err = kim_os_preferences_dictionary_to_options (dictionary, &options);
+ }
+ }
+
+ if (!err && !dictionary) {
+ err = kim_os_preferences_get_options_compat (&options);
+ }
+
+ if (!err) {
+ *out_options = options;
+ }
+
+ if (dictionary) { CFRelease (dictionary); }
+
+ return check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_os_preferences_set_options_for_key (kim_preference_key in_key,
+ kim_options in_options)
+{
+ kim_error err = KIM_NO_ERROR;
+ CFMutableDictionaryRef dictionary = NULL;
+
+ if (!err && !in_options) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+
+ if (!err) {
+ dictionary = CFDictionaryCreateMutable (kCFAllocatorDefault, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ if (!dictionary) { err = check_error (KIM_OUT_OF_MEMORY_ERR); }
+ }
+
+ if (!err) {
+ err = kim_os_preferences_options_to_dictionary (in_options, dictionary);
+ }
+
+ if (!err) {
+ err = kim_os_preferences_set_value (in_key, dictionary);
+ }
+
+ if (dictionary) { CFRelease (dictionary); }
+
+ return check_error (err);
+}
+
+#pragma mark -
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_os_preferences_get_favorites_for_key (kim_preference_key in_key,
+ kim_favorites io_favorites)
+{
+ kim_error err = KIM_NO_ERROR;
+ CFArrayRef value = NULL;
+
+ if (!err && !io_favorites) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+
+ if (!err) {
+ err = kim_os_preferences_copy_value (in_key, CFArrayGetTypeID (),
+ (CFPropertyListRef *) &value);
+ }
+
+ if (!err && value) {
+ if (!value || CFArrayGetCount (value) < 1) {
+ err = kim_favorites_remove_all_identities (io_favorites);
+
+ } else {
+ CFIndex count = CFArrayGetCount (value);
+ CFIndex i;
+
+ for (i = 0; !err && i < count; i++) {
+ CFDictionaryRef dictionary = NULL;
+ kim_options options = KIM_OPTIONS_DEFAULT;
+ CFStringRef cfstring = NULL;
+
+ dictionary = (CFDictionaryRef) CFArrayGetValueAtIndex (value, i);
+ if (!dictionary || CFGetTypeID (dictionary) != CFDictionaryGetTypeID ()) {
+ err = check_error (KIM_PREFERENCES_READ_ERR);
+ }
+
+ if (!err) {
+ err = kim_os_preferences_copy_value_for_dict_key (dictionary,
+ kim_preference_key_client_identity,
+ CFStringGetTypeID (),
+ (CFPropertyListRef *) &cfstring);
+ }
+
+ if (!err && cfstring) {
+ kim_string string = NULL;
+ kim_identity identity = NULL;
+
+ err = kim_os_string_create_from_cfstring (&string, cfstring);
+
+ if (!err) {
+ err = kim_identity_create_from_string (&identity, string);
+ }
+
+ if (!err && (CFDictionaryGetCount (dictionary) > 1)) {
+ err = kim_os_preferences_dictionary_to_options (dictionary,
+ &options);
+ }
+
+ if (!err) {
+ err = kim_favorites_add_identity (io_favorites, identity,
+ options);
+ }
+
+ kim_string_free (&string);
+ kim_options_free (&options);
+ kim_identity_free (&identity);
+ }
+ }
+
+ if (err) {
+ kim_favorites_remove_all_identities (io_favorites);
+ }
+ }
}
+ if (value) { CFRelease (value); }
+
return check_error (err);
}
/* ------------------------------------------------------------------------ */
+kim_error kim_os_preferences_set_favorites_for_key (kim_preference_key in_key,
+ kim_favorites in_favorites)
+{
+ kim_error err = KIM_NO_ERROR;
+ kim_count count = 0;
+ CFMutableArrayRef array = NULL;
+
+ if (!err && !in_favorites) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+
+ if (!err) {
+ err = kim_favorites_get_number_of_identities (in_favorites, &count);
+ }
+
+ if (!err) {
+ array = CFArrayCreateMutable (kCFAllocatorDefault, count,
+ &kCFTypeArrayCallBacks);
+ if (!array) { err = KIM_OUT_OF_MEMORY_ERR; }
+ }
+
+ if (!err) {
+ kim_count i;
+
+ for (i = 0; !err && i < count; i++) {
+ kim_identity identity = NULL;
+ kim_options options = NULL;
+ kim_string string = NULL;
+ CFStringRef cfstring = NULL;
+ CFMutableDictionaryRef dictionary = NULL;
+
+ err = kim_favorites_get_identity_at_index (in_favorites, i,
+ &identity,
+ &options);
+
+ if (!err) {
+ err = kim_identity_get_string (identity, &string);
+ }
+
+ if (!err) {
+ err = kim_os_string_get_cfstring (string, &cfstring);
+ }
+
+ if (!err) {
+ dictionary = CFDictionaryCreateMutable (kCFAllocatorDefault, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ if (!dictionary) { err = check_error (KIM_OUT_OF_MEMORY_ERR); }
+ }
+
+ if (!err) {
+ err = kim_os_preferences_set_value_for_dict_key (dictionary,
+ kim_preference_key_client_identity,
+ cfstring);
+ }
+
+ if (!err && options) {
+ err = kim_os_preferences_options_to_dictionary (options,
+ dictionary);
+ }
+
+ if (!err) {
+ CFArrayAppendValue (array, dictionary);
+ }
+
+ if (dictionary) { CFRelease (dictionary); }
+ if (cfstring ) { CFRelease (cfstring); }
+ kim_string_free (&string);
+ kim_options_free (&options);
+ kim_identity_free (&identity);
+ }
+ }
+
+ if (!err) {
+ err = kim_os_preferences_set_value (in_key, array);
+ }
+
+ if (array) { CFRelease (array); }
+
+ return check_error (err);
+}
+
if (!err) {
err = kim_options_set_lifetime (options, TEST_LIFETIME);
- fail_if_error (state, "kim_options_set_data", err,
+ fail_if_error (state, "kim_options_set_lifetime", err,
"while setting the lifetime to %d", TEST_LIFETIME);
}
end_test (state);
}
+
+
+struct favorite_identity {
+ kim_string identity;
+ kim_lifetime lifetime;
+ kim_lifetime renewal_lifetime;
+};
+
+struct favorite_identity fids[] = {
+{ "bob@EXAMPLE.COM", 7777, 8888 },
+{ "alice@UNIVERSITY.EDU", 12345, 54321 },
+{ "bob@COMPANY.COM", 5555, 6666 },
+{ "alice/admin@EXAMPLE.COM", 2222, 3333 },
+{ NULL, 0, 0 }
+};
+
+/* ------------------------------------------------------------------------ */
+
+void test_kim_preferences_add_favorite_identity (kim_test_state_t state)
+{
+ kim_error err = KIM_NO_ERROR;
+
+ start_test (state, "kim_preferences_add_favorite_identity");
+
+ if (!err) {
+ kim_preferences prefs = NULL;
+ kim_options options = NULL;
+ kim_count i;
+
+ err = kim_preferences_create (&prefs);
+ fail_if_error (state, "kim_preferences_create", err,
+ "while creating preferences");
+
+ if (!err) {
+ err = kim_preferences_remove_all_favorite_identities (prefs);
+ fail_if_error (state, "kim_preferences_remove_all_favorite_identities", err,
+ "while removing all favorite identities");
+ }
+
+ if (!err) {
+ err = kim_options_create (&options);
+ fail_if_error (state, "kim_options_create", err,
+ "while creating options");
+ }
+
+ for (i = 0; !err && fids[i].identity; i++) {
+ kim_identity identity = NULL;
+
+ err = kim_identity_create_from_string (&identity, fids[i].identity);
+ fail_if_error (state, "kim_identity_create_from_string", err,
+ "while creating the identity for %s",
+ fids[i].identity);
+
+ if (!err) {
+ err = kim_options_set_lifetime (options, fids[i].lifetime);
+ fail_if_error (state, "kim_options_set_lifetime", err,
+ "while setting the lifetime to %d",
+ (int) fids[i].lifetime);
+ }
+
+ if (!err) {
+ err = kim_options_set_renewal_lifetime (options, fids[i].renewal_lifetime);
+ fail_if_error (state, "kim_options_set_renewal_lifetime", err,
+ "while setting the renewal lifetime to %d",
+ (int) fids[i].renewal_lifetime);
+ }
+
+ if (!err) {
+ err = kim_preferences_add_favorite_identity (prefs, identity, options);
+ fail_if_error (state, "kim_preferences_add_favorite_identity", err,
+ "while adding %s to the favorite identities",
+ fids[i].identity);
+ }
+
+ kim_identity_free (&identity);
+ }
+
+ if (!err) {
+ err = kim_preferences_synchronize (prefs);
+ fail_if_error (state, "kim_preferences_synchronize", err,
+ "while setting the favorite identities");
+ }
+
+ kim_options_free (&options);
+ kim_preferences_free (&prefs);
+ }
+
+ if (!err) {
+ kim_preferences prefs = NULL;
+ kim_count count, i;
+
+ err = kim_preferences_create (&prefs);
+ fail_if_error (state, "kim_preferences_create", err,
+ "while creating preferences");
+
+ if (!err) {
+ err = kim_preferences_get_number_of_favorite_identities (prefs, &count);
+ fail_if_error (state, "kim_preferences_get_number_of_favorite_identities", err,
+ "while getting number of favorite identities");
+ }
+
+
+ for (i = 0; !err && fids[i].identity; i++) {
+ kim_identity identity = NULL;
+ kim_count j;
+ kim_boolean found = 0;
+
+ err = kim_identity_create_from_string (&identity, fids[i].identity);
+ fail_if_error (state, "kim_identity_create_from_string", err,
+ "while creating the identity for %s",
+ fids[i].identity);
+
+ for (j = 0; j < count; j++) {
+ kim_identity compare_identity = NULL;
+ kim_options compare_options = NULL;
+ kim_comparison comparison;
+
+ err = kim_preferences_get_favorite_identity_at_index (prefs, j,
+ &compare_identity,
+ &compare_options);
+ fail_if_error (state, "kim_preferences_get_favorite_identity_at_index", err,
+ "while getting favorite identity %d", (int) j);
+
+ if (!err) {
+ err = kim_identity_compare (identity, compare_identity,
+ &comparison);
+ fail_if_error (state, "kim_identity_compare", err,
+ "while comparing %s to favorite identity %d",
+ fids[i].identity, (int) i);
+ }
+
+ if (!err && kim_comparison_is_equal_to (comparison)) {
+ kim_lifetime compare_lifetime;
+ kim_lifetime compare_renewal_lifetime;
+
+ found = 1;
+
+ err = kim_options_get_lifetime (compare_options, &compare_lifetime);
+ fail_if_error (state, "kim_options_get_lifetime", err,
+ "while getting the lifetime for %s",
+ fids[i].identity);
+
+ if (!err && fids[i].lifetime != compare_lifetime) {
+ log_failure (state, "Unexpected lifetime for %s (got %d, expected %d)",
+ fids[i].identity, (int) compare_lifetime,
+ (int) fids[i].lifetime);
+ }
+
+ if (!err) {
+ err = kim_options_get_renewal_lifetime (compare_options,
+ &compare_renewal_lifetime);
+ fail_if_error (state, "kim_options_get_renewal_lifetime", err,
+ "while getting the lifetime for %s",
+ fids[i].identity);
+ }
+
+ if (!err && fids[i].renewal_lifetime != compare_renewal_lifetime) {
+ log_failure (state, "Unexpected renewal lifetime for %s (got %d, expected %d)",
+ fids[i].identity,
+ (int) compare_renewal_lifetime,
+ (int) fids[i].renewal_lifetime);
+ }
+ }
+
+ kim_identity_free (&compare_identity);
+ kim_options_free (&compare_options);
+ }
+
+ if (!err && !found) {
+ log_failure (state, "Favorite identity %s not found in favorite identities list",
+ fids[i].identity);
+ }
+ }
+
+ if (!err && i != count) {
+ log_failure (state, "Unexpected number of favorite identities (got %d, expected %d)",
+ (int) count, (int) i);
+ }
+
+ kim_preferences_free (&prefs);
+ }
+
+ end_test (state);
+}
+