示例#1
0
文件: main.c 项目: Deanzou/ppp
//----------------------------------------------------------------------
//	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);
}