//---------------------------------------------------------------------- // 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 */ }
/* Implementation of OSXKeychain.findGenericPassword(). See the Java docs for * explanations of the parameters. */ JNIEXPORT jstring JNICALL Java_com_mcdermottroe_apple_OSXKeychain__1findGenericPassword(JNIEnv* env, jobject obj, jstring serviceName, jstring accountName) { OSStatus status; jstring_unpacked service_name; jstring_unpacked account_name; jstring result = NULL; /* Buffer for the return from SecKeychainFindGenericPassword. */ void* password; UInt32 password_length; /* Query the keychain. */ status = SecKeychainSetPreferenceDomain(kSecPreferencesDomainUser); if (status != errSecSuccess) { throw_osxkeychainexception(env, status); return NULL; } /* Unpack the params. */ jstring_unpack(env, serviceName, &service_name); jstring_unpack(env, accountName, &account_name); if (service_name.str == NULL || account_name.str == NULL) { jstring_unpacked_free(env, serviceName, &service_name); jstring_unpacked_free(env, accountName, &account_name); return NULL; } status = SecKeychainFindGenericPassword( NULL, service_name.len, service_name.str, account_name.len, account_name.str, &password_length, &password, NULL ); if (status != errSecSuccess) { throw_osxkeychainexception(env, status); } else { // the returned value from keychain is not // null terminated, so a copy is created. char *password_buffer = malloc(password_length+1); memcpy(password_buffer, password, password_length); password_buffer[password_length] = 0; /* Create the return value. */ result = (*env)->NewStringUTF(env, password_buffer); /* Clean up. */ bzero(password_buffer, password_length); free(password_buffer); SecKeychainItemFreeContent(NULL, password); } jstring_unpacked_free(env, serviceName, &service_name); jstring_unpacked_free(env, accountName, &account_name); return result; }
/* * Function: EAPOLClientItemIDSetIdentity * * Purpose: * Associate an identity with the specified itemID in the specified * domain. * * If the identity is NULL, the identity preference is removed. * * Returns: * FALSE if the operation did not succeed, TRUE otherwise. */ Boolean EAPOLClientItemIDSetIdentity(EAPOLClientItemIDRef itemID, EAPOLClientDomain domain, SecIdentityRef identity) { SecPreferencesDomain current_domain; SecPreferencesDomain required_domain; OSStatus status; CFStringRef unique_string; switch (domain) { case kEAPOLClientDomainUser: required_domain = kSecPreferencesDomainUser; break; case kEAPOLClientDomainSystem: if (EAPOLClientItemIDGetAuthorizationExternalForm(itemID) != NULL) { return (authEAPOLClientItemIDSetIdentity(itemID, identity)); } required_domain = kSecPreferencesDomainSystem; break; default: return (FALSE); } status = SecKeychainGetPreferenceDomain(¤t_domain); if (status != noErr) { return (FALSE); } if (required_domain != current_domain) { status = SecKeychainSetPreferenceDomain(required_domain); if (status != noErr) { return (FALSE); } } unique_string = EAPOLClientItemIDCopyUniqueString(itemID, domain, FALSE); status = SecIdentitySetPreferred(identity, unique_string, NULL); if (status != noErr) { fprintf(stderr, "SecIdentitySetPreference failed %s (%d)\n", EAPSecurityErrorString(status), (int)status); } if (current_domain != required_domain) { (void)SecKeychainSetPreferenceDomain(current_domain); } my_CFRelease(&unique_string); return (status == noErr); }
/* * Function: EAPOLClientItemIDCopyIdentity * * Purpose: * Retrieve the identity associated with the particular itemID * in the specified domain. * * Returns: * non-NULL SecIdentityRef when match can be found for the item ID, * NULL otherwise. */ SecIdentityRef EAPOLClientItemIDCopyIdentity(EAPOLClientItemIDRef itemID, EAPOLClientDomain domain) { SecPreferencesDomain current_domain; SecIdentityRef identity = NULL; SecPreferencesDomain required_domain; OSStatus status; CFStringRef unique_string; switch (domain) { case kEAPOLClientDomainUser: required_domain = kSecPreferencesDomainUser; break; case kEAPOLClientDomainSystem: required_domain = kSecPreferencesDomainSystem; break; default: return (NULL); } status = SecKeychainGetPreferenceDomain(¤t_domain); if (status != noErr) { return (NULL); } if (current_domain != required_domain) { status = SecKeychainSetPreferenceDomain(required_domain); if (status != noErr) { return (NULL); } } unique_string = EAPOLClientItemIDCopyUniqueString(itemID, domain, FALSE); identity = SecIdentityCopyPreferred(unique_string, NULL, NULL); if (current_domain != required_domain) { (void)SecKeychainSetPreferenceDomain(current_domain); } my_CFRelease(&unique_string); return (identity); }
/* Implementation of OSXKeychain.deleteGenericPassword(). See the Java docs for * explanations of the parameters. */ JNIEXPORT void JNICALL Java_com_mcdermottroe_apple_OSXKeychain__1deleteGenericPassword(JNIEnv* env, jobject obj, jstring serviceName, jstring accountName) { OSStatus status; jstring_unpacked service_name; jstring_unpacked account_name; SecKeychainItemRef itemToDelete; /* Query the keychain. */ status = SecKeychainSetPreferenceDomain(kSecPreferencesDomainUser); if (status != errSecSuccess) { throw_osxkeychainexception(env, status); return; } /* Unpack the params. */ jstring_unpack(env, serviceName, &service_name); jstring_unpack(env, accountName, &account_name); if (service_name.str == NULL || account_name.str == NULL) { jstring_unpacked_free(env, serviceName, &service_name); jstring_unpacked_free(env, accountName, &account_name); return; } status = SecKeychainFindGenericPassword( NULL, service_name.len, service_name.str, account_name.len, account_name.str, NULL, NULL, &itemToDelete ); if (status != errSecSuccess) { throw_osxkeychainexception(env, status); } else { status = SecKeychainItemDelete(itemToDelete); if (status != errSecSuccess) { throw_osxkeychainexception(env, status); } } /* Clean up. */ jstring_unpacked_free(env, serviceName, &service_name); jstring_unpacked_free(env, accountName, &account_name); }
static void * get_password_from_keychain( const char * account, unsigned accountLength) { OSStatus status ; SecKeychainItemRef item; void * passwordData = NULL; UInt32 passwordLength = 0; void * password = NULL; // Set the domain to System (daemon) status = SecKeychainSetPreferenceDomain(kSecPreferencesDomainSystem); status = SecKeychainGetUserInteractionAllowed (false); status = SecKeychainFindGenericPassword ( NULL, // default keychain strlen(KEYCHAIN_SERVICE), // length of service name KEYCHAIN_SERVICE, // service name accountLength, // length of account name account, // account name &passwordLength, // length of password &passwordData, // pointer to password data &item // the item reference ); if (status != noErr) { message("%s: SecKeychainFindGenericPassword failed with error %d\n", PROGNAME, (int)status); return NULL; } if (item == NULL || passwordLength == 0) { message("%s: SecKeychainFindGenericPassword found no results for %s\n", PROGNAME, account); return NULL; } password = calloc(1, passwordLength + 1); memcpy(password, (const void *)passwordData, passwordLength); return password; }
int main(int ac, char *av[]) { char *p = NULL; kern_return_t kr = KERN_FAILURE; long n; int ch; mach_msg_header_t hdr; while ((ch = getopt(ac, av, "dt:")) != -1) switch (ch) { case 'd': opt_debug = 1; break; case 't': n = strtol(optarg, &p, 0); if ('\0' == optarg[0] || '\0' != *p || n > LONG_MAX || n < 0) { fprintf(stderr, "Invalid idle timeout: %s\n", optarg); exit(EXIT_FAILURE); } maxidle = n; break; case '?': default: fprintf(stderr, "Usage: mDNSResponderHelper [-d] [-t maxidle]\n"); exit(EXIT_FAILURE); } ac -= optind; av += optind; (void)ac; // Unused (void)av; // Unused initialize_logging(); helplog(ASL_LEVEL_INFO, "Starting"); initialize_id(); #ifndef NO_SECURITYFRAMEWORK // We should normally be running as a system daemon. However, that might not be the case in some scenarios (e.g. debugging). // Explicitly ensure that our Keychain operations utilize the system domain. if (opt_debug) SecKeychainSetPreferenceDomain(kSecPreferencesDomainSystem); #endif gPort = register_service(kmDNSHelperServiceName); if (!gPort) exit(EXIT_FAILURE); if (maxidle) actualidle = maxidle; signal(SIGTERM, handle_sigterm); if (initialize_timer()) exit(EXIT_FAILURE); for (n=0; n<100000; n++) if (!gRunLoop) usleep(100); if (!gRunLoop) { helplog(ASL_LEVEL_ERR, "gRunLoop not set after waiting"); exit(EXIT_FAILURE); } for(;;) { hdr.msgh_bits = 0; hdr.msgh_local_port = gPort; hdr.msgh_remote_port = MACH_PORT_NULL; hdr.msgh_size = sizeof(hdr); hdr.msgh_id = 0; kr = mach_msg(&hdr, MACH_RCV_LARGE | MACH_RCV_MSG, 0, hdr.msgh_size, gPort, 0, 0); if (MACH_RCV_TOO_LARGE != kr) helplog(ASL_LEVEL_ERR, "main MACH_RCV_MSG error: %d %X %s", kr, kr, mach_error_string(kr)); kr = mach_msg_server_once(helper_server, MAX_MSG_SIZE, gPort, MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT) | MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0)); if (KERN_SUCCESS != kr) { helplog(ASL_LEVEL_ERR, "mach_msg_server: %d %X %s", kr, kr, mach_error_string(kr)); exit(EXIT_FAILURE); } } exit(EXIT_SUCCESS); }
/* Implementation of OSXKeychain.findInternetPassword(). See the Java docs for * explanations of the parameters. */ JNIEXPORT jstring JNICALL Java_com_mcdermottroe_apple_OSXKeychain__1findInternetPassword(JNIEnv* env, jobject obj, jstring serverName, jstring securityDomain, jstring accountName, jstring path, jint port) { OSStatus status; jstring_unpacked server_name; jstring_unpacked security_domain; jstring_unpacked account_name; jstring_unpacked server_path; jstring result = NULL; /* This is the password buffer which will be used by * SecKeychainFindInternetPassword */ void* password; UInt32 password_length; /* Query the keychain */ status = SecKeychainSetPreferenceDomain(kSecPreferencesDomainUser); if (status != errSecSuccess) { throw_osxkeychainexception(env, status); return NULL; } /* Unpack all the jstrings into useful structures. */ jstring_unpack(env, serverName, &server_name); jstring_unpack(env, securityDomain, &security_domain); jstring_unpack(env, accountName, &account_name); jstring_unpack(env, path, &server_path); if (server_name.str == NULL || security_domain.str == NULL || account_name.str == NULL || server_path.str == NULL) { jstring_unpacked_free(env, serverName, &server_name); jstring_unpacked_free(env, securityDomain, &security_domain); jstring_unpacked_free(env, accountName, &account_name); jstring_unpacked_free(env, path, &server_path); return NULL; } status = SecKeychainFindInternetPassword( NULL, server_name.len, server_name.str, security_domain.len, security_domain.str, account_name.len, account_name.str, server_path.len, server_path.str, port, kSecProtocolTypeAny, kSecAuthenticationTypeAny, &password_length, &password, NULL ); if (status != errSecSuccess) { throw_osxkeychainexception(env, status); } else { // the returned value from keychain is not // null terminated, so a copy is created. char* password_buffer = (char *) malloc(password_length+1); memcpy(password_buffer, password, password_length); password_buffer[password_length] = 0; /* Create the return value. */ result = (*env)->NewStringUTF(env, password_buffer); /* Clean up. */ bzero(password_buffer, password_length); free(password_buffer); SecKeychainItemFreeContent(NULL, password); } jstring_unpacked_free(env, serverName, &server_name); jstring_unpacked_free(env, securityDomain, &security_domain); jstring_unpacked_free(env, accountName, &account_name); jstring_unpacked_free(env, path, &server_path); return result; }