mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
MacOsCredentialStore, disabled by default
This commit is contained in:
+4
-4
@@ -38,7 +38,7 @@ import javax.crypto.spec.SecretKeySpec
|
||||
|
||||
internal val LOG = Logger.getInstance(FilePasswordSafeProvider::class.java)
|
||||
|
||||
class FilePasswordSafeProvider @JvmOverloads constructor(keyToValue: Map<String, String>? = null, baseDirectory: Path = Paths.get(PathManager.getConfigPath()), var memoryOnly: Boolean = false) : PasswordSafeProvider() {
|
||||
class FilePasswordSafeProvider @JvmOverloads constructor(keyToValue: Map<String, String>? = null, baseDirectory: Path = Paths.get(PathManager.getConfigPath()), var memoryOnly: Boolean = false) : PasswordSafeProvider {
|
||||
private val db = ContainerUtil.newConcurrentMap<String, String>()
|
||||
|
||||
private val dbFile = baseDirectory.resolve("pdb")
|
||||
@@ -156,11 +156,11 @@ class FilePasswordSafeProvider @JvmOverloads constructor(keyToValue: Map<String,
|
||||
needToSave.set(true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getName() = "File PasswordSafe"
|
||||
}
|
||||
|
||||
private fun getRawKey(key: String?, requestor: Class<*>?) = "${if (requestor == null) "" else "${requestor.name}/"}$key"
|
||||
internal fun getRawKey(key: String?, requestor: Class<*>?) = "${if (requestor == null) "" else "${requestor.name}/"}$key"
|
||||
|
||||
internal fun toOldKey(hash: ByteArray) = "old-hashed-key|" + Base64.getEncoder().encodeToString(hash)
|
||||
|
||||
internal fun generate(): ByteArray {
|
||||
val bytes = ByteArray(16)
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.ide.passwordSafe
|
||||
|
||||
import com.intellij.ide.passwordSafe.impl.PasswordSafeProvider
|
||||
import com.intellij.ide.passwordSafe.macOs.deleteGenericPassword
|
||||
import com.intellij.ide.passwordSafe.macOs.findGenericPassword
|
||||
import com.intellij.ide.passwordSafe.macOs.saveGenericPassword
|
||||
import com.intellij.openapi.diagnostic.catchAndLog
|
||||
import java.security.MessageDigest
|
||||
|
||||
internal class MacOsCredentialStore(serviceName: String) : PasswordSafeProvider {
|
||||
private val serviceName = serviceName.toByteArray()
|
||||
|
||||
override fun getPassword(requestor: Class<*>?, key: String): String? {
|
||||
val rawKey = getRawKey(key, requestor)
|
||||
// try old key - as hash
|
||||
@Suppress("CanBeVal")
|
||||
var value: String?
|
||||
try {
|
||||
value = findGenericPassword(serviceName, rawKey)
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
LOG.error(e)
|
||||
return null
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
LOG.catchAndLog {
|
||||
val oldKey = toOldKey(MessageDigest.getInstance("SHA-256").digest(rawKey.toByteArray()))
|
||||
value = findGenericPassword(serviceName, oldKey)
|
||||
if (value != null) {
|
||||
LOG.catchAndLog { deleteGenericPassword(serviceName, oldKey) }
|
||||
saveGenericPassword(serviceName, key, value!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
override fun setPassword(requestor: Class<*>?, key: String, value: String?) {
|
||||
LOG.catchAndLog {
|
||||
val rawKey = getRawKey(key, requestor)
|
||||
if (value == null) {
|
||||
deleteGenericPassword(serviceName, rawKey)
|
||||
}
|
||||
else {
|
||||
saveGenericPassword(serviceName, rawKey, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,17 +15,16 @@
|
||||
*/
|
||||
package com.intellij.ide.passwordSafe.impl
|
||||
|
||||
import com.intellij.ide.passwordSafe.FilePasswordSafeProvider
|
||||
import com.intellij.ide.passwordSafe.LOG
|
||||
import com.intellij.ide.passwordSafe.PasswordSafe
|
||||
import com.intellij.ide.passwordSafe.PasswordSafeSettingsListener
|
||||
import com.intellij.ide.passwordSafe.*
|
||||
import com.intellij.ide.passwordSafe.config.PasswordSafeSettings
|
||||
import com.intellij.ide.passwordSafe.config.PasswordSafeSettings.ProviderType
|
||||
import com.intellij.ide.passwordSafe.macOs.isMacOsCredentialsStoreSupported
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.components.SettingsSavingComponent
|
||||
import com.intellij.openapi.diagnostic.catchAndLog
|
||||
|
||||
class PasswordSafeImpl(/* public - backward compatibility */val settings: PasswordSafeSettings) : PasswordSafe(), SettingsSavingComponent {
|
||||
private val currentProvider: FilePasswordSafeProvider
|
||||
private @Volatile var currentProvider: PasswordSafeProvider
|
||||
|
||||
// it is helper storage to support set password as memory-only (see setPassword memoryOnly flag)
|
||||
private val memoryHelperProvider = lazy { FilePasswordSafeProvider(emptyMap(), memoryOnly = true) }
|
||||
@@ -33,13 +32,28 @@ class PasswordSafeImpl(/* public - backward compatibility */val settings: Passwo
|
||||
override fun isMemoryOnly() = settings.providerType == ProviderType.MEMORY_ONLY
|
||||
|
||||
init {
|
||||
currentProvider = FilePasswordSafeProvider(memoryOnly = settings.providerType == ProviderType.MEMORY_ONLY)
|
||||
if (settings.providerType == ProviderType.MEMORY_ONLY) {
|
||||
currentProvider = FilePasswordSafeProvider(memoryOnly = true)
|
||||
}
|
||||
else {
|
||||
currentProvider = createPersistentCredentialStore()
|
||||
}
|
||||
|
||||
ApplicationManager.getApplication().messageBus.connect().subscribe(PasswordSafeSettings.TOPIC, object: PasswordSafeSettingsListener {
|
||||
override fun typeChanged(oldValue: ProviderType, newValue: ProviderType) {
|
||||
val memoryOnly = newValue == ProviderType.MEMORY_ONLY
|
||||
currentProvider.memoryOnly = memoryOnly
|
||||
if (memoryOnly) {
|
||||
currentProvider.deleteFileStorage()
|
||||
val provider = currentProvider
|
||||
if (provider is FilePasswordSafeProvider) {
|
||||
provider.memoryOnly = true
|
||||
provider.deleteFileStorage()
|
||||
}
|
||||
else {
|
||||
currentProvider = FilePasswordSafeProvider(memoryOnly = true)
|
||||
}
|
||||
}
|
||||
else {
|
||||
currentProvider = createPersistentCredentialStore(currentProvider as? FilePasswordSafeProvider)
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -77,7 +91,7 @@ class PasswordSafeImpl(/* public - backward compatibility */val settings: Passwo
|
||||
}
|
||||
|
||||
override fun save() {
|
||||
currentProvider.save()
|
||||
(currentProvider as? FilePasswordSafeProvider)?.let { it.save() }
|
||||
}
|
||||
|
||||
fun clearPasswords() {
|
||||
@@ -88,7 +102,7 @@ class PasswordSafeImpl(/* public - backward compatibility */val settings: Passwo
|
||||
}
|
||||
}
|
||||
finally {
|
||||
currentProvider.clear()
|
||||
(currentProvider as? FilePasswordSafeProvider)?.let { it.clear() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,3 +118,17 @@ class PasswordSafeImpl(/* public - backward compatibility */val settings: Passwo
|
||||
val memoryProvider: PasswordSafeProvider
|
||||
get() = memoryHelperProvider.value
|
||||
}
|
||||
|
||||
private fun createPersistentCredentialStore(existing: FilePasswordSafeProvider? = null): PasswordSafeProvider {
|
||||
LOG.catchAndLog {
|
||||
if (isMacOsCredentialsStoreSupported && com.intellij.util.SystemProperties.getBooleanProperty("use.osx.keychain", false)) {
|
||||
return MacOsCredentialStore("IntelliJ Platform")
|
||||
}
|
||||
}
|
||||
|
||||
existing?.let {
|
||||
it.memoryOnly = false
|
||||
return it
|
||||
}
|
||||
return FilePasswordSafeProvider()
|
||||
}
|
||||
@@ -31,7 +31,6 @@ import com.intellij.openapi.util.SystemInfo
|
||||
import gnu.trove.THashMap
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Paths
|
||||
import java.util.*
|
||||
import java.util.function.Function
|
||||
|
||||
private val TEST_PASSWORD_VALUE = "test password"
|
||||
@@ -112,8 +111,6 @@ internal fun convertOldDb(oldKey: String, @Suppress("DEPRECATION") db: PasswordD
|
||||
return newDb
|
||||
}
|
||||
|
||||
fun toOldKey(hash: ByteArray) = "old-hashed-key|" + Base64.getEncoder().encodeToString(hash)
|
||||
|
||||
private fun rawTestKey(oldKey: String) = EncryptionUtil.hash("com.intellij.ide.passwordSafe.impl.providers.masterKey.MasterKeyPasswordSafe/TEST_PASSWORD:${oldKey}".toByteArray())
|
||||
|
||||
internal class PasswordDatabaseConvertor : ApplicationLoadListener {
|
||||
|
||||
+2
-7
@@ -20,16 +20,11 @@ import com.intellij.ide.passwordSafe.PasswordStorage;
|
||||
/**
|
||||
* The provider for password safe component
|
||||
*/
|
||||
public abstract class PasswordSafeProvider implements PasswordStorage {
|
||||
public interface PasswordSafeProvider extends PasswordStorage {
|
||||
/**
|
||||
* @return true, the implementation is supported in the current environment
|
||||
*/
|
||||
public boolean isSupported() {
|
||||
default boolean isSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name of provider
|
||||
*/
|
||||
public abstract String getName();
|
||||
}
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
/**
|
||||
* Base Java-based provider for password safe that assumes a simple key-value storage.
|
||||
*/
|
||||
public abstract class BasePasswordSafeProvider extends PasswordSafeProvider {
|
||||
public abstract class BasePasswordSafeProvider implements PasswordSafeProvider {
|
||||
|
||||
/**
|
||||
* <p>Get secret key for the provider.</p>
|
||||
|
||||
-5
@@ -83,11 +83,6 @@ public class MemoryPasswordSafe extends BasePasswordSafeProvider {
|
||||
database.get().put(new ByteArrayWrapper(key), encryptedPassword);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Memory PasswordSafe";
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
database.get().clear();
|
||||
}
|
||||
|
||||
@@ -13,100 +13,51 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.ide.passwordSafe
|
||||
package com.intellij.ide.passwordSafe.macOs
|
||||
|
||||
import com.intellij.ide.passwordSafe.LOG
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
import com.sun.jna.Pointer
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.CharBuffer
|
||||
|
||||
val isOSXCredentialsStoreSupported: Boolean
|
||||
val isMacOsCredentialsStoreSupported: Boolean
|
||||
get() = SystemInfo.isMacIntel64 && SystemInfo.isMacOSLeopard
|
||||
|
||||
private val LIBRARY = com.sun.jna.Native.loadLibrary("Security", MacOsKeychainLibrary::class.java) as MacOsKeychainLibrary
|
||||
|
||||
fun saveGenericPassword(serviceName: ByteArray, accountName: String, password: String) {
|
||||
saveGenericPassword(serviceName, accountName, password.toByteArray())
|
||||
}
|
||||
|
||||
private fun saveGenericPassword(serviceName: ByteArray, accountName: String, passwordData: ByteArray) {
|
||||
saveGenericPassword(serviceName, accountName, passwordData, passwordData.size)
|
||||
}
|
||||
|
||||
fun findGenericPassword(serviceName: ByteArray, accountName: String): String? {
|
||||
val accountNameBytes = accountName.toByteArray()
|
||||
val passwordSize = IntArray(1)
|
||||
val passwordData = arrayOf<Pointer?>(null)
|
||||
checkForError("find", LIBRARY.SecKeychainFindGenericPassword(null, serviceName.size, serviceName, accountNameBytes.size, accountNameBytes, passwordSize, passwordData))
|
||||
val pointer = passwordData[0] ?: return null
|
||||
|
||||
val result = String(pointer.getByteArray(0, passwordSize[0]))
|
||||
LIBRARY.SecKeychainItemFreeContent(null, pointer)
|
||||
return result
|
||||
}
|
||||
|
||||
fun deleteGenericPassword(serviceName: ByteArray, accountName: String) {
|
||||
val itemRef = arrayOf<Pointer?>(null)
|
||||
val accountNameBytes = accountName.toByteArray()
|
||||
checkForError("find (for delete)", LIBRARY.SecKeychainFindGenericPassword(null, serviceName.size, serviceName, accountNameBytes.size, accountNameBytes, null, null, itemRef))
|
||||
val pointer = itemRef[0]
|
||||
if (pointer != null) {
|
||||
checkForError("delete", LIBRARY.SecKeychainItemDelete(pointer))
|
||||
LIBRARY.CFRelease(pointer)
|
||||
}
|
||||
}
|
||||
|
||||
// http://developer.apple.com/mac/library/DOCUMENTATION/Security/Reference/keychainservices/Reference/reference.html
|
||||
// It is very, very important to use CFRelease/SecKeychainItemFreeContent You must do it, otherwise you can get "An invalid record was encountered."
|
||||
interface MacOsKeychainLibrary : com.sun.jna.Library {
|
||||
companion object {
|
||||
private val LIBRARY = com.sun.jna.Native.loadLibrary("Security", MacOsKeychainLibrary::class.java) as MacOsKeychainLibrary
|
||||
|
||||
fun saveGenericPassword(serviceName: ByteArray, accountName: String, password: CharArray) {
|
||||
saveGenericPassword(serviceName, accountName, Charsets.UTF_8.encode(CharBuffer.wrap(password)))
|
||||
}
|
||||
|
||||
fun saveGenericPassword(serviceName: ByteArray, accountName: String, password: String) {
|
||||
saveGenericPassword(serviceName, accountName, Charsets.UTF_8.encode(password))
|
||||
}
|
||||
|
||||
private fun saveGenericPassword(serviceName: ByteArray, accountName: String, passwordBuffer: ByteBuffer) {
|
||||
val passwordData: ByteArray
|
||||
val passwordDataSize = passwordBuffer.limit()
|
||||
if (passwordBuffer.hasArray() && passwordBuffer.arrayOffset() == 0) {
|
||||
passwordData = passwordBuffer.array()
|
||||
}
|
||||
else {
|
||||
passwordData = ByteArray(passwordDataSize)
|
||||
passwordBuffer.get(passwordData)
|
||||
}
|
||||
saveGenericPassword(serviceName, accountName, passwordData, passwordDataSize)
|
||||
}
|
||||
|
||||
fun findGenericPassword(serviceName: ByteArray, accountName: String): String? {
|
||||
val accountNameBytes = accountName.toByteArray()
|
||||
val passwordSize = IntArray(1)
|
||||
val passwordData = arrayOf<Pointer?>(null)
|
||||
checkForError("find", LIBRARY.SecKeychainFindGenericPassword(null, serviceName.size, serviceName, accountNameBytes.size, accountNameBytes, passwordSize, passwordData))
|
||||
val pointer = passwordData[0] ?: return null
|
||||
|
||||
val result = String(pointer.getByteArray(0, passwordSize[0]))
|
||||
LIBRARY.SecKeychainItemFreeContent(null, pointer)
|
||||
return result
|
||||
}
|
||||
|
||||
private fun saveGenericPassword(serviceName: ByteArray, accountName: String, password: ByteArray, passwordSize: Int) {
|
||||
val accountNameBytes = accountName.toByteArray()
|
||||
val itemRef = arrayOf<Pointer?>(null)
|
||||
checkForError("find (for save)", LIBRARY.SecKeychainFindGenericPassword(null, serviceName.size, serviceName, accountNameBytes.size, accountNameBytes, null, null, itemRef))
|
||||
val pointer = itemRef[0]
|
||||
if (pointer == null) {
|
||||
checkForError("save (new)", LIBRARY.SecKeychainAddGenericPassword(null, serviceName.size, serviceName, accountNameBytes.size, accountNameBytes, passwordSize, password))
|
||||
}
|
||||
else {
|
||||
checkForError("save (update)", LIBRARY.SecKeychainItemModifyContent(pointer, null, passwordSize, password))
|
||||
LIBRARY.CFRelease(pointer)
|
||||
}
|
||||
}
|
||||
|
||||
fun deleteGenericPassword(serviceName: ByteArray, accountName: String) {
|
||||
val itemRef = arrayOf<Pointer?>(null)
|
||||
val accountNameBytes = accountName.toByteArray()
|
||||
checkForError("find (for delete)", LIBRARY.SecKeychainFindGenericPassword(null, serviceName.size, serviceName, accountNameBytes.size, accountNameBytes, null, null, itemRef))
|
||||
val pointer = itemRef[0]
|
||||
if (pointer != null) {
|
||||
checkForError("delete", LIBRARY.SecKeychainItemDelete(pointer))
|
||||
LIBRARY.CFRelease(pointer)
|
||||
}
|
||||
}
|
||||
|
||||
fun checkForError(message: String, code: Int) {
|
||||
if (code != 0 && code != /* errSecItemNotFound, always returned from find it seems */-25300) {
|
||||
val translated = LIBRARY.SecCopyErrorMessageString(code, null)
|
||||
val builder = StringBuilder(message).append(": ")
|
||||
if (translated == null) {
|
||||
builder.append(code)
|
||||
}
|
||||
else {
|
||||
val buf = CharArray(LIBRARY.CFStringGetLength(translated).toInt())
|
||||
for (i in 0..buf.size - 1) {
|
||||
buf[i] = LIBRARY.CFStringGetCharacterAtIndex(translated, i.toLong())
|
||||
}
|
||||
LIBRARY.CFRelease(translated)
|
||||
builder.append(buf).append(" (").append(code).append(')')
|
||||
}
|
||||
LOG.error(builder.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun SecKeychainAddGenericPassword(keychain: Pointer?, serviceNameLength: Int, serviceName: ByteArray, accountNameLength: Int, accountName: ByteArray, passwordLength: Int, passwordData: ByteArray, itemRef: Pointer? = null): Int
|
||||
|
||||
fun SecKeychainItemModifyContent(/*SecKeychainItemRef*/ itemRef: Pointer, /*SecKeychainAttributeList**/ attrList: Pointer?, length: Int, data: ByteArray): Int
|
||||
@@ -134,3 +85,36 @@ interface MacOsKeychainLibrary : com.sun.jna.Library {
|
||||
|
||||
fun SecKeychainItemFreeContent(/*SecKeychainAttributeList*/attrList: Pointer?, data: Pointer?)
|
||||
}
|
||||
|
||||
private fun saveGenericPassword(serviceName: ByteArray, accountName: String, password: ByteArray, passwordSize: Int) {
|
||||
val accountNameBytes = accountName.toByteArray()
|
||||
val itemRef = arrayOf<Pointer?>(null)
|
||||
checkForError("find (for save)", LIBRARY.SecKeychainFindGenericPassword(null, serviceName.size, serviceName, accountNameBytes.size, accountNameBytes, null, null, itemRef))
|
||||
val pointer = itemRef[0]
|
||||
if (pointer == null) {
|
||||
checkForError("save (new)", LIBRARY.SecKeychainAddGenericPassword(null, serviceName.size, serviceName, accountNameBytes.size, accountNameBytes, passwordSize, password))
|
||||
}
|
||||
else {
|
||||
checkForError("save (update)", LIBRARY.SecKeychainItemModifyContent(pointer, null, passwordSize, password))
|
||||
LIBRARY.CFRelease(pointer)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkForError(message: String, code: Int) {
|
||||
if (code != 0 && code != /* errSecItemNotFound, always returned from find it seems */-25300) {
|
||||
val translated = LIBRARY.SecCopyErrorMessageString(code, null)
|
||||
val builder = StringBuilder(message).append(": ")
|
||||
if (translated == null) {
|
||||
builder.append(code)
|
||||
}
|
||||
else {
|
||||
val buf = CharArray(LIBRARY.CFStringGetLength(translated).toInt())
|
||||
for (i in 0..buf.size - 1) {
|
||||
buf[i] = LIBRARY.CFStringGetCharacterAtIndex(translated, i.toLong())
|
||||
}
|
||||
LIBRARY.CFRelease(translated)
|
||||
builder.append(buf).append(" (").append(code).append(')')
|
||||
}
|
||||
LOG.error(builder.toString())
|
||||
}
|
||||
}
|
||||
@@ -163,7 +163,7 @@
|
||||
serviceImplementation="com.intellij.ide.passwordSafe.config.PasswordSafeSettings"/>
|
||||
<applicationService serviceInterface="com.intellij.ide.passwordSafe.PasswordSafe"
|
||||
serviceImplementation="com.intellij.ide.passwordSafe.impl.PasswordSafeImpl"/>
|
||||
<ApplicationLoadListener implementation="com.intellij.ide.passwordSafe.masterKey.PasswordDatabaseConvertor"/>
|
||||
<ApplicationLoadListener implementation="com.intellij.ide.passwordSafe.PasswordDatabaseConvertor"/>
|
||||
|
||||
<applicationConfigurable parentId="preferences.general" instance="com.intellij.ide.passwordSafe.config.PasswordSafeConfigurable" id="application.passwordSafe"
|
||||
displayName="Passwords"/>
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.jetbrains.settingsRepository
|
||||
import com.intellij.configurationStore.StateStorageManagerImpl
|
||||
import com.intellij.configurationStore.StreamProvider
|
||||
import com.intellij.ide.ApplicationLoadListener
|
||||
import com.intellij.ide.passwordSafe.isOSXCredentialsStoreSupported
|
||||
import com.intellij.ide.passwordSafe.macOs.isMacOsCredentialsStoreSupported
|
||||
import com.intellij.openapi.application.Application
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.PathManager
|
||||
@@ -56,7 +56,7 @@ val icsManager by lazy(LazyThreadSafetyMode.NONE) {
|
||||
class IcsManager(dir: Path) {
|
||||
val credentialsStore = object : AtomicNotNullLazyValue<CredentialsStore>() {
|
||||
override fun compute(): CredentialsStore {
|
||||
if (isOSXCredentialsStoreSupported && SystemProperties.getBooleanProperty("ics.use.osx.keychain", true)) {
|
||||
if (isMacOsCredentialsStoreSupported && SystemProperties.getBooleanProperty("use.osx.keychain", true)) {
|
||||
catchAndLog {
|
||||
return OsXCredentialsStore("IntelliJ Platform Settings Repository")
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package org.jetbrains.settingsRepository.git
|
||||
|
||||
import com.intellij.ide.passwordSafe.isOSXCredentialsStoreSupported
|
||||
import com.intellij.ide.passwordSafe.macOs.isMacOsCredentialsStoreSupported
|
||||
import com.intellij.openapi.ui.MessageDialogBuilder
|
||||
import com.intellij.openapi.ui.Messages
|
||||
import com.intellij.openapi.util.NotNullLazyValue
|
||||
@@ -94,7 +94,7 @@ class JGitCredentialsProvider(private val credentialsStore: NotNullLazyValue<Cre
|
||||
}
|
||||
else {
|
||||
// we open password protected SSH key file using OS X keychain - "git credentials" is pointless in this case
|
||||
if (sshKeyFile == null || !isOSXCredentialsStoreSupported) {
|
||||
if (sshKeyFile == null || !isMacOsCredentialsStoreSupported) {
|
||||
if (credentialsFromGit == null) {
|
||||
credentialsFromGit = getCredentialsUsingGit(uri, repository)
|
||||
}
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
*/
|
||||
package org.jetbrains.keychain
|
||||
|
||||
import com.intellij.ide.passwordSafe.MacOsKeychainLibrary
|
||||
import com.intellij.ide.passwordSafe.macOs.deleteGenericPassword
|
||||
import com.intellij.ide.passwordSafe.macOs.findGenericPassword
|
||||
import com.intellij.ide.passwordSafe.macOs.saveGenericPassword
|
||||
import com.intellij.openapi.util.PasswordUtil
|
||||
import gnu.trove.THashMap
|
||||
|
||||
@@ -39,7 +41,7 @@ class OsXCredentialsStore(serviceName: String) : CredentialsStore {
|
||||
return credentials
|
||||
}
|
||||
|
||||
val data = MacOsKeychainLibrary.findGenericPassword(getServiceName(sshKeyFile), accountName) ?: return null
|
||||
val data = findGenericPassword(getServiceName(sshKeyFile), accountName) ?: return null
|
||||
if (sshKeyFile == null) {
|
||||
val separatorIndex = data.indexOf('@')
|
||||
if (separatorIndex > 0) {
|
||||
@@ -73,12 +75,12 @@ class OsXCredentialsStore(serviceName: String) : CredentialsStore {
|
||||
}
|
||||
|
||||
val data = if (sshKeyFile == null) "${PasswordUtil.encodePassword(credentials.id)}@${PasswordUtil.encodePassword(credentials.token)}" else credentials.token!!
|
||||
MacOsKeychainLibrary.saveGenericPassword(getServiceName(sshKeyFile), accountName, data)
|
||||
saveGenericPassword(getServiceName(sshKeyFile), accountName, data)
|
||||
}
|
||||
|
||||
override fun reset(host: String) {
|
||||
if (accountToCredentials.remove(host) != null) {
|
||||
MacOsKeychainLibrary.deleteGenericPassword(serviceName, host)
|
||||
deleteGenericPassword(serviceName, host)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user