From 363551723bed0cf47dfa6cded2da74825659c7ca Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 5 Sep 2017 05:15:21 +0200 Subject: [PATCH] token-import: add logging --- .../results/GenericOperationResult.java | 25 +++ .../operations/results/OperationResult.java | 30 ++++ .../ui/CreateSecurityTokenImportFragment.java | 30 +++- .../CreateSecurityTokenImportPresenter.java | 31 +++- .../keychain/ui/PublicKeyRetrievalLoader.java | 148 ++++++++++++++---- OpenKeychain/src/main/res/values/strings.xml | 30 ++++ 6 files changed, 253 insertions(+), 41 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/GenericOperationResult.java diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/GenericOperationResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/GenericOperationResult.java new file mode 100644 index 000000000..2ae0e5479 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/GenericOperationResult.java @@ -0,0 +1,25 @@ +package org.sufficientlysecure.keychain.operations.results; + + +import android.os.Parcel; + + +public class GenericOperationResult extends OperationResult { + public GenericOperationResult(int result, OperationLog log) { + super(result, log); + } + + public GenericOperationResult(Parcel source) { + super(source); + } + + public static final Creator CREATOR = new Creator() { + public GenericOperationResult createFromParcel(final Parcel source) { + return new GenericOperationResult(source); + } + + public GenericOperationResult[] newArray(final int size) { + return new GenericOperationResult[size]; + } + }; +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java index f844acb0d..5b0efcb82 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java @@ -905,6 +905,36 @@ public abstract class OperationResult implements Parcelable { MSG_BENCH_S2K_100MS_ITS (LogLevel.INFO, R.string.msg_bench_s2k_100ms_its), MSG_BENCH_SUCCESS (LogLevel.OK, R.string.msg_bench_success), + MSG_RET_CURI_ERROR_IO (LogLevel.ERROR, R.string.msg_ret_curi_error_io), + MSG_RET_CURI_ERROR_NO_MATCH (LogLevel.ERROR, R.string.msg_ret_curi_error_no_match), + MSG_RET_CURI_ERROR_NOT_FOUND (LogLevel.ERROR, R.string.msg_ret_curi_error_not_found), + MSG_RET_CURI_FOUND (LogLevel.DEBUG, R.string.msg_ret_curi_found), + MSG_RET_CURI_MISMATCH (LogLevel.ERROR, R.string.msg_ret_curi_mismatch), + MSG_RET_CURI_OK (LogLevel.OK, R.string.msg_ret_curi_ok), + MSG_RET_CURI_OPEN (LogLevel.DEBUG, R.string.msg_ret_curi_open), + MSG_RET_CURI_START (LogLevel.START, R.string.msg_ret_curi_start), + MSG_RET_KS_ERROR_NOT_FOUND (LogLevel.ERROR, R.string.msg_ret_ks_error_not_found), + MSG_RET_KS_ERROR (LogLevel.ERROR, R.string.msg_ret_ks_error), + MSG_RET_KS_FP_MATCH (LogLevel.DEBUG, R.string.msg_ret_ks_fp_match), + MSG_RET_KS_FP_MISMATCH (LogLevel.ERROR, R.string.msg_ret_ks_fp_mismatch), + MSG_RET_KS_OK (LogLevel.OK, R.string.msg_ret_ks_ok), + MSG_RET_KS_START (LogLevel.START, R.string.msg_ret_ks_start), + MSG_RET_LOCAL_SEARCH(LogLevel.DEBUG, R.string.msg_ret_local_search), + MSG_RET_LOCAL_FP_MATCH (LogLevel.DEBUG, R.string.msg_ret_local_fp_match), + MSG_RET_LOCAL_FP_MISMATCH (LogLevel.ERROR, R.string.msg_ret_local_fp_mismatch), + MSG_RET_LOCAL_NOT_FOUND (LogLevel.ERROR, R.string.msg_ret_local_not_found), + MSG_RET_LOCAL_OK (LogLevel.OK, R.string.msg_ret_local_ok), + MSG_RET_LOCAL_SECRET (LogLevel.INFO, R.string.msg_ret_local_secret), + MSG_RET_LOCAL_START (LogLevel.START, R.string.msg_ret_local_start), + MSG_RET_URI_ERROR_NO_MATCH(LogLevel.ERROR, R.string.msg_ret_uri_error_no_match), + MSG_RET_URI_ERROR_FETCH (LogLevel.ERROR, R.string.msg_ret_uri_error_fetch), + MSG_RET_URI_ERROR_PARSE (LogLevel.ERROR, R.string.msg_ret_uri_error_parse), + MSG_RET_URI_FETCHING (LogLevel.DEBUG, R.string.msg_ret_uri_fetching), + MSG_RET_URI_OK (LogLevel.OK, R.string.msg_ret_uri_ok), + MSG_RET_URI_START (LogLevel.START, R.string.msg_ret_uri_start), + MSG_RET_URI_NULL (LogLevel.ERROR, R.string.msg_ret_uri_null), + MSG_RET_URI_TEST (LogLevel.DEBUG, R.string.msg_ret_uri_test), + ; public final int mMsgId; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportFragment.java index 38f4fbc1b..d06409027 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportFragment.java @@ -30,6 +30,7 @@ import android.support.v7.app.AlertDialog.Builder; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; @@ -39,6 +40,7 @@ import org.bouncycastle.util.encoders.Hex; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; +import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.operations.results.PromoteKeyResult; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.service.ImportKeyringParcel; @@ -137,6 +139,19 @@ public class CreateSecurityTokenImportFragment extends Fragment implements Creat inflater.inflate(R.menu.token_setup, menu); } + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.view_log: { + presenter.onClickViewLog(); + return true; + } + default: { + return super.onOptionsItemSelected(item); + } + } + } + @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); @@ -267,6 +282,13 @@ public class CreateSecurityTokenImportFragment extends Fragment implements Creat }).show(); } + @Override + public void showDisplayLogActivity(OperationResult result) { + Intent intent = new Intent(getActivity(), LogDisplayActivity.class); + intent.putExtra(LogDisplayFragment.EXTRA_RESULT, result); + startActivity(intent); + } + @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { @@ -327,13 +349,13 @@ public class CreateSecurityTokenImportFragment extends Fragment implements Creat @Override public void onCryptoOperationSuccess(ImportKeyResult result) { currentImportKeyringParcel = null; - presenter.onImportSuccess(); + presenter.onImportSuccess(result); } @Override public void onCryptoOperationError(ImportKeyResult result) { currentImportKeyringParcel = null; - presenter.onImportError(); + presenter.onImportError(result); } }, null); @@ -347,13 +369,13 @@ public class CreateSecurityTokenImportFragment extends Fragment implements Creat @Override public void onCryptoOperationSuccess(PromoteKeyResult result) { currentPromoteKeyringParcel = null; - presenter.onPromoteSuccess(); + presenter.onPromoteSuccess(result); } @Override public void onCryptoOperationError(PromoteKeyResult result) { currentPromoteKeyringParcel = null; - presenter.onPromoteError(); + presenter.onPromoteError(result); } }, null); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportPresenter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportPresenter.java index 998a4a21a..7daa36b90 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportPresenter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportPresenter.java @@ -25,6 +25,9 @@ import android.support.v4.app.LoaderManager; import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.support.v4.content.Loader; +import org.sufficientlysecure.keychain.operations.results.GenericOperationResult; +import org.sufficientlysecure.keychain.operations.results.OperationResult; +import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.ui.CreateSecurityTokenImportFragment.StatusLine; import org.sufficientlysecure.keychain.ui.PublicKeyRetrievalLoader.ContentUriRetrievalLoader; import org.sufficientlysecure.keychain.ui.PublicKeyRetrievalLoader.KeyRetrievalResult; @@ -57,6 +60,7 @@ class CreateSecurityTokenImportPresenter { private byte[] importKeyData; private Long masterKeyId; + private OperationLog log; CreateSecurityTokenImportPresenter(Context context, byte[] tokenFingerprints, byte[] tokenAid, String tokenUserId, String tokenUrl, LoaderManager loaderManager) { @@ -75,6 +79,8 @@ class CreateSecurityTokenImportPresenter { this.tokenFingerprints[i] = new byte[20]; System.arraycopy(tokenFingerprints, i*20, this.tokenFingerprints[i], 0, 20); } + + this.log = new OperationLog(); } public void setView(CreateSecurityTokenImportMvpView view) { @@ -153,6 +159,8 @@ class CreateSecurityTokenImportPresenter { } } + log.add(data.getOperationResult(), 0); + if (data.isSuccess()) { processResult(data); } else { @@ -194,22 +202,30 @@ class CreateSecurityTokenImportPresenter { view.operationImportKey(importKeyData); } - void onImportSuccess() { + void onImportSuccess(OperationResult result) { + log.add(result, 0); + view.statusLineOk(); view.statusLineAdd(StatusLine.TOKEN_PROMOTE); view.operationPromote(masterKeyId, tokenAid); } - void onImportError() { + void onImportError(OperationResult result) { + log.add(result, 0); + view.statusLineError(); } - void onPromoteSuccess() { + void onPromoteSuccess(OperationResult result) { + log.add(result, 0); + view.statusLineOk(); view.showActionViewKey(); } - void onPromoteError() { + void onPromoteError(OperationResult result) { + log.add(result, 0); + view.statusLineError(); } @@ -252,6 +268,11 @@ class CreateSecurityTokenImportPresenter { loaderManager.restartLoader(LOADER_CONTENT_URI, args, loaderCallbacks); } + void onClickViewLog() { + OperationResult result = new GenericOperationResult(GenericOperationResult.RESULT_OK, log); + view.showDisplayLogActivity(result); + } + interface CreateSecurityTokenImportMvpView { void statusLineAdd(StatusLine statusLine); void statusLineOk(); @@ -271,5 +292,7 @@ class CreateSecurityTokenImportPresenter { void showFileSelectDialog(); void showConfirmResetDialog(); + + void showDisplayLogActivity(OperationResult result); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PublicKeyRetrievalLoader.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PublicKeyRetrievalLoader.java index a407fed58..f8287a37a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PublicKeyRetrievalLoader.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PublicKeyRetrievalLoader.java @@ -33,16 +33,22 @@ import android.util.Log; import com.google.auto.value.AutoValue; import okhttp3.Call; +import okhttp3.HttpUrl; import okhttp3.Request.Builder; import okhttp3.Response; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.keyimport.HkpKeyserverAddress; import org.sufficientlysecure.keychain.keyimport.HkpKeyserverClient; import org.sufficientlysecure.keychain.keyimport.KeyserverClient.QueryFailedException; +import org.sufficientlysecure.keychain.keyimport.KeyserverClient.QueryNotFoundException; import org.sufficientlysecure.keychain.network.OkHttpClientFactory; +import org.sufficientlysecure.keychain.operations.results.GenericOperationResult; +import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; +import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing.IteratorWithIOThrow; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing; import org.sufficientlysecure.keychain.provider.KeyRepository; import org.sufficientlysecure.keychain.provider.KeyRepository.NotFoundException; @@ -94,59 +100,102 @@ public abstract class PublicKeyRetrievalLoader extends AsyncTaskLoader uncachedKeyRingIterator = UncachedKeyRing.fromStream( + new BufferedInputStream(execute.body().byteStream())); + while (uncachedKeyRingIterator.hasNext()) { + UncachedKeyRing keyRing = uncachedKeyRingIterator.next(); + log.add(LogType.MSG_RET_URI_TEST, 1, KeyFormattingUtils.convertKeyIdToHex(keyRing.getMasterKeyId())); if (Arrays.equals(fingerprints[0], keyRing.getFingerprint())) { - return KeyRetrievalResult.createWithKeyringdata(keyRing.getMasterKeyId(), keyRing.getEncoded()); + log.add(LogType.MSG_RET_URI_OK, 1); + return KeyRetrievalResult.createWithKeyringdata(log, keyRing.getMasterKeyId(), keyRing.getEncoded()); } } - } catch (IOException | PgpGeneralException e) { + + log.add(LogType.MSG_RET_URI_ERROR_NO_MATCH, 1); + } catch (IOException e) { + log.add(LogType.MSG_RET_URI_ERROR_FETCH, 1); Log.e(Constants.TAG, "error retrieving key from uri", e); } - return KeyRetrievalResult.createWithError(); + return KeyRetrievalResult.createWithError(log); } } @@ -161,26 +210,37 @@ public abstract class PublicKeyRetrievalLoader extends AsyncTaskLoader uncachedKeyRingIterator = UncachedKeyRing.fromStream( new BufferedInputStream(is)); while (uncachedKeyRingIterator.hasNext()) { UncachedKeyRing keyRing = uncachedKeyRingIterator.next(); + log.add(LogType.MSG_RET_CURI_FOUND, 1, KeyFormattingUtils.convertKeyIdToHex(keyRing.getMasterKeyId())); if (Arrays.equals(fingerprint, keyRing.getFingerprint())) { - return KeyRetrievalResult.createWithKeyringdata(keyRing.getMasterKeyId(), keyRing.getEncoded()); + log.add(LogType.MSG_RET_CURI_OK, 1); + return KeyRetrievalResult.createWithKeyringdata(log, keyRing.getMasterKeyId(), keyRing.getEncoded()); + } else { + log.add(LogType.MSG_RET_CURI_MISMATCH, 1); } } + log.add(LogType.MSG_RET_CURI_ERROR_NO_MATCH, 1); } catch (IOException e) { - Log.e(Constants.TAG, "error retrieving key from keyserver", e); + Log.e(Constants.TAG, "error reading keyring from file", e); + log.add(LogType.MSG_RET_CURI_ERROR_IO, 1); } - return KeyRetrievalResult.createWithError(); + return KeyRetrievalResult.createWithError(log); } } @@ -243,6 +315,8 @@ public abstract class PublicKeyRetrievalLoader extends AsyncTaskLoaderReady for use! View Key + "Error reading data!" + "No matching key found" + "Couldn't open file!" + "Found key: %s" + "Key doesn't match" + "Key found" + "Opening Uri: %s" + "Loading key from file or document…" + "Unknown error searching for key!" + "Key not found" + "Retrieved key's fingerprint matches" + "Retrieved key's fingerprint doesn't match!" + "Key found" + "Looking for key on keyservers…" + "Searching for key: %s" + "Local key's fingerprint matches" + "Local key's fingerprint doesn't match!" + "No key found" + "Key found" + "Local key contains secret key material" + "Looking for key in local key list…" + "Unknown error fetching Uri!" + "Token Uri is malformed!" + "No matching key found at Uri" + "Fetching Uri: %s" + "Key found" + "Looking for key at token Uri…" + "No Uri saved on Security Token" + "Checking if found key matches: %s" +