diff --git a/src/main/java/eu/siacs/conversations/crypto/OmemoSetting.java b/src/main/java/eu/siacs/conversations/crypto/OmemoSetting.java new file mode 100644 index 0000000000000000000000000000000000000000..5326ecae04d38fc1bc16fd68bf4ebb29d926c73e --- /dev/null +++ b/src/main/java/eu/siacs/conversations/crypto/OmemoSetting.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2018, Daniel Gultsch All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package eu.siacs.conversations.crypto; + + +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; + +import eu.siacs.conversations.R; +import eu.siacs.conversations.entities.Message; +import eu.siacs.conversations.ui.SettingsActivity; + +public class OmemoSetting { + + private static boolean always = false; + private static int encryption = Message.ENCRYPTION_AXOLOTL; + + public static boolean isAlways() { + return always; + } + + public static int getEncryption() { + return encryption; + } + + public static void load(final Context context, final SharedPreferences sharedPreferences) { + final String value = sharedPreferences.getString(SettingsActivity.OMEMO_SETTING, context.getResources().getString(R.string.omemo_setting_default)); + switch (value) { + case "always": + always = true; + encryption = Message.ENCRYPTION_AXOLOTL; + break; + case "default_off": + always = false; + encryption = Message.ENCRYPTION_NONE; + break; + default: + always = false; + encryption = Message.ENCRYPTION_AXOLOTL; + break; + + } + } + + public static void load(final Context context) { + load(context, PreferenceManager.getDefaultSharedPreferences(context)); + } +} diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index 33f6ebab7bf655f864a5ed33e4180a1aae4fe422..c12c0faa14de948d150569ee56dde9c6ac16f1d5 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -20,6 +20,7 @@ import java.util.Locale; import java.util.concurrent.atomic.AtomicBoolean; import eu.siacs.conversations.Config; +import eu.siacs.conversations.crypto.OmemoSetting; import eu.siacs.conversations.crypto.PgpDecryptionService; import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.xmpp.chatstate.ChatState; @@ -592,14 +593,15 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl } public int getNextEncryption() { - final int defaultEncryption; if (!Config.supportOmemo() && !Config.supportOpenPgp()) { return Message.ENCRYPTION_NONE; } - if (contactJid.asBareJid().equals(Config.BUG_REPORTS)) { - defaultEncryption = Message.ENCRYPTION_NONE; - } else if (suitableForOmemoByDefault(this)) { - defaultEncryption = Message.ENCRYPTION_AXOLOTL; + if (OmemoSetting.isAlways()) { + return suitableForOmemoByDefault(this) ? Message.ENCRYPTION_AXOLOTL : Message.ENCRYPTION_NONE; + } + final int defaultEncryption; + if (suitableForOmemoByDefault(this)) { + defaultEncryption = OmemoSetting.getEncryption(); } else { defaultEncryption = Message.ENCRYPTION_NONE; } @@ -612,6 +614,9 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl } private static boolean suitableForOmemoByDefault(final Conversation conversation) { + if (conversation.getJid().asBareJid().equals(Config.BUG_REPORTS)) { + return false; + } final String contact = conversation.getJid().getDomain(); final String account = conversation.getAccount().getServer(); if (Config.OMEMO_EXCEPTIONS.CONTACT_DOMAINS.contains(contact) || Config.OMEMO_EXCEPTIONS.ACCOUNT_DOMAINS.contains(account)) { diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index d2cce081559cb6e1cd01d46bc0733c136b641cd4..30af69c7289c90e1a94658b5bd3c07df94e11fa1 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -63,6 +63,7 @@ import java.util.concurrent.atomic.AtomicLong; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; +import eu.siacs.conversations.crypto.OmemoSetting; import eu.siacs.conversations.crypto.PgpDecryptionService; import eu.siacs.conversations.crypto.PgpEngine; import eu.siacs.conversations.crypto.axolotl.AxolotlService; @@ -932,6 +933,7 @@ public class XmppConnectionService extends Service { @SuppressLint("TrulyRandom") @Override public void onCreate() { + OmemoSetting.load(this); ExceptionHelper.init(getApplicationContext()); PRNGFixes.apply(); Resolver.init(this); diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java index 29c17ecfd1810de2cd3783b25b541bd2ac33e40c..3631685484724d3d19f30a3731a1e32e79179a25 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java @@ -60,6 +60,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; +import eu.siacs.conversations.crypto.OmemoSetting; import eu.siacs.conversations.databinding.ActivityConversationsBinding; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Conversation; @@ -364,6 +365,7 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); + OmemoSetting.load(this); new EmojiService(this).init(); this.binding = DataBindingUtil.setContentView(this, R.layout.activity_conversations); setSupportActionBar((Toolbar) binding.toolbar); diff --git a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java index 4913b223120323551608d96eaaf0edf6c3b1947e..e143e48ee3d1c2077badb9f9bc10a999ff599210 100644 --- a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java @@ -32,6 +32,7 @@ import java.util.List; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; +import eu.siacs.conversations.crypto.OmemoSetting; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.services.ExportLogsService; import eu.siacs.conversations.services.MemorizingTrustManager; @@ -52,6 +53,7 @@ public class SettingsActivity extends XmppActivity implements public static final String BROADCAST_LAST_ACTIVITY = "last_activity"; public static final String THEME = "theme"; public static final String SHOW_DYNAMIC_TAGS = "show_dynamic_tags"; + public static final String OMEMO_SETTING = "omemo"; public static final int REQUEST_WRITE_LOGS = 0xbf8701; private SettingsFragment mSettingsFragment; @@ -84,6 +86,8 @@ public class SettingsActivity extends XmppActivity implements super.onStart(); PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this); + changeOmemoSettingSummary(); + if (Config.FORCE_ORBOT) { PreferenceCategory connectionOptions = (PreferenceCategory) mSettingsFragment.findPreference("connection_options"); PreferenceScreen expert = (PreferenceScreen) mSettingsFragment.findPreference("expert"); @@ -231,6 +235,26 @@ public class SettingsActivity extends XmppActivity implements } } + private void changeOmemoSettingSummary() { + ListPreference omemoPreference = (ListPreference) mSettingsFragment.findPreference(OMEMO_SETTING); + if (omemoPreference != null) { + String value = omemoPreference.getValue(); + switch (value) { + case "always": + omemoPreference.setSummary(R.string.pref_omemo_setting_summary_always); + break; + case "default_on": + omemoPreference.setSummary(R.string.pref_omemo_setting_summary_default_on); + break; + case "default_off": + omemoPreference.setSummary(R.string.pref_omemo_setting_summary_default_off); + break; + } + } else { + Log.d(Config.LOGTAG,"unable to find preference named "+OMEMO_SETTING); + } + } + private boolean isCallable(final Intent i) { return i != null && getPackageManager().queryIntentActivities(i, PackageManager.MATCH_DEFAULT_ONLY).size() > 0; } @@ -350,7 +374,10 @@ public class SettingsActivity extends XmppActivity implements TREAT_VIBRATE_AS_SILENT, MANUALLY_CHANGE_PRESENCE, BROADCAST_LAST_ACTIVITY); - if (name.equals(KEEP_FOREGROUND_SERVICE)) { + if (name.equals(OMEMO_SETTING)) { + OmemoSetting.load(this, preferences); + changeOmemoSettingSummary(); + } else if (name.equals(KEEP_FOREGROUND_SERVICE)) { xmppConnectionService.toggleForegroundService(); } else if (resendPresence.contains(name)) { if (xmppConnectionServiceBound) { diff --git a/src/main/java/eu/siacs/conversations/ui/util/ConversationMenuConfigurator.java b/src/main/java/eu/siacs/conversations/ui/util/ConversationMenuConfigurator.java index ae9f3324801abc670a08cf97baf272b4f6974bd2..1ba05badcb461a1d75b81b9f047647896c6791da 100644 --- a/src/main/java/eu/siacs/conversations/ui/util/ConversationMenuConfigurator.java +++ b/src/main/java/eu/siacs/conversations/ui/util/ConversationMenuConfigurator.java @@ -38,6 +38,7 @@ import android.view.MenuItem; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; +import eu.siacs.conversations.crypto.OmemoSetting; import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; @@ -77,7 +78,9 @@ public class ConversationMenuConfigurator { final MenuItem axolotl = menu.findItem(R.id.encryption_choice_axolotl); boolean visible; - if (conversation.getMode() == Conversation.MODE_MULTI) { + if (OmemoSetting.isAlways()) { + visible = false; + } else if (conversation.getMode() == Conversation.MODE_MULTI) { visible = (Config.supportOpenPgp() || Config.supportOmemo()) && Config.multipleEncryptionChoices(); } else { visible = Config.multipleEncryptionChoices(); diff --git a/src/main/res/menu/fragment_conversation.xml b/src/main/res/menu/fragment_conversation.xml index d0d245c991a3b6fc0e593b56ff47b994cce95174..0725a2fd293d88aab82fb5f49a3ff9d097299b0c 100644 --- a/src/main/res/menu/fragment_conversation.xml +++ b/src/main/res/menu/fragment_conversation.xml @@ -69,7 +69,7 @@ android:id="@+id/action_muc_details" android:icon="?attr/icon_group" android:orderInCategory="40" - app:showAsAction="ifRoom" + app:showAsAction="never" android:title="@string/action_muc_details"/> 2592000 15811200 + + always + default_on + default_off + + + @string/always + @string/default_on + @string/default_off + + On by default + Off by default diff --git a/src/main/res/values/defaults.xml b/src/main/res/values/defaults.xml index 27c060127ddb1d89fce1343fe1160c2b08ae9e28..c21999c394b8f06a989f2b89cefbc419f25020bb 100644 --- a/src/main/res/values/defaults.xml +++ b/src/main/res/values/defaults.xml @@ -42,4 +42,5 @@ false true true + default_on diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index c5ccc844e712f126eca28f4d77c54f01136995d8..549c1bc79f847cea1df031159d5dc0695a24e8b0 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -735,4 +735,8 @@ Are you sure you want to disable OMEMO encryption for this conversation?\nThis will allow your server administrator to read your messages, but it might be the only way to communicate with people using outdated clients. Disable now Draft: + OMEMO Encryption + OMEMO will always be used for one-on-one and private group chats. + OMEMO will be used by default for new conversations. + OMEMO will have to be turned on explicitly for new conversations. diff --git a/src/main/res/xml/preferences.xml b/src/main/res/xml/preferences.xml index e38cb3f3a7cd3f592e73bfd52476cde12cb685b4..e1dac40d2f83114e6951d3e73b7c7d01a598335a 100644 --- a/src/main/res/xml/preferences.xml +++ b/src/main/res/xml/preferences.xml @@ -17,6 +17,14 @@ +