@@ -27,7 +27,7 @@ public abstract class Connection implements AutoCloseable {
27
27
private final PropertyChangeSupport support ;
28
28
29
29
private TweetNaclFast .Box box ;
30
- private Optional < Credentials > credentials ;
30
+ private Credentials credentials ;
31
31
private final String clientID ;
32
32
private static final int nonceLength = 24 ;
33
33
private byte [] nonce ;
@@ -87,7 +87,6 @@ public Connection() {
87
87
new Random ().nextBytes (array );
88
88
clientID = b64encode (array );
89
89
nonce = TweetNaclFast .randombytes (nonceLength );
90
- credentials = Optional .empty ();
91
90
support = new PropertyChangeSupport (this );
92
91
scheduler = Executors .newSingleThreadScheduledExecutor ();
93
92
}
@@ -116,18 +115,18 @@ public void run() {
116
115
if (!isSignal (response )) LOG .trace ("Response added to queue: {}" , response );
117
116
queue .offer (response );
118
117
errorCount = 0 ;
119
- } else {
120
- errorCount ++;
121
- if (errorCount > MAX_ERROR_COUNT ) {
122
- LOG .info ("Too much errors - stopping MessagePublisher" );
123
- doStop ();
124
- try {
125
- terminateConnection ();
126
- } catch (IOException e ) {
127
- LOG .error (e .toString (), e .getCause ());
128
- }
129
- reconnect ();
118
+ continue ;
119
+ }
120
+ errorCount ++;
121
+ if (errorCount > MAX_ERROR_COUNT ) {
122
+ LOG .info ("Too much errors - stopping MessagePublisher" );
123
+ doStop ();
124
+ try {
125
+ terminateConnection ();
126
+ } catch (IOException e ) {
127
+ LOG .error (e .toString (), e .getCause ());
130
128
}
129
+ reconnect ();
131
130
}
132
131
}
133
132
LOG .debug ("MessagePublisher stopped" );
@@ -270,8 +269,13 @@ private synchronized byte[] sendEncryptedMessage(Map<String, Object> msg) throws
270
269
throw new IllegalStateException (NOT_CONNECTED );
271
270
}
272
271
273
- var publicKey = credentials .orElseThrow (() -> new IllegalStateException (KEYEXCHANGE_MISSING )).getServerPublicKey ();
274
- var keyPair = credentials .orElseThrow (() -> new IllegalStateException (KEYEXCHANGE_MISSING )).getOwnKeypair ();
272
+ var publicKey = Optional .ofNullable (credentials ).orElseThrow (
273
+ () -> new IllegalStateException (KEYEXCHANGE_MISSING )
274
+ ).getServerPublicKey ();
275
+
276
+ var keyPair = Optional .ofNullable (credentials ).orElseThrow (
277
+ () -> new IllegalStateException (KEYEXCHANGE_MISSING )
278
+ ).getOwnKeypair ();
275
279
276
280
if (msg .containsKey ("triggerUnlock" ) && msg .get ("triggerUnlock" ).equals ("true" )) {
277
281
msg .remove ("triggerUnlock" );
@@ -386,11 +390,11 @@ protected void changePublicKeys() throws IOException, KeepassProxyAccessExceptio
386
390
var publicKey = b64decode (response .getString ("publicKey" ).getBytes ());
387
391
box = new TweetNaclFast .Box (publicKey , keyPair .getSecretKey ());
388
392
389
- if (credentials .isEmpty ()) {
390
- setCredentials (Optional . of ( new Credentials ()) );
393
+ if (Optional . ofNullable ( credentials ) .isEmpty ()) {
394
+ setCredentials (null );
391
395
}
392
- credentials .orElseThrow (() -> new IllegalStateException (MISSING_CLASS )).setOwnKeypair (keyPair );
393
- credentials .orElseThrow (() -> new IllegalStateException (MISSING_CLASS )).setServerPublicKey (publicKey );
396
+ Optional . ofNullable ( credentials ) .orElseThrow (() -> new IllegalStateException (MISSING_CLASS )).setOwnKeypair (keyPair );
397
+ Optional . ofNullable ( credentials ) .orElseThrow (() -> new IllegalStateException (MISSING_CLASS )).setServerPublicKey (publicKey );
394
398
support .firePropertyChange ("credentialsCreated" , null , credentials );
395
399
396
400
}
@@ -404,7 +408,8 @@ protected void changePublicKeys() throws IOException, KeepassProxyAccessExceptio
404
408
*/
405
409
public void associate () throws IOException , KeepassProxyAccessException {
406
410
var idKeyPair = TweetNaclFast .Box .keyPair ();
407
- var keyPair = credentials .orElseThrow (() -> new IllegalStateException (KEYEXCHANGE_MISSING )).getOwnKeypair ();
411
+ var keyPair = Optional .ofNullable (credentials ).orElseThrow (
412
+ () -> new IllegalStateException (KEYEXCHANGE_MISSING )).getOwnKeypair ();
408
413
409
414
// Send associate request
410
415
var nonce = sendEncryptedMessage (Map .of (
@@ -427,8 +432,12 @@ public void associate() throws IOException, KeepassProxyAccessException {
427
432
LOG .error (e .toString (), e .getCause ());
428
433
}
429
434
assert response != null ;
430
- credentials .orElseThrow (() -> new IllegalStateException (MISSING_CLASS )).setAssociateId (response .getString ("id" ));
431
- credentials .orElseThrow (() -> new IllegalStateException (MISSING_CLASS )).setIdKeyPublicKey (idKeyPair .getPublicKey ());
435
+ Optional .ofNullable (credentials ).orElseThrow (
436
+ () -> new IllegalStateException (MISSING_CLASS )).setAssociateId (response .getString ("id" ));
437
+
438
+ Optional .ofNullable (credentials ).orElseThrow (
439
+ () -> new IllegalStateException (MISSING_CLASS )).setIdKeyPublicKey (idKeyPair .getPublicKey ());
440
+
432
441
support .firePropertyChange ("associated" , null , credentials );
433
442
};
434
443
scheduler .schedule (lookupResponse , RESPONSE_DELAY_MS , TimeUnit .MILLISECONDS );
@@ -438,16 +447,20 @@ public void associate() throws IOException, KeepassProxyAccessException {
438
447
/**
439
448
* Request for receiving the database hash (SHA256) of the current active KeePassXC database.
440
449
*
441
- * @return The database hash of the current active KeePassXC database.
450
+ * @return The database hash of the current active KeePassXC database. Empty if the database is locked.
442
451
* @throws IOException Retrieving the hash failed due to technical reasons.
443
452
* @throws KeepassProxyAccessException It was impossible to get the hash.
444
453
*/
445
- public String getDatabasehash () throws IOException , KeepassProxyAccessException {
454
+ public Optional < String > getDatabasehash () throws IOException , KeepassProxyAccessException {
446
455
// Send get-databasehash request
447
456
var nonce = sendEncryptedMessage (Map .of ("action" , Message .GET_DATABASE_HASH .action ));
448
457
var response = getEncryptedResponseAndDecrypt (Message .GET_DATABASE_HASH .action , nonce );
449
458
450
- return response .getString ("hash" );
459
+ if (response .has ("hash" ) && !response .getString ("hash" ).isBlank ()) {
460
+ return Optional .of (response .getString ("hash" ));
461
+ }
462
+
463
+ return Optional .empty ();
451
464
}
452
465
453
466
/**
@@ -459,15 +472,15 @@ public String getDatabasehash() throws IOException, KeepassProxyAccessException
459
472
* @throws IOException Retrieving the hash failed due to technical reasons.
460
473
* @throws KeepassProxyAccessException It was impossible to get the hash.
461
474
*/
462
- public String getDatabasehash (boolean triggerUnlock ) throws IOException , KeepassProxyAccessException {
475
+ public Optional < String > getDatabasehash (boolean triggerUnlock ) throws IOException , KeepassProxyAccessException {
463
476
// Send get-databasehash request with triggerUnlock, if needed
464
477
var map = new HashMap <String , Object >(); // Map.of can't be used here, because we need a mutable object
465
478
map .put ("action" , Message .GET_DATABASE_HASH .action );
466
479
map .put ("triggerUnlock" , Boolean .toString (triggerUnlock ));
467
480
var nonce = sendEncryptedMessage (map );
468
481
var response = getEncryptedResponseAndDecrypt (Message .GET_DATABASE_HASH .action , nonce );
469
482
470
- return response .getString ("hash" );
483
+ return Optional . ofNullable ( response .getString ("hash" ) );
471
484
}
472
485
473
486
/**
@@ -832,15 +845,15 @@ private JSONArray checkKeysList(List<Map<String, String>> list) throws KeepassPr
832
845
}
833
846
834
847
// Getters and Setters
835
- public String getIdKeyPairPublicKey () {
836
- return credentials .map (value -> b64encode (value .getIdKeyPublicKey ())). orElse ( "" );
848
+ public Optional < String > getIdKeyPairPublicKey () {
849
+ return Optional . ofNullable ( credentials ) .map (value -> b64encode (value .getIdKeyPublicKey ()));
837
850
}
838
851
839
- public String getAssociateId () {
840
- return credentials . map (Credentials ::getAssociateId ). orElse ( "" );
852
+ public Optional < String > getAssociateId () {
853
+ return Optional . ofNullable ( this . credentials ). flatMap (Credentials ::getAssociateId );
841
854
}
842
855
843
- public void setCredentials (Optional < Credentials > credentials ) {
856
+ public void setCredentials (Credentials credentials ) {
844
857
this .credentials = credentials ;
845
858
}
846
859
0 commit comments