//---------------------------------------------------------------------- // dsauth_get_admin_password //---------------------------------------------------------------------- static int dsauth_get_admin_password(u_int32_t acctlen, char* acctname, u_int32_t *password_len, char **password) { #if !TARGET_OS_EMBEDDED // This file is not built for Embedded SecKeychainRef keychain = 0; OSStatus status; if ((status = SecKeychainSetPreferenceDomain(kSecPreferencesDomainSystem)) == noErr) { if ((status = SecKeychainCopyDomainDefault(kSecPreferencesDomainSystem, &keychain)) == noErr) { status = SecKeychainFindGenericPassword(keychain, strlen(serviceName), serviceName, acctlen, acctname, (UInt32*)password_len, (void**)password, NULL); } } if (keychain) CFRelease(keychain); if (status == noErr) return 0; else { error("DSAuth plugin: Error %d while retrieving key agent password from the system keychain.\n", status); return -1; } #else error("System Keychain support not available"); return -1; #endif /* TARGET_OS_EMBEDDED */ }
/* * Function: EAPOLClientItemIDRemovePasswordItem * * Purpose: * Remove the password item in secure storage for the specified itemID * in the specified domain. * * Returns: * FALSE if the operation did not succeed, TRUE otherwise. */ Boolean EAPOLClientItemIDRemovePasswordItem(EAPOLClientItemIDRef itemID, EAPOLClientDomain domain) { SecKeychainRef keychain = NULL; OSStatus status = errSecParam; CFStringRef unique_string; switch (domain) { case kEAPOLClientDomainUser: status = SecKeychainCopyDomainDefault(kSecPreferencesDomainUser, &keychain); if (status != noErr) { fprintf(stderr, "EAPOLClientItemIDSetPasswordItem can't get" " User keychain, %s (%d)\n", EAPSecurityErrorString(status), (int)status); return (FALSE); } break; case kEAPOLClientDomainSystem: if (EAPOLClientItemIDGetAuthorizationExternalForm(itemID) != NULL) { return (authEAPOLClientItemIDRemovePasswordItem(itemID)); } status = SecKeychainCopyDomainDefault(kSecPreferencesDomainSystem, &keychain); if (status != noErr) { fprintf(stderr, "EAPOLClientItemIDSetPasswordItem can't get" " System keychain, %s (%d)\n", EAPSecurityErrorString(status), (int)status); return (FALSE); } break; default: return (FALSE); } unique_string = EAPOLClientItemIDCopyUniqueString(itemID, domain, TRUE); status = EAPSecKeychainPasswordItemRemove(keychain, unique_string); my_CFRelease(&unique_string); my_CFRelease(&keychain); return (status == noErr); }
/* * Function: EAPOLClientItemIDSetPasswordItem * * Purpose: * Set the password item in secure storage for the specified itemID * in the specified domain. * * Passing an empty 'username' or 'password' removes the corresponding * attribute. If both 'username' and 'password' are empty, the item is * also removed. An empty value is a non-NULL CFDataRef of length 0. * * Passing NULL for 'username' or 'password' means that the corresponding * item attribute is left alone. If both 'username" and 'password' are * NULL, the call has no effect, but TRUE is still returned. * * Passing non-NULL, non-empty 'username' or 'password' sets the * corresponding item attribute to the specified value. If the item * does not exist, it will be created. * * Returns: * FALSE if the operation did not succeed, TRUE otherwise. */ Boolean EAPOLClientItemIDSetPasswordItem(EAPOLClientItemIDRef itemID, EAPOLClientDomain domain, CFDataRef name, CFDataRef password) { CFMutableDictionaryRef attrs = NULL; CFDataRef data; SecKeychainRef keychain = NULL; CFDataRef ssid; OSStatus status = errSecParam; CFStringRef unique_string; if (name == NULL && password == NULL) { return (TRUE); } switch (domain) { case kEAPOLClientDomainUser: status = SecKeychainCopyDomainDefault(kSecPreferencesDomainUser, &keychain); if (status != noErr) { fprintf(stderr, "EAPOLClientItemIDSetPasswordItem can't get" " User keychain, %s (%d)\n", EAPSecurityErrorString(status), (int)status); return (FALSE); } break; case kEAPOLClientDomainSystem: if (EAPOLClientItemIDGetAuthorizationExternalForm(itemID) != NULL) { return (authEAPOLClientItemIDSetPasswordItem(itemID, name, password)); } status = SecKeychainCopyDomainDefault(kSecPreferencesDomainSystem, &keychain); if (status != noErr) { fprintf(stderr, "EAPOLClientItemIDSetPasswordItem can't get" " System keychain, %s (%d)\n", EAPSecurityErrorString(status), (int)status); return (FALSE); } break; default: return (FALSE); } /* populate an attributes dictionary */ attrs = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); /* Description */ data = CFDataCreate(NULL, (UInt8 *)kItemDescription, kItemDescriptionLength); CFDictionarySetValue(attrs, kEAPSecKeychainPropDescription, data); CFRelease(data); /* Label */ switch (itemID->type) { case kEAPOLClientItemIDTypeWLANSSID: CFDictionarySetValue(attrs, kEAPSecKeychainPropLabel, itemID->u.ssid); break; case kEAPOLClientItemIDTypeWLANDomain: { CFDataRef label_data; label_data = my_CFDataCreateWithString(itemID->u.domain); CFDictionarySetValue(attrs, kEAPSecKeychainPropLabel, label_data); CFRelease(label_data); break; } case kEAPOLClientItemIDTypeProfileID: { CFDataRef label_data; label_data = my_CFDataCreateWithString(itemID->u.profileID); CFDictionarySetValue(attrs, kEAPSecKeychainPropLabel, label_data); CFRelease(label_data); break; } case kEAPOLClientItemIDTypeProfile: ssid = EAPOLClientProfileGetWLANSSIDAndSecurityType(itemID->u.profile, NULL); if (ssid != NULL) { CFDictionarySetValue(attrs, kEAPSecKeychainPropLabel, ssid); } else { CFStringRef label; CFDataRef label_data; label = EAPOLClientProfileGetUserDefinedName(itemID->u.profile); if (label == NULL) { label = EAPOLClientProfileGetWLANDomain(itemID->u.profile); if (label == NULL) { label = EAPOLClientProfileGetID(itemID->u.profile); } } label_data = my_CFDataCreateWithString(label); CFDictionarySetValue(attrs, kEAPSecKeychainPropLabel, label_data); CFRelease(label_data); } break; case kEAPOLClientItemIDTypeDefault: { CFDataRef label_data; /* XXX localize? */ label_data = my_CFDataCreateWithString(CFSTR("Default")); CFDictionarySetValue(attrs, kEAPSecKeychainPropLabel, label_data); CFRelease(label_data); break; } default: goto done; } /* Account */ if (name != NULL) { CFDictionarySetValue(attrs, kEAPSecKeychainPropAccount, name); } /* Password */ if (password != NULL) { CFDictionarySetValue(attrs, kEAPSecKeychainPropPassword, password); }; if (domain == kEAPOLClientDomainUser) { CFArrayRef trusted_apps; /* Trusted Applications */ trusted_apps = copy_trusted_applications(FALSE); if (trusted_apps != NULL) { CFDictionarySetValue(attrs, kEAPSecKeychainPropTrustedApplications, trusted_apps); CFRelease(trusted_apps); } } else { CFDictionarySetValue(attrs, kEAPSecKeychainPropAllowRootAccess, kCFBooleanTrue); } unique_string = EAPOLClientItemIDCopyUniqueString(itemID, domain, TRUE); status = EAPSecKeychainPasswordItemSet2(keychain, unique_string, attrs); if (status == errSecItemNotFound) { status = EAPSecKeychainPasswordItemCreate(keychain, unique_string, attrs); } my_CFRelease(&unique_string); if (status != noErr) { EAPLOG(LOG_NOTICE, "EAPOLClientItemID: failed to set keychain item, %d", (int)status); } done: my_CFRelease(&attrs); my_CFRelease(&keychain); return (status == noErr); }
/* * Function: EAPOLClientItemIDCopyPasswordItem * * Purpose: * Retrieve the password item from secure storage for the particular itemID * in the specified domain. * * Returns: * FALSE if no such item exists, and both *username_p and *password_p * are set to NULL. * * TRUE if an item exists, and either of both *username_p and *password_p * are set to a non-NULL value. */ Boolean EAPOLClientItemIDCopyPasswordItem(EAPOLClientItemIDRef itemID, EAPOLClientDomain domain, CFDataRef * username_p, CFDataRef * password_p) { CFDictionaryRef attrs = NULL; int count; SecKeychainRef keychain = NULL; const void * keys[2]; CFArrayRef req_props = NULL; OSStatus status = errSecParam; CFStringRef unique_string; count = 0; if (username_p == NULL && password_p == NULL) { return (FALSE); } switch (domain) { case kEAPOLClientDomainUser: status = SecKeychainCopyDomainDefault(kSecPreferencesDomainUser, &keychain); if (status != noErr) { fprintf(stderr, "EAPOLClientItemIDCopyPasswordItem can't get" " User keychain\n"); return (FALSE); } break; case kEAPOLClientDomainSystem: if (EAPOLClientItemIDGetAuthorizationExternalForm(itemID) != NULL) { return (authEAPOLClientItemIDCopyPasswordItem(itemID, username_p, password_p)); } status = SecKeychainCopyDomainDefault(kSecPreferencesDomainSystem, &keychain); if (status != noErr) { fprintf(stderr, "EAPOLClientItemIDCopyPasswordItem can't get" " System keychain\n"); return (FALSE); } break; default: return (FALSE); } if (username_p != NULL) { keys[count] = kEAPSecKeychainPropAccount; count++; *username_p = NULL; } if (password_p != NULL) { keys[count] = kEAPSecKeychainPropPassword; count++; *password_p = NULL; } req_props = CFArrayCreate(NULL, keys, count, &kCFTypeArrayCallBacks); unique_string = EAPOLClientItemIDCopyUniqueString(itemID, domain, TRUE); status = EAPSecKeychainPasswordItemCopy2(keychain, unique_string, req_props, &attrs); if (status != noErr) { goto done; } if (username_p != NULL) { *username_p = my_CFDictionaryCopyValue(attrs, kEAPSecKeychainPropAccount); } if (password_p != NULL) { *password_p = my_CFDictionaryCopyValue(attrs, kEAPSecKeychainPropPassword); } done: my_CFRelease(&unique_string); my_CFRelease(&req_props); my_CFRelease(&attrs); my_CFRelease(&keychain); return (status == noErr); }