1
0
mirror of https://github.com/moparisthebest/k-9 synced 2024-11-30 13:12:25 -05:00

pgp issues 2152, 2900, and 3673. also option to disable not-yet-encrypted drafts related to issue 1424.

This commit is contained in:
ashley willis 2011-11-19 00:49:04 -06:00
parent 97bfb5e229
commit 51c662f0d0
10 changed files with 157 additions and 14 deletions

View File

@ -595,6 +595,10 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin
<string name="account_settings_crypto_app_not_available">not available</string> <string name="account_settings_crypto_app_not_available">not available</string>
<string name="account_settings_crypto_auto_signature">Auto-sign</string> <string name="account_settings_crypto_auto_signature">Auto-sign</string>
<string name="account_settings_crypto_auto_signature_summary">Use the account\'s email address to guess the signature key.</string> <string name="account_settings_crypto_auto_signature_summary">Use the account\'s email address to guess the signature key.</string>
<string name="account_settings_crypto_auto_encrypt">Auto-encrypt</string>
<string name="account_settings_crypto_auto_encrypt_summary">Automatically set encrypt if a public key matches a recipient.</string>
<string name="account_settings_crypto_dont_sync_drafts">Don\'t sync drafts</string>
<string name="account_settings_crypto_dont_sync_drafts_summary">Don\'t sync drafts marked to be encrypted. Must change drafts folder\'s sync and push class to none, or these drafts will be deleted!</string>
<string name="account_settings_mail_check_frequency_label">Folder poll frequency</string> <string name="account_settings_mail_check_frequency_label">Folder poll frequency</string>
<string name="account_settings_second_class_check_frequency_label">2nd class check frequency</string> <string name="account_settings_second_class_check_frequency_label">2nd class check frequency</string>

View File

@ -474,6 +474,20 @@
android:summary="@string/account_settings_crypto_auto_signature_summary" android:summary="@string/account_settings_crypto_auto_signature_summary"
android:dependency="crypto_app"/> android:dependency="crypto_app"/>
<CheckBoxPreference
android:persistent="false"
android:key="crypto_auto_encrypt"
android:title="@string/account_settings_crypto_auto_encrypt"
android:summary="@string/account_settings_crypto_auto_encrypt_summary"
android:dependency="crypto_app"/>
<CheckBoxPreference
android:persistent="false"
android:key="crypto_dont_sync_drafts"
android:title="@string/account_settings_crypto_dont_sync_drafts"
android:summary="@string/account_settings_crypto_dont_sync_drafts_summary"
android:dependency="crypto_app"/>
</PreferenceScreen> </PreferenceScreen>
</PreferenceScreen> </PreferenceScreen>

View File

@ -149,6 +149,8 @@ public class Account implements BaseAccount {
private boolean mSyncRemoteDeletions; private boolean mSyncRemoteDeletions;
private String mCryptoApp; private String mCryptoApp;
private boolean mCryptoAutoSignature; private boolean mCryptoAutoSignature;
private boolean mCryptoAutoEncrypt;
private boolean mCryptoDontSyncDrafts;
private CryptoProvider mCryptoProvider = null; private CryptoProvider mCryptoProvider = null;
@ -240,6 +242,8 @@ public class Account implements BaseAccount {
mSyncRemoteDeletions = true; mSyncRemoteDeletions = true;
mCryptoApp = Apg.NAME; mCryptoApp = Apg.NAME;
mCryptoAutoSignature = false; mCryptoAutoSignature = false;
mCryptoAutoEncrypt = false;
mCryptoDontSyncDrafts = false;
mEnabled = true; mEnabled = true;
searchableFolders = Searchable.ALL; searchableFolders = Searchable.ALL;
@ -408,6 +412,8 @@ public class Account implements BaseAccount {
mCryptoApp = prefs.getString(mUuid + ".cryptoApp", Apg.NAME); mCryptoApp = prefs.getString(mUuid + ".cryptoApp", Apg.NAME);
mCryptoAutoSignature = prefs.getBoolean(mUuid + ".cryptoAutoSignature", false); mCryptoAutoSignature = prefs.getBoolean(mUuid + ".cryptoAutoSignature", false);
mCryptoAutoEncrypt = prefs.getBoolean(mUuid + ".cryptoAutoEncrypt", false);
mCryptoDontSyncDrafts = prefs.getBoolean(mUuid + ".cryptoDontSyncDrafts", false);
mEnabled = prefs.getBoolean(mUuid + ".enabled", true); mEnabled = prefs.getBoolean(mUuid + ".enabled", true);
} }
@ -480,6 +486,8 @@ public class Account implements BaseAccount {
editor.remove(mUuid + ".stripSignature"); editor.remove(mUuid + ".stripSignature");
editor.remove(mUuid + ".cryptoApp"); editor.remove(mUuid + ".cryptoApp");
editor.remove(mUuid + ".cryptoAutoSignature"); editor.remove(mUuid + ".cryptoAutoSignature");
editor.remove(mUuid + ".cryptoAutoEncrypt");
editor.remove(mUuid + ".cryptoDontSyncDrafts");
editor.remove(mUuid + ".enabled"); editor.remove(mUuid + ".enabled");
editor.remove(mUuid + ".enableMoveButtons"); editor.remove(mUuid + ".enableMoveButtons");
editor.remove(mUuid + ".hideMoveButtonsEnum"); editor.remove(mUuid + ".hideMoveButtonsEnum");
@ -643,6 +651,8 @@ public class Account implements BaseAccount {
editor.putBoolean(mUuid + ".stripSignature", mStripSignature); editor.putBoolean(mUuid + ".stripSignature", mStripSignature);
editor.putString(mUuid + ".cryptoApp", mCryptoApp); editor.putString(mUuid + ".cryptoApp", mCryptoApp);
editor.putBoolean(mUuid + ".cryptoAutoSignature", mCryptoAutoSignature); editor.putBoolean(mUuid + ".cryptoAutoSignature", mCryptoAutoSignature);
editor.putBoolean(mUuid + ".cryptoAutoEncrypt", mCryptoAutoEncrypt);
editor.putBoolean(mUuid + ".cryptoDontSyncDrafts", mCryptoAutoEncrypt);
editor.putBoolean(mUuid + ".enabled", mEnabled); editor.putBoolean(mUuid + ".enabled", mEnabled);
editor.putBoolean(mUuid + ".vibrate", mNotificationSetting.shouldVibrate()); editor.putBoolean(mUuid + ".vibrate", mNotificationSetting.shouldVibrate());
@ -1466,6 +1476,22 @@ public class Account implements BaseAccount {
mCryptoAutoSignature = cryptoAutoSignature; mCryptoAutoSignature = cryptoAutoSignature;
} }
public boolean isCryptoAutoEncrypt() {
return mCryptoAutoEncrypt;
}
public void setCryptoAutoEncrypt(boolean cryptoAutoEncrypt) {
mCryptoAutoEncrypt = cryptoAutoEncrypt;
}
public boolean isCryptoDontSyncDrafts() {
return mCryptoDontSyncDrafts;
}
public void setCryptoDontSyncDrafts(boolean cryptoDontSyncDrafts) {
mCryptoDontSyncDrafts = cryptoDontSyncDrafts;
}
public String getInboxFolderName() { public String getInboxFolderName() {
return mInboxFolderName; return mInboxFolderName;
} }

View File

@ -208,6 +208,8 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
private ImageButton mAddBccFromContacts; private ImageButton mAddBccFromContacts;
private PgpData mPgpData = null; private PgpData mPgpData = null;
private boolean mAutoEncrypt = false;
private boolean mDontSyncDrafts = false;
private String mReferences; private String mReferences;
private String mInReplyTo; private String mInReplyTo;
@ -442,6 +444,28 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
public void afterTextChanged(android.text.Editable s) { } public void afterTextChanged(android.text.Editable s) { }
}; };
TextWatcher recipientWatcher = new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, int before, int after) { }
public void onTextChanged(CharSequence s, int start, int before, int count) {
mDraftNeedsSaving = true;
}
public void afterTextChanged(android.text.Editable s) {
final CryptoProvider crypto = mAccount.getCryptoProvider();
if (mAutoEncrypt && crypto.isAvailable(getApplicationContext())) {
for (Address address : getRecipientAddresses()) {
long ids[] = crypto.getPublicKeyIdsFromEmail(getApplicationContext(),
address.getAddress());
if (ids != null && ids.length > 0) {
mEncryptCheckbox.setChecked(true);
break;
}
}
}
}
};
TextWatcher sigwatcher = new TextWatcher() { TextWatcher sigwatcher = new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, public void beforeTextChanged(CharSequence s, int start,
int before, int after) { } int before, int after) { }
@ -455,9 +479,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
public void afterTextChanged(android.text.Editable s) { } public void afterTextChanged(android.text.Editable s) { }
}; };
mToView.addTextChangedListener(watcher); mToView.addTextChangedListener(recipientWatcher);
mCcView.addTextChangedListener(watcher); mCcView.addTextChangedListener(recipientWatcher);
mBccView.addTextChangedListener(watcher); mBccView.addTextChangedListener(recipientWatcher);
mSubjectView.addTextChangedListener(watcher); mSubjectView.addTextChangedListener(watcher);
mMessageContentView.addTextChangedListener(watcher); mMessageContentView.addTextChangedListener(watcher);
@ -616,6 +640,11 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
mCryptoSignatureUserId = (TextView)findViewById(R.id.userId); mCryptoSignatureUserId = (TextView)findViewById(R.id.userId);
mCryptoSignatureUserIdRest = (TextView)findViewById(R.id.userIdRest); mCryptoSignatureUserIdRest = (TextView)findViewById(R.id.userIdRest);
mEncryptCheckbox = (CheckBox)findViewById(R.id.cb_encrypt); mEncryptCheckbox = (CheckBox)findViewById(R.id.cb_encrypt);
if (mSourceMessageBody != null) {
// mSourceMessageBody is set to something when replying to and forwarding decrypted
// messages, so the sender probably wants the message to be encrypted.
mEncryptCheckbox.setChecked(true);
}
initializeCrypto(); initializeCrypto();
final CryptoProvider crypto = mAccount.getCryptoProvider(); final CryptoProvider crypto = mAccount.getCryptoProvider();
@ -649,6 +678,8 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
} }
} }
updateEncryptLayout(); updateEncryptLayout();
mAutoEncrypt = mAccount.isCryptoAutoEncrypt();
mDontSyncDrafts = mAccount.isCryptoDontSyncDrafts();
} else { } else {
mEncryptLayout.setVisibility(View.GONE); mEncryptLayout.setVisibility(View.GONE);
} }
@ -776,6 +807,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
mCryptoSignatureUserId.setVisibility(View.INVISIBLE); mCryptoSignatureUserId.setVisibility(View.INVISIBLE);
mCryptoSignatureUserIdRest.setVisibility(View.INVISIBLE); mCryptoSignatureUserIdRest.setVisibility(View.INVISIBLE);
} else { } else {
mMessageFormat = MessageFormat.TEXT;
// if a signature key is selected, then the checkbox itself has no text // if a signature key is selected, then the checkbox itself has no text
mCryptoSignatureCheckbox.setText(""); mCryptoSignatureCheckbox.setText("");
mCryptoSignatureCheckbox.setChecked(true); mCryptoSignatureCheckbox.setChecked(true);
@ -919,6 +951,12 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
return Address.parseUnencoded(view.getText().toString().trim()); return Address.parseUnencoded(view.getText().toString().trim());
} }
private Address[] getRecipientAddresses() {
String addresses = mToView.getText().toString() + mCcView.getText().toString()
+ mBccView.getText().toString();
return Address.parseUnencoded(addresses.trim());
}
/* /*
* Build the Body that will contain the text of the message. We'll decide where to * Build the Body that will contain the text of the message. We'll decide where to
* include it later. Draft messages are treated somewhat differently in that signatures are not * include it later. Draft messages are treated somewhat differently in that signatures are not
@ -960,7 +998,6 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
// Place the signature immediately after the reply. // Place the signature immediately after the reply.
if (!isDraft) { if (!isDraft) {
if (mQuoteStyle == QuoteStyle.HEADER || replyAfterQuote || mAccount.isSignatureBeforeQuotedText()) { if (mQuoteStyle == QuoteStyle.HEADER || replyAfterQuote || mAccount.isSignatureBeforeQuotedText()) {
Log.d("ASH", "appending signature after new content");
text = appendSignature(text); text = appendSignature(text);
} }
} }
@ -1461,6 +1498,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
return; return;
} }
if (mEncryptCheckbox.isChecked() && !mPgpData.hasEncryptionKeys()) { if (mEncryptCheckbox.isChecked() && !mPgpData.hasEncryptionKeys()) {
mMessageFormat = MessageFormat.TEXT;
// key selection before encryption // key selection before encryption
StringBuilder emails = new StringBuilder(); StringBuilder emails = new StringBuilder();
Address[][] addresses = new Address[][] { getAddresses(mToView), Address[][] addresses = new Address[][] { getAddresses(mToView),
@ -2876,7 +2914,8 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
} }
final MessagingController messagingController = MessagingController.getInstance(getApplication()); final MessagingController messagingController = MessagingController.getInstance(getApplication());
Message draftMessage = messagingController.saveDraft(mAccount, message); Message draftMessage = messagingController.saveDraft(mAccount, message,
mDontSyncDrafts && mEncryptCheckbox.isChecked());
mDraftUid = draftMessage.getUid(); mDraftUid = draftMessage.getUid();
// Don't display the toast if the user is just changing the orientation // Don't display the toast if the user is just changing the orientation

View File

@ -97,6 +97,8 @@ public class AccountSettings extends K9PreferenceActivity {
private static final String PREFERENCE_SYNC_REMOTE_DELETIONS = "account_sync_remote_deletetions"; private static final String PREFERENCE_SYNC_REMOTE_DELETIONS = "account_sync_remote_deletetions";
private static final String PREFERENCE_CRYPTO_APP = "crypto_app"; private static final String PREFERENCE_CRYPTO_APP = "crypto_app";
private static final String PREFERENCE_CRYPTO_AUTO_SIGNATURE = "crypto_auto_signature"; private static final String PREFERENCE_CRYPTO_AUTO_SIGNATURE = "crypto_auto_signature";
private static final String PREFERENCE_CRYPTO_AUTO_ENCRYPT = "crypto_auto_encrypt";
private static final String PREFERENCE_CRYPTO_DONT_SYNC_DRAFTS = "crypto_dont_sync_drafts";
private static final String PREFERENCE_LOCAL_STORAGE_PROVIDER = "local_storage_provider"; private static final String PREFERENCE_LOCAL_STORAGE_PROVIDER = "local_storage_provider";
@ -161,6 +163,8 @@ public class AccountSettings extends K9PreferenceActivity {
private ListPreference mMaxPushFolders; private ListPreference mMaxPushFolders;
private ListPreference mCryptoApp; private ListPreference mCryptoApp;
private CheckBoxPreference mCryptoAutoSignature; private CheckBoxPreference mCryptoAutoSignature;
private CheckBoxPreference mCryptoAutoEncrypt;
private CheckBoxPreference mCryptoDontSyncDrafts;
private ListPreference mLocalStorageProvider; private ListPreference mLocalStorageProvider;
@ -681,14 +685,24 @@ public class AccountSettings extends K9PreferenceActivity {
mCryptoAutoSignature = (CheckBoxPreference) findPreference(PREFERENCE_CRYPTO_AUTO_SIGNATURE); mCryptoAutoSignature = (CheckBoxPreference) findPreference(PREFERENCE_CRYPTO_AUTO_SIGNATURE);
mCryptoAutoSignature.setChecked(mAccount.getCryptoAutoSignature()); mCryptoAutoSignature.setChecked(mAccount.getCryptoAutoSignature());
mCryptoAutoEncrypt = (CheckBoxPreference) findPreference(PREFERENCE_CRYPTO_AUTO_ENCRYPT);
mCryptoAutoEncrypt.setChecked(mAccount.isCryptoAutoEncrypt());
mCryptoDontSyncDrafts = (CheckBoxPreference) findPreference(PREFERENCE_CRYPTO_DONT_SYNC_DRAFTS);
mCryptoDontSyncDrafts.setChecked(mAccount.isCryptoDontSyncDrafts());
handleCryptoAppDependencies(); handleCryptoAppDependencies();
} }
private void handleCryptoAppDependencies() { private void handleCryptoAppDependencies() {
if ("".equals(mCryptoApp.getValue())) { if ("".equals(mCryptoApp.getValue())) {
mCryptoAutoSignature.setEnabled(false); mCryptoAutoSignature.setEnabled(false);
mCryptoAutoEncrypt.setEnabled(false);
mCryptoDontSyncDrafts.setEnabled(false);
} else { } else {
mCryptoAutoSignature.setEnabled(true); mCryptoAutoSignature.setEnabled(true);
mCryptoAutoEncrypt.setEnabled(true);
mCryptoDontSyncDrafts.setEnabled(true);
} }
} }
@ -734,6 +748,8 @@ public class AccountSettings extends K9PreferenceActivity {
mAccount.setStripSignature(mStripSignature.isChecked()); mAccount.setStripSignature(mStripSignature.isChecked());
mAccount.setCryptoApp(mCryptoApp.getValue()); mAccount.setCryptoApp(mCryptoApp.getValue());
mAccount.setCryptoAutoSignature(mCryptoAutoSignature.isChecked()); mAccount.setCryptoAutoSignature(mCryptoAutoSignature.isChecked());
mAccount.setCryptoAutoEncrypt(mCryptoAutoEncrypt.isChecked());
mAccount.setCryptoDontSyncDrafts(mCryptoDontSyncDrafts.isChecked());
mAccount.setLocalStorageProviderId(mLocalStorageProvider.getValue()); mAccount.setLocalStorageProviderId(mLocalStorageProvider.getValue());
// In webdav account we use the exact folder name also for inbox, // In webdav account we use the exact folder name also for inbox,

View File

@ -4059,7 +4059,7 @@ public class MessagingController implements Runnable {
* @param message Message to save. * @param message Message to save.
* @return Message representing the entry in the local store. * @return Message representing the entry in the local store.
*/ */
public Message saveDraft(final Account account, final Message message) { public Message saveDraft(final Account account, final Message message, final boolean dontSyncDraft) {
Message localMessage = null; Message localMessage = null;
try { try {
LocalStore localStore = account.getLocalStore(); LocalStore localStore = account.getLocalStore();
@ -4072,14 +4072,15 @@ public class MessagingController implements Runnable {
// Fetch the message back from the store. This is the Message that's returned to the caller. // Fetch the message back from the store. This is the Message that's returned to the caller.
localMessage = localFolder.getMessage(message.getUid()); localMessage = localFolder.getMessage(message.getUid());
localMessage.setFlag(Flag.X_DOWNLOADED_FULL, true); localMessage.setFlag(Flag.X_DOWNLOADED_FULL, true);
if (!dontSyncDraft) {
PendingCommand command = new PendingCommand(); PendingCommand command = new PendingCommand();
command.command = PENDING_COMMAND_APPEND; command.command = PENDING_COMMAND_APPEND;
command.arguments = new String[] { command.arguments = new String[] {
localFolder.getName(), localFolder.getName(),
localMessage.getUid() localMessage.getUid()
}; };
queuePendingCommand(account, command); queuePendingCommand(account, command);
}
processPendingCommands(account); processPendingCommands(account);
} catch (MessagingException e) { } catch (MessagingException e) {

View File

@ -232,6 +232,41 @@ public class Apg extends CryptoProvider {
return ids; return ids;
} }
/**
* Get public key ids based on a given email.
*
* @param context
* @param email The email in question.
* @return key ids
*/
@Override
public long[] getPublicKeyIdsFromEmail(Context context, String email) {
long ids[] = null;
try {
Uri contentUri = Uri.withAppendedPath(Apg.CONTENT_URI_PUBLIC_KEY_RING_BY_EMAILS,
email);
Cursor c = context.getContentResolver().query(contentUri,
new String[] { "master_key_id" },
null, null, null);
if (c != null && c.getCount() > 0) {
ids = new long[c.getCount()];
while (c.moveToNext()) {
ids[c.getPosition()] = c.getLong(0);
}
}
if (c != null) {
c.close();
}
} catch (SecurityException e) {
Toast.makeText(context,
context.getResources().getString(R.string.insufficient_apg_permissions),
Toast.LENGTH_LONG).show();
}
return ids;
}
/** /**
* Get the user id based on the key id. * Get the user id based on the key id.
* *

View File

@ -24,6 +24,7 @@ abstract public class CryptoProvider {
abstract public boolean encrypt(Activity activity, String data, PgpData pgpData); abstract public boolean encrypt(Activity activity, String data, PgpData pgpData);
abstract public boolean decrypt(Activity activity, String data, PgpData pgpData); abstract public boolean decrypt(Activity activity, String data, PgpData pgpData);
abstract public long[] getSecretKeyIdsFromEmail(Context context, String email); abstract public long[] getSecretKeyIdsFromEmail(Context context, String email);
abstract public long[] getPublicKeyIdsFromEmail(Context context, String email);
abstract public String getUserId(Context context, long keyId); abstract public String getUserId(Context context, long keyId);
abstract public String getName(); abstract public String getName();
abstract public boolean test(Context context); abstract public boolean test(Context context);

View File

@ -37,6 +37,11 @@ public class None extends CryptoProvider {
return null; return null;
} }
@Override
public long[] getPublicKeyIdsFromEmail(Context context, String email) {
return null;
}
@Override @Override
public String getUserId(Context context, long keyId) { public String getUserId(Context context, long keyId) {
return null; return null;

View File

@ -27,6 +27,8 @@ public class AccountSettings {
s.put("chipColor", new ColorSetting(0xFF0000FF)); s.put("chipColor", new ColorSetting(0xFF0000FF));
s.put("cryptoApp", new StringSetting(Apg.NAME)); s.put("cryptoApp", new StringSetting(Apg.NAME));
s.put("cryptoAutoSignature", new BooleanSetting(false)); s.put("cryptoAutoSignature", new BooleanSetting(false));
//s.put("cryptoAutoEncrypt", new BooleanSetting(false)); // added to version 3?
//s.put("cryptoDontSyncDrafts", new BooleanSetting(false)); // added to version 3?
s.put("defaultQuotedTextShown", new BooleanSetting(Account.DEFAULT_QUOTED_TEXT_SHOWN)); s.put("defaultQuotedTextShown", new BooleanSetting(Account.DEFAULT_QUOTED_TEXT_SHOWN));
s.put("deletePolicy", new DeletePolicySetting(Account.DELETE_POLICY_NEVER)); s.put("deletePolicy", new DeletePolicySetting(Account.DELETE_POLICY_NEVER));
s.put("displayCount", new IntegerResourceSetting(K9.DEFAULT_VISIBLE_LIMIT, s.put("displayCount", new IntegerResourceSetting(K9.DEFAULT_VISIBLE_LIMIT,