From b393f54a038ba810aeb0f91d162976e16b7429c9 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 27 Feb 2018 20:33:21 +0100 Subject: [PATCH] get rid of customizable resources --- .../siacs/conversations/entities/Account.java | 16 +- .../persistance/DatabaseBackend.java | 6 +- .../services/XmppConnectionService.java | 11 - .../conversations/ui/SettingsActivity.java | 83 ++--- .../conversations/xmpp/XmppConnection.java | 325 +++++++++--------- src/main/res/values/arrays.xml | 7 - src/main/res/values/strings.xml | 2 - src/main/res/xml/preferences.xml | 8 - 8 files changed, 199 insertions(+), 259 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Account.java b/src/main/java/eu/siacs/conversations/entities/Account.java index 16b6fc068..babe378f7 100644 --- a/src/main/java/eu/siacs/conversations/entities/Account.java +++ b/src/main/java/eu/siacs/conversations/entities/Account.java @@ -42,6 +42,7 @@ public class Account extends AbstractEntity { public static final String PORT = "port"; public static final String STATUS = "status"; public static final String STATUS_MESSAGE = "status_message"; + public static final String RESOURCE = "resource"; public static final String PINNED_MECHANISM_KEY = "pinned_mechanism"; @@ -229,6 +230,7 @@ public class Account extends AbstractEntity { protected String rosterVersion; protected State status = State.OFFLINE; protected final JSONObject keys; + protected String resource; protected String avatar; protected String displayName = null; protected String hostname = null; @@ -238,7 +240,6 @@ public class Account extends AbstractEntity { private PgpDecryptionService pgpDecryptionService = null; private XmppConnection xmppConnection = null; private long mEndGracePeriod = 0L; - private String otrFingerprint; private final Roster roster = new Roster(this); private List bookmarks = new CopyOnWriteArrayList<>(); private final Collection blocklist = new CopyOnWriteArraySet<>(); @@ -256,9 +257,6 @@ public class Account extends AbstractEntity { final Presence.Status status, String statusMessage) { this.uuid = uuid; this.jid = jid; - if (jid.isBareJid()) { - this.setResource("mobile"); - } this.password = password; this.options = options; this.rosterVersion = rosterVersion; @@ -280,8 +278,10 @@ public class Account extends AbstractEntity { public static Account fromCursor(final Cursor cursor) { Jid jid = null; try { - jid = Jid.fromParts(cursor.getString(cursor.getColumnIndex(USERNAME)), - cursor.getString(cursor.getColumnIndex(SERVER)), "mobile"); + jid = Jid.fromParts( + cursor.getString(cursor.getColumnIndex(USERNAME)), + cursor.getString(cursor.getColumnIndex(SERVER)), + cursor.getString(cursor.getColumnIndex(RESOURCE))); } catch (final InvalidJidException ignored) { } return new Account(cursor.getString(cursor.getColumnIndex(UUID)), @@ -317,6 +317,7 @@ public class Account extends AbstractEntity { } public boolean setJid(final Jid next) { + final Jid previousFull = this.jid; final Jid prev = this.jid != null ? this.jid.toBareJid() : null; final boolean changed = prev == null || (next != null && !prev.equals(next.toBareJid())); if (changed) { @@ -328,7 +329,7 @@ public class Account extends AbstractEntity { } } this.jid = next; - return changed; + return next != null && next.equals(previousFull); } public Jid getServer() { @@ -483,6 +484,7 @@ public class Account extends AbstractEntity { values.put(PORT, port); values.put(STATUS, presenceStatus.toShowString()); values.put(STATUS_MESSAGE, presenceStatusMessage); + values.put(RESOURCE,jid.getResourcepart()); return values; } diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 2036f26e0..9c3bcae65 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -62,7 +62,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { private static DatabaseBackend instance = null; private static final String DATABASE_NAME = "history"; - private static final int DATABASE_VERSION = 39; + private static final int DATABASE_VERSION = 40; private static String CREATE_CONTATCS_STATEMENT = "create table " + Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, " @@ -184,6 +184,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { + Account.AVATAR + " TEXT, " + Account.KEYS + " TEXT, " + Account.HOSTNAME + " TEXT, " + + Account.RESOURCE + " TEXT," + Account.PORT + " NUMBER DEFAULT 5222)"); db.execSQL("create table " + Conversation.TABLENAME + " (" + Conversation.UUID + " TEXT PRIMARY KEY, " + Conversation.NAME @@ -305,6 +306,9 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.execSQL("ALTER TABLE " + Account.TABLENAME + " ADD COLUMN " + Account.STATUS + " TEXT"); db.execSQL("ALTER TABLE " + Account.TABLENAME + " ADD COLUMN " + Account.STATUS_MESSAGE + " TEXT"); } + if (oldVersion < 40 && newVersion >= 40) { + db.execSQL("ALTER TABLE " + Account.TABLENAME + " ADD COLUMN " + Account.RESOURCE + " TEXT"); + } /* Any migrations that alter the Account table need to happen BEFORE this migration, as it * depends on account de-serialization. */ diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 40a03d4e9..19cdf9466 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1125,17 +1125,6 @@ public class XmppConnectionService extends Service { } public XmppConnection createConnection(final Account account) { - final SharedPreferences sharedPref = getPreferences(); - String resource; - try { - resource = sharedPref.getString("resource", getString(R.string.default_resource)).toLowerCase(Locale.ENGLISH); - if (resource.trim().isEmpty()) { - throw new Exception(); - } - } catch (Exception e) { - resource = "conversations"; - } - account.setResource(resource); final XmppConnection connection = new XmppConnection(account, this); connection.setOnMessagePacketReceivedListener(this.mMessageParser); connection.setOnStatusChangedListener(this.statusListener); diff --git a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java index 7dffb1710..ad0cb58f6 100644 --- a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java @@ -1,5 +1,6 @@ package eu.siacs.conversations.ui; +import android.support.annotation.NonNull; import android.support.v7.app.AlertDialog; import android.app.FragmentManager; import android.content.DialogInterface; @@ -68,7 +69,7 @@ public class SettingsActivity extends XmppActivity implements this.mTheme = findTheme(); setTheme(this.mTheme); - getWindow().getDecorView().setBackgroundColor(Color.get(this,R.attr.color_background_primary)); + getWindow().getDecorView().setBackgroundColor(Color.get(this, R.attr.color_background_primary)); } @@ -81,15 +82,6 @@ public class SettingsActivity extends XmppActivity implements public void onStart() { super.onStart(); PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this); - ListPreference resources = (ListPreference) mSettingsFragment.findPreference("resource"); - if (resources != null) { - ArrayList entries = new ArrayList<>(Arrays.asList(resources.getEntries())); - if (!entries.contains(Build.MODEL)) { - entries.add(0, Build.MODEL); - resources.setEntries(entries.toArray(new CharSequence[entries.size()])); - resources.setEntryValues(entries.toArray(new CharSequence[entries.size()])); - } - } if (Config.FORCE_ORBOT) { PreferenceCategory connectionOptions = (PreferenceCategory) mSettingsFragment.findPreference("connection_options"); @@ -281,37 +273,31 @@ public class SettingsActivity extends XmppActivity implements } } final boolean[] checkedItems = new boolean[accounts.size()]; - builder.setMultiChoiceItems(accounts.toArray(new CharSequence[accounts.size()]), checkedItems, new DialogInterface.OnMultiChoiceClickListener() { - @Override - public void onClick(DialogInterface dialog, int which, boolean isChecked) { - checkedItems[which] = isChecked; - final AlertDialog alertDialog = (AlertDialog) dialog; - for (boolean item : checkedItems) { - if (item) { - alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(true); - return; - } + builder.setMultiChoiceItems(accounts.toArray(new CharSequence[accounts.size()]), checkedItems, (dialog, which, isChecked) -> { + checkedItems[which] = isChecked; + final AlertDialog alertDialog = (AlertDialog) dialog; + for (boolean item : checkedItems) { + if (item) { + alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(true); + return; } - alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(false); } + alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(false); }); builder.setNegativeButton(R.string.cancel, null); - builder.setPositiveButton(R.string.delete_selected_keys, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - for (int i = 0; i < checkedItems.length; ++i) { - if (checkedItems[i]) { - try { - Jid jid = Jid.fromString(accounts.get(i).toString()); - Account account = xmppConnectionService.findAccountByJid(jid); - if (account != null) { - account.getAxolotlService().regenerateKeys(true); - } - } catch (InvalidJidException e) { - // + builder.setPositiveButton(R.string.delete_selected_keys, (dialog, which) -> { + for (int i = 0; i < checkedItems.length; ++i) { + if (checkedItems[i]) { + try { + Jid jid = Jid.fromString(accounts.get(i).toString()); + Account account = xmppConnectionService.findAccountByJid(jid); + if (account != null) { + account.getAxolotlService().regenerateKeys(true); } - + } catch (InvalidJidException e) { + // } + } } }); @@ -338,23 +324,7 @@ public class SettingsActivity extends XmppActivity implements TREAT_VIBRATE_AS_SILENT, MANUALLY_CHANGE_PRESENCE, BROADCAST_LAST_ACTIVITY); - if (name.equals("resource")) { - String resource = preferences.getString("resource", "mobile") - .toLowerCase(Locale.US); - if (xmppConnectionServiceBound) { - for (Account account : xmppConnectionService.getAccounts()) { - if (account.setResource(resource)) { - if (account.isEnabled()) { - XmppConnection connection = account.getXmppConnection(); - if (connection != null) { - connection.resetStreamId(); - } - xmppConnectionService.reconnectAccountInBackground(account); - } - } - } - } - } else if (name.equals(KEEP_FOREGROUND_SERVICE)) { + if (name.equals(KEEP_FOREGROUND_SERVICE)) { xmppConnectionService.toggleForegroundService(); } else if (resendPresence.contains(name)) { if (xmppConnectionServiceBound) { @@ -383,7 +353,7 @@ public class SettingsActivity extends XmppActivity implements } @Override - public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (grantResults.length > 0) if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { if (requestCode == REQUEST_WRITE_LOGS) { @@ -399,12 +369,7 @@ public class SettingsActivity extends XmppActivity implements } private void displayToast(final String msg) { - runOnUiThread(new Runnable() { - @Override - public void run() { - Toast.makeText(SettingsActivity.this, msg, Toast.LENGTH_LONG).show(); - } - }); + runOnUiThread(() -> Toast.makeText(SettingsActivity.this, msg, Toast.LENGTH_LONG).show()); } private void reconnectAccounts() { diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 95bd4175e..2ab136b97 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -50,6 +50,7 @@ import javax.net.ssl.X509KeyManager; import javax.net.ssl.X509TrustManager; import eu.siacs.conversations.Config; +import eu.siacs.conversations.R; import eu.siacs.conversations.crypto.DomainHostnameVerifier; import eu.siacs.conversations.crypto.XmppDomainVerifier; import eu.siacs.conversations.crypto.axolotl.AxolotlService; @@ -102,94 +103,6 @@ public class XmppConnection implements Runnable { private static final int PACKET_IQ = 0; private static final int PACKET_MESSAGE = 1; private static final int PACKET_PRESENCE = 2; - protected final Account account; - private Socket socket; - private XmlReader tagReader; - private TagWriter tagWriter = new TagWriter(); - private final Features features = new Features(this); - private boolean shouldAuthenticate = true; - private boolean inSmacksSession = false; - private boolean isBound = false; - private Element streamFeatures; - private final HashMap disco = new HashMap<>(); - - private String streamId = null; - private int smVersion = 3; - private final SparseArray mStanzaQueue = new SparseArray<>(); - - private int stanzasReceived = 0; - private int stanzasSent = 0; - private long lastPacketReceived = 0; - private long lastPingSent = 0; - private long lastConnect = 0; - private long lastSessionStarted = 0; - private long lastDiscoStarted = 0; - private AtomicInteger mPendingServiceDiscoveries = new AtomicInteger(0); - private AtomicBoolean mWaitForDisco = new AtomicBoolean(true); - private AtomicBoolean mWaitingForSmCatchup = new AtomicBoolean(false); - private AtomicInteger mSmCatchupMessageCounter = new AtomicInteger(0); - private boolean mInteractive = false; - private int attempt = 0; - private final Hashtable> packetCallbacks = new Hashtable<>(); - private OnPresencePacketReceived presenceListener = null; - private OnJinglePacketReceived jingleListener = null; - private OnIqPacketReceived unregisteredIqListener = null; - private OnMessagePacketReceived messageListener = null; - private OnStatusChanged statusListener = null; - private OnBindListener bindListener = null; - private final ArrayList advancedStreamFeaturesLoadedListeners = new ArrayList<>(); - private OnMessageAcknowledged acknowledgedListener = null; - private final XmppConnectionService mXmppConnectionService; - - private SaslMechanism saslMechanism; - private URL redirectionUrl = null; - private String verifiedHostname = null; - private Thread mThread; - private CountDownLatch mStreamCountDownLatch; - - private class MyKeyManager implements X509KeyManager { - @Override - public String chooseClientAlias(String[] strings, Principal[] principals, Socket socket) { - return account.getPrivateKeyAlias(); - } - - @Override - public String chooseServerAlias(String s, Principal[] principals, Socket socket) { - return null; - } - - @Override - public X509Certificate[] getCertificateChain(String alias) { - Log.d(Config.LOGTAG, "getting certificate chain"); - try { - return KeyChain.getCertificateChain(mXmppConnectionService, alias); - } catch (Exception e) { - Log.d(Config.LOGTAG, e.getMessage()); - return new X509Certificate[0]; - } - } - - @Override - public String[] getClientAliases(String s, Principal[] principals) { - final String alias = account.getPrivateKeyAlias(); - return alias != null ? new String[]{alias} : new String[0]; - } - - @Override - public String[] getServerAliases(String s, Principal[] principals) { - return new String[0]; - } - - @Override - public PrivateKey getPrivateKey(String alias) { - try { - return KeyChain.getPrivateKey(mXmppConnectionService, alias); - } catch (Exception e) { - return null; - } - } - } - public final OnIqPacketReceived registrationResponseListener = new OnIqPacketReceived() { @Override public void onIqPacketReceived(Account account, IqPacket packet) { @@ -217,6 +130,47 @@ public class XmppConnection implements Runnable { } } }; + protected final Account account; + private final Features features = new Features(this); + private final HashMap disco = new HashMap<>(); + private final SparseArray mStanzaQueue = new SparseArray<>(); + private final Hashtable> packetCallbacks = new Hashtable<>(); + private final ArrayList advancedStreamFeaturesLoadedListeners = new ArrayList<>(); + private final XmppConnectionService mXmppConnectionService; + private Socket socket; + private XmlReader tagReader; + private TagWriter tagWriter = new TagWriter(); + private boolean shouldAuthenticate = true; + private boolean inSmacksSession = false; + private boolean isBound = false; + private Element streamFeatures; + private String streamId = null; + private int smVersion = 3; + private int stanzasReceived = 0; + private int stanzasSent = 0; + private long lastPacketReceived = 0; + private long lastPingSent = 0; + private long lastConnect = 0; + private long lastSessionStarted = 0; + private long lastDiscoStarted = 0; + private AtomicInteger mPendingServiceDiscoveries = new AtomicInteger(0); + private AtomicBoolean mWaitForDisco = new AtomicBoolean(true); + private AtomicBoolean mWaitingForSmCatchup = new AtomicBoolean(false); + private AtomicInteger mSmCatchupMessageCounter = new AtomicInteger(0); + private boolean mInteractive = false; + private int attempt = 0; + private OnPresencePacketReceived presenceListener = null; + private OnJinglePacketReceived jingleListener = null; + private OnIqPacketReceived unregisteredIqListener = null; + private OnMessagePacketReceived messageListener = null; + private OnStatusChanged statusListener = null; + private OnBindListener bindListener = null; + private OnMessageAcknowledged acknowledgedListener = null; + private SaslMechanism saslMechanism; + private URL redirectionUrl = null; + private String verifiedHostname = null; + private Thread mThread; + private CountDownLatch mStreamCountDownLatch; public XmppConnection(final Account account, final XmppConnectionService service) { this.account = account; @@ -479,19 +433,6 @@ public class XmppConnection implements Runnable { return tag != null && tag.isStart("stream"); } - private static class TlsFactoryVerifier { - private final SSLSocketFactory factory; - private final DomainHostnameVerifier verifier; - - public TlsFactoryVerifier(final SSLSocketFactory factory, final DomainHostnameVerifier verifier) throws IOException { - this.factory = factory; - this.verifier = verifier; - if (factory == null || verifier == null) { - throw new IOException("could not setup ssl"); - } - } - } - private TlsFactoryVerifier getTlsFactoryVerifier() throws NoSuchAlgorithmException, KeyManagementException, IOException { final SSLContext sc = SSLSocketHelper.getSSLContext(); MemorizingTrustManager trustManager = this.mXmppConnectionService.getMemorizingTrustManager(); @@ -836,7 +777,6 @@ public class XmppConnection implements Runnable { tagWriter.writeTag(startTLS); } - private void switchOverToTls(final Tag currentTag) throws XmlPullParserException, IOException { tagReader.readTag(); try { @@ -1069,55 +1009,52 @@ public class XmppConnection implements Runnable { return; } clearIqCallbacks(); + if (account.getJid().isBareJid()) { + account.setResource(this.createNewResource()); + } final IqPacket iq = new IqPacket(IqPacket.TYPE.SET); final String resource = Config.USE_RANDOM_RESOURCE_ON_EVERY_BIND ? nextRandomId() : account.getResource(); iq.addChild("bind", Namespace.BIND).addChild("resource").setContent(resource); - this.sendUnmodifiedIqPacket(iq, new OnIqPacketReceived() { - @Override - public void onIqPacketReceived(final Account account, final IqPacket packet) { - if (packet.getType() == IqPacket.TYPE.TIMEOUT) { - return; - } - final Element bind = packet.findChild("bind"); - if (bind != null && packet.getType() == IqPacket.TYPE.RESULT) { - isBound = true; - final Element jid = bind.findChild("jid"); - if (jid != null && jid.getContent() != null) { - try { - Jid assignedJid = Jid.fromString(jid.getContent()); - if (!account.getJid().getDomainpart().equals(assignedJid.getDomainpart())) { - Log.d(Config.LOGTAG,account.getJid().toBareJid()+": server tried to re-assign domain to "+assignedJid.getDomainpart()); - throw new StateChangingError(Account.State.BIND_FAILURE); - } - if (account.setJid(assignedJid)) { - Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": bare jid changed during bind. updating database"); - mXmppConnectionService.databaseBackend.updateAccount(account); - } - if (streamFeatures.hasChild("session") - && !streamFeatures.findChild("session").hasChild("optional")) { - sendStartSession(); - } else { - sendPostBindInitialization(); - } - return; - } catch (final InvalidJidException e) { - Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": server reported invalid jid (" + jid.getContent() + ") on bind"); + this.sendUnmodifiedIqPacket(iq, (account, packet) -> { + if (packet.getType() == IqPacket.TYPE.TIMEOUT) { + return; + } + final Element bind = packet.findChild("bind"); + if (bind != null && packet.getType() == IqPacket.TYPE.RESULT) { + isBound = true; + final Element jid = bind.findChild("jid"); + if (jid != null && jid.getContent() != null) { + try { + Jid assignedJid = Jid.fromString(jid.getContent()); + if (!account.getJid().getDomainpart().equals(assignedJid.getDomainpart())) { + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": server tried to re-assign domain to "+assignedJid.getDomainpart()); + throw new StateChangingError(Account.State.BIND_FAILURE); } - } else { - Log.d(Config.LOGTAG, account.getJid() + ": disconnecting because of bind failure. (no jid)"); + if (account.setJid(assignedJid)) { + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": jid changed during bind. updating database"); + mXmppConnectionService.databaseBackend.updateAccount(account); + } + if (streamFeatures.hasChild("session") + && !streamFeatures.findChild("session").hasChild("optional")) { + sendStartSession(); + } else { + sendPostBindInitialization(); + } + return; + } catch (final InvalidJidException e) { + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": server reported invalid jid (" + jid.getContent() + ") on bind"); } } else { - Log.d(Config.LOGTAG, account.getJid() + ": disconnecting because of bind failure (" + packet.toString()); + Log.d(Config.LOGTAG, account.getJid() + ": disconnecting because of bind failure. (no jid)"); } - final Element error = packet.findChild("error"); - final String resource = account.getResource().split("\\.")[0]; - if (packet.getType() == IqPacket.TYPE.ERROR && error != null && error.hasChild("conflict")) { - account.setResource(resource + "." + nextRandomId()); - } else { - account.setResource(resource); - } - throw new StateChangingError(Account.State.BIND_FAILURE); + } else { + Log.d(Config.LOGTAG, account.getJid() + ": disconnecting because of bind failure (" + packet.toString()); } + final Element error = packet.findChild("error"); + if (packet.getType() == IqPacket.TYPE.ERROR && error != null && error.hasChild("conflict")) { + account.setResource(createNewResource()); + } + throw new StateChangingError(Account.State.BIND_FAILURE); },true); } @@ -1337,18 +1274,14 @@ public class XmppConnection implements Runnable { }); } - private void processStreamError(final Tag currentTag) - throws XmlPullParserException, IOException { + private void processStreamError(final Tag currentTag) throws XmlPullParserException, IOException { final Element streamError = tagReader.readElement(currentTag); if (streamError == null) { return; } if (streamError.hasChild("conflict")) { - final String resource = account.getResource().split("\\.")[0]; - account.setResource(resource + "." + nextRandomId()); - Log.d(Config.LOGTAG, - account.getJid().toBareJid() + ": switching resource due to conflict (" - + account.getResource() + ")"); + account.setResource(createNewResource()); + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": switching resource due to conflict (" + account.getResource() + ")"); throw new IOException(); } else if (streamError.hasChild("host-unknown")) { throw new StateChangingException(Account.State.HOST_UNKNOWN); @@ -1370,8 +1303,16 @@ public class XmppConnection implements Runnable { tagWriter.writeTag(stream); } + private String createNewResource() { + return mXmppConnectionService.getString(R.string.app_name)+'.'+nextRandomId(true); + } + private String nextRandomId() { - return CryptoHelper.random(10, mXmppConnectionService.getRNG()); + return nextRandomId(false); + } + + private String nextRandomId(boolean s) { + return CryptoHelper.random(s ? 3 : 9, mXmppConnectionService.getRNG()); } public String sendIqPacket(final IqPacket packet, final OnIqPacketReceived callback) { @@ -1662,6 +1603,75 @@ public class XmppConnection implements Runnable { return Identity.UNKNOWN; } + private IqGenerator getIqGenerator() { + return mXmppConnectionService.getIqGenerator(); + } + + public enum Identity { + FACEBOOK, + SLACK, + EJABBERD, + PROSODY, + NIMBUZZ, + UNKNOWN + } + + private static class TlsFactoryVerifier { + private final SSLSocketFactory factory; + private final DomainHostnameVerifier verifier; + + public TlsFactoryVerifier(final SSLSocketFactory factory, final DomainHostnameVerifier verifier) throws IOException { + this.factory = factory; + this.verifier = verifier; + if (factory == null || verifier == null) { + throw new IOException("could not setup ssl"); + } + } + } + + private class MyKeyManager implements X509KeyManager { + @Override + public String chooseClientAlias(String[] strings, Principal[] principals, Socket socket) { + return account.getPrivateKeyAlias(); + } + + @Override + public String chooseServerAlias(String s, Principal[] principals, Socket socket) { + return null; + } + + @Override + public X509Certificate[] getCertificateChain(String alias) { + Log.d(Config.LOGTAG, "getting certificate chain"); + try { + return KeyChain.getCertificateChain(mXmppConnectionService, alias); + } catch (Exception e) { + Log.d(Config.LOGTAG, e.getMessage()); + return new X509Certificate[0]; + } + } + + @Override + public String[] getClientAliases(String s, Principal[] principals) { + final String alias = account.getPrivateKeyAlias(); + return alias != null ? new String[]{alias} : new String[0]; + } + + @Override + public String[] getServerAliases(String s, Principal[] principals) { + return new String[0]; + } + + @Override + public PrivateKey getPrivateKey(String alias) { + try { + return KeyChain.getPrivateKey(mXmppConnectionService, alias); + } catch (Exception e) { + return null; + } + } + } + private class StateChangingError extends Error { private final Account.State state; @@ -1678,15 +1688,6 @@ public class XmppConnection implements Runnable { } } - public enum Identity { - FACEBOOK, - SLACK, - EJABBERD, - PROSODY, - NIMBUZZ, - UNKNOWN - } - public class Features { XmppConnection connection; private boolean carbonsEnabled = false; @@ -1818,8 +1819,4 @@ public class XmppConnection implements Runnable { return hasDiscoFeature(account.getJid().toBareJid(), Namespace.STANZA_IDS); } } - - private IqGenerator getIqGenerator() { - return mXmppConnectionService.getIqGenerator(); - } } diff --git a/src/main/res/values/arrays.xml b/src/main/res/values/arrays.xml index 63838b7e3..8773fda1a 100644 --- a/src/main/res/values/arrays.xml +++ b/src/main/res/values/arrays.xml @@ -1,13 +1,6 @@ - - Mobile - Phone - Tablet - @string/app_name - Android - @string/pref_theme_light @string/pref_theme_dark diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 528727f7e..d00bd968a 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -100,8 +100,6 @@ No OpenPGP Keys found Conversations is unable to encrypt your messages because your contacts are not announcing their public key.\n\nPlease ask your contacts to setup OpenPGP. General - XMPP resource - The name this client identifies itself with Accept files Automatically accept files smaller than… Attachments diff --git a/src/main/res/xml/preferences.xml b/src/main/res/xml/preferences.xml index 39969edec..460f71dbf 100644 --- a/src/main/res/xml/preferences.xml +++ b/src/main/res/xml/preferences.xml @@ -9,14 +9,6 @@ android:key="grant_new_contacts" android:summary="@string/pref_grant_presence_updates_summary" android:title="@string/pref_grant_presence_updates"/> - -