Detailed changes
@@ -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<Bookmark> bookmarks = new CopyOnWriteArrayList<>();
private final Collection<Jid> 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;
}
@@ -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.
*/
@@ -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);
@@ -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<CharSequence> 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() {
@@ -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,21 +103,49 @@ 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;
+ public final OnIqPacketReceived registrationResponseListener = new OnIqPacketReceived() {
+ @Override
+ public void onIqPacketReceived(Account account, IqPacket packet) {
+ if (packet.getType() == IqPacket.TYPE.RESULT) {
+ account.setOption(Account.OPTION_REGISTER, false);
+ throw new StateChangingError(Account.State.REGISTRATION_SUCCESSFUL);
+ } else {
+ final List<String> PASSWORD_TOO_WEAK_MSGS = Arrays.asList(
+ "The password is too weak",
+ "Please use a longer password.");
+ Element error = packet.findChild("error");
+ Account.State state = Account.State.REGISTRATION_FAILED;
+ if (error != null) {
+ if (error.hasChild("conflict")) {
+ state = Account.State.REGISTRATION_CONFLICT;
+ } else if (error.hasChild("resource-constraint")
+ && "wait".equals(error.getAttribute("type"))) {
+ state = Account.State.REGISTRATION_PLEASE_WAIT;
+ } else if (error.hasChild("not-acceptable")
+ && PASSWORD_TOO_WEAK_MSGS.contains(error.findChildContent("text"))) {
+ state = Account.State.REGISTRATION_PASSWORD_TOO_WEAK;
+ }
+ }
+ throw new StateChangingError(state);
+ }
+ }
+ };
protected final Account account;
+ private final Features features = new Features(this);
+ private final HashMap<Jid, ServiceDiscoveryResult> disco = new HashMap<>();
+ private final SparseArray<AbstractAcknowledgeableStanza> mStanzaQueue = new SparseArray<>();
+ private final Hashtable<String, Pair<IqPacket, OnIqPacketReceived>> packetCallbacks = new Hashtable<>();
+ private final ArrayList<OnAdvancedStreamFeaturesLoaded> advancedStreamFeaturesLoadedListeners = new ArrayList<>();
+ private final XmppConnectionService mXmppConnectionService;
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<Jid, ServiceDiscoveryResult> disco = new HashMap<>();
-
private String streamId = null;
private int smVersion = 3;
- private final SparseArray<AbstractAcknowledgeableStanza> mStanzaQueue = new SparseArray<>();
-
private int stanzasReceived = 0;
private int stanzasSent = 0;
private long lastPacketReceived = 0;
@@ -130,94 +159,19 @@ public class XmppConnection implements Runnable {
private AtomicInteger mSmCatchupMessageCounter = new AtomicInteger(0);
private boolean mInteractive = false;
private int attempt = 0;
- private final Hashtable<String, Pair<IqPacket, OnIqPacketReceived>> 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<OnAdvancedStreamFeaturesLoaded> 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) {
- if (packet.getType() == IqPacket.TYPE.RESULT) {
- account.setOption(Account.OPTION_REGISTER, false);
- throw new StateChangingError(Account.State.REGISTRATION_SUCCESSFUL);
- } else {
- final List<String> PASSWORD_TOO_WEAK_MSGS = Arrays.asList(
- "The password is too weak",
- "Please use a longer password.");
- Element error = packet.findChild("error");
- Account.State state = Account.State.REGISTRATION_FAILED;
- if (error != null) {
- if (error.hasChild("conflict")) {
- state = Account.State.REGISTRATION_CONFLICT;
- } else if (error.hasChild("resource-constraint")
- && "wait".equals(error.getAttribute("type"))) {
- state = Account.State.REGISTRATION_PLEASE_WAIT;
- } else if (error.hasChild("not-acceptable")
- && PASSWORD_TOO_WEAK_MSGS.contains(error.findChildContent("text"))) {
- state = Account.State.REGISTRATION_PASSWORD_TOO_WEAK;
- }
- }
- throw new StateChangingError(state);
- }
- }
- };
-
public XmppConnection(final Account account, final XmppConnectionService service) {
this.account = account;
final String tag = account.getJid().toBareJid().toPreppedString();
@@ -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();
- }
}
@@ -1,13 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <string-array name="resources">
- <item>Mobile</item>
- <item>Phone</item>
- <item>Tablet</item>
- <item>@string/app_name</item>
- <item>Android</item>
- </string-array>
<string-array name="themes">
<item>@string/pref_theme_light</item>
<item>@string/pref_theme_dark</item>
@@ -100,8 +100,6 @@
<string name="no_pgp_keys">No OpenPGP Keys found</string>
<string name="contacts_have_no_pgp_keys">Conversations is unable to encrypt your messages because your contacts are not announcing their public key.\n\n<small>Please ask your contacts to setup OpenPGP.</small></string>
<string name="pref_general">General</string>
- <string name="pref_xmpp_resource">XMPP resource</string>
- <string name="pref_xmpp_resource_summary">The name this client identifies itself with</string>
<string name="pref_accept_files">Accept files</string>
<string name="pref_accept_files_summary">Automatically accept files smaller thanβ¦</string>
<string name="pref_attachments">Attachments</string>
@@ -9,14 +9,6 @@
android:key="grant_new_contacts"
android:summary="@string/pref_grant_presence_updates_summary"
android:title="@string/pref_grant_presence_updates"/>
-
- <ListPreference
- android:defaultValue="@string/default_resource"
- android:entries="@array/resources"
- android:entryValues="@array/resources"
- android:key="resource"
- android:summary="@string/pref_xmpp_resource_summary"
- android:title="@string/pref_xmpp_resource"/>
<PreferenceScreen
android:key="huawei"
android:title="@string/huawei_protected_apps"