Skip to content

Commit

Permalink
ssh: simplify passphrase implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
mwarning committed Mar 20, 2022
1 parent 1783e50 commit c5f04ce
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 27 deletions.
34 changes: 15 additions & 19 deletions app/src/main/java/app/trigger/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<Integer, String> ssh_passphrases_cache = new HashMap<>();

public enum Action {
open_door,
Expand Down Expand Up @@ -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;
}
}
}

Expand All @@ -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 {
Expand Down Expand Up @@ -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);
Expand Down
12 changes: 8 additions & 4 deletions app/src/main/java/app/trigger/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/java/app/trigger/SshDoorSetup.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -129,4 +130,8 @@ public boolean canClose() {
public boolean canRing() {
return !Utils.isEmpty(ring_command);
}

boolean needsPassphrase() {
return this.keypair != null && this.keypair.encrypted;
}
}
7 changes: 3 additions & 4 deletions app/src/main/java/app/trigger/ssh/SshRequestHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,17 @@ 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");
// Since this class deals with Ed25519 keys, we need to make sure this is available.
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() {
Expand Down Expand Up @@ -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.");
Expand Down

0 comments on commit c5f04ce

Please sign in to comment.