diff --git a/app/src/main/java/app/trigger/MainActivity.java b/app/src/main/java/app/trigger/MainActivity.java index ca7c6706..3d60dadc 100644 --- a/app/src/main/java/app/trigger/MainActivity.java +++ b/app/src/main/java/app/trigger/MainActivity.java @@ -72,7 +72,6 @@ public class MainActivity extends AppCompatActivity implements OnTaskCompleted { private Bitmap state_unknown_default_image; private int ignore_wifi_check_for_setup_id = -1; - private HashMap ssh_passphrases_cache = new HashMap<>(); public enum Action { open_door, @@ -457,27 +456,25 @@ private boolean checkConnectedWifi(Setup setup, Action action) { private boolean checkSshPassphrase(Setup setup, Action action) { if (setup instanceof SshDoorSetup) { SshDoorSetup door = (SshDoorSetup) setup; - Integer id = door.getId(); - // check if passphrase is needed - if (door.keypair == null || !door.keypair.encrypted) { + // check if passphrase is not needed + if (!door.needsPassphrase() || !Utils.isEmpty(door.passphrase_tmp)) { return true; } - // try specific passphrase - if (ssh_passphrases_cache.containsKey(id)) { - String passphrase = ssh_passphrases_cache.get(id); - if (SshRequestHandler.testPassphrase(door.keypair, passphrase)) { - return true; + // try other passphrases + for (Setup s : Settings.getSetups()) { + if (s instanceof SshDoorSetup) { + continue; } - } - // try other passphrases - for (String passphrase : ssh_passphrases_cache.values()) { - if (SshRequestHandler.testPassphrase(door.keypair, passphrase)) { - showMessage("Use previous passphrase"); - ssh_passphrases_cache.put(id, passphrase); - return true; + SshDoorSetup ss = (SshDoorSetup) s; + if (ss.needsPassphrase() && !Utils.isEmpty(ss.passphrase_tmp)) { + if (SshRequestHandler.testPassphrase(door.keypair, ss.passphrase_tmp)) { + showMessage("Reuse passphrase from " + door.getName()); + door.passphrase_tmp = ss.passphrase_tmp; + return true; + } } } @@ -492,7 +489,7 @@ private boolean checkSshPassphrase(Setup setup, Action action) { okButton.setOnClickListener((View v) -> { String passphrase = passphraseEditText.getText().toString(); if (SshRequestHandler.testPassphrase(door.keypair, passphrase)) { - ssh_passphrases_cache.put(id, passphrase); + door.passphrase_tmp = passphrase; showMessage("Passphrase accepted"); callRequestHandler(action); } else { @@ -529,8 +526,7 @@ private void callRequestHandler(Action action) { HttpsRequestHandler handler = new HttpsRequestHandler(this, (HttpsDoorSetup) setup, action); handler.start(); } else if (setup instanceof SshDoorSetup) { - String passphrase = ssh_passphrases_cache.get(setup.getId()); - SshRequestHandler handler = new SshRequestHandler(this, (SshDoorSetup) setup, action, passphrase); + SshRequestHandler handler = new SshRequestHandler(this, (SshDoorSetup) setup, action); handler.start(); } else if (setup instanceof BluetoothDoorSetup) { BluetoothRequestHandler handler = new BluetoothRequestHandler(this, (BluetoothDoorSetup) setup, action); diff --git a/app/src/main/java/app/trigger/Settings.java b/app/src/main/java/app/trigger/Settings.java index 638c51bd..fce292d9 100644 --- a/app/src/main/java/app/trigger/Settings.java +++ b/app/src/main/java/app/trigger/Settings.java @@ -345,7 +345,9 @@ static JSONObject toJsonObject(Setup setup) { Class type = field.getType(); Object value = field.get(setup); - if (type == String.class) { + if (name.endsWith("_tmp")) { + // field is not meant to be stored + } else if (type == String.class) { obj.put(name, (String) value); } else if (type == Boolean.class) { obj.put(name, (Boolean) value); @@ -389,7 +391,9 @@ private static void setSetupField(Setup setup, JSONObject object, String name) for (Field field : fields) { if (field.getName().equals(name)) { Class type = field.getType(); - if (type == String.class && value_type == String.class) { + if (name.endsWith("_tmp")) { + // field is not meant to be loaded + } else if (type == String.class && value_type == String.class) { field.set(setup, value); } else if (type == Boolean.class && value_type == Boolean.class) { field.set(setup, (Boolean) value); @@ -578,8 +582,8 @@ private static Setup loadSetup_pre_172(int id) { try { String value = sharedPreferences.getString(key, ""); - if (name.equals("type")) { - // ignore, object field is read only + if (name.equals("type") || name.endsWith("_tmp")) { + // ignore, object field is not meant to be stored } else if (type == String.class) { field.set(setup, value); } else if (type == Boolean.class) { diff --git a/app/src/main/java/app/trigger/SshDoorSetup.java b/app/src/main/java/app/trigger/SshDoorSetup.java index 210ea66e..45dc6046 100644 --- a/app/src/main/java/app/trigger/SshDoorSetup.java +++ b/app/src/main/java/app/trigger/SshDoorSetup.java @@ -35,6 +35,7 @@ public class SshDoorSetup implements Setup { public String ssids; public int timeout; // milliseconds + public String passphrase_tmp; public SshDoorSetup(int id, String name) { this.id = id; @@ -129,4 +130,8 @@ public boolean canClose() { public boolean canRing() { return !Utils.isEmpty(ring_command); } + + boolean needsPassphrase() { + return this.keypair != null && this.keypair.encrypted; + } } diff --git a/app/src/main/java/app/trigger/ssh/SshRequestHandler.java b/app/src/main/java/app/trigger/ssh/SshRequestHandler.java index de775073..ef8dd3fe 100644 --- a/app/src/main/java/app/trigger/ssh/SshRequestHandler.java +++ b/app/src/main/java/app/trigger/ssh/SshRequestHandler.java @@ -32,7 +32,6 @@ public class SshRequestHandler extends Thread implements ConnectionMonitor { private final OnTaskCompleted listener; private final SshDoorSetup setup; private final Action action; - private final String passphrase; static { Log.d(TAG, "Ed25519Provider.insertIfNeeded2"); @@ -40,11 +39,10 @@ public class SshRequestHandler extends Thread implements ConnectionMonitor { Ed25519Provider.insertIfNeeded(); } - public SshRequestHandler(OnTaskCompleted listener, SshDoorSetup setup, Action action, String passphrase) { + public SshRequestHandler(OnTaskCompleted listener, SshDoorSetup setup, Action action) { this.listener = listener; this.setup = setup; this.action = action; - this.passphrase = passphrase; } public void run() { @@ -100,11 +98,12 @@ public void run() { // authentication by key pair if (keypair != null && !connection.isAuthenticationComplete()) { - KeyPair kp = decodeKeyPair(setup.keypair, this.passphrase); + KeyPair kp = decodeKeyPair(setup.keypair, setup.passphrase_tmp); if (kp != null) { connection.authenticateWithPublicKey(username, kp); } else { if (keypair.encrypted) { + setup.passphrase_tmp = ""; // reset (incorrect) passphrase listener.onTaskResult(setup.getId(), ReplyCode.LOCAL_ERROR, "Key pair passphrase was not accepted."); } else { listener.onTaskResult(setup.getId(), ReplyCode.LOCAL_ERROR, "Failed to decode key pair.");