diff options
Diffstat (limited to 'OpenKeychain/src')
28 files changed, 388 insertions, 161 deletions
diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml index 2dcdb3251..93c75cca6 100644 --- a/OpenKeychain/src/main/AndroidManifest.xml +++ b/OpenKeychain/src/main/AndroidManifest.xml @@ -682,6 +682,9 @@ <activity android:name=".ui.PassphraseDialogActivity" android:theme="@android:style/Theme.NoDisplay" /> + <activity + android:name=".ui.OrbotRequiredDialogActivity" + android:theme="@android:style/Theme.NoDisplay" /> <activity android:name=".ui.PassphraseWizardActivity" /> <!-- NOTE: singleTop is set to get NFC foreground dispatch to work. diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java index 07aeeaff6..87a2325d8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java @@ -19,7 +19,9 @@ package org.sufficientlysecure.keychain.operations; import android.content.Context; +import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.keyimport.HkpKeyserver; +import org.sufficientlysecure.keychain.keyimport.Keyserver; import org.sufficientlysecure.keychain.operations.results.CertifyResult; import org.sufficientlysecure.keychain.operations.results.ExportResult; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; @@ -44,7 +46,10 @@ import org.sufficientlysecure.keychain.service.input.RequiredInputParcel.NfcSign import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.util.ParcelableProxy; import org.sufficientlysecure.keychain.util.Passphrase; +import org.sufficientlysecure.keychain.util.Preferences; +import org.sufficientlysecure.keychain.util.orbot.OrbotHelper; +import java.net.Proxy; import java.util.ArrayList; import java.util.concurrent.atomic.AtomicBoolean; @@ -187,11 +192,24 @@ public class CertifyOperation extends BaseOperation<CertifyActionsParcel> { return new CertifyResult(CertifyResult.RESULT_CANCELLED, log); } + // these variables are used inside the following loop, but they need to be created only once HkpKeyserver keyServer = null; ExportOperation exportOperation = null; + Proxy proxy = null; if (parcel.keyServerUri != null) { keyServer = new HkpKeyserver(parcel.keyServerUri); exportOperation = new ExportOperation(mContext, mProviderHelper, mProgressable); + if (cryptoInput.getParcelableProxy() == null) { + // explicit proxy not set + if (!OrbotHelper.isOrbotInRequiredState(mContext)) { + return new CertifyResult(null, + RequiredInputParcel.createOrbotRequiredOperation()); + } + proxy = Preferences.getPreferences(mContext).getProxyPrefs() + .parcelableProxy.getProxy(); + } else { + proxy = cryptoInput.getParcelableProxy().getProxy(); + } } // Write all certified keys into the database @@ -211,8 +229,10 @@ public class CertifyOperation extends BaseOperation<CertifyActionsParcel> { SaveKeyringResult result = mProviderHelper.savePublicKeyRing(certifiedKey); if (exportOperation != null) { - ExportResult uploadResult = importExportOperation.uploadKeyRingToServer(keyServer, certifiedKey, - parcelableProxy.getProxy()); + ExportResult uploadResult = exportOperation.uploadKeyRingToServer( + keyServer, + certifiedKey, + proxy); log.add(uploadResult, 2); if (uploadResult.success()) { @@ -229,12 +249,12 @@ public class CertifyOperation extends BaseOperation<CertifyActionsParcel> { } log.add(result, 2); - } if (certifyOk == 0) { log.add(LogType.MSG_CRT_ERROR_NOTHING, 0); - return new CertifyResult(CertifyResult.RESULT_ERROR, log, certifyOk, certifyError, uploadOk, uploadError); + return new CertifyResult(CertifyResult.RESULT_ERROR, log, certifyOk, certifyError, + uploadOk, uploadError); } // since only verified keys are synced to contacts, we need to initiate a sync now diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ExportOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ExportOperation.java index 01a45bc79..3457665b0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ExportOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ExportOperation.java @@ -27,6 +27,7 @@ import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.keyimport.HkpKeyserver; import org.sufficientlysecure.keychain.keyimport.Keyserver.AddKeyException; +import org.sufficientlysecure.keychain.operations.results.CertifyResult; import org.sufficientlysecure.keychain.operations.results.ExportResult; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; @@ -40,9 +41,12 @@ import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.ExportKeyringParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; +import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.util.FileHelper; import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.Preferences; +import org.sufficientlysecure.keychain.util.orbot.OrbotHelper; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; @@ -51,6 +55,7 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.net.Proxy; import java.util.concurrent.atomic.AtomicBoolean; /** @@ -62,7 +67,6 @@ import java.util.concurrent.atomic.AtomicBoolean; * @see org.sufficientlysecure.keychain.ui.adapter.ImportKeysAdapter#getSelectedEntries() * For the export operation, the input consists of a set of key ids and * either the name of a file or an output uri to write to. - * TODO rework uploadKeyRingToServer */ public class ExportOperation extends BaseOperation<ExportKeyringParcel> { @@ -76,25 +80,39 @@ public class ExportOperation extends BaseOperation<ExportKeyringParcel> { super(context, providerHelper, progressable, cancelled); } - public void uploadKeyRingToServer(HkpKeyserver server, CanonicalizedPublicKeyRing keyring) - throws AddKeyException { - uploadKeyRingToServer(server, keyring.getUncachedKeyRing()); + public ExportResult uploadKeyRingToServer(HkpKeyserver server, CanonicalizedPublicKeyRing keyring, + Proxy proxy) { + return uploadKeyRingToServer(server, keyring.getUncachedKeyRing(), proxy); } - public void uploadKeyRingToServer(HkpKeyserver server, UncachedKeyRing keyring) throws - AddKeyException { + public ExportResult uploadKeyRingToServer(HkpKeyserver server, UncachedKeyRing keyring, Proxy proxy) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ArmoredOutputStream aos = null; + OperationLog log = new OperationLog(); + log.add(LogType.MSG_EXPORT_UPLOAD_PUBLIC, 0, KeyFormattingUtils.convertKeyIdToHex( + keyring.getPublicKey().getKeyId() + )); + try { aos = new ArmoredOutputStream(bos); keyring.encode(aos); aos.close(); String armoredKey = bos.toString("UTF-8"); - server.add(armoredKey); + server.add(armoredKey, proxy); + + log.add(LogType.MSG_EXPORT_UPLOAD_SUCCESS, 1); + return new ExportResult(ExportResult.RESULT_OK, log); } catch (IOException e) { Log.e(Constants.TAG, "IOException", e); - throw new AddKeyException(); + + log.add(LogType.MSG_EXPORT_ERROR_KEY, 1); + return new ExportResult(ExportResult.RESULT_ERROR, log); + } catch (AddKeyException e) { + Log.e(Constants.TAG, "AddKeyException", e); + + log.add(LogType.MSG_EXPORT_ERROR_UPLOAD, 1); + return new ExportResult(ExportResult.RESULT_ERROR, log); } finally { try { if (aos != null) { @@ -314,17 +332,28 @@ public class ExportOperation extends BaseOperation<ExportKeyringParcel> { public ExportResult execute(ExportKeyringParcel exportInput, CryptoInputParcel cryptoInput) { switch (exportInput.mExportType) { case UPLOAD_KEYSERVER: { + Proxy proxy; + if (cryptoInput.getParcelableProxy() == null) { + // explicit proxy not set + if (!OrbotHelper.isOrbotInRequiredState(mContext)) { + return new ExportResult(null, + RequiredInputParcel.createOrbotRequiredOperation()); + } + proxy = Preferences.getPreferences(mContext).getProxyPrefs() + .parcelableProxy.getProxy(); + } else { + proxy = cryptoInput.getParcelableProxy().getProxy(); + } + HkpKeyserver hkpKeyserver = new HkpKeyserver(exportInput.mKeyserver); try { CanonicalizedPublicKeyRing keyring = mProviderHelper.getCanonicalizedPublicKeyRing( exportInput.mCanonicalizedPublicKeyringUri); - uploadKeyRingToServer(hkpKeyserver, keyring); - // TODO: replace with proper log - return new ExportResult(ExportResult.RESULT_OK, new OperationLog()); - } catch (Exception e) { + return uploadKeyRingToServer(hkpKeyserver, keyring, proxy); + } catch (ProviderHelper.NotFoundException e) { + Log.e(Constants.TAG, "error uploading key", e); return new ExportResult(ExportResult.RESULT_ERROR, new OperationLog()); - // TODO: Implement better exception handling, replace with log } } case EXPORT_FILE: { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java index 44a67086f..39a898487 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java @@ -28,6 +28,7 @@ import org.sufficientlysecure.keychain.keyimport.Keyserver; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.operations.results.ConsolidateResult; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; +import org.sufficientlysecure.keychain.operations.results.InputPendingResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; @@ -39,12 +40,16 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.ContactSyncAdapterService; import org.sufficientlysecure.keychain.service.ImportKeyringParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; +import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.ParcelableFileCache; import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize; +import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.util.ProgressScaler; +import org.sufficientlysecure.keychain.util.orbot.OrbotHelper; import java.io.IOException; +import java.net.Proxy; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; @@ -89,39 +94,39 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> { // Overloaded functions for using progressable supplied in constructor during import public ImportKeyResult serialKeyRingImport(Iterator<ParcelableKeyRing> entries, int num, - String keyServerUri) { - return serialKeyRingImport(entries, num, keyServerUri, mProgressable); + String keyServerUri, Proxy proxy) { + return serialKeyRingImport(entries, num, keyServerUri, mProgressable, proxy); } public ImportKeyResult serialKeyRingImport(List<ParcelableKeyRing> entries, - String keyServerUri) { + String keyServerUri, Proxy proxy) { Iterator<ParcelableKeyRing> it = entries.iterator(); int numEntries = entries.size(); - return serialKeyRingImport(it, numEntries, keyServerUri, mProgressable); + return serialKeyRingImport(it, numEntries, keyServerUri, mProgressable, proxy); } public ImportKeyResult serialKeyRingImport(List<ParcelableKeyRing> entries, String keyServerUri, - Progressable progressable) { + Progressable progressable, Proxy proxy) { Iterator<ParcelableKeyRing> it = entries.iterator(); int numEntries = entries.size(); - return serialKeyRingImport(it, numEntries, keyServerUri, progressable); + return serialKeyRingImport(it, numEntries, keyServerUri, progressable, proxy); } public ImportKeyResult serialKeyRingImport(ParcelableFileCache<ParcelableKeyRing> cache, - String keyServerUri) { + String keyServerUri, Proxy proxy) { // get entries from cached file try { IteratorWithSize<ParcelableKeyRing> it = cache.readCache(); int numEntries = it.getSize(); - return serialKeyRingImport(it, numEntries, keyServerUri, mProgressable); + return serialKeyRingImport(it, numEntries, keyServerUri, mProgressable, proxy); } catch (IOException e) { // Special treatment here, we need a lot @@ -146,7 +151,8 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> { * @return */ public ImportKeyResult serialKeyRingImport(Iterator<ParcelableKeyRing> entries, int num, - String keyServerUri, Progressable progressable) { + String keyServerUri, Progressable progressable, + Proxy proxy) { updateProgress(R.string.progress_importing, 0, 100); OperationLog log = new OperationLog(); @@ -208,10 +214,11 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> { if (entry.mExpectedFingerprint != null) { log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER, 2, "0x" + entry.mExpectedFingerprint.substring(24)); - data = keyServer.get("0x" + entry.mExpectedFingerprint).getBytes(); + data = keyServer.get("0x" + entry.mExpectedFingerprint, proxy) + .getBytes(); } else { log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER, 2, entry.mKeyIdHex); - data = keyServer.get(entry.mKeyIdHex).getBytes(); + data = keyServer.get(entry.mKeyIdHex, proxy).getBytes(); } key = UncachedKeyRing.decodeFromData(data); if (key != null) { @@ -234,7 +241,7 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> { try { log.add(LogType.MSG_IMPORT_FETCH_KEYBASE, 2, entry.mKeybaseName); - byte[] data = keybaseServer.get(entry.mKeybaseName).getBytes(); + byte[] data = keybaseServer.get(entry.mKeybaseName, proxy).getBytes(); UncachedKeyRing keybaseKey = UncachedKeyRing.decodeFromData(data); // If there already is a key, merge the two @@ -374,11 +381,9 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> { } @Override - public ImportKeyResult execute(ImportKeyringParcel importInput, CryptoInputParcel cryptoInput) { - return importKeys(importInput.mKeyList, importInput.mKeyserver); - } - - public ImportKeyResult importKeys(ArrayList<ParcelableKeyRing> keyList, String keyServer) { + public OperationResult execute(ImportKeyringParcel importInput, CryptoInputParcel cryptoInput) { + ArrayList<ParcelableKeyRing> keyList = importInput.mKeyList; + String keyServer = importInput.mKeyserver; ImportKeyResult result; @@ -386,8 +391,21 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> { ParcelableFileCache<ParcelableKeyRing> cache = new ParcelableFileCache<>(mContext, "key_import.pcl"); - result = serialKeyRingImport(cache, keyServer); + result = serialKeyRingImport(cache, null, null); } else { + Proxy proxy; + if (cryptoInput.getParcelableProxy() == null) { + // explicit proxy not set + if(!OrbotHelper.isOrbotInRequiredState(mContext)) { + // show dialog to enable/install dialog + return new ImportKeyResult(null, + RequiredInputParcel.createOrbotRequiredOperation()); + } + proxy = Preferences.getPreferences(mContext).getProxyPrefs().parcelableProxy + .getProxy(); + } else { + proxy = cryptoInput.getParcelableProxy().getProxy(); + } // if there is more than one key with the same fingerprint, we do a serial import to // prevent // https://github.com/open-keychain/open-keychain/issues/1221 @@ -397,9 +415,10 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> { } if (keyFingerprintSet.size() == keyList.size()) { // all keys have unique fingerprints - result = multiThreadedKeyImport(keyList.iterator(), keyList.size(), keyServer); + result = multiThreadedKeyImport(keyList.iterator(), keyList.size(), keyServer, + proxy); } else { - result = serialKeyRingImport(keyList, keyServer); + result = serialKeyRingImport(keyList, keyServer, proxy); } } @@ -408,7 +427,8 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> { } private ImportKeyResult multiThreadedKeyImport(Iterator<ParcelableKeyRing> keyListIterator, - int totKeys, final String keyServer) { + int totKeys, final String keyServer, + final Proxy proxy) { Log.d(Constants.TAG, "Multi-threaded key import starting"); if (keyListIterator != null) { KeyImportAccumulator accumulator = new KeyImportAccumulator(totKeys, mProgressable); @@ -436,7 +456,7 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> { ArrayList<ParcelableKeyRing> list = new ArrayList<>(); list.add(pkRing); - return serialKeyRingImport(list, keyServer, ignoreProgressable); + return serialKeyRingImport(list, keyServer, ignoreProgressable, proxy); } }; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java index 57b99951d..4e9c6a943 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java @@ -32,6 +32,7 @@ import de.measite.minidns.record.TXT; import org.json.JSONObject; import org.spongycastle.openpgp.PGPUtil; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.operations.results.CertifyResult; import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult; import org.sufficientlysecure.keychain.operations.results.KeybaseVerificationResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; @@ -41,9 +42,13 @@ import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.KeybaseVerificationParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; +import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; +import org.sufficientlysecure.keychain.util.Preferences; +import org.sufficientlysecure.keychain.util.orbot.OrbotHelper; import java.io.ByteArrayInputStream; import java.io.InputStream; +import java.net.Proxy; import java.util.ArrayList; import java.util.List; @@ -57,6 +62,18 @@ public class KeybaseVerificationOperation extends BaseOperation<KeybaseVerificat @Override public KeybaseVerificationResult execute(KeybaseVerificationParcel keybaseInput, CryptoInputParcel cryptoInput) { + Proxy proxy; + if (cryptoInput.getParcelableProxy() == null) { + // explicit proxy not set + if (!OrbotHelper.isOrbotInRequiredState(mContext)) { + return new KeybaseVerificationResult(null, + RequiredInputParcel.createOrbotRequiredOperation()); + } + proxy = Preferences.getPreferences(mContext).getProxyPrefs() + .parcelableProxy.getProxy(); + } else { + proxy = cryptoInput.getParcelableProxy().getProxy(); + } String requiredFingerprint = keybaseInput.mRequiredFingerprint; @@ -76,7 +93,7 @@ public class KeybaseVerificationOperation extends BaseOperation<KeybaseVerificat return new KeybaseVerificationResult(OperationResult.RESULT_ERROR, log); } - if (!prover.fetchProofData()) { + if (!prover.fetchProofData(proxy)) { log.add(OperationResult.LogType.MSG_KEYBASE_ERROR_FETCH_PROOF, 1); return new KeybaseVerificationResult(OperationResult.RESULT_ERROR, log); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/ExportResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/ExportResult.java index c8edce259..199a3f565 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/ExportResult.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/ExportResult.java @@ -19,7 +19,9 @@ package org.sufficientlysecure.keychain.operations.results; import android.os.Parcel; -public class ExportResult extends OperationResult { +import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; + +public class ExportResult extends InputPendingResult { final int mOkPublic, mOkSecret; @@ -33,6 +35,14 @@ public class ExportResult extends OperationResult { mOkSecret = okSecret; } + + public ExportResult(OperationLog log, RequiredInputParcel requiredInputParcel) { + super(log, requiredInputParcel); + // we won't use these values + mOkPublic = -1; + mOkSecret = -1; + } + /** Construct from a parcel - trivial because we have no extra data. */ public ExportResult(Parcel source) { super(source); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/ImportKeyResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/ImportKeyResult.java index 2a032cef2..ca7079078 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/ImportKeyResult.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/ImportKeyResult.java @@ -23,6 +23,8 @@ import android.content.Intent; import android.os.Parcel; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; +import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.ui.LogDisplayActivity; import org.sufficientlysecure.keychain.ui.LogDisplayFragment; import org.sufficientlysecure.keychain.ui.util.Notify; @@ -30,7 +32,7 @@ import org.sufficientlysecure.keychain.ui.util.Notify.ActionListener; import org.sufficientlysecure.keychain.ui.util.Notify.Showable; import org.sufficientlysecure.keychain.ui.util.Notify.Style; -public class ImportKeyResult extends OperationResult { +public class ImportKeyResult extends InputPendingResult { public final int mNewKeys, mUpdatedKeys, mBadKeys, mSecret; public final long[] mImportedMasterKeyIds; @@ -80,7 +82,7 @@ public class ImportKeyResult extends OperationResult { } public ImportKeyResult(int result, OperationLog log) { - this(result, log, 0, 0, 0, 0, new long[] { }); + this(result, log, 0, 0, 0, 0, new long[]{}); } public ImportKeyResult(int result, OperationLog log, @@ -94,6 +96,16 @@ public class ImportKeyResult extends OperationResult { mImportedMasterKeyIds = importedMasterKeyIds; } + public ImportKeyResult(OperationLog log, RequiredInputParcel requiredInputParcel) { + super(log, requiredInputParcel); + // just assign default values, we won't use them anyway + mNewKeys = 0; + mUpdatedKeys = 0; + mBadKeys = 0; + mSecret = 0; + mImportedMasterKeyIds = new long[]{}; + } + @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/KeybaseVerificationResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/KeybaseVerificationResult.java index 420cbbf01..173f7f575 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/KeybaseVerificationResult.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/KeybaseVerificationResult.java @@ -24,7 +24,9 @@ import android.os.Parcelable; import com.textuality.keybase.lib.KeybaseException; import com.textuality.keybase.lib.prover.Prover; -public class KeybaseVerificationResult extends OperationResult implements Parcelable { +import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; + +public class KeybaseVerificationResult extends InputPendingResult { public final String mProofUrl; public final String mPresenceUrl; public final String mPresenceLabel; @@ -44,6 +46,13 @@ public class KeybaseVerificationResult extends OperationResult implements Parcel mPresenceLabel = prover.getPresenceLabel(); } + public KeybaseVerificationResult(OperationLog log, RequiredInputParcel requiredInputParcel) { + super(log, requiredInputParcel); + mProofUrl = null; + mPresenceUrl = null; + mPresenceLabel = null; + } + protected KeybaseVerificationResult(Parcel in) { super(in); mProofUrl = in.readString(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index 353c3fcca..4b7d679d1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -1252,7 +1252,7 @@ public class ProviderHelper { ImportKeyResult result = new ImportOperation(mContext, this, new ProgressFixedScaler(progress, 10, 25, 100, R.string.progress_con_reimport)) - .serialKeyRingImport(itSecrets, numSecrets, null); + .serialKeyRingImport(itSecrets, numSecrets, null, null); log.add(result, indent); } else { log.add(LogType.MSG_CON_REIMPORT_SECRET_SKIP, indent); @@ -1280,7 +1280,7 @@ public class ProviderHelper { ImportKeyResult result = new ImportOperation(mContext, this, new ProgressFixedScaler(progress, 25, 99, 100, R.string.progress_con_reimport)) - .serialKeyRingImport(itPublics, numPublics, null); + .serialKeyRingImport(itPublics, numPublics, null, null); log.add(result, indent); } else { log.add(LogType.MSG_CON_REIMPORT_PUBLIC_SKIP, indent); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CertifyActionsParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CertifyActionsParcel.java index d32d75279..e76dcfb49 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CertifyActionsParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CertifyActionsParcel.java @@ -41,7 +41,6 @@ public class CertifyActionsParcel implements Parcelable { public ArrayList<CertifyAction> mCertifyActions = new ArrayList<>(); public String keyServerUri; - public ParcelableProxy parcelableProxy; public CertifyActionsParcel(long masterKeyId) { mMasterKeyId = masterKeyId; @@ -53,7 +52,6 @@ public class CertifyActionsParcel implements Parcelable { // just like parcelables, this is meant for ad-hoc IPC only and is NOT portable! mLevel = CertifyLevel.values()[source.readInt()]; keyServerUri = source.readString(); - parcelableProxy = source.readParcelable(ParcelableProxy.class.getClassLoader()); mCertifyActions = (ArrayList<CertifyAction>) source.readSerializable(); } @@ -67,7 +65,6 @@ public class CertifyActionsParcel implements Parcelable { destination.writeLong(mMasterKeyId); destination.writeInt(mLevel.ordinal()); destination.writeString(keyServerUri); - destination.writeParcelable(parcelableProxy, flags); destination.writeSerializable(mCertifyActions); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/CryptoInputParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/CryptoInputParcel.java index ee7caf2d8..e85b8d633 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/CryptoInputParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/CryptoInputParcel.java @@ -26,6 +26,7 @@ import java.util.Map; import android.os.Parcel; import android.os.Parcelable; +import org.sufficientlysecure.keychain.util.ParcelableProxy; import org.sufficientlysecure.keychain.util.Passphrase; /** @@ -35,6 +36,8 @@ public class CryptoInputParcel implements Parcelable { final Date mSignatureTime; final Passphrase mPassphrase; + // used to supply an explicit proxy to operations that require it + private ParcelableProxy mParcelableProxy; // this map contains both decrypted session keys and signed hashes to be // used in the crypto operation described by this parcel. @@ -43,26 +46,37 @@ public class CryptoInputParcel implements Parcelable { public CryptoInputParcel() { mSignatureTime = new Date(); mPassphrase = null; + mParcelableProxy = null; } public CryptoInputParcel(Date signatureTime, Passphrase passphrase) { mSignatureTime = signatureTime == null ? new Date() : signatureTime; mPassphrase = passphrase; + mParcelableProxy = null; } public CryptoInputParcel(Passphrase passphrase) { mSignatureTime = new Date(); mPassphrase = passphrase; + mParcelableProxy = null; } public CryptoInputParcel(Date signatureTime) { mSignatureTime = signatureTime == null ? new Date() : signatureTime; mPassphrase = null; + mParcelableProxy = null; + } + + public CryptoInputParcel(ParcelableProxy parcelableProxy) { + mSignatureTime = new Date(); // just for compatibility with parcel-ing + mPassphrase = null; + mParcelableProxy = parcelableProxy; } protected CryptoInputParcel(Parcel source) { mSignatureTime = new Date(source.readLong()); mPassphrase = source.readParcelable(getClass().getClassLoader()); + mParcelableProxy = source.readParcelable(getClass().getClassLoader()); { int count = source.readInt(); @@ -85,6 +99,7 @@ public class CryptoInputParcel implements Parcelable { public void writeToParcel(Parcel dest, int flags) { dest.writeLong(mSignatureTime.getTime()); dest.writeParcelable(mPassphrase, 0); + dest.writeParcelable(mParcelableProxy, 0); dest.writeInt(mCryptoData.size()); for (HashMap.Entry<ByteBuffer, byte[]> entry : mCryptoData.entrySet()) { @@ -93,6 +108,10 @@ public class CryptoInputParcel implements Parcelable { } } + public void addParcelableProxy(ParcelableProxy parcelableProxy) { + mParcelableProxy = parcelableProxy; + } + public void addCryptoData(byte[] hash, byte[] signedHash) { mCryptoData.put(ByteBuffer.wrap(hash), signedHash); } @@ -101,6 +120,10 @@ public class CryptoInputParcel implements Parcelable { mCryptoData.putAll(cachedSessionKeys); } + public ParcelableProxy getParcelableProxy() { + return mParcelableProxy; + } + public Map<ByteBuffer, byte[]> getCryptoData() { return mCryptoData; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/RequiredInputParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/RequiredInputParcel.java index 4eca8d8f9..e378296a5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/RequiredInputParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/RequiredInputParcel.java @@ -15,7 +15,7 @@ import java.util.Date; public class RequiredInputParcel implements Parcelable { public enum RequiredInputType { - PASSPHRASE, PASSPHRASE_SYMMETRIC, NFC_SIGN, NFC_DECRYPT, NFC_MOVE_KEY_TO_CARD + PASSPHRASE, PASSPHRASE_SYMMETRIC, NFC_SIGN, NFC_DECRYPT, NFC_MOVE_KEY_TO_CARD, ENABLE_ORBOT } public Date mSignatureTime; @@ -77,6 +77,10 @@ public class RequiredInputParcel implements Parcelable { return mSubKeyId; } + public static RequiredInputParcel createOrbotRequiredOperation() { + return new RequiredInputParcel(RequiredInputType.ENABLE_ORBOT, null, null, null, 0L, 0L); + } + public static RequiredInputParcel createNfcSignOperation( long masterKeyId, long subKeyId, byte[] inputHash, int signAlgo, Date signatureTime) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java index 6c57074a7..ab631c6fe 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java @@ -54,6 +54,7 @@ import org.sufficientlysecure.keychain.ui.base.CachingCryptoOperationFragment; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.ui.widget.CertifyKeySpinner; import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.Preferences; import java.util.ArrayList; @@ -312,8 +313,8 @@ public class CertifyKeyFragment actionsParcel.mCertifyActions.addAll(certifyActions); if (mUploadKeyCheckbox.isChecked()) { - actionsParcel.keyServerUri = Preferences.getPreferences(getActivity()).getPreferredKeyserver(); - actionsParcel.parcelableProxy = mProxyPrefs.parcelableProxy; + actionsParcel.keyServerUri = Preferences.getPreferences(getActivity()) + .getPreferredKeyserver(); } // cached for next cryptoOperation loop diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateYubiKeyImportFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateYubiKeyImportFragment.java index 93614db56..13cafc73c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateYubiKeyImportFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateYubiKeyImportFragment.java @@ -131,7 +131,7 @@ public class CreateYubiKeyImportFragment } }; - if (OrbotHelper.isOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTor, proxyPrefs, + if (OrbotHelper.putOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTor, proxyPrefs, getActivity())) { importKey(proxyPrefs.parcelableProxy); } @@ -153,7 +153,7 @@ public class CreateYubiKeyImportFragment } }; - if (OrbotHelper.isOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTor, proxyPrefs, + if (OrbotHelper.putOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTor, proxyPrefs, getActivity())) { refreshSearch(proxyPrefs.parcelableProxy); } @@ -245,7 +245,7 @@ public class CreateYubiKeyImportFragment } }; - if (OrbotHelper.isOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTor, proxyPrefs, + if (OrbotHelper.putOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTor, proxyPrefs, getActivity())) { refreshSearch(proxyPrefs.parcelableProxy); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java index adb15111d..ea736f938 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java @@ -19,15 +19,11 @@ package org.sufficientlysecure.keychain.ui; import java.util.ArrayList; -import android.app.Activity; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; -import android.os.Message; -import android.os.Messenger; import android.support.v4.app.Fragment; -import android.os.Parcelable; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; @@ -52,7 +48,6 @@ import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.ImportKeyringParcel; -import org.sufficientlysecure.keychain.ui.base.CachingCryptoOperationFragment; import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State; @@ -438,7 +433,7 @@ public abstract class DecryptFragment extends Fragment implements LoaderManager. } }; - if (OrbotHelper.isOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTor, proxyPrefs, + if (OrbotHelper.putOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTor, proxyPrefs, getActivity())) { lookupUnknownKey(signatureKeyId, proxyPrefs.parcelableProxy); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index e2b90056d..2e8e6f6bd 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -364,7 +364,7 @@ public class ImportKeysActivity extends BaseNfcActivity mListFragment.loadNew(loaderState, mProxyPrefs.parcelableProxy); } }; - if (OrbotHelper.isOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTor, mProxyPrefs, this)) { + if (OrbotHelper.putOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTor, mProxyPrefs, this)) { mListFragment.loadNew(loaderState, mProxyPrefs.parcelableProxy); } } else if (loaderState instanceof ImportKeysListFragment.BytesLoaderState) { // must always be true @@ -450,8 +450,6 @@ public class ImportKeysActivity extends BaseNfcActivity ImportKeysListFragment.CloudLoaderState sls = (ImportKeysListFragment.CloudLoaderState) ls; - data.putParcelable(KeychainService.EXTRA_PARCELABLE_PROXY, mProxyPrefs.parcelableProxy); - // get selected key entries ArrayList<ParcelableKeyRing> keys = new ArrayList<>(); { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java index 1a03b8102..f45f1b350 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java @@ -195,23 +195,23 @@ public class ImportKeysProxyActivity extends FragmentActivity } } - public void importKeys(byte[] keyringData, ParcelableProxy parcelableProxy) { + public void importKeys(byte[] keyringData) { ParcelableKeyRing keyEntry = new ParcelableKeyRing(keyringData); ArrayList<ParcelableKeyRing> selectedEntries = new ArrayList<>(); selectedEntries.add(keyEntry); - startImportService(selectedEntries, parcelableProxy); + startImportService(selectedEntries); } - public void importKeys(String fingerprint, ParcelableProxy parcelableProxy) { + public void importKeys(String fingerprint) { ParcelableKeyRing keyEntry = new ParcelableKeyRing(fingerprint, null, null); ArrayList<ParcelableKeyRing> selectedEntries = new ArrayList<>(); selectedEntries.add(keyEntry); - startImportService(selectedEntries, parcelableProxy); + startImportService(selectedEntries); } - private void startImportService(ArrayList<ParcelableKeyRing> keyRings, ParcelableProxy parcelableProxy) { + private void startImportService(ArrayList<ParcelableKeyRing> keyRings) { // search config { @@ -275,18 +275,8 @@ public class ImportKeysProxyActivity extends FragmentActivity NdefMessage msg = (NdefMessage) rawMsgs[0]; // record 0 contains the MIME type, record 1 is the AAR, if present final byte[] receivedKeyringBytes = msg.getRecords()[0].getPayload(); - final Preferences.ProxyPrefs proxyPrefs = Preferences.getPreferences(this) - .getProxyPrefs(); - Runnable ignoreTor = new Runnable() { - @Override - public void run() { - importKeys(receivedKeyringBytes, new ParcelableProxy(null, -1, null)); - } - }; - if (OrbotHelper.isOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTor, proxyPrefs, this)) { - importKeys(receivedKeyringBytes, proxyPrefs.parcelableProxy); - } + importKeys(receivedKeyringBytes); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index 88e7e6025..007a67fbf 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -557,7 +557,7 @@ public class KeyListFragment extends LoaderFragment startActivityForResult(intent, REQUEST_ACTION); } - private void updateAllKeys(ParcelableProxy parcelableProxy) { + private void updateAllKeys() { Activity activity = getActivity(); if (activity == null) { return; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/OrbotRequiredDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/OrbotRequiredDialogActivity.java new file mode 100644 index 000000000..0e73ebf5d --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/OrbotRequiredDialogActivity.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de> + * Copyright (C) 2015 Adithya Abraham Philip <adithyaphilip@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package org.sufficientlysecure.keychain.ui; + +import android.content.Intent; +import android.os.Bundle; +import android.support.v4.app.FragmentActivity; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround; +import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; +import org.sufficientlysecure.keychain.util.ParcelableProxy; +import org.sufficientlysecure.keychain.util.Preferences; +import org.sufficientlysecure.keychain.util.orbot.OrbotHelper; + +/** + * Simply encapsulates a dialog. If orbot is not installed, it shows an install dialog, else a dialog to enable orbot. + */ +public class OrbotRequiredDialogActivity extends FragmentActivity { + + // to provide any previous crypto input into which proxy preference is merged + public static final String EXTRA_CRYPTO_INPUT = "extra_crypto_input"; + + public static final String RESULT_CRYPTO_INPUT = "result_crypto_input"; + + private CryptoInputParcel mCryptoInputParcel; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mCryptoInputParcel = getIntent().getParcelableExtra(EXTRA_CRYPTO_INPUT); + if (mCryptoInputParcel == null) { + mCryptoInputParcel = new CryptoInputParcel(); + } + showDialog(); + } + + /** + * Displays an install or start orbot dialog depending on orbot's presence and state + */ + public void showDialog() { + DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(new Runnable() { + public void run() { + Runnable ignoreTor = new Runnable() { + @Override + public void run() { + Intent intent = new Intent(); + mCryptoInputParcel.addParcelableProxy(ParcelableProxy.getForNoProxy()); + intent.putExtra(RESULT_CRYPTO_INPUT, mCryptoInputParcel); + setResult(RESULT_OK, intent); + finish(); + } + }; + if (OrbotHelper.putOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTor, + Preferences.getPreferences(OrbotRequiredDialogActivity.this) + .getProxyPrefs(), + OrbotRequiredDialogActivity.this)) { + // no action required after all + Intent intent = new Intent(); + intent.putExtra(RESULT_CRYPTO_INPUT, mCryptoInputParcel); + setResult(RESULT_OK, intent); + finish(); + } + } + }); + } +}
\ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsActivity.java index 81e4b9eda..f72a552d5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsActivity.java @@ -18,9 +18,11 @@ package org.sufficientlysecure.keychain.ui; +import android.annotation.TargetApi; import android.app.Activity; import android.content.Context; import android.content.Intent; +import android.os.Build; import android.os.Bundle; import android.preference.CheckBoxPreference; import android.preference.EditTextPreference; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java index ee37b4b98..fb47db872 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java @@ -37,7 +37,6 @@ import org.sufficientlysecure.keychain.service.ExportKeyringParcel; import org.sufficientlysecure.keychain.ui.base.BaseActivity; import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.util.Log; -import org.sufficientlysecure.keychain.util.ParcelableProxy; import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.util.orbot.OrbotHelper; @@ -78,19 +77,7 @@ public class UploadKeyActivity extends BaseActivity mUploadButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - final Preferences.ProxyPrefs proxyPrefs = Preferences.getPreferences(UploadKeyActivity.this) - .getProxyPrefs(); - Runnable ignoreTor = new Runnable() { - @Override - public void run() { - uploadKey(proxyPrefs.parcelableProxy); - } - }; - - if (OrbotHelper.isOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTor, proxyPrefs, - UploadKeyActivity.this)) { - uploadKey(proxyPrefs.parcelableProxy); - } + uploadKey(); } }); @@ -146,8 +133,7 @@ public class UploadKeyActivity extends BaseActivity @Override public void onCryptoOperationSuccess(ExportResult result) { - Toast.makeText(UploadKeyActivity.this, R.string.msg_crt_upload_success, - Toast.LENGTH_SHORT).show(); + result.createNotify(this).show(); } @Override @@ -157,7 +143,7 @@ public class UploadKeyActivity extends BaseActivity @Override public void onCryptoOperationError(ExportResult result) { - // TODO: Implement proper log for key upload then show error + result.createNotify(this).show(); } @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java index f6b580b01..40cbba5b3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java @@ -211,7 +211,7 @@ public class ViewKeyTrustFragment extends LoaderFragment implements } }; - if (OrbotHelper.isOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTor, proxyPrefs, + if (OrbotHelper.putOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTor, proxyPrefs, getActivity())) { mStartSearch.setEnabled(false); new DescribeKey(proxyPrefs.parcelableProxy).execute(fingerprint); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java index 240dd0972..484c065c4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java @@ -39,6 +39,7 @@ import org.sufficientlysecure.keychain.service.ServiceProgressHandler; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.ui.NfcOperationActivity; +import org.sufficientlysecure.keychain.ui.OrbotRequiredDialogActivity; import org.sufficientlysecure.keychain.ui.PassphraseDialogActivity; import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment; import org.sufficientlysecure.keychain.util.Log; @@ -62,6 +63,7 @@ public class CryptoOperationHelper<T extends Parcelable, S extends OperationResu public static final int REQUEST_CODE_PASSPHRASE = 0x00008001; public static final int REQUEST_CODE_NFC = 0x00008002; + public static final int REQUEST_CODE_ENABLE_ORBOT = 0x00008004; // keeps track of request code used to start an activity from this CryptoOperationHelper. // this is necessary when multiple CryptoOperationHelpers are used in the same fragment/activity @@ -116,11 +118,13 @@ public class CryptoOperationHelper<T extends Parcelable, S extends OperationResu mProgressMessageResource = id; } - private void initiateInputActivity(RequiredInputParcel requiredInput) { + private void initiateInputActivity(RequiredInputParcel requiredInput, + CryptoInputParcel cryptoInputParcel) { Activity activity = mUseFragment ? mFragment.getActivity() : mActivity; switch (requiredInput.mType) { + // don't forget to set mRequestedCode! case NFC_MOVE_KEY_TO_CARD: case NFC_DECRYPT: case NFC_SIGN: { @@ -130,7 +134,7 @@ public class CryptoOperationHelper<T extends Parcelable, S extends OperationResu if (mUseFragment) { mFragment.startActivityForResult(intent, mRequestedCode); } else { - mActivity.startActivityForResult(intent, mRequestedCode); + activity.startActivityForResult(intent, mRequestedCode); } return; } @@ -143,18 +147,32 @@ public class CryptoOperationHelper<T extends Parcelable, S extends OperationResu if (mUseFragment) { mFragment.startActivityForResult(intent, mRequestedCode); } else { - mActivity.startActivityForResult(intent, mRequestedCode); + activity.startActivityForResult(intent, mRequestedCode); } return; } - } - throw new RuntimeException("Unhandled pending result!"); + case ENABLE_ORBOT: { + Intent intent = new Intent(activity, OrbotRequiredDialogActivity.class); + intent.putExtra(OrbotRequiredDialogActivity.EXTRA_CRYPTO_INPUT, cryptoInputParcel); + mRequestedCode = REQUEST_CODE_ENABLE_ORBOT; + if (mUseFragment) { + mFragment.startActivityForResult(intent, mRequestedCode); + } else { + activity.startActivityForResult(intent, mRequestedCode); + } + return; + } + + default: { + throw new RuntimeException("Unhandled pending result!"); + } + } } /** - * Attempts the result of an activity started by this helper. Returns true if requestCode is recognized, - * false otherwise. + * Attempts the result of an activity started by this helper. Returns true if requestCode is + * recognized, false otherwise. * * @param requestCode * @param resultCode @@ -196,6 +214,18 @@ public class CryptoOperationHelper<T extends Parcelable, S extends OperationResu break; } + case REQUEST_CODE_ENABLE_ORBOT: { + Log.e("PHILIP", "request rec"); + if (resultCode == Activity.RESULT_OK && data != null) { + CryptoInputParcel cryptoInput = + data.getParcelableExtra( + OrbotRequiredDialogActivity.RESULT_CRYPTO_INPUT); + Log.e("PHILIP", "initiating next op"); + cryptoOperation(cryptoInput); + return true; + } + } + default: { return false; } @@ -225,7 +255,7 @@ public class CryptoOperationHelper<T extends Parcelable, S extends OperationResu } - public void cryptoOperation(CryptoInputParcel cryptoInput, boolean showProgress) { + public void cryptoOperation(final CryptoInputParcel cryptoInput, boolean showProgress) { FragmentActivity activity = mUseFragment ? mFragment.getActivity() : mActivity; @@ -257,7 +287,7 @@ public class CryptoOperationHelper<T extends Parcelable, S extends OperationResu final OperationResult result = returnData.getParcelable(OperationResult.EXTRA_RESULT); - onHandleResult(result); + onHandleResult(result, cryptoInput); } } @@ -299,7 +329,7 @@ public class CryptoOperationHelper<T extends Parcelable, S extends OperationResu } } - public void onHandleResult(OperationResult result) { + public void onHandleResult(OperationResult result, CryptoInputParcel oldCryptoInput) { Log.d(Constants.TAG, "Handling result in OperationHelper success: " + result.success()); if (result instanceof InputPendingResult) { @@ -307,7 +337,7 @@ public class CryptoOperationHelper<T extends Parcelable, S extends OperationResu if (pendingResult.isPending()) { RequiredInputParcel requiredInput = pendingResult.getRequiredInputParcel(); - initiateInputActivity(requiredInput); + initiateInputActivity(requiredInput, oldCryptoInput); return; } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddEditKeyserverDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddEditKeyserverDialogFragment.java index ede4dac4a..b8d93dc00 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddEditKeyserverDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddEditKeyserverDialogFragment.java @@ -54,19 +54,11 @@ import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.keyimport.HkpKeyserver; import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.util.TlsHelper; import org.sufficientlysecure.keychain.util.orbot.OrbotHelper; -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; import java.net.Proxy; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; - -import javax.net.ssl.HttpsURLConnection; -import java.io.IOException; public class AddEditKeyserverDialogFragment extends DialogFragment implements OnEditorActionListener { private static final String ARG_MESSENGER = "arg_messenger"; @@ -220,7 +212,7 @@ public class AddEditKeyserverDialogFragment extends DialogFragment implements On @Override public void onClick(View v) { // behaviour same for edit and add - String keyserverUrl = mKeyserverEditText.getText().toString(); + final String keyserverUrl = mKeyserverEditText.getText().toString(); if (mVerifyKeyserverCheckBox.isChecked()) { final Preferences.ProxyPrefs proxyPrefs = Preferences.getPreferences(getActivity()) .getProxyPrefs(); @@ -231,7 +223,7 @@ public class AddEditKeyserverDialogFragment extends DialogFragment implements On } }; - if (OrbotHelper.isOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTor, proxyPrefs, + if (OrbotHelper.putOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTor, proxyPrefs, getActivity())) { verifyConnection(keyserverUrl, proxyPrefs.parcelableProxy.getProxy()); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/OrbotStartDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/OrbotStartDialogFragment.java index 4736eddca..dba04994c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/OrbotStartDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/OrbotStartDialogFragment.java @@ -15,9 +15,9 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - package org.sufficientlysecure.keychain.ui.dialog; +import android.app.Activity; import android.app.Dialog; import android.content.DialogInterface; import android.os.Bundle; @@ -25,6 +25,7 @@ import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.support.v4.app.DialogFragment; +import android.view.ContextThemeWrapper; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; @@ -62,8 +63,15 @@ public class OrbotStartDialogFragment extends DialogFragment { int title = getArguments().getInt(ARG_TITLE); final int message = getArguments().getInt(ARG_MESSAGE); int middleButton = getArguments().getInt(ARG_MIDDLE_BUTTON); + final Activity activity = getActivity(); + + // if the dialog is displayed from the application class, design is missing. + // hack to get holo design (which is not automatically applied due to activity's + // Theme.NoDisplay) + ContextThemeWrapper theme = new ContextThemeWrapper(activity, + R.style.Theme_AppCompat_Light_Dialog); - CustomAlertDialogBuilder builder = new CustomAlertDialogBuilder(getActivity()); + CustomAlertDialogBuilder builder = new CustomAlertDialogBuilder(theme); builder.setTitle(title).setMessage(message); builder.setNegativeButton(R.string.orbot_start_dialog_cancel, new DialogInterface.OnClickListener() { @@ -97,4 +105,4 @@ public class OrbotStartDialogFragment extends DialogFragment { return builder.show(); } -} +}
\ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/EmailKeyHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/EmailKeyHelper.java index b814f72b2..d7491ab26 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/EmailKeyHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/EmailKeyHelper.java @@ -27,6 +27,7 @@ import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.service.ImportKeyringParcel; import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; +import java.net.Proxy; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -34,6 +35,7 @@ import java.util.Locale; import java.util.Set; public class EmailKeyHelper { + // TODO: Make this not require a proxy in it's constructor, redesign when it is to be used // to import keys, simply use CryptoOperationHelper with this callback public abstract class ImportContactKeysCallback implements CryptoOperationHelper.Callback<ImportKeyringParcel, ImportKeyResult> { @@ -41,14 +43,15 @@ public class EmailKeyHelper { private ArrayList<ParcelableKeyRing> mKeyList; private String mKeyserver; - public ImportContactKeysCallback(Context context, String keyserver) { - this(context, ContactHelper.getContactMails(context), keyserver); + public ImportContactKeysCallback(Context context, String keyserver, Proxy proxy) { + this(context, ContactHelper.getContactMails(context), keyserver, proxy); } - public ImportContactKeysCallback(Context context, List<String> mails, String keyserver) { + public ImportContactKeysCallback(Context context, List<String> mails, String keyserver, + Proxy proxy) { Set<ImportKeysListEntry> entries = new HashSet<>(); for (String mail : mails) { - entries.addAll(getEmailKeys(context, mail)); + entries.addAll(getEmailKeys(context, mail, proxy)); } // Put them in a list and import @@ -65,7 +68,7 @@ public class EmailKeyHelper { } } - public static Set<ImportKeysListEntry> getEmailKeys(Context context, String mail) { + public static Set<ImportKeysListEntry> getEmailKeys(Context context, String mail, Proxy proxy) { Set<ImportKeysListEntry> keys = new HashSet<>(); // Try _hkp._tcp SRV record first @@ -73,7 +76,7 @@ public class EmailKeyHelper { if (mailparts.length == 2) { HkpKeyserver hkp = HkpKeyserver.resolve(mailparts[1]); if (hkp != null) { - keys.addAll(getEmailKeys(mail, hkp)); + keys.addAll(getEmailKeys(mail, hkp, proxy)); } } @@ -82,16 +85,17 @@ public class EmailKeyHelper { String server = Preferences.getPreferences(context).getPreferredKeyserver(); if (server != null) { HkpKeyserver hkp = new HkpKeyserver(server); - keys.addAll(getEmailKeys(mail, hkp)); + keys.addAll(getEmailKeys(mail, hkp, proxy)); } } return keys; } - public static List<ImportKeysListEntry> getEmailKeys(String mail, Keyserver keyServer) { + public static List<ImportKeysListEntry> getEmailKeys(String mail, Keyserver keyServer, + Proxy proxy) { Set<ImportKeysListEntry> keys = new HashSet<>(); try { - for (ImportKeysListEntry key : keyServer.search(mail)) { + for (ImportKeysListEntry key : keyServer.search(mail, proxy)) { if (key.isRevoked() || key.isExpired()) continue; for (String userId : key.getUserIds()) { if (userId.toLowerCase().contains(mail.toLowerCase(Locale.ENGLISH))) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableProxy.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableProxy.java index 4898e7f1a..661650824 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableProxy.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableProxy.java @@ -29,10 +29,7 @@ import java.net.Proxy; public class ParcelableProxy implements Parcelable { private String mProxyHost; private int mProxyPort; - private int mProxyType; - - private final int TYPE_HTTP = 1; - private final int TYPE_SOCKS = 2; + private Proxy.Type mProxyType; public ParcelableProxy(String hostName, int port, Proxy.Type type) { mProxyHost = hostName; @@ -41,37 +38,23 @@ public class ParcelableProxy implements Parcelable { mProxyPort = port; - switch (type) { - case HTTP: { - mProxyType = TYPE_HTTP; - break; - } - case SOCKS: { - mProxyType = TYPE_SOCKS; - break; - } - } + mProxyType = type; + } + + public static ParcelableProxy getForNoProxy() { + return new ParcelableProxy(null, -1, null); } public Proxy getProxy() { if (mProxyHost == null) return null; - Proxy.Type type = null; - switch (mProxyType) { - case TYPE_HTTP: - type = Proxy.Type.HTTP; - break; - case TYPE_SOCKS: - type = Proxy.Type.SOCKS; - break; - } - return new Proxy(type, new InetSocketAddress(mProxyHost, mProxyPort)); + return new Proxy(mProxyType, new InetSocketAddress(mProxyHost, mProxyPort)); } protected ParcelableProxy(Parcel in) { mProxyHost = in.readString(); mProxyPort = in.readInt(); - mProxyType = in.readInt(); + mProxyType = (Proxy.Type) in.readSerializable(); } @Override @@ -83,7 +66,7 @@ public class ParcelableProxy implements Parcelable { public void writeToParcel(Parcel dest, int flags) { dest.writeString(mProxyHost); dest.writeInt(mProxyPort); - dest.writeInt(mProxyType); + dest.writeSerializable(mProxyType); } @SuppressWarnings("unused") diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/orbot/OrbotHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/orbot/OrbotHelper.java index 2cbf45699..6a78b34f5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/orbot/OrbotHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/orbot/OrbotHelper.java @@ -59,6 +59,7 @@ import android.support.v4.app.DialogFragment; import android.support.v4.app.FragmentActivity; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.service.ConsolidateInputParcel; import org.sufficientlysecure.keychain.ui.dialog.SupportInstallDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.OrbotStartDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.PreferenceInstallDialogFragment; @@ -130,6 +131,16 @@ public class OrbotHelper { return intent; } + public static boolean isOrbotInRequiredState(Context context) { + Preferences.ProxyPrefs proxyPrefs = Preferences.getPreferences(context).getProxyPrefs(); + if (!proxyPrefs.torEnabled) { + return true; + } else if (!OrbotHelper.isOrbotInstalled(context) || !OrbotHelper.isOrbotRunning()) { + return false; + } + return true; + } + /** * checks if Tor is enabled and if it is, that Orbot is installed and runnign. Generates appropriate dialogs. * @@ -139,8 +150,9 @@ public class OrbotHelper { * @param fragmentActivity * @return true if Tor is not enabled or Tor is enabled and Orbot is installed and running, else false */ - public static boolean isOrbotInRequiredState(int middleButton, final Runnable middleButtonRunnable, - Preferences.ProxyPrefs proxyPrefs, FragmentActivity fragmentActivity) { + public static boolean putOrbotInRequiredState(int middleButton, final Runnable middleButtonRunnable, + Preferences.ProxyPrefs proxyPrefs, + FragmentActivity fragmentActivity) { Handler ignoreTorHandler = new Handler() { @Override public void handleMessage(Message msg) { |