@@ -18,8 +18,8 @@ class MacKeychain {
18
18
* Associates the specified password with the specified key in the system keychain.
19
19
*
20
20
* @param serviceName Service name
21
- * @param account Unique account identifier
22
- * @param password Passphrase to store
21
+ * @param account Unique account identifier
22
+ * @param password Passphrase to store
23
23
* @see <a href="https://developer.apple.com/documentation/security/1398366-seckeychainaddgenericpassword">SecKeychainAddGenericPassword</a>
24
24
*/
25
25
public void storePassword (String serviceName , String account , CharSequence password ) throws KeychainAccessException {
@@ -38,13 +38,18 @@ public void storePassword(String serviceName, String account, CharSequence passw
38
38
* Loads the password associated with the specified key from the system keychain.
39
39
*
40
40
* @param serviceName Service name
41
- * @param account Unique account identifier
41
+ * @param account Unique account identifier
42
42
* @return password or <code>null</code> if no such keychain entry could be loaded from the keychain.
43
43
* @see <a href="https://developer.apple.com/documentation/security/1397301-seckeychainfindgenericpassword">SecKeychainFindGenericPassword</a>
44
44
*/
45
45
public char [] loadPassword (String serviceName , String account ) {
46
46
byte [] pwBytes = Native .INSTANCE .loadPassword (serviceName .getBytes (UTF_8 ), account .getBytes (UTF_8 ));
47
47
if (pwBytes == null ) {
48
+ // this if-statement is a workaround for https://github.com/cryptomator/integrations-mac/issues/13:
49
+ if ("Cryptomator" .equals (serviceName ) && tryMigratePassword (account )) {
50
+ // on success: retry
51
+ return loadPassword (serviceName , account );
52
+ }
48
53
return null ;
49
54
} else {
50
55
CharBuffer pwBuf = UTF_8 .decode (ByteBuffer .wrap (pwBytes ));
@@ -56,14 +61,36 @@ public char[] loadPassword(String serviceName, String account) {
56
61
}
57
62
}
58
63
64
+ /**
65
+ * Fix for <a href="https://github.com/cryptomator/integrations-mac/issues/13">Issue 13</a>.
66
+ * Attempts to find the account with the old hard-coded service name 'Cryptomator\0'
67
+ *
68
+ * @param account Unique account identifier
69
+ * @return <code>true</code> on success
70
+ */
71
+ private boolean tryMigratePassword (String account ) {
72
+ byte [] oldServiceName = {'C' , 'r' , 'y' , 'p' , 't' , 'o' , 'm' , 'a' , 't' , 'o' , 'r' , '\0' };
73
+ byte [] newServiceName = {'C' , 'r' , 'y' , 'p' , 't' , 'o' , 'm' , 'a' , 't' , 'o' , 'r' };
74
+ byte [] pwBytes = Native .INSTANCE .loadPassword (oldServiceName , account .getBytes (UTF_8 ));
75
+ if (pwBytes == null ) {
76
+ return false ;
77
+ }
78
+ int errorCode = Native .INSTANCE .storePassword (newServiceName , account .getBytes (UTF_8 ), pwBytes );
79
+ Arrays .fill (pwBytes , (byte ) 0x00 );
80
+ if (errorCode != OSSTATUS_SUCCESS ) {
81
+ return false ;
82
+ }
83
+ Native .INSTANCE .deletePassword (oldServiceName , account .getBytes (UTF_8 ));
84
+ return true ;
85
+ }
86
+
59
87
/**
60
88
* Deletes the password associated with the specified key from the system keychain.
61
89
*
62
90
* @param serviceName Service name
63
- * @param account Unique account identifier
91
+ * @param account Unique account identifier
64
92
* @return <code>true</code> if the passwords has been deleted, <code>false</code> if no entry for the given key exists.
65
93
* @see <a href="https://developer.apple.com/documentation/security/1395547-secitemdelete">SecKeychainItemDelete</a>
66
-
67
94
*/
68
95
public boolean deletePassword (String serviceName , String account ) throws KeychainAccessException {
69
96
int errorCode = Native .INSTANCE .deletePassword (serviceName .getBytes (UTF_8 ), account .getBytes (UTF_8 ));
0 commit comments