mirror of
https://github.com/moparisthebest/k-9
synced 2024-11-27 11:42:16 -05:00
Removed everything related to settings file encryption
The plan is to (re)add this feature later. With a proven method to encrypt files; maybe OpenPGP.
This commit is contained in:
parent
fd16ff8fe6
commit
470ba8bb03
@ -1030,8 +1030,6 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin
|
||||
<string name="error_unable_to_connect">Unable to connect.</string>
|
||||
|
||||
<string name="import_export_action">Settings Import & Export</string>
|
||||
<string name="settings_export_encryption_password_prompt">Please enter a password to protect your exported settings:</string>
|
||||
<string name="settings_import_encryption_password_prompt">Please enter the password you used when exporting your settings:</string>
|
||||
<string name="settings_export_account">Export account settings</string>
|
||||
<string name="settings_export_all">Export settings and accounts</string>
|
||||
<string name="settings_import_dialog_title">Import</string>
|
||||
|
@ -893,11 +893,7 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
|
||||
}
|
||||
|
||||
private void onImport(Uri uri) {
|
||||
//Toast.makeText(this, "Import is disabled for now", Toast.LENGTH_SHORT).show();
|
||||
|
||||
Log.i(K9.LOG_TAG, "onImport importing from URI " + uri.toString());
|
||||
|
||||
ListImportContentsAsyncTask asyncTask = new ListImportContentsAsyncTask(this, uri, null);
|
||||
ListImportContentsAsyncTask asyncTask = new ListImportContentsAsyncTask(this, uri);
|
||||
setNonConfigurationInstance(asyncTask);
|
||||
asyncTask.execute();
|
||||
}
|
||||
@ -954,9 +950,8 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
|
||||
}
|
||||
}
|
||||
|
||||
private void showImportSelectionDialog(ImportContents importContents, Uri uri,
|
||||
String encryptionKey) {
|
||||
ImportSelectionDialog dialog = new ImportSelectionDialog(importContents, uri, encryptionKey);
|
||||
private void showImportSelectionDialog(ImportContents importContents, Uri uri) {
|
||||
ImportSelectionDialog dialog = new ImportSelectionDialog(importContents, uri);
|
||||
dialog.show(this);
|
||||
setNonConfigurationInstance(dialog);
|
||||
}
|
||||
@ -964,16 +959,14 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
|
||||
private static class ImportSelectionDialog implements NonConfigurationInstance {
|
||||
private ImportContents mImportContents;
|
||||
private Uri mUri;
|
||||
private String mEncryptionKey;
|
||||
private Dialog mDialog;
|
||||
private ListView mImportSelectionView;
|
||||
private SparseBooleanArray mSelection;
|
||||
|
||||
|
||||
ImportSelectionDialog(ImportContents importContents, Uri uri, String encryptionKey) {
|
||||
ImportSelectionDialog(ImportContents importContents, Uri uri) {
|
||||
mImportContents = importContents;
|
||||
mUri = uri;
|
||||
mEncryptionKey = encryptionKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1069,7 +1062,7 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
|
||||
activity.setNonConfigurationInstance(null);
|
||||
|
||||
ImportAsyncTask importAsyncTask = new ImportAsyncTask(activity,
|
||||
includeGlobals, accountUuids, overwrite, mEncryptionKey, mUri);
|
||||
includeGlobals, accountUuids, overwrite, mUri);
|
||||
activity.setNonConfigurationInstance(importAsyncTask);
|
||||
importAsyncTask.execute();
|
||||
}
|
||||
@ -1296,23 +1289,7 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
|
||||
accountUuids.add(account.getUuid());
|
||||
}
|
||||
|
||||
/* Disabled for now
|
||||
// Prompt the user for a password
|
||||
new PasswordEntryDialog(this,
|
||||
getString(R.string.settings_export_encryption_password_prompt),
|
||||
new PasswordEntryDialog.PasswordEntryListener() {
|
||||
public void passwordChosen(final String chosenPassword) {
|
||||
// Got the password. Now run export task in the background.
|
||||
new ExportAsyncTask(includeGlobals, accountUuids, chosenPassword).execute();
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
// User cancelled the export. Nothing more to do.
|
||||
}
|
||||
})
|
||||
.show();
|
||||
*/
|
||||
ExportAsyncTask asyncTask = new ExportAsyncTask(this, includeGlobals, accountUuids, null);
|
||||
ExportAsyncTask asyncTask = new ExportAsyncTask(this, includeGlobals, accountUuids);
|
||||
setNonConfigurationInstance(asyncTask);
|
||||
asyncTask.execute();
|
||||
}
|
||||
@ -1323,16 +1300,14 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
|
||||
private static class ExportAsyncTask extends ExtendedAsyncTask<Void, Void, Boolean> {
|
||||
private boolean mIncludeGlobals;
|
||||
private Set<String> mAccountUuids;
|
||||
private String mEncryptionKey;
|
||||
private String mFileName;
|
||||
|
||||
|
||||
private ExportAsyncTask(Accounts activity, boolean includeGlobals,
|
||||
Set<String> accountUuids, String encryptionKey) {
|
||||
Set<String> accountUuids) {
|
||||
super(activity);
|
||||
mIncludeGlobals = includeGlobals;
|
||||
mAccountUuids = accountUuids;
|
||||
mEncryptionKey = encryptionKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1346,7 +1321,7 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
|
||||
protected Boolean doInBackground(Void... params) {
|
||||
try {
|
||||
mFileName = StorageExporter.exportToFile(mContext, mIncludeGlobals,
|
||||
mAccountUuids, mEncryptionKey);
|
||||
mAccountUuids);
|
||||
} catch (StorageImportExportException e) {
|
||||
Log.w(K9.LOG_TAG, "Exception during export", e);
|
||||
return false;
|
||||
@ -1381,18 +1356,15 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
|
||||
private boolean mIncludeGlobals;
|
||||
private List<String> mAccountUuids;
|
||||
private boolean mOverwrite;
|
||||
private String mEncryptionKey;
|
||||
private Uri mUri;
|
||||
private ImportResults mImportResults;
|
||||
|
||||
private ImportAsyncTask(Accounts activity, boolean includeGlobals,
|
||||
List<String> accountUuids, boolean overwrite, String encryptionKey,
|
||||
Uri uri) {
|
||||
List<String> accountUuids, boolean overwrite, Uri uri) {
|
||||
super(activity);
|
||||
mIncludeGlobals = includeGlobals;
|
||||
mAccountUuids = accountUuids;
|
||||
mOverwrite = overwrite;
|
||||
mEncryptionKey = encryptionKey;
|
||||
mUri = uri;
|
||||
}
|
||||
|
||||
@ -1409,7 +1381,7 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
|
||||
InputStream is = mContext.getContentResolver().openInputStream(mUri);
|
||||
try {
|
||||
mImportResults = StorageImporter.importSettings(mContext, is,
|
||||
mEncryptionKey, mIncludeGlobals, mAccountUuids, mOverwrite);
|
||||
mIncludeGlobals, mAccountUuids, mOverwrite);
|
||||
} finally {
|
||||
try {
|
||||
is.close();
|
||||
@ -1456,14 +1428,12 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
|
||||
|
||||
private static class ListImportContentsAsyncTask extends ExtendedAsyncTask<Void, Void, Boolean> {
|
||||
private Uri mUri;
|
||||
private String mEncryptionKey;
|
||||
private ImportContents mImportContents;
|
||||
|
||||
private ListImportContentsAsyncTask(Accounts activity, Uri uri, String encryptionKey) {
|
||||
private ListImportContentsAsyncTask(Accounts activity, Uri uri) {
|
||||
super(activity);
|
||||
|
||||
mUri = uri;
|
||||
mEncryptionKey = encryptionKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1479,8 +1449,7 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
|
||||
ContentResolver resolver = mContext.getContentResolver();
|
||||
InputStream is = resolver.openInputStream(mUri);
|
||||
try {
|
||||
mImportContents = StorageImporter.getImportStreamContents(mContext, is,
|
||||
mEncryptionKey);
|
||||
mImportContents = StorageImporter.getImportStreamContents(mContext, is);
|
||||
} finally {
|
||||
try {
|
||||
is.close();
|
||||
@ -1507,7 +1476,7 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
|
||||
removeProgressDialog();
|
||||
|
||||
if (success) {
|
||||
activity.showImportSelectionDialog(mImportContents, mUri, mEncryptionKey);
|
||||
activity.showImportSelectionDialog(mImportContents, mUri);
|
||||
} else {
|
||||
String filename = mUri.getLastPathSegment();
|
||||
//TODO: better error messages
|
||||
|
@ -1,78 +0,0 @@
|
||||
package com.fsck.k9.activity;
|
||||
|
||||
import com.fsck.k9.R;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.AlertDialog.Builder;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
|
||||
public class PasswordEntryDialog {
|
||||
public interface PasswordEntryListener {
|
||||
void passwordChosen(String chosenPassword);
|
||||
void cancel();
|
||||
}
|
||||
PasswordEntryListener listener;
|
||||
private EditText passwordView;
|
||||
AlertDialog dialog;
|
||||
public PasswordEntryDialog(Context context, String headerText, PasswordEntryListener listener) {
|
||||
this.listener = listener;
|
||||
View view = LayoutInflater.from(context).inflate(R.layout.password_entry_dialog, null);
|
||||
Builder builder = new AlertDialog.Builder(context);
|
||||
passwordView = (EditText)view.findViewById(R.id.password_text_box);
|
||||
|
||||
builder.setView(view);
|
||||
builder.setPositiveButton(R.string.okay_action, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (PasswordEntryDialog.this.listener != null) {
|
||||
String chosenPassword = passwordView.getText().toString();
|
||||
PasswordEntryDialog.this.listener.passwordChosen(chosenPassword);
|
||||
}
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(R.string.cancel_action, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (PasswordEntryDialog.this.listener != null) {
|
||||
PasswordEntryDialog.this.listener.cancel();
|
||||
}
|
||||
}
|
||||
});
|
||||
dialog = builder.create();
|
||||
passwordView.addTextChangedListener(new TextWatcher() {
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable arg0) { }
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { }
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence arg0, int arg1, int arg2,
|
||||
int arg3) {
|
||||
|
||||
Button okButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
|
||||
String chosenPassword = passwordView.getText().toString();
|
||||
okButton.setEnabled(chosenPassword.length() > 0);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
dialog.setMessage(headerText);
|
||||
|
||||
|
||||
}
|
||||
public void show() {
|
||||
dialog.show();
|
||||
Button okButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
|
||||
okButton.setEnabled(false);
|
||||
}
|
||||
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
package com.fsck.k9.preferences;
|
||||
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
public class K9Krypto {
|
||||
final Base64 mBase64;
|
||||
final Cipher mCipher;
|
||||
|
||||
private final static String AES = "AES";
|
||||
private final static String SECURE_RANDOM_TYPE = "SHA1PRNG";
|
||||
|
||||
public enum MODE {
|
||||
ENCRYPT(Cipher.ENCRYPT_MODE), DECRYPT(Cipher.DECRYPT_MODE);
|
||||
|
||||
int mode;
|
||||
private MODE(int nMode) {
|
||||
mode = nMode;
|
||||
}
|
||||
}
|
||||
|
||||
public K9Krypto(String key, MODE mode) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException {
|
||||
mBase64 = new Base64();
|
||||
KeyGenerator keyGenerator = KeyGenerator.getInstance(AES);
|
||||
SecureRandom secureRandom = SecureRandom.getInstance(SECURE_RANDOM_TYPE);
|
||||
secureRandom.setSeed(key.getBytes());
|
||||
keyGenerator.init(128, secureRandom);
|
||||
SecretKey secretKey = keyGenerator.generateKey();
|
||||
byte[] processedKey = secretKey.getEncoded();
|
||||
mCipher = setupCipher(mode.mode, processedKey);
|
||||
}
|
||||
|
||||
public String encrypt(String plainText) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
|
||||
byte[] encryptedText = mCipher.doFinal(plainText.getBytes());
|
||||
byte[] encryptedEncodedText = mBase64.encode(encryptedText);
|
||||
return new String(encryptedEncodedText);
|
||||
}
|
||||
|
||||
public String decrypt(String encryptedEncodedText) throws IllegalBlockSizeException, BadPaddingException {
|
||||
byte[] encryptedText = mBase64.decode(encryptedEncodedText.getBytes());
|
||||
byte[] plainText = mCipher.doFinal(encryptedText);
|
||||
return new String(plainText);
|
||||
}
|
||||
|
||||
private Cipher setupCipher(int mode, byte[] processedKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
|
||||
SecretKeySpec secretKeySpec = new SecretKeySpec(processedKey, AES);
|
||||
Cipher cipher = Cipher.getInstance(AES);
|
||||
cipher.init(mode, secretKeySpec);
|
||||
return cipher;
|
||||
}
|
||||
|
||||
}
|
@ -12,7 +12,6 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.Map.Entry;
|
||||
import javax.crypto.CipherOutputStream;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
import android.content.Context;
|
||||
@ -77,7 +76,7 @@ public class StorageExporter {
|
||||
|
||||
|
||||
public static String exportToFile(Context context, boolean includeGlobals,
|
||||
Set<String> accountUuids, String encryptionKey)
|
||||
Set<String> accountUuids)
|
||||
throws StorageImportExportException {
|
||||
|
||||
OutputStream os = null;
|
||||
@ -91,12 +90,7 @@ public class StorageExporter {
|
||||
filename = file.getAbsolutePath();
|
||||
os = new FileOutputStream(filename);
|
||||
|
||||
if (encryptionKey == null) {
|
||||
exportPreferences(context, os, includeGlobals, accountUuids);
|
||||
} else {
|
||||
exportPreferencesEncrypted(context, os, includeGlobals, accountUuids,
|
||||
encryptionKey);
|
||||
}
|
||||
exportPreferences(context, os, includeGlobals, accountUuids);
|
||||
|
||||
// If all went well, we return the name of the file just written.
|
||||
return filename;
|
||||
@ -113,19 +107,6 @@ public class StorageExporter {
|
||||
}
|
||||
}
|
||||
|
||||
public static void exportPreferencesEncrypted(Context context, OutputStream os, boolean includeGlobals,
|
||||
Set<String> accountUuids, String encryptionKey) throws StorageImportExportException {
|
||||
|
||||
try {
|
||||
K9Krypto k = new K9Krypto(encryptionKey, K9Krypto.MODE.ENCRYPT);
|
||||
CipherOutputStream cos = new CipherOutputStream(os, k.mCipher);
|
||||
|
||||
exportPreferences(context, cos, includeGlobals, accountUuids);
|
||||
} catch (Exception e) {
|
||||
throw new StorageImportExportException();
|
||||
}
|
||||
}
|
||||
|
||||
public static void exportPreferences(Context context, OutputStream os, boolean includeGlobals,
|
||||
Set<String> accountUuids) throws StorageImportExportException {
|
||||
|
||||
|
@ -35,7 +35,7 @@ public class StorageImporter {
|
||||
/**
|
||||
* Class to list the contents of an import file/stream.
|
||||
*
|
||||
* @see StorageImporter#getImportStreamContents(Context,InputStream,String)
|
||||
* @see StorageImporter#getImportStreamContents(Context,InputStream)
|
||||
*/
|
||||
public static class ImportContents {
|
||||
/**
|
||||
@ -100,10 +100,6 @@ public class StorageImporter {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isImportStreamEncrypted(Context context, InputStream inputStream) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an import {@link InputStream} and returns information on whether it contains global
|
||||
* settings and/or account settings. For all account configurations found, the name of the
|
||||
@ -111,12 +107,11 @@ public class StorageImporter {
|
||||
*
|
||||
* @param context
|
||||
* @param inputStream
|
||||
* @param encryptionKey
|
||||
* @return
|
||||
* @throws StorageImportExportException
|
||||
*/
|
||||
public static ImportContents getImportStreamContents(Context context, InputStream inputStream,
|
||||
String encryptionKey) throws StorageImportExportException {
|
||||
public static ImportContents getImportStreamContents(Context context, InputStream inputStream)
|
||||
throws StorageImportExportException {
|
||||
|
||||
try {
|
||||
// Parse the import stream but don't save individual settings (overview=true)
|
||||
@ -151,13 +146,12 @@ public class StorageImporter {
|
||||
*
|
||||
* @param context
|
||||
* @param inputStream
|
||||
* @param encryptionKey
|
||||
* @param globalSettings
|
||||
* @param accountUuids
|
||||
* @param overwrite
|
||||
* @throws StorageImportExportException
|
||||
*/
|
||||
public static ImportResults importSettings(Context context, InputStream inputStream, String encryptionKey,
|
||||
public static ImportResults importSettings(Context context, InputStream inputStream,
|
||||
boolean globalSettings, List<String> accountUuids, boolean overwrite)
|
||||
throws StorageImportExportException {
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user