/* Implementation of OSXKeychain.addInternetPassword(). See the Java docs for * explanation of the parameters. */ JNIEXPORT void JNICALL Java_com_mcdermottroe_apple_OSXKeychain__1addInternetPassword(JNIEnv* env, jobject obj, jstring serverName, jstring securityDomain, jstring accountName, jstring path, jint port, jint protocol, jint authenticationType, jstring password) { OSStatus status; jstring_unpacked server_name; jstring_unpacked security_domain; jstring_unpacked account_name; jstring_unpacked server_path; jstring_unpacked server_password; /* Unpack the string params. */ jstring_unpack(env, serverName, &server_name); jstring_unpack(env, securityDomain, &security_domain); jstring_unpack(env, accountName, &account_name); jstring_unpack(env, path, &server_path); jstring_unpack(env, password, &server_password); /* check for allocation failures */ if (server_name.str == NULL || security_domain.str == NULL || account_name.str == NULL || server_path.str == NULL || server_password.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); jstring_unpacked_free(env, password, &server_password); return; } /* Add the details to the keychain. */ status = SecKeychainAddInternetPassword( 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, protocol, authenticationType, server_password.len, server_password.str, NULL ); if (status != errSecSuccess) { throw_osxkeychainexception(env, status); } /* Clean up. */ 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); jstring_unpacked_free(env, password, &server_password); }
void gnc_keyring_set_password (const gchar *access_method, const gchar *server, guint32 port, const gchar *service, const gchar *user, const gchar* password) { #ifdef HAVE_GNOME_KEYRING GnomeKeyringResult gkr_result; guint32 item_id = 0; gkr_result = gnome_keyring_set_network_password_sync (NULL, user, NULL, server, service, access_method, NULL, port, password, &item_id); if (gkr_result != GNOME_KEYRING_RESULT_OK) { PWARN ("Gnome-keyring error: %s", gnome_keyring_result_to_message(gkr_result)); PWARN ("The user will be prompted for a password again next time."); } #endif /* HAVE_GNOME_KEYRING */ #ifdef HAVE_OSX_KEYCHAIN OSStatus status; SecKeychainItemRef *itemRef = NULL; /* mysql and postgres aren't valid protocols on Mac OS X. * So we use the security domain parameter to allow us to * distinguish between these two. */ // FIXME I'm not sure this works if a password was already in the keychain // I may have to do a lookup first and if it exists, run some update // update function instead status = SecKeychainAddInternetPassword ( NULL, /* keychain */ strlen(server), server, /* servername */ strlen(access_method), access_method, /* securitydomain */ strlen(user), user, /* acountname */ strlen(service), service, /* path */ port, /* port */ kSecProtocolTypeAny, /* protocol */ kSecAuthenticationTypeDefault, /* auth type */ strlen(password), password, /* passworddata */ itemRef ); if ( status != noErr ) { CFStringRef osx_resultstring = SecCopyErrorMessageString( status, NULL ); const gchar *resultstring = CFStringGetCStringPtr(osx_resultstring, GetApplicationTextEncoding()); PWARN ( "OS X keychain error: %s", resultstring ); PWARN ( "The user will be prompted for a password again next time." ); CFRelease ( osx_resultstring ); } #endif /* HAVE_OSX_KEYCHAIN */ }
static void add_internet_password(void) { /* Only store complete credentials */ if (!protocol || !host || !username || !password) return; if (SecKeychainAddInternetPassword( KEYCHAIN_ARGS, KEYCHAIN_ITEM(password), NULL)) return; }
bool OsxWallet::setCredentials(const QString &realm, const QString &user, const QString &password) { const QByteArray realm_data = realm.toUtf8(); const QByteArray user_data = user.toUtf8(); const QByteArray password_data = password.toUtf8(); /* check whether the entry already exists */ SecKeychainItemRef itemRef = NULL; int rc = SecKeychainFindInternetPassword(keychain, realm_data.size(), realm_data.constData(), 0, NULL, user_data.size(), user_data.constData(), 0, NULL, 0, kSecProtocolTypeAny, kSecAuthenticationTypeAny, 0, NULL, &itemRef); if (rc == errSecSuccess) { // FIXME: we should not update username! SecKeychainAttribute attr; SecKeychainAttributeList attrList; attr.tag = kSecAccountItemAttr; attr.length = user_data.size(); attr.data = (void*)user_data.constData(); attrList.count = 1; attrList.attr = &attr; rc = SecKeychainItemModifyAttributesAndData(itemRef, &attrList, password_data.size(), password_data.constData()); CFRelease(itemRef); } else { rc = SecKeychainAddInternetPassword(keychain, realm_data.size(), realm_data.constData(), 0, NULL, user_data.size(), user_data.constData(), 0, NULL, 0, kSecProtocolTypeAny, kSecAuthenticationTypeAny, password_data.size(), password_data.constData(), NULL); } return (rc == errSecSuccess); }
void tests(int dont_skip) { SecKeychainRef source, dest; ok_status(SecKeychainCreate("source", 4, "test", FALSE, NULL, &source), "create source keychain"); ok_status(SecKeychainCreate("dest", 4, "test", FALSE, NULL, &dest), "create dest keychain"); SecKeychainItemRef original = NULL; ok_status(SecKeychainAddInternetPassword(source, 19, "members.spamcop.net", 0, NULL, 5, "smith", 0, NULL, 80, kSecProtocolTypeHTTP, kSecAuthenticationTypeDefault, 4, "test", &original), "add internet password"); SecKeychainAttribute origAttrs[] = { { kSecCreationDateItemAttr }, { kSecModDateItemAttr } }; SecKeychainAttributeList origAttrList = { sizeof(origAttrs) / sizeof(*origAttrs), origAttrs }; ok_status(SecKeychainItemCopyContent(original, NULL, &origAttrList, NULL, NULL), "SecKeychainItemCopyContent"); /* Must sleep 1 second to trigger mod date bug. */ sleep(1); SecKeychainItemRef copy; ok_status(SecKeychainItemCreateCopy(original, dest, NULL, ©), "copy item"); SecKeychainAttribute copyAttrs[] = { { kSecCreationDateItemAttr }, { kSecModDateItemAttr } }; SecKeychainAttributeList copyAttrList = { sizeof(copyAttrs) / sizeof(*copyAttrs), copyAttrs }; ok_status(SecKeychainItemCopyContent(copy, NULL, ©AttrList, NULL, NULL), "SecKeychainItemCopyContent"); is(origAttrs[0].length, 16, "creation date length 16"); is(origAttrs[1].length, 16, "mod date length 16"); is(origAttrs[0].length, copyAttrs[0].length, "creation date length same"); is(origAttrs[1].length, copyAttrs[1].length, "mod date length same"); TODO: { todo("<rdar://problem/3731664> Moving/copying a keychain item " "between keychains erroneously updates dates"); diag("original creation: %.*s copy creation: %.*s", (int)origAttrs[0].length, (const char *)origAttrs[0].data, (int)copyAttrs[0].length, (const char *)copyAttrs[0].data); ok(!memcmp(origAttrs[0].data, copyAttrs[0].data, origAttrs[0].length), "creation date same"); diag("original mod: %.*s copy mod: %.*s", (int)origAttrs[1].length, (const char *)origAttrs[1].data, (int)copyAttrs[1].length, (const char *)copyAttrs[1].data); ok(!memcmp(origAttrs[1].data, copyAttrs[1].data, origAttrs[1].length), "mod date same"); } ok_status(SecKeychainItemFreeContent(&origAttrList, NULL), "SecKeychainItemCopyContent"); ok_status(SecKeychainItemFreeContent(©AttrList, NULL), "SecKeychainItemCopyContent"); is(CFGetRetainCount(original), 1, "original retaincount is 1"); CFRelease(original); is(CFGetRetainCount(copy), 1, "copy retaincount is 1"); CFRelease(copy); is(CFGetRetainCount(source), 1, "source retaincount is 1"); ok_status(SecKeychainDelete(source), "delete keychain source"); CFRelease(source); ok_status(SecKeychainDelete(dest), "delete keychain dest"); is(CFGetRetainCount(dest), 1, "dest retaincount is 1"); CFRelease(dest); ok(tests_end(1), "cleanup"); }
void SG_password__set( SG_context *pCtx, const char *szRepoSpec, SG_string *pUserName, SG_string *pPassword) { const char *username, *password; SG_string *path = NULL; SG_string *server = NULL; SecProtocolType proto; SG_uint32 port; SG_bool isValid = SG_FALSE; OSStatus saveRes, findRes; SecKeychainItemRef item = NULL; SG_NULLARGCHECK(pUserName); SG_NULLARGCHECK(pPassword); SG_NULLARGCHECK(szRepoSpec); username = SG_string__sz(pUserName); password = SG_string__sz(pPassword); SG_ERR_CHECK( _sg_password__parse_url(pCtx, szRepoSpec, &isValid, &proto, &server, &path, &port) ); if (! isValid) SG_ERR_THROW(SG_ERR_NOTIMPLEMENTED); findRes = SecKeychainFindInternetPassword( NULL, SG_STRLEN( SG_string__sz(server) ), SG_string__sz(server), 0, NULL, SG_STRLEN(username), username, SG_STRLEN( SG_string__sz(path) ), SG_string__sz(path), port, proto, kSecAuthenticationTypeDefault, NULL, NULL, &item); if (findRes == errSecSuccess) { saveRes = SecKeychainItemModifyAttributesAndData(item, NULL, SG_STRLEN(password), password); } else { saveRes = SecKeychainAddInternetPassword( NULL, SG_STRLEN( SG_string__sz(server) ), SG_string__sz(server), 0, NULL, SG_STRLEN(username), username, SG_STRLEN( SG_string__sz(path) ), SG_string__sz(path), port, proto, kSecAuthenticationTypeDefault, SG_STRLEN(password), password, NULL); } if (saveRes != errSecSuccess) _SG_THROW_MAC_SEC_ERROR(saveRes); fail: if (item) CFRelease(item); SG_STRING_NULLFREE(pCtx, path); SG_STRING_NULLFREE(pCtx, server); }
VALUE set_internet_password_for(VALUE self, VALUE data) { VALUE ret = Qfalse; CHECK_FETCH_HASH_KEY(account) CHECK_FETCH_HASH_KEY(protocol) CHECK_FETCH_HASH_KEY(server) CHECK_FETCH_HASH_KEY(password) VALUE sym_auth = rb_eval_string(":auth"); VALUE auth; if (!rb_funcall(data, rb_intern("has_key?"), 1, sym_auth)) { auth = kSecAuthenticationTypeDefault; } else { auth = rb_funcall(rb_funcall(data, rb_intern("fetch"), 1, sym_auth), rb_intern("to_s"), 0); auth = String2FourChar(StringValuePtr(auth)); } VALUE sym_port = rb_eval_string(":port"); VALUE port; if (!rb_funcall(data, rb_intern("has_key?"), 1, sym_port)) { port = 0; } else { port = rb_funcall(rb_funcall(data, rb_intern("fetch"), 1, sym_port), rb_intern("to_i"), 0); port = NUM2INT(port); } VALUE sym_path = rb_eval_string(":path"); VALUE path; if (!rb_funcall(data, rb_intern("has_key?"), 1, sym_path)) { path = rb_str_new2(""); } else { path = rb_funcall(rb_funcall(data, rb_intern("fetch"), 1, sym_path), rb_intern("to_s"), 0); } OSStatus status = SecKeychainAddInternetPassword ( NULL, // default keychain strlen(StringValuePtr(server)), // length of serverName StringValuePtr(server), // serverName 0, // length of domain NULL, // no domain strlen(StringValuePtr(account)), // length of account name StringValuePtr(account), // account name strlen(StringValuePtr(path)), // length of path StringValuePtr(path), // path port, // ignore port String2FourChar(StringValuePtr(protocol)), // protocol auth, // auth type strlen(StringValuePtr(password)), StringValuePtr(password), NULL ); if (status == noErr) { ret = Qtrue; } else if (status == errSecDuplicateItem) { // Try updating instead SecKeychainItemRef itemRef = nil; status = SecKeychainFindInternetPassword ( NULL, // default keychain strlen(StringValuePtr(server)), // length of serverName StringValuePtr(server), // serverName 0, // length of domain NULL, // no domain strlen(StringValuePtr(account)), // length of account name StringValuePtr(account), // account name strlen(StringValuePtr(path)), // length of path StringValuePtr(path), // path port, // ignore port String2FourChar(StringValuePtr(protocol)), // protocol auth, nil, nil, &itemRef ); if (status != noErr) rb_raise(rb_eStandardError, getStatusString(status)); status = SecKeychainItemModifyAttributesAndData ( itemRef, // the item reference NULL, // no change to attributes strlen(StringValuePtr(password)), // length of password StringValuePtr(password) // pointer to password data ); if (status != noErr) rb_raise(rb_eStandardError, getStatusString(status)); ret = Qtrue; } else { rb_raise(rb_eStandardError, getStatusString(status)); } return ret; }