aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/main/java/dev/msfjarvis/aps/util/git
diff options
context:
space:
mode:
authorHarsh Shandilya <me@msfjarvis.dev>2021-05-15 12:56:49 +0530
committerHarsh Shandilya <me@msfjarvis.dev>2021-05-15 15:40:20 +0530
commit7e2eb2425e7b9b6ccb37b7b89f19de3fa7a20c44 (patch)
tree6b8a9557ac51b5fab5d2ad7611084cf0de6c57cf /app/src/main/java/dev/msfjarvis/aps/util/git
parent2fcb285e276594842798be6990b92ba09e733f49 (diff)
downloadHardenedPass-7e2eb2425e7b9b6ccb37b7b89f19de3fa7a20c44.tar.gz
HardenedPass-7e2eb2425e7b9b6ccb37b7b89f19de3fa7a20c44.zip
all: reformat with Spotless again
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
Diffstat (limited to 'app/src/main/java/dev/msfjarvis/aps/util/git')
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/ErrorMessages.kt3
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/GitCommandExecutor.kt6
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/GitCommit.kt7
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/GitLogModel.kt4
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/operation/BreakOutOfDetached.kt16
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/operation/CloneOperation.kt3
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/operation/CredentialFinder.kt15
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/operation/GitOperation.kt33
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/operation/PushOperation.kt3
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/operation/ResetToRemoteOperation.kt3
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/sshj/OpenKeychainKeyProvider.kt36
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/sshj/OpenKeychainWrappedKeyAlgorithmFactory.kt12
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshKey.kt45
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshjConfig.kt36
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshjSessionFactory.kt29
15 files changed, 178 insertions, 73 deletions
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/ErrorMessages.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/ErrorMessages.kt
index 04809fdd..36dc445f 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/ErrorMessages.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/ErrorMessages.kt
@@ -14,7 +14,8 @@ import java.net.UnknownHostException
/**
* Supertype for all Git-related [Exception] s that can be thrown by [GitCommandExecutor.execute].
*/
-sealed class GitException(@StringRes res: Int, vararg fmt: String) : Exception(buildMessage(res, *fmt)) {
+sealed class GitException(@StringRes res: Int, vararg fmt: String) :
+ Exception(buildMessage(res, *fmt)) {
override val message = super.message!!
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/GitCommandExecutor.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/GitCommandExecutor.kt
index 4546aee1..7be06385 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/GitCommandExecutor.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/GitCommandExecutor.kt
@@ -74,11 +74,13 @@ class GitCommandExecutor(
// Code imported (modified) from Gerrit PushOp, license Apache v2
for (rru in result.remoteUpdates) {
when (rru.status) {
- RemoteRefUpdate.Status.REJECTED_NONFASTFORWARD -> throw PushException.NonFastForward
+ RemoteRefUpdate.Status.REJECTED_NONFASTFORWARD ->
+ throw PushException.NonFastForward
RemoteRefUpdate.Status.REJECTED_NODELETE,
RemoteRefUpdate.Status.REJECTED_REMOTE_CHANGED,
RemoteRefUpdate.Status.NON_EXISTING,
- RemoteRefUpdate.Status.NOT_ATTEMPTED, -> throw PushException.Generic(rru.status.name)
+ RemoteRefUpdate.Status.NOT_ATTEMPTED, ->
+ throw PushException.Generic(rru.status.name)
RemoteRefUpdate.Status.REJECTED_OTHER_REASON -> {
throw if ("non-fast-forward" == rru.message) {
PushException.RemoteRejected
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/GitCommit.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/GitCommit.kt
index 68b1c167..490f5e2c 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/GitCommit.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/GitCommit.kt
@@ -15,4 +15,9 @@ import java.util.Date
* @property authorName name of the commit's author without email address.
* @property time time when the commit was created.
*/
-data class GitCommit(val hash: String, val shortMessage: String, val authorName: String, val time: Date)
+data class GitCommit(
+ val hash: String,
+ val shortMessage: String,
+ val authorName: String,
+ val time: Date
+)
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/GitLogModel.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/GitLogModel.kt
index 1ba65086..bfef2571 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/GitLogModel.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/GitLogModel.kt
@@ -40,7 +40,9 @@ class GitLogModel {
// Additionally, tests with 1000 commits in the log have not produced a significant delay in the
// user experience.
private val cache: MutableList<GitCommit> by lazy(LazyThreadSafetyMode.NONE) {
- commits().map { GitCommit(it.hash, it.shortMessage, it.authorIdent.name, it.time) }.toMutableList()
+ commits()
+ .map { GitCommit(it.hash, it.shortMessage, it.authorIdent.name, it.time) }
+ .toMutableList()
}
val size = cache.size
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/BreakOutOfDetached.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/BreakOutOfDetached.kt
index 196d6d48..fd0aedf7 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/BreakOutOfDetached.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/BreakOutOfDetached.kt
@@ -11,13 +11,17 @@ import org.eclipse.jgit.api.RebaseCommand
import org.eclipse.jgit.api.ResetCommand
import org.eclipse.jgit.lib.RepositoryState
-class BreakOutOfDetached(callingActivity: ContinuationContainerActivity) : GitOperation(callingActivity) {
+class BreakOutOfDetached(callingActivity: ContinuationContainerActivity) :
+ GitOperation(callingActivity) {
private val merging = repository.repositoryState == RepositoryState.MERGING
private val resetCommands =
arrayOf(
// git checkout -b conflict-branch
- git.checkout().setCreateBranch(true).setName("conflicting-$remoteBranch-${System.currentTimeMillis()}"),
+ git
+ .checkout()
+ .setCreateBranch(true)
+ .setName("conflicting-$remoteBranch-${System.currentTimeMillis()}"),
// push the changes
git.push().setRemote("origin"),
// switch back to ${gitBranch}
@@ -47,8 +51,12 @@ class BreakOutOfDetached(callingActivity: ContinuationContainerActivity) : GitOp
if (!git.repository.repositoryState.isRebasing && !merging) {
MaterialAlertDialogBuilder(callingActivity)
.setTitle(callingActivity.resources.getString(R.string.git_abort_and_push_title))
- .setMessage(callingActivity.resources.getString(R.string.git_break_out_of_detached_unneeded))
- .setPositiveButton(callingActivity.resources.getString(R.string.dialog_ok)) { _, _ -> callingActivity.finish() }
+ .setMessage(
+ callingActivity.resources.getString(R.string.git_break_out_of_detached_unneeded)
+ )
+ .setPositiveButton(callingActivity.resources.getString(R.string.dialog_ok)) { _, _ ->
+ callingActivity.finish()
+ }
.show()
false
} else {
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/CloneOperation.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/CloneOperation.kt
index a5a4f5d0..75db2ea5 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/CloneOperation.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/CloneOperation.kt
@@ -14,7 +14,8 @@ import org.eclipse.jgit.api.GitCommand
* @param uri URL to clone the repository from
* @param callingActivity the calling activity
*/
-class CloneOperation(callingActivity: ContinuationContainerActivity, uri: String) : GitOperation(callingActivity) {
+class CloneOperation(callingActivity: ContinuationContainerActivity, uri: String) :
+ GitOperation(callingActivity) {
override val commands: Array<GitCommand<out Any>> =
arrayOf(
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/CredentialFinder.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/CredentialFinder.kt
index 40869cf2..e06cc996 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/CredentialFinder.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/CredentialFinder.kt
@@ -24,7 +24,8 @@ import dev.msfjarvis.aps.util.settings.PreferenceKeys
import kotlin.coroutines.Continuation
import kotlin.coroutines.resume
-class CredentialFinder(val callingActivity: FragmentActivity, val authMode: AuthMode) : InteractivePasswordFinder() {
+class CredentialFinder(val callingActivity: FragmentActivity, val authMode: AuthMode) :
+ InteractivePasswordFinder() {
override fun askForPassword(cont: Continuation<String?>, isRetry: Boolean) {
val gitOperationPrefs = callingActivity.getEncryptedGitPrefs()
@@ -49,18 +50,22 @@ class CredentialFinder(val callingActivity: FragmentActivity, val authMode: Auth
rememberRes = R.string.git_operation_remember_password
errorRes = R.string.git_operation_wrong_password
}
- else -> throw IllegalStateException("Only SshKey and Password connection mode ask for passwords")
+ else ->
+ throw IllegalStateException("Only SshKey and Password connection mode ask for passwords")
}
if (isRetry) gitOperationPrefs.edit { remove(credentialPref) }
val storedCredential = gitOperationPrefs.getString(credentialPref, null)
if (storedCredential == null) {
val layoutInflater = LayoutInflater.from(callingActivity)
- @SuppressLint("InflateParams") val dialogView = layoutInflater.inflate(R.layout.git_credential_layout, null)
- val credentialLayout = dialogView.findViewById<TextInputLayout>(R.id.git_auth_passphrase_layout)
+ @SuppressLint("InflateParams")
+ val dialogView = layoutInflater.inflate(R.layout.git_credential_layout, null)
+ val credentialLayout =
+ dialogView.findViewById<TextInputLayout>(R.id.git_auth_passphrase_layout)
val editCredential = dialogView.findViewById<TextInputEditText>(R.id.git_auth_credential)
editCredential.setHint(hintRes)
- val rememberCredential = dialogView.findViewById<MaterialCheckBox>(R.id.git_auth_remember_credential)
+ val rememberCredential =
+ dialogView.findViewById<MaterialCheckBox>(R.id.git_auth_remember_credential)
rememberCredential.setText(rememberRes)
if (isRetry) {
credentialLayout.error = callingActivity.resources.getString(errorRes)
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/GitOperation.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/GitOperation.kt
index 0d0dac9c..dbea37e8 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/GitOperation.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/GitOperation.kt
@@ -60,7 +60,8 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) {
private val authActivity
get() = callingActivity as ContinuationContainerActivity
- private class HttpsCredentialsProvider(private val passwordFinder: PasswordFinder) : CredentialsProvider() {
+ private class HttpsCredentialsProvider(private val passwordFinder: PasswordFinder) :
+ CredentialsProvider() {
private var cachedPassword: CharArray? = null
@@ -72,7 +73,8 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) {
is CredentialItem.Username -> item.value = uri?.user
is CredentialItem.Password -> {
item.value =
- cachedPassword?.clone() ?: passwordFinder.reqPassword(null).also { cachedPassword = it.clone() }
+ cachedPassword?.clone()
+ ?: passwordFinder.reqPassword(null).also { cachedPassword = it.clone() }
}
else -> UnsupportedCredentialItem(uri, item.javaClass.name)
}
@@ -102,7 +104,10 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) {
.onFailure { e -> e(e) }
}
- private fun registerAuthProviders(authMethod: SshAuthMethod, credentialsProvider: CredentialsProvider? = null) {
+ private fun registerAuthProviders(
+ authMethod: SshAuthMethod,
+ credentialsProvider: CredentialsProvider? = null
+ ) {
sshSessionFactory = SshjSessionFactory(authMethod, hostKeyFile)
commands.filterIsInstance<TransportCommand<*, *>>().forEach { command ->
command.setTransportConfigCallback { transport: Transport ->
@@ -132,12 +137,12 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) {
MaterialAlertDialogBuilder(callingActivity)
.setMessage(callingActivity.resources.getString(R.string.ssh_preferences_dialog_text))
.setTitle(callingActivity.resources.getString(R.string.ssh_preferences_dialog_title))
- .setPositiveButton(callingActivity.resources.getString(R.string.ssh_preferences_dialog_import)) { _, _ ->
- getSshKey(false)
- }
- .setNegativeButton(callingActivity.resources.getString(R.string.ssh_preferences_dialog_generate)) { _, _ ->
- getSshKey(true)
- }
+ .setPositiveButton(
+ callingActivity.resources.getString(R.string.ssh_preferences_dialog_import)
+ ) { _, _ -> getSshKey(false) }
+ .setNegativeButton(
+ callingActivity.resources.getString(R.string.ssh_preferences_dialog_generate)
+ ) { _, _ -> getSshKey(true) }
.setNeutralButton(callingActivity.resources.getString(R.string.dialog_cancel)) { _, _ ->
// Finish the blank GitActivity so user doesn't have to press back
callingActivity.finish()
@@ -153,9 +158,10 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) {
val result =
withContext(Dispatchers.Main) {
suspendCoroutine<BiometricAuthenticator.Result> { cont ->
- BiometricAuthenticator.authenticate(callingActivity, R.string.biometric_prompt_title_ssh_auth) {
- if (it !is BiometricAuthenticator.Result.Failure) cont.resume(it)
- }
+ BiometricAuthenticator.authenticate(
+ callingActivity,
+ R.string.biometric_prompt_title_ssh_auth
+ ) { if (it !is BiometricAuthenticator.Result.Failure) cont.resume(it) }
}
}
when (result) {
@@ -193,7 +199,8 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) {
}
AuthMode.OpenKeychain -> registerAuthProviders(SshAuthMethod.OpenKeychain(authActivity))
AuthMode.Password -> {
- val httpsCredentialProvider = HttpsCredentialsProvider(CredentialFinder(callingActivity, AuthMode.Password))
+ val httpsCredentialProvider =
+ HttpsCredentialsProvider(CredentialFinder(callingActivity, AuthMode.Password))
registerAuthProviders(SshAuthMethod.Password(authActivity), httpsCredentialProvider)
}
AuthMode.None -> {}
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/PushOperation.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/PushOperation.kt
index a9f168ad..14f16164 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/PushOperation.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/PushOperation.kt
@@ -7,7 +7,8 @@ package dev.msfjarvis.aps.util.git.operation
import dev.msfjarvis.aps.util.git.sshj.ContinuationContainerActivity
import org.eclipse.jgit.api.GitCommand
-class PushOperation(callingActivity: ContinuationContainerActivity) : GitOperation(callingActivity) {
+class PushOperation(callingActivity: ContinuationContainerActivity) :
+ GitOperation(callingActivity) {
override val commands: Array<GitCommand<out Any>> =
arrayOf(
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/ResetToRemoteOperation.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/ResetToRemoteOperation.kt
index dccd69b0..16114f65 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/ResetToRemoteOperation.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/ResetToRemoteOperation.kt
@@ -7,7 +7,8 @@ package dev.msfjarvis.aps.util.git.operation
import dev.msfjarvis.aps.util.git.sshj.ContinuationContainerActivity
import org.eclipse.jgit.api.ResetCommand
-class ResetToRemoteOperation(callingActivity: ContinuationContainerActivity) : GitOperation(callingActivity) {
+class ResetToRemoteOperation(callingActivity: ContinuationContainerActivity) :
+ GitOperation(callingActivity) {
override val commands =
arrayOf(
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/OpenKeychainKeyProvider.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/OpenKeychainKeyProvider.kt
index acb7d8d7..d726c353 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/OpenKeychainKeyProvider.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/OpenKeychainKeyProvider.kt
@@ -106,7 +106,8 @@ class OpenKeychainKeyProvider private constructor(val activity: ContinuationCont
val response = sshPublicKeyResponse.response as SshPublicKeyResponse
val sshPublicKey = response.sshPublicKey!!
publicKey =
- parseSshPublicKey(sshPublicKey) ?: throw IllegalStateException("OpenKeychain API returned invalid SSH key")
+ parseSshPublicKey(sshPublicKey)
+ ?: throw IllegalStateException("OpenKeychain API returned invalid SSH key")
}
is ApiResponse.NoSuchKey ->
if (isRetry) {
@@ -122,13 +123,17 @@ class OpenKeychainKeyProvider private constructor(val activity: ContinuationCont
private suspend fun selectKey() {
when (val keySelectionResponse = executeApiRequest(KeySelectionRequest())) {
- is ApiResponse.Success -> keyId = (keySelectionResponse.response as KeySelectionResponse).keyId
+ is ApiResponse.Success ->
+ keyId = (keySelectionResponse.response as KeySelectionResponse).keyId
is ApiResponse.GeneralError -> throw keySelectionResponse.exception
is ApiResponse.NoSuchKey -> throw keySelectionResponse.exception
}
}
- private suspend fun executeApiRequest(request: Request, resultOfUserInteraction: Intent? = null): ApiResponse {
+ private suspend fun executeApiRequest(
+ request: Request,
+ resultOfUserInteraction: Intent? = null
+ ): ApiResponse {
d { "executeRequest($request) called" }
val result =
withContext(Dispatchers.Main) {
@@ -141,7 +146,11 @@ class OpenKeychainKeyProvider private constructor(val activity: ContinuationCont
}
private suspend fun parseResult(request: Request, result: Intent): ApiResponse {
- return when (result.getIntExtra(SshAuthenticationApi.EXTRA_RESULT_CODE, SshAuthenticationApi.RESULT_CODE_ERROR)) {
+ return when (result.getIntExtra(
+ SshAuthenticationApi.EXTRA_RESULT_CODE,
+ SshAuthenticationApi.RESULT_CODE_ERROR
+ )
+ ) {
SshAuthenticationApi.RESULT_CODE_SUCCESS -> {
ApiResponse.Success(
when (request) {
@@ -153,20 +162,27 @@ class OpenKeychainKeyProvider private constructor(val activity: ContinuationCont
)
}
SshAuthenticationApi.RESULT_CODE_USER_INTERACTION_REQUIRED -> {
- val pendingIntent: PendingIntent = result.getParcelableExtra(SshAuthenticationApi.EXTRA_PENDING_INTENT)!!
+ val pendingIntent: PendingIntent =
+ result.getParcelableExtra(SshAuthenticationApi.EXTRA_PENDING_INTENT)!!
val resultOfUserInteraction: Intent =
withContext(Dispatchers.Main) {
suspendCoroutine { cont ->
activity.stashedCont = cont
- activity.continueAfterUserInteraction.launch(IntentSenderRequest.Builder(pendingIntent).build())
+ activity.continueAfterUserInteraction.launch(
+ IntentSenderRequest.Builder(pendingIntent).build()
+ )
}
}
executeApiRequest(request, resultOfUserInteraction)
}
else -> {
- val error = result.getParcelableExtra<SshAuthenticationApiError>(SshAuthenticationApi.EXTRA_ERROR)
+ val error =
+ result.getParcelableExtra<SshAuthenticationApiError>(SshAuthenticationApi.EXTRA_ERROR)
val exception =
- UserAuthException(DisconnectReason.UNKNOWN, "Request ${request::class.simpleName} failed: ${error?.message}")
+ UserAuthException(
+ DisconnectReason.UNKNOWN,
+ "Request ${request::class.simpleName} failed: ${error?.message}"
+ )
when (error?.error) {
SshAuthenticationApiError.NO_AUTH_KEY, SshAuthenticationApiError.NO_SUCH_KEY ->
ApiResponse.NoSuchKey(exception)
@@ -181,7 +197,9 @@ class OpenKeychainKeyProvider private constructor(val activity: ContinuationCont
privateKey =
object : OpenKeychainPrivateKey {
override suspend fun sign(challenge: ByteArray, hashAlgorithm: Int) =
- when (val signingResponse = executeApiRequest(SigningRequest(challenge, keyId, hashAlgorithm))) {
+ when (val signingResponse =
+ executeApiRequest(SigningRequest(challenge, keyId, hashAlgorithm))
+ ) {
is ApiResponse.Success -> (signingResponse.response as SigningResponse).signature
is ApiResponse.GeneralError -> throw signingResponse.exception
is ApiResponse.NoSuchKey -> throw signingResponse.exception
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/OpenKeychainWrappedKeyAlgorithmFactory.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/OpenKeychainWrappedKeyAlgorithmFactory.kt
index 0ab01ba5..56831b1d 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/OpenKeychainWrappedKeyAlgorithmFactory.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/OpenKeychainWrappedKeyAlgorithmFactory.kt
@@ -28,7 +28,8 @@ class OpenKeychainWrappedKeyAlgorithmFactory(private val factory: Factory.Named<
override fun create() = OpenKeychainWrappedKeyAlgorithm(factory.create())
}
-class OpenKeychainWrappedKeyAlgorithm(private val keyAlgorithm: KeyAlgorithm) : KeyAlgorithm by keyAlgorithm {
+class OpenKeychainWrappedKeyAlgorithm(private val keyAlgorithm: KeyAlgorithm) :
+ KeyAlgorithm by keyAlgorithm {
private val hashAlgorithm =
when (keyAlgorithm.keyAlgorithm) {
@@ -39,11 +40,14 @@ class OpenKeychainWrappedKeyAlgorithm(private val keyAlgorithm: KeyAlgorithm) :
else -> SshAuthenticationApi.SHA512
}
- override fun newSignature() = OpenKeychainWrappedSignature(keyAlgorithm.newSignature(), hashAlgorithm)
+ override fun newSignature() =
+ OpenKeychainWrappedSignature(keyAlgorithm.newSignature(), hashAlgorithm)
}
-class OpenKeychainWrappedSignature(private val wrappedSignature: Signature, private val hashAlgorithm: Int) :
- Signature by wrappedSignature {
+class OpenKeychainWrappedSignature(
+ private val wrappedSignature: Signature,
+ private val hashAlgorithm: Int
+) : Signature by wrappedSignature {
private val data = ByteArrayOutputStream()
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshKey.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshKey.kt
index 37414707..3d23658e 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshKey.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshKey.kt
@@ -115,7 +115,8 @@ object SshKey {
private var type: Type?
get() = Type.fromValue(context.sharedPrefs.getString(PreferenceKeys.GIT_REMOTE_KEY_TYPE))
- set(value) = context.sharedPrefs.edit { putString(PreferenceKeys.GIT_REMOTE_KEY_TYPE, value?.value) }
+ set(value) =
+ context.sharedPrefs.edit { putString(PreferenceKeys.GIT_REMOTE_KEY_TYPE, value?.value) }
private val isStrongBoxSupported by lazy(LazyThreadSafetyMode.NONE) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
@@ -138,13 +139,20 @@ object SshKey {
}
}
- enum class Algorithm(val algorithm: String, val applyToSpec: KeyGenParameterSpec.Builder.() -> Unit) {
+ enum class Algorithm(
+ val algorithm: String,
+ val applyToSpec: KeyGenParameterSpec.Builder.() -> Unit
+ ) {
Rsa(
KeyProperties.KEY_ALGORITHM_RSA,
{
setKeySize(3072)
setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
- setDigests(KeyProperties.DIGEST_SHA1, KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
+ setDigests(
+ KeyProperties.DIGEST_SHA1,
+ KeyProperties.DIGEST_SHA256,
+ KeyProperties.DIGEST_SHA512
+ )
}
),
Ecdsa(
@@ -163,7 +171,9 @@ object SshKey {
private fun delete() {
androidKeystore.deleteEntry(KEYSTORE_ALIAS)
// Remove Tink key set used by AndroidX's EncryptedFile.
- context.getSharedPreferences(ANDROIDX_SECURITY_KEYSET_PREF_NAME, Context.MODE_PRIVATE).edit { clear() }
+ context.getSharedPreferences(ANDROIDX_SECURITY_KEYSET_PREF_NAME, Context.MODE_PRIVATE).edit {
+ clear()
+ }
if (privateKeyFile.isFile) {
privateKeyFile.delete()
}
@@ -177,7 +187,8 @@ object SshKey {
fun import(uri: Uri) {
// First check whether the content at uri is likely an SSH private key.
val fileSize =
- context.contentResolver.query(uri, arrayOf(OpenableColumns.SIZE), null, null, null)?.use { cursor ->
+ context.contentResolver.query(uri, arrayOf(OpenableColumns.SIZE), null, null, null)?.use {
+ cursor ->
// Cursor returns only a single row.
cursor.moveToFirst()
cursor.getInt(0)
@@ -186,7 +197,9 @@ object SshKey {
// We assume that an SSH key's ideal size is > 0 bytes && < 100 kilobytes.
if (fileSize > 100_000 || fileSize == 0)
- throw IllegalArgumentException(context.getString(R.string.ssh_key_import_error_not_an_ssh_key_message))
+ throw IllegalArgumentException(
+ context.getString(R.string.ssh_key_import_error_not_an_ssh_key_message)
+ )
val sshKeyInputStream =
context.contentResolver.openInputStream(uri)
@@ -199,7 +212,9 @@ object SshKey {
!Regex("BEGIN .* PRIVATE KEY").containsMatchIn(lines.first()) ||
!Regex("END .* PRIVATE KEY").containsMatchIn(lines.last())
)
- throw IllegalArgumentException(context.getString(R.string.ssh_key_import_error_not_an_ssh_key_message))
+ throw IllegalArgumentException(
+ context.getString(R.string.ssh_key_import_error_not_an_ssh_key_message)
+ )
// At this point, we are reasonably confident that we have actually been provided a private
// key and delete the old key.
@@ -249,7 +264,9 @@ object SshKey {
val encryptedPrivateKeyFile = getOrCreateWrappedPrivateKeyFile(requireAuthentication)
// Generate the ed25519 key pair and encrypt the private key.
val keyPair = net.i2p.crypto.eddsa.KeyPairGenerator().generateKeyPair()
- encryptedPrivateKeyFile.openFileOutput().use { os -> os.write((keyPair.private as EdDSAPrivateKey).seed) }
+ encryptedPrivateKeyFile.openFileOutput().use { os ->
+ os.write((keyPair.private as EdDSAPrivateKey).seed)
+ }
// Write public key in SSH format to .ssh_key.pub.
publicKeyFile.writeText(toSshPublicKey(keyPair.public))
@@ -288,7 +305,8 @@ object SshKey {
fun provide(client: SSHClient, passphraseFinder: InteractivePasswordFinder): KeyProvider? =
when (type) {
- Type.LegacyGenerated, Type.Imported -> client.loadKeys(privateKeyFile.absolutePath, passphraseFinder)
+ Type.LegacyGenerated, Type.Imported ->
+ client.loadKeys(privateKeyFile.absolutePath, passphraseFinder)
Type.KeystoreNative -> KeystoreNativeKeyProvider
Type.KeystoreWrappedEd25519 -> KeystoreWrappedEd25519KeyProvider
null -> null
@@ -305,7 +323,10 @@ object SshKey {
override fun getPrivate(): PrivateKey =
runCatching { androidKeystore.sshPrivateKey!! }.getOrElse { error ->
e(error)
- throw IOException("Failed to access private key '$KEYSTORE_ALIAS' from Android Keystore", error)
+ throw IOException(
+ "Failed to access private key '$KEYSTORE_ALIAS' from Android Keystore",
+ error
+ )
}
override fun getType(): KeyType = KeyType.fromKey(public)
@@ -326,7 +347,9 @@ object SshKey {
// for `requireAuthentication` is not used as the key already exists at this point.
val encryptedPrivateKeyFile = runBlocking { getOrCreateWrappedPrivateKeyFile(false) }
val rawPrivateKey = encryptedPrivateKeyFile.openFileInput().use { it.readBytes() }
- EdDSAPrivateKey(EdDSAPrivateKeySpec(rawPrivateKey, EdDSANamedCurveTable.ED_25519_CURVE_SPEC))
+ EdDSAPrivateKey(
+ EdDSAPrivateKeySpec(rawPrivateKey, EdDSANamedCurveTable.ED_25519_CURVE_SPEC)
+ )
}
.getOrElse { error ->
e(error)
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshjConfig.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshjConfig.kt
index e93787f4..f8053ef3 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshjConfig.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshjConfig.kt
@@ -37,7 +37,8 @@ fun setUpBouncyCastleForSshj() {
// Replace the Android BC provider with the Java BouncyCastle provider since the former does
// not include all the required algorithms.
// Note: This may affect crypto operations in other parts of the application.
- val bcIndex = Security.getProviders().indexOfFirst { it.name == BouncyCastleProvider.PROVIDER_NAME }
+ val bcIndex =
+ Security.getProviders().indexOfFirst { it.name == BouncyCastleProvider.PROVIDER_NAME }
if (bcIndex == -1) {
// No Android BC found, install Java BC at lowest priority.
Security.addProvider(BouncyCastleProvider())
@@ -77,9 +78,11 @@ private abstract class AbstractLogger(private val name: String) : Logger {
override fun trace(msg: String, t: Throwable?) = t(msg, t)
override fun trace(marker: Marker, msg: String) = trace(msg)
override fun trace(marker: Marker?, format: String, arg: Any?) = trace(format, arg)
- override fun trace(marker: Marker?, format: String, arg1: Any?, arg2: Any?) = trace(format, arg1, arg2)
+ override fun trace(marker: Marker?, format: String, arg1: Any?, arg2: Any?) =
+ trace(format, arg1, arg2)
- override fun trace(marker: Marker?, format: String, vararg arguments: Any?) = trace(format, *arguments)
+ override fun trace(marker: Marker?, format: String, vararg arguments: Any?) =
+ trace(format, *arguments)
override fun trace(marker: Marker?, msg: String, t: Throwable?) = trace(msg, t)
@@ -90,9 +93,11 @@ private abstract class AbstractLogger(private val name: String) : Logger {
override fun debug(msg: String, t: Throwable?) = d(msg, t)
override fun debug(marker: Marker, msg: String) = debug(msg)
override fun debug(marker: Marker?, format: String, arg: Any?) = debug(format, arg)
- override fun debug(marker: Marker?, format: String, arg1: Any?, arg2: Any?) = debug(format, arg1, arg2)
+ override fun debug(marker: Marker?, format: String, arg1: Any?, arg2: Any?) =
+ debug(format, arg1, arg2)
- override fun debug(marker: Marker?, format: String, vararg arguments: Any?) = debug(format, *arguments)
+ override fun debug(marker: Marker?, format: String, vararg arguments: Any?) =
+ debug(format, *arguments)
override fun debug(marker: Marker?, msg: String, t: Throwable?) = debug(msg, t)
@@ -103,9 +108,11 @@ private abstract class AbstractLogger(private val name: String) : Logger {
override fun info(msg: String, t: Throwable?) = i(msg, t)
override fun info(marker: Marker, msg: String) = info(msg)
override fun info(marker: Marker?, format: String, arg: Any?) = info(format, arg)
- override fun info(marker: Marker?, format: String, arg1: Any?, arg2: Any?) = info(format, arg1, arg2)
+ override fun info(marker: Marker?, format: String, arg1: Any?, arg2: Any?) =
+ info(format, arg1, arg2)
- override fun info(marker: Marker?, format: String, vararg arguments: Any?) = info(format, *arguments)
+ override fun info(marker: Marker?, format: String, vararg arguments: Any?) =
+ info(format, *arguments)
override fun info(marker: Marker?, msg: String, t: Throwable?) = info(msg, t)
@@ -116,9 +123,11 @@ private abstract class AbstractLogger(private val name: String) : Logger {
override fun warn(msg: String, t: Throwable?) = w(msg, t)
override fun warn(marker: Marker, msg: String) = warn(msg)
override fun warn(marker: Marker?, format: String, arg: Any?) = warn(format, arg)
- override fun warn(marker: Marker?, format: String, arg1: Any?, arg2: Any?) = warn(format, arg1, arg2)
+ override fun warn(marker: Marker?, format: String, arg1: Any?, arg2: Any?) =
+ warn(format, arg1, arg2)
- override fun warn(marker: Marker?, format: String, vararg arguments: Any?) = warn(format, *arguments)
+ override fun warn(marker: Marker?, format: String, vararg arguments: Any?) =
+ warn(format, *arguments)
override fun warn(marker: Marker?, msg: String, t: Throwable?) = warn(msg, t)
@@ -129,9 +138,11 @@ private abstract class AbstractLogger(private val name: String) : Logger {
override fun error(msg: String, t: Throwable?) = e(msg, t)
override fun error(marker: Marker, msg: String) = error(msg)
override fun error(marker: Marker?, format: String, arg: Any?) = error(format, arg)
- override fun error(marker: Marker?, format: String, arg1: Any?, arg2: Any?) = error(format, arg1, arg2)
+ override fun error(marker: Marker?, format: String, arg1: Any?, arg2: Any?) =
+ error(format, arg1, arg2)
- override fun error(marker: Marker?, format: String, vararg arguments: Any?) = error(format, *arguments)
+ override fun error(marker: Marker?, format: String, vararg arguments: Any?) =
+ error(format, *arguments)
override fun error(marker: Marker?, msg: String, t: Throwable?) = error(msg, t)
}
@@ -148,7 +159,8 @@ object TimberLoggerFactory : LoggerFactory {
// Replace slf4j's "{}" format string style with standard Java's "%s".
// The supposedly redundant escape on the } is not redundant.
- @Suppress("RegExpRedundantEscape") private fun String.fix() = replace("""(?!<\\)\{\}""".toRegex(), "%s")
+ @Suppress("RegExpRedundantEscape")
+ private fun String.fix() = replace("""(?!<\\)\{\}""".toRegex(), "%s")
override fun t(message: String, t: Throwable?, vararg args: Any?) {
Timber.tag(name).v(t, message.fix(), *args)
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshjSessionFactory.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshjSessionFactory.kt
index 95676d7f..bc068f52 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshjSessionFactory.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshjSessionFactory.kt
@@ -52,7 +52,10 @@ abstract class InteractivePasswordFinder : PasswordFinder {
abstract fun askForPassword(cont: Continuation<String?>, isRetry: Boolean)
final override fun reqPassword(resource: Resource<*>?): CharArray {
- val password = runBlocking(Dispatchers.Main) { suspendCoroutine<String?> { cont -> askForPassword(cont, isRetry) } }
+ val password =
+ runBlocking(Dispatchers.Main) {
+ suspendCoroutine<String?> { cont -> askForPassword(cont, isRetry) }
+ }
isRetry = true
return password?.toCharArray() ?: throw SSHException(DisconnectReason.AUTH_CANCELLED_BY_USER)
}
@@ -60,11 +63,17 @@ abstract class InteractivePasswordFinder : PasswordFinder {
final override fun shouldRetry(resource: Resource<*>?) = true
}
-class SshjSessionFactory(private val authMethod: SshAuthMethod, private val hostKeyFile: File) : SshSessionFactory() {
+class SshjSessionFactory(private val authMethod: SshAuthMethod, private val hostKeyFile: File) :
+ SshSessionFactory() {
private var currentSession: SshjSession? = null
- override fun getSession(uri: URIish, credentialsProvider: CredentialsProvider?, fs: FS?, tms: Int): RemoteSession {
+ override fun getSession(
+ uri: URIish,
+ credentialsProvider: CredentialsProvider?,
+ fs: FS?,
+ tms: Int
+ ): RemoteSession {
return currentSession
?: SshjSession(uri, uri.user, authMethod, hostKeyFile).connect().also {
d { "New SSH connection created" }
@@ -81,7 +90,9 @@ private fun makeTofuHostKeyVerifier(hostKeyFile: File): HostKeyVerifier {
if (!hostKeyFile.exists()) {
return HostKeyVerifier { _, _, key ->
val digest =
- runCatching { SecurityUtils.getMessageDigest("SHA-256") }.getOrElse { e -> throw SSHRuntimeException(e) }
+ runCatching { SecurityUtils.getMessageDigest("SHA-256") }.getOrElse { e ->
+ throw SSHRuntimeException(e)
+ }
digest.update(PlainBuffer().putPublicKey(key).compactData)
val digestData = digest.digest()
val hostKeyEntry = "SHA256:${Base64.encodeToString(digestData, Base64.NO_WRAP)}"
@@ -115,7 +126,9 @@ private class SshjSession(
val userPlusHost = "${uri.user}@${uri.host}"
val realUser = userPlusHost.substringBeforeLast('@')
val realHost = userPlusHost.substringAfterLast('@')
- uri.setUser(realUser).setHost(realHost).also { d { "After fixup: user=${it.user}, host=${it.host}" } }
+ uri.setUser(realUser).setHost(realHost).also {
+ d { "After fixup: user=${it.user}, host=${it.host}" }
+ }
} else {
uri
}
@@ -131,7 +144,8 @@ private class SshjSession(
ssh.auth(username, passwordAuth)
}
is SshAuthMethod.SshKey -> {
- val pubkeyAuth = AuthPublickey(SshKey.provide(ssh, CredentialFinder(authMethod.activity, AuthMode.SshKey)))
+ val pubkeyAuth =
+ AuthPublickey(SshKey.provide(ssh, CredentialFinder(authMethod.activity, AuthMode.SshKey)))
ssh.auth(username, pubkeyAuth, passwordAuth)
}
is SshAuthMethod.OpenKeychain -> {
@@ -174,7 +188,8 @@ private class SshjSession(
}
}
-private class SshjProcess(private val command: Session.Command, private val timeout: Long) : Process() {
+private class SshjProcess(private val command: Session.Command, private val timeout: Long) :
+ Process() {
override fun waitFor(): Int {
command.join(timeout, TimeUnit.SECONDS)