Add setting to save OpenKeychain auth keyid (#554)
* Add setting to save OpenKeychain auth keyid * Hide pref not disable Co-Authored-By: Reagan Sanders <vexofp@gmail.com> Signed-off-by: Harsh Shandilya <msfjarvis@gmail.com>
This commit is contained in:
parent
2fcec8685b
commit
cdf45bc323
11 changed files with 67 additions and 15 deletions
|
@ -66,6 +66,7 @@ class UserPreference : AppCompatActivity() {
|
|||
|
||||
// Git preferences
|
||||
val gitServerPreference = findPreference<Preference>("git_server_info")
|
||||
val openkeystoreIdPreference = findPreference<Preference>("ssh_openkeystore_clear_keyid")
|
||||
val gitConfigPreference = findPreference<Preference>("git_config")
|
||||
val sshKeyPreference = findPreference<Preference>("ssh_key")
|
||||
val sshKeygenPreference = findPreference<Preference>("ssh_keygen")
|
||||
|
@ -114,6 +115,7 @@ class UserPreference : AppCompatActivity() {
|
|||
OpenPgpUtils.convertKeyIdToHex(java.lang.Long.valueOf(s))
|
||||
}
|
||||
}
|
||||
openkeystoreIdPreference?.isVisible = sharedPreferences.getString("ssh_openkeystore_keyid", null)?.isNotEmpty() ?: false
|
||||
|
||||
// see if the autofill service is enabled and check the preference accordingly
|
||||
autoFillEnablePreference?.isChecked = callingActivity.isServiceEnabled
|
||||
|
@ -156,6 +158,12 @@ class UserPreference : AppCompatActivity() {
|
|||
true
|
||||
}
|
||||
|
||||
openkeystoreIdPreference?.onPreferenceClickListener = ClickListener {
|
||||
sharedPreferences.edit().putString("ssh_openkeystore_keyid", null).apply()
|
||||
it.isVisible = false
|
||||
true
|
||||
}
|
||||
|
||||
gitServerPreference?.onPreferenceClickListener = ClickListener {
|
||||
val intent = Intent(callingActivity, GitActivity::class.java)
|
||||
intent.putExtra("Operation", GitActivity.EDIT_SERVER)
|
||||
|
|
|
@ -64,6 +64,7 @@ class CloneOperation(fileDir: File, callingActivity: Activity) : GitOperation(fi
|
|||
}
|
||||
|
||||
override fun onError(errorMessage: String) {
|
||||
super.onError(errorMessage)
|
||||
MaterialAlertDialogBuilder(callingActivity)
|
||||
.setTitle(callingActivity.resources.getString(R.string.jgit_error_dialog_title))
|
||||
.setMessage("Error occured during the clone operation, " +
|
||||
|
|
|
@ -613,7 +613,7 @@ open class GitActivity : AppCompatActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(
|
||||
public override fun onActivityResult(
|
||||
requestCode: Int,
|
||||
resultCode: Int,
|
||||
data: Intent?
|
||||
|
@ -625,9 +625,17 @@ open class GitActivity : AppCompatActivity() {
|
|||
// background thread - the actual signing of the SSH challenge. We pass through the
|
||||
// completed signature to the ApiIdentity, which will be blocked in the other thread
|
||||
// waiting for it.
|
||||
if (requestCode == SshApiSessionFactory.POST_SIGNATURE && identity != null)
|
||||
if (requestCode == SshApiSessionFactory.POST_SIGNATURE && identity != null) {
|
||||
identity!!.postSignature(data)
|
||||
|
||||
// If the signature failed (usually because it was cancelled), reset state
|
||||
if (data == null) {
|
||||
identity = null
|
||||
identityBuilder = null
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (resultCode == AppCompatActivity.RESULT_CANCELED) {
|
||||
setResult(AppCompatActivity.RESULT_CANCELED)
|
||||
finish()
|
||||
|
|
|
@ -235,14 +235,11 @@ abstract class GitOperation(fileDir: File, internal val callingActivity: Activit
|
|||
* Action to execute on error
|
||||
*/
|
||||
open fun onError(errorMessage: String) {
|
||||
MaterialAlertDialogBuilder(callingActivity)
|
||||
.setTitle(callingActivity.resources.getString(R.string.jgit_error_dialog_title))
|
||||
.setMessage(callingActivity.resources.getString(R.string.jgit_error_dialog_text) + errorMessage)
|
||||
.setPositiveButton(callingActivity.resources.getString(R.string.dialog_ok)) { _, _ ->
|
||||
callingActivity.setResult(Activity.RESULT_CANCELED)
|
||||
callingActivity.finish()
|
||||
}
|
||||
.show()
|
||||
if (SshSessionFactory.getInstance() is SshApiSessionFactory) {
|
||||
// Clear stored key id from settings on auth failure
|
||||
PreferenceManager.getDefaultSharedPreferences(callingActivity.applicationContext)
|
||||
.edit().putString("ssh_openkeystore_keyid", null).apply()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -38,6 +38,7 @@ class PullOperation(fileDir: File, callingActivity: Activity) : GitOperation(fil
|
|||
}
|
||||
|
||||
override fun onError(errorMessage: String) {
|
||||
super.onError(errorMessage)
|
||||
MaterialAlertDialogBuilder(callingActivity)
|
||||
.setTitle(callingActivity.resources.getString(R.string.jgit_error_dialog_title))
|
||||
.setMessage("Error occured during the pull operation, " +
|
||||
|
|
|
@ -39,6 +39,7 @@ class PushOperation(fileDir: File, callingActivity: Activity) : GitOperation(fil
|
|||
|
||||
override fun onError(errorMessage: String) {
|
||||
// TODO handle the "Nothing to push" case
|
||||
super.onError(errorMessage)
|
||||
MaterialAlertDialogBuilder(callingActivity)
|
||||
.setTitle(callingActivity.resources.getString(R.string.jgit_error_dialog_title))
|
||||
.setMessage(callingActivity.getString(R.string.jgit_error_push_dialog_text) + errorMessage)
|
||||
|
|
|
@ -44,6 +44,7 @@ class ResetToRemoteOperation(fileDir: File, callingActivity: Activity) : GitOper
|
|||
}
|
||||
|
||||
override fun onError(errorMessage: String) {
|
||||
super.onError(errorMessage)
|
||||
MaterialAlertDialogBuilder(callingActivity)
|
||||
.setTitle(callingActivity.resources.getString(R.string.jgit_error_dialog_title))
|
||||
.setMessage("Error occured during the sync operation, " +
|
||||
|
|
|
@ -52,6 +52,7 @@ class SyncOperation(fileDir: File, callingActivity: Activity) : GitOperation(fil
|
|||
}
|
||||
|
||||
override fun onError(errorMessage: String) {
|
||||
super.onError(errorMessage)
|
||||
MaterialAlertDialogBuilder(callingActivity)
|
||||
.setTitle(callingActivity.resources.getString(R.string.jgit_error_dialog_title))
|
||||
.setMessage("Error occured during the sync operation, " +
|
||||
|
|
|
@ -8,7 +8,9 @@ import android.app.Activity;
|
|||
import android.app.PendingIntent;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentSender;
|
||||
import android.content.SharedPreferences;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.jcraft.jsch.Identity;
|
||||
import com.jcraft.jsch.JSch;
|
||||
|
@ -16,6 +18,7 @@ import com.jcraft.jsch.JSchException;
|
|||
import com.jcraft.jsch.Session;
|
||||
import com.jcraft.jsch.UserInfo;
|
||||
import com.zeapo.pwdstore.R;
|
||||
import com.zeapo.pwdstore.git.GitActivity;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import org.eclipse.jgit.errors.UnsupportedCredentialItem;
|
||||
|
@ -104,7 +107,8 @@ public class SshApiSessionFactory extends GitConfigSessionFactory {
|
|||
private SshAuthenticationApi api;
|
||||
private String keyId, description, alg;
|
||||
private byte[] publicKey;
|
||||
private Activity callingActivity;
|
||||
private GitActivity callingActivity;
|
||||
private SharedPreferences settings;
|
||||
|
||||
/**
|
||||
* Construct a new IdentityBuilder
|
||||
|
@ -112,7 +116,7 @@ public class SshApiSessionFactory extends GitConfigSessionFactory {
|
|||
* @param callingActivity Activity that will be used to launch pending intents and that will
|
||||
* receive and handle the results.
|
||||
*/
|
||||
public IdentityBuilder(Activity callingActivity) {
|
||||
public IdentityBuilder(GitActivity callingActivity) {
|
||||
this.callingActivity = callingActivity;
|
||||
|
||||
List<String> providers =
|
||||
|
@ -124,6 +128,11 @@ public class SshApiSessionFactory extends GitConfigSessionFactory {
|
|||
// TODO: Handle multiple available providers? Are there actually any in practice beyond
|
||||
// OpenKeychain?
|
||||
connection = new SshAuthenticationConnection(callingActivity, providers.get(0));
|
||||
|
||||
settings =
|
||||
PreferenceManager.getDefaultSharedPreferences(
|
||||
callingActivity.getApplicationContext());
|
||||
keyId = settings.getString("ssh_openkeystore_keyid", null);
|
||||
}
|
||||
|
||||
/** Free any resources associated with this IdentityBuilder */
|
||||
|
@ -146,7 +155,24 @@ public class SshApiSessionFactory extends GitConfigSessionFactory {
|
|||
case SshAuthenticationApi.RESULT_CODE_ERROR:
|
||||
SshAuthenticationApiError error =
|
||||
result.getParcelableExtra(SshAuthenticationApi.EXTRA_ERROR);
|
||||
throw new RuntimeException(error.getMessage());
|
||||
// On an OpenKeychain SSH API error, clear out the stored keyid
|
||||
settings.edit().putString("ssh_openkeystore_keyid", null).apply();
|
||||
|
||||
switch (error.getError()) {
|
||||
// If the problem was just a bad keyid, reset to allow them to choose a
|
||||
// different one
|
||||
case (SshAuthenticationApiError.NO_SUCH_KEY):
|
||||
case (SshAuthenticationApiError.NO_AUTH_KEY):
|
||||
keyId = null;
|
||||
publicKey = null;
|
||||
description = null;
|
||||
alg = null;
|
||||
return executeApi(new KeySelectionRequest(), requestCode);
|
||||
|
||||
// Other errors are fatal
|
||||
default:
|
||||
throw new RuntimeException(error.getMessage());
|
||||
}
|
||||
case SshAuthenticationApi.RESULT_CODE_SUCCESS:
|
||||
break;
|
||||
case SshAuthenticationApi.RESULT_CODE_USER_INTERACTION_REQUIRED:
|
||||
|
@ -181,6 +207,7 @@ public class SshApiSessionFactory extends GitConfigSessionFactory {
|
|||
if (intent.hasExtra(SshAuthenticationApi.EXTRA_KEY_ID)) {
|
||||
keyId = intent.getStringExtra(SshAuthenticationApi.EXTRA_KEY_ID);
|
||||
description = intent.getStringExtra(SshAuthenticationApi.EXTRA_KEY_DESCRIPTION);
|
||||
settings.edit().putString("ssh_openkeystore_keyid", keyId).apply();
|
||||
}
|
||||
|
||||
if (intent.hasExtra(SshAuthenticationApi.EXTRA_SSH_PUBLIC_KEY)) {
|
||||
|
@ -209,7 +236,8 @@ public class SshApiSessionFactory extends GitConfigSessionFactory {
|
|||
// We can immediately try the next phase without needing to post
|
||||
// back
|
||||
// though onActivityResult
|
||||
tryBuild(requestCode);
|
||||
callingActivity.onActivityResult(
|
||||
requestCode, Activity.RESULT_OK, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -342,7 +370,9 @@ public class SshApiSessionFactory extends GitConfigSessionFactory {
|
|||
*/
|
||||
public void postSignature(Intent data) {
|
||||
try {
|
||||
signature = handleSignResult(data);
|
||||
if (data != null) {
|
||||
signature = handleSignResult(data);
|
||||
}
|
||||
} finally {
|
||||
if (latch != null) latch.countDown();
|
||||
}
|
||||
|
|
|
@ -271,4 +271,5 @@
|
|||
<string name="biometric_auth_title">Enable biometric authentication</string>
|
||||
<string name="biometric_auth_summary">When enabled, Password Store will prompt you for your fingerprint when launching the app</string>
|
||||
<string name="biometric_auth_summary_error">Fingerprint hardware not accessible or missing</string>
|
||||
<string name="ssh_openkeystore_clear_keyid">Clear remembered OpenKeystore SSH Key ID</string>
|
||||
</resources>
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
<androidx.preference.Preference
|
||||
android:key="hotp_remember_clear_choice"
|
||||
android:title="@string/hotp_remember_clear_choice" />
|
||||
<androidx.preference.Preference
|
||||
android:key="ssh_openkeystore_clear_keyid"
|
||||
android:title="@string/ssh_openkeystore_clear_keyid" />
|
||||
<androidx.preference.Preference
|
||||
android:key="ssh_see_key"
|
||||
android:title="@string/pref_ssh_see_key_title" />
|
||||
|
|
Loading…
Reference in a new issue