mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-160375 Exception on attempt to connect to db with passwords converted from idea 2016.2
This commit is contained in:
@@ -84,7 +84,7 @@ fun findGenericPassword(serviceName: ByteArray, accountName: String?): Credentia
|
||||
checkForError("find", LIBRARY.SecKeychainFindGenericPassword(null, serviceName.size, serviceName, accountNameBytes?.size ?: 0, accountNameBytes, passwordSize, passwordRef, itemRef))
|
||||
|
||||
val pointer = passwordRef.value ?: return null
|
||||
val password = SecureString(pointer.getByteArray(0, passwordSize.get(0)))
|
||||
val password = OneTimeString(pointer.getByteArray(0, passwordSize.get(0)))
|
||||
LIBRARY.SecKeychainItemFreeContent(null, pointer)
|
||||
|
||||
var effectiveAccountName = accountName
|
||||
|
||||
@@ -59,7 +59,7 @@ fun Credentials?.isEmpty() = this == null || (userName == null && password == nu
|
||||
|
||||
// input will be cleared
|
||||
@JvmOverloads
|
||||
fun SecureString(value: ByteArray, offset: Int = 0, length: Int = value.size - offset): OneTimeString {
|
||||
fun OneTimeString(value: ByteArray, offset: Int = 0, length: Int = value.size - offset): OneTimeString {
|
||||
if (length == 0) {
|
||||
return OneTimeString(ArrayUtil.EMPTY_CHAR_ARRAY)
|
||||
}
|
||||
@@ -82,6 +82,8 @@ fun SecureString(value: ByteArray, offset: Int = 0, length: Int = value.size - o
|
||||
return OneTimeString(charArray, 0, charBuffer.position())
|
||||
}
|
||||
|
||||
private val oneTimeStringEnabled = com.intellij.util.SystemProperties.getBooleanProperty("one.time.string.enabled", false)
|
||||
|
||||
@Suppress("EqualsOrHashCode")
|
||||
// todo - eliminate toString
|
||||
class OneTimeString @JvmOverloads constructor(value: CharArray, offset: Int = 0, length: Int = value.size) : CharArrayCharSequence(value, offset, offset + length) {
|
||||
@@ -90,17 +92,22 @@ class OneTimeString @JvmOverloads constructor(value: CharArray, offset: Int = 0,
|
||||
constructor(value: String): this(value.toCharArray()) {
|
||||
}
|
||||
|
||||
private fun consume() {
|
||||
if (!consumed.compareAndSet(null, ExceptionUtil.currentStackTrace())) {
|
||||
private fun consume(willBeCleared: Boolean) {
|
||||
if (!oneTimeStringEnabled) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!willBeCleared) {
|
||||
consumed.get()?.let { throw IllegalStateException("Already consumed at $it") }
|
||||
}
|
||||
else if (!consumed.compareAndSet(null, ExceptionUtil.currentStackTrace())) {
|
||||
throw IllegalStateException("Already consumed at ${consumed.get()}")
|
||||
}
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun toString(clear: Boolean = true): String {
|
||||
if (clear) {
|
||||
consume()
|
||||
}
|
||||
consume(clear)
|
||||
// todo clear
|
||||
return super.toString()
|
||||
}
|
||||
@@ -108,12 +115,10 @@ class OneTimeString @JvmOverloads constructor(value: CharArray, offset: Int = 0,
|
||||
// string will be cleared and not valid after
|
||||
@JvmOverloads
|
||||
fun toByteArray(clear: Boolean = true): ByteArray {
|
||||
if (clear) {
|
||||
consume()
|
||||
}
|
||||
consume(clear)
|
||||
|
||||
val result = Charsets.UTF_8.encode(CharBuffer.wrap(myChars, myStart, length))
|
||||
if (clear) {
|
||||
if (clear && oneTimeStringEnabled) {
|
||||
myChars.fill('\u0000', myStart, myEnd)
|
||||
}
|
||||
return result.toByteArray()
|
||||
@@ -121,9 +126,7 @@ class OneTimeString @JvmOverloads constructor(value: CharArray, offset: Int = 0,
|
||||
|
||||
@JvmOverloads
|
||||
fun toCharArray(clear: Boolean = true): CharArray {
|
||||
if (clear) {
|
||||
consume()
|
||||
}
|
||||
consume(clear)
|
||||
// todo clear
|
||||
return chars
|
||||
}
|
||||
@@ -136,7 +139,7 @@ class OneTimeString @JvmOverloads constructor(value: CharArray, offset: Int = 0,
|
||||
}
|
||||
|
||||
fun appendTo(builder: StringBuilder) {
|
||||
consumed.get()?.let { throw IllegalStateException("Already consumed at $it") }
|
||||
consume(false)
|
||||
builder.append(myChars, myStart, length)
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.openapi.util;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -51,15 +52,15 @@ public class PasswordUtil {
|
||||
|
||||
@NotNull
|
||||
public static char[] decodePasswordAsCharArray(@Nullable String password) throws NumberFormatException {
|
||||
if (password == null) {
|
||||
if (StringUtil.isEmpty(password)) {
|
||||
return ArrayUtil.EMPTY_CHAR_ARRAY;
|
||||
}
|
||||
|
||||
char[] result = new char[password.length()];
|
||||
for (int i = 0; i < password.length(); i += 4) {
|
||||
char[] result = new char[password.length() / 4];
|
||||
for (int i = 0, j = 0; i < password.length(); i += 4, j++) {
|
||||
int c = Integer.parseInt(password.substring(i, i + 4), 16);
|
||||
c ^= 0xdfaa;
|
||||
result[i] = new Character((char)c).charValue();
|
||||
result[j] = new Character((char)c).charValue();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
+1
-1
@@ -200,7 +200,7 @@ public class EncryptionUtil {
|
||||
if (len < 0 || len > plain.length - 4) {
|
||||
throw new IllegalStateException("Unmatched password is used");
|
||||
}
|
||||
return CredentialAttributesKt.SecureString(plain, 4, len);
|
||||
return CredentialAttributesKt.OneTimeString(plain, 4, len);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user