Merge pull request #668 from SamWhited/auth-pinning

Auth mechanism pinning
This commit is contained in:
Daniel Gultsch 2014-11-15 17:44:51 +01:00
commit 69ab8a2adb
18 changed files with 294 additions and 279 deletions

View file

@ -17,7 +17,13 @@ public class DigestMd5 extends SaslMechanism {
super(tagWriter, account, rng); super(tagWriter, account, rng);
} }
public static String getMechanism() { @Override
public int getPriority() {
return 10;
}
@Override
public String getMechanism() {
return "DIGEST-MD5"; return "DIGEST-MD5";
} }

View file

@ -12,7 +12,13 @@ public class Plain extends SaslMechanism {
super(tagWriter, account, null); super(tagWriter, account, null);
} }
public static String getMechanism() { @Override
public int getPriority() {
return 0;
}
@Override
public String getMechanism() {
return "PLAIN"; return "PLAIN";
} }

View file

@ -44,6 +44,15 @@ public abstract class SaslMechanism {
this.rng = rng; this.rng = rng;
} }
/**
* The priority is used to pin the authentication mechanism. If authentication fails, it MAY be retried with another
* mechanism of the same priority, but MUST NOT be tried with a mechanism of lower priority (to prevent downgrade
* attacks).
* @return An arbitrary int representing the priority
*/
public abstract int getPriority();
public abstract String getMechanism();
public String getClientFirstMessage() { public String getClientFirstMessage() {
return ""; return "";
} }

View file

@ -43,7 +43,13 @@ public class ScramSha1 extends SaslMechanism {
clientFirstMessageBare = ""; clientFirstMessageBare = "";
} }
public static String getMechanism() { @Override
public int getPriority() {
return 20;
}
@Override
public String getMechanism() {
return "SCRAM-SHA-1"; return "SCRAM-SHA-1";
} }

View file

@ -34,30 +34,83 @@ public class Account extends AbstractEntity {
public static final String KEYS = "keys"; public static final String KEYS = "keys";
public static final String AVATAR = "avatar"; public static final String AVATAR = "avatar";
public static final String PINNED_MECHANISM_KEY = "pinned_mechanism";
public static final int OPTION_USETLS = 0; public static final int OPTION_USETLS = 0;
public static final int OPTION_DISABLED = 1; public static final int OPTION_DISABLED = 1;
public static final int OPTION_REGISTER = 2; public static final int OPTION_REGISTER = 2;
public static final int OPTION_USECOMPRESSION = 3; public static final int OPTION_USECOMPRESSION = 3;
public static final int STATUS_CONNECTING = 0; public static enum State {
public static final int STATUS_DISABLED = -2; DISABLED,
public static final int STATUS_OFFLINE = -1; OFFLINE,
public static final int STATUS_ONLINE = 1; CONNECTING,
public static final int STATUS_NO_INTERNET = 2; ONLINE,
public static final int STATUS_UNAUTHORIZED = 3; NO_INTERNET,
public static final int STATUS_SERVER_NOT_FOUND = 5; UNAUTHORIZED(true),
SERVER_NOT_FOUND(true),
REGISTRATION_FAILED(true),
REGISTRATION_CONFLICT(true),
REGISTRATION_SUCCESSFUL,
REGISTRATION_NOT_SUPPORTED(true),
SECURITY_ERROR(true),
INCOMPATIBLE_SERVER(true);
private boolean isError;
public boolean isError() {
return this.isError;
}
private State(final boolean isError) {
this.isError = isError;
}
private State() {
this(false);
}
public int getReadableId() {
switch (this) {
case DISABLED:
return R.string.account_status_disabled;
case ONLINE:
return R.string.account_status_online;
case CONNECTING:
return R.string.account_status_connecting;
case OFFLINE:
return R.string.account_status_offline;
case UNAUTHORIZED:
return R.string.account_status_unauthorized;
case SERVER_NOT_FOUND:
return R.string.account_status_not_found;
case NO_INTERNET:
return R.string.account_status_no_internet;
case REGISTRATION_FAILED:
return R.string.account_status_regis_fail;
case REGISTRATION_CONFLICT:
return R.string.account_status_regis_conflict;
case REGISTRATION_SUCCESSFUL:
return R.string.account_status_regis_success;
case REGISTRATION_NOT_SUPPORTED:
return R.string.account_status_regis_not_sup;
case SECURITY_ERROR:
return R.string.account_status_security_error;
case INCOMPATIBLE_SERVER:
return R.string.account_status_incompatible_server;
default:
return R.string.account_status_unknown;
}
}
}
public static final int STATUS_REGISTRATION_FAILED = 7;
public static final int STATUS_REGISTRATION_CONFLICT = 8;
public static final int STATUS_REGISTRATION_SUCCESSFULL = 9;
public static final int STATUS_REGISTRATION_NOT_SUPPORTED = 10;
public List<Conversation> pendingConferenceJoins = new CopyOnWriteArrayList<>(); public List<Conversation> pendingConferenceJoins = new CopyOnWriteArrayList<>();
public List<Conversation> pendingConferenceLeaves = new CopyOnWriteArrayList<>(); public List<Conversation> pendingConferenceLeaves = new CopyOnWriteArrayList<>();
protected Jid jid; protected Jid jid;
protected String password; protected String password;
protected int options = 0; protected int options = 0;
protected String rosterVersion; protected String rosterVersion;
protected int status = -1; protected State status = State.OFFLINE;
protected JSONObject keys = new JSONObject(); protected JSONObject keys = new JSONObject();
protected String avatar; protected String avatar;
protected boolean online = false; protected boolean online = false;
@ -79,8 +132,8 @@ public class Account extends AbstractEntity {
} }
public Account(final String uuid, final Jid jid, public Account(final String uuid, final Jid jid,
final String password, final int options, final String rosterVersion, final String keys, final String password, final int options, final String rosterVersion, final String keys,
final String avatar) { final String avatar) {
this.uuid = uuid; this.uuid = uuid;
this.jid = jid; this.jid = jid;
if (jid.isBareJid()) { if (jid.isBareJid()) {
@ -149,28 +202,24 @@ public class Account extends AbstractEntity {
this.password = password; this.password = password;
} }
public int getStatus() { public State getStatus() {
if (isOptionSet(OPTION_DISABLED)) { if (isOptionSet(OPTION_DISABLED)) {
return STATUS_DISABLED; return State.DISABLED;
} else { } else {
return this.status; return this.status;
} }
} }
public void setStatus(final int status) { public void setStatus(final State status) {
this.status = status; this.status = status;
} }
public boolean errorStatus() { public boolean errorStatus() {
int s = getStatus(); return getStatus().isError();
return (s == STATUS_REGISTRATION_FAILED
|| s == STATUS_REGISTRATION_CONFLICT
|| s == STATUS_REGISTRATION_NOT_SUPPORTED
|| s == STATUS_SERVER_NOT_FOUND || s == STATUS_UNAUTHORIZED);
} }
public boolean hasErrorStatus() { public boolean hasErrorStatus() {
return getXmppConnection() != null && getStatus() > STATUS_NO_INTERNET && (getXmppConnection().getAttempt() >= 2); return getXmppConnection() != null && getStatus().isError() && getXmppConnection().getAttempt() >= 2;
} }
public String getResource() { public String getResource() {
@ -250,7 +299,7 @@ public class Account extends AbstractEntity {
if (this.otrFingerprint == null) { if (this.otrFingerprint == null) {
try { try {
DSAPublicKey pubkey = (DSAPublicKey) this.otrEngine DSAPublicKey pubkey = (DSAPublicKey) this.otrEngine
.getPublicKey(); .getPublicKey();
if (pubkey == null) { if (pubkey == null) {
return null; return null;
} }
@ -350,39 +399,9 @@ public class Account extends AbstractEntity {
return this.avatar; return this.avatar;
} }
public int getReadableStatusId() {
switch (getStatus()) {
case Account.STATUS_DISABLED:
return R.string.account_status_disabled;
case Account.STATUS_ONLINE:
return R.string.account_status_online;
case Account.STATUS_CONNECTING:
return R.string.account_status_connecting;
case Account.STATUS_OFFLINE:
return R.string.account_status_offline;
case Account.STATUS_UNAUTHORIZED:
return R.string.account_status_unauthorized;
case Account.STATUS_SERVER_NOT_FOUND:
return R.string.account_status_not_found;
case Account.STATUS_NO_INTERNET:
return R.string.account_status_no_internet;
case Account.STATUS_REGISTRATION_FAILED:
return R.string.account_status_regis_fail;
case Account.STATUS_REGISTRATION_CONFLICT:
return R.string.account_status_regis_conflict;
case Account.STATUS_REGISTRATION_SUCCESSFULL:
return R.string.account_status_regis_success;
case Account.STATUS_REGISTRATION_NOT_SUPPORTED:
return R.string.account_status_regis_not_sup;
default:
return R.string.account_status_unknown;
}
}
public void activateGracePeriod() { public void activateGracePeriod() {
this.mEndGracePeriod = SystemClock.elapsedRealtime() this.mEndGracePeriod = SystemClock.elapsedRealtime()
+ (Config.CARBON_GRACE_PERIOD * 1000); + (Config.CARBON_GRACE_PERIOD * 1000);
} }
public void deactivateGracePeriod() { public void deactivateGracePeriod() {

View file

@ -365,7 +365,7 @@ public class NotificationService {
} }
private boolean inMiniGracePeriod(Account account) { private boolean inMiniGracePeriod(Account account) {
int miniGrace = account.getStatus() == Account.STATUS_ONLINE ? Config.MINI_GRACE_PERIOD int miniGrace = account.getStatus() == Account.State.ONLINE ? Config.MINI_GRACE_PERIOD
: Config.MINI_GRACE_PERIOD * 2; : Config.MINI_GRACE_PERIOD * 2;
return SystemClock.elapsedRealtime() < (this.mLastNotification + miniGrace); return SystemClock.elapsedRealtime() < (this.mLastNotification + miniGrace);
} }

View file

@ -156,7 +156,7 @@ public class XmppConnectionService extends Service {
if (mOnAccountUpdate != null) { if (mOnAccountUpdate != null) {
mOnAccountUpdate.onAccountUpdate(); mOnAccountUpdate.onAccountUpdate();
} }
if (account.getStatus() == Account.STATUS_ONLINE) { if (account.getStatus() == Account.State.ONLINE) {
for (Conversation conversation : account.pendingConferenceLeaves) { for (Conversation conversation : account.pendingConferenceLeaves) {
leaveMuc(conversation); leaveMuc(conversation);
} }
@ -184,17 +184,17 @@ public class XmppConnectionService extends Service {
} }
syncDirtyContacts(account); syncDirtyContacts(account);
scheduleWakeupCall(Config.PING_MAX_INTERVAL, true); scheduleWakeupCall(Config.PING_MAX_INTERVAL, true);
} else if (account.getStatus() == Account.STATUS_OFFLINE) { } else if (account.getStatus() == Account.State.OFFLINE) {
resetSendingToWaiting(account); resetSendingToWaiting(account);
if (!account.isOptionSet(Account.OPTION_DISABLED)) { if (!account.isOptionSet(Account.OPTION_DISABLED)) {
int timeToReconnect = mRandom.nextInt(50) + 10; int timeToReconnect = mRandom.nextInt(50) + 10;
scheduleWakeupCall(timeToReconnect, false); scheduleWakeupCall(timeToReconnect, false);
} }
} else if (account.getStatus() == Account.STATUS_REGISTRATION_SUCCESSFULL) { } else if (account.getStatus() == Account.State.REGISTRATION_SUCCESSFUL) {
databaseBackend.updateAccount(account); databaseBackend.updateAccount(account);
reconnectAccount(account, true); reconnectAccount(account, true);
} else if ((account.getStatus() != Account.STATUS_CONNECTING) } else if ((account.getStatus() != Account.State.CONNECTING)
&& (account.getStatus() != Account.STATUS_NO_INTERNET)) { && (account.getStatus() != Account.State.NO_INTERNET)) {
if (connection != null) { if (connection != null) {
int next = connection.getTimeToNextAttempt(); int next = connection.getTimeToNextAttempt();
Log.d(Config.LOGTAG, account.getJid().toBareJid() Log.d(Config.LOGTAG, account.getJid().toBareJid()
@ -203,7 +203,7 @@ public class XmppConnectionService extends Service {
+ (connection.getAttempt() + 1) + " time"); + (connection.getAttempt() + 1) + " time");
scheduleWakeupCall((int) (next * 1.2), false); scheduleWakeupCall((int) (next * 1.2), false);
} }
} }
UIHelper.showErrorNotification(getApplicationContext(), UIHelper.showErrorNotification(getApplicationContext(),
getAccounts()); getAccounts());
} }
@ -261,11 +261,11 @@ public class XmppConnectionService extends Service {
if (conversation.getAccount() == account) { if (conversation.getAccount() == account) {
for (Message message : conversation.getMessages()) { for (Message message : conversation.getMessages()) {
if ((message.getStatus() == Message.STATUS_UNSEND || message if ((message.getStatus() == Message.STATUS_UNSEND || message
.getStatus() == Message.STATUS_WAITING) .getStatus() == Message.STATUS_WAITING)
&& message.getUuid().equals(uuid)) { && message.getUuid().equals(uuid)) {
markMessage(message, Message.STATUS_SEND); markMessage(message, Message.STATUS_SEND);
return; return;
} }
} }
} }
} }
@ -279,8 +279,8 @@ public class XmppConnectionService extends Service {
if (pgpServiceConnection.isBound()) { if (pgpServiceConnection.isBound()) {
if (this.mPgpEngine == null) { if (this.mPgpEngine == null) {
this.mPgpEngine = new PgpEngine(new OpenPgpApi( this.mPgpEngine = new PgpEngine(new OpenPgpApi(
getApplicationContext(), getApplicationContext(),
pgpServiceConnection.getService()), this); pgpServiceConnection.getService()), this);
} }
return mPgpEngine; return mPgpEngine;
} else { } else {
@ -340,7 +340,7 @@ public class XmppConnectionService extends Service {
} }
public void attachImageToConversation(final Conversation conversation, public void attachImageToConversation(final Conversation conversation,
final Uri uri, final UiCallback<Message> callback) { final Uri uri, final UiCallback<Message> callback) {
final Message message; final Message message;
if (conversation.getNextEncryption(forceEncryption()) == Message.ENCRYPTION_PGP) { if (conversation.getNextEncryption(forceEncryption()) == Message.ENCRYPTION_PGP) {
message = new Message(conversation, "", message = new Message(conversation, "",
@ -399,22 +399,22 @@ public class XmppConnectionService extends Service {
for (Account account : accounts) { for (Account account : accounts) {
if (!account.isOptionSet(Account.OPTION_DISABLED)) { if (!account.isOptionSet(Account.OPTION_DISABLED)) {
if (!hasInternetConnection()) { if (!hasInternetConnection()) {
account.setStatus(Account.STATUS_NO_INTERNET); account.setStatus(Account.State.NO_INTERNET);
if (statusListener != null) { if (statusListener != null) {
statusListener.onStatusChanged(account); statusListener.onStatusChanged(account);
} }
} else { } else {
if (account.getStatus() == Account.STATUS_NO_INTERNET) { if (account.getStatus() == Account.State.NO_INTERNET) {
account.setStatus(Account.STATUS_OFFLINE); account.setStatus(Account.State.OFFLINE);
if (statusListener != null) { if (statusListener != null) {
statusListener.onStatusChanged(account); statusListener.onStatusChanged(account);
} }
} }
if (account.getStatus() == Account.STATUS_ONLINE) { if (account.getStatus() == Account.State.ONLINE) {
long lastReceived = account.getXmppConnection() long lastReceived = account.getXmppConnection()
.getLastPacketReceived(); .getLastPacketReceived();
long lastSent = account.getXmppConnection() long lastSent = account.getXmppConnection()
.getLastPingSent(); .getLastPingSent();
if (lastSent - lastReceived >= Config.PING_TIMEOUT * 1000) { if (lastSent - lastReceived >= Config.PING_TIMEOUT * 1000) {
Log.d(Config.LOGTAG, account.getJid() Log.d(Config.LOGTAG, account.getJid()
+ ": ping timeout"); + ": ping timeout");
@ -423,15 +423,15 @@ public class XmppConnectionService extends Service {
account.getXmppConnection().sendPing(); account.getXmppConnection().sendPing();
this.scheduleWakeupCall(2, false); this.scheduleWakeupCall(2, false);
} }
} else if (account.getStatus() == Account.STATUS_OFFLINE) { } else if (account.getStatus() == Account.State.OFFLINE) {
if (account.getXmppConnection() == null) { if (account.getXmppConnection() == null) {
account.setXmppConnection(this account.setXmppConnection(this
.createConnection(account)); .createConnection(account));
} }
new Thread(account.getXmppConnection()).start(); new Thread(account.getXmppConnection()).start();
} else if ((account.getStatus() == Account.STATUS_CONNECTING) } else if ((account.getStatus() == Account.State.CONNECTING)
&& ((SystemClock.elapsedRealtime() - account && ((SystemClock.elapsedRealtime() - account
.getXmppConnection().getLastConnect()) / 1000 >= Config.CONNECT_TIMEOUT)) { .getXmppConnection().getLastConnect()) / 1000 >= Config.CONNECT_TIMEOUT)) {
Log.d(Config.LOGTAG, account.getJid() Log.d(Config.LOGTAG, account.getJid()
+ ": time out during connect reconnecting"); + ": time out during connect reconnecting");
reconnectAccount(account, true); reconnectAccount(account, true);
@ -449,9 +449,9 @@ public class XmppConnectionService extends Service {
} }
} }
/*PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE); /*PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
if (!pm.isScreenOn()) { if (!pm.isScreenOn()) {
removeStaleListeners(); removeStaleListeners();
}*/ }*/
if (wakeLock.isHeld()) { if (wakeLock.isHeld()) {
try { try {
wakeLock.release(); wakeLock.release();
@ -463,7 +463,7 @@ public class XmppConnectionService extends Service {
public boolean hasInternetConnection() { public boolean hasInternetConnection() {
ConnectivityManager cm = (ConnectivityManager) getApplicationContext() ConnectivityManager cm = (ConnectivityManager) getApplicationContext()
.getSystemService(Context.CONNECTIVITY_SERVICE); .getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return activeNetwork != null && activeNetwork.isConnected(); return activeNetwork != null && activeNetwork.isConnected();
} }
@ -487,7 +487,7 @@ public class XmppConnectionService extends Service {
}; };
this.databaseBackend = DatabaseBackend this.databaseBackend = DatabaseBackend
.getInstance(getApplicationContext()); .getInstance(getApplicationContext());
this.accounts = databaseBackend.getAccounts(); this.accounts = databaseBackend.getAccounts();
for (Account account : this.accounts) { for (Account account : this.accounts) {
@ -534,7 +534,7 @@ public class XmppConnectionService extends Service {
} }
Context context = getApplicationContext(); Context context = getApplicationContext();
AlarmManager alarmManager = (AlarmManager) context AlarmManager alarmManager = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE); .getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, EventReceiver.class); Intent intent = new Intent(context, EventReceiver.class);
alarmManager.cancel(PendingIntent.getBroadcast(context, 0, intent, 0)); alarmManager.cancel(PendingIntent.getBroadcast(context, 0, intent, 0));
Log.d(Config.LOGTAG, "good bye"); Log.d(Config.LOGTAG, "good bye");
@ -545,7 +545,7 @@ public class XmppConnectionService extends Service {
long timeToWake = SystemClock.elapsedRealtime() + seconds * 1000; long timeToWake = SystemClock.elapsedRealtime() + seconds * 1000;
Context context = getApplicationContext(); Context context = getApplicationContext();
AlarmManager alarmManager = (AlarmManager) context AlarmManager alarmManager = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE); .getSystemService(Context.ALARM_SERVICE);
if (ping) { if (ping) {
if (this.pingIntent == null) { if (this.pingIntent == null) {
@ -566,7 +566,7 @@ public class XmppConnectionService extends Service {
context, 0, this.pingIntent, 0); context, 0, this.pingIntent, 0);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
timeToWake, pendingPingIntent); timeToWake, pendingPingIntent);
} }
} }
} else { } else {
Intent intent = new Intent(context, EventReceiver.class); Intent intent = new Intent(context, EventReceiver.class);
@ -591,7 +591,7 @@ public class XmppConnectionService extends Service {
connection.setOnJinglePacketReceivedListener(this.jingleListener); connection.setOnJinglePacketReceivedListener(this.jingleListener);
connection.setOnBindListener(this.mOnBindListener); connection.setOnBindListener(this.mOnBindListener);
connection connection
.setOnMessageAcknowledgeListener(this.mOnMessageAcknowledgedListener); .setOnMessageAcknowledgeListener(this.mOnMessageAcknowledgedListener);
return connection; return connection;
} }
@ -602,7 +602,7 @@ public class XmppConnectionService extends Service {
MessagePacket packet = null; MessagePacket packet = null;
boolean saveInDb = true; boolean saveInDb = true;
boolean send = false; boolean send = false;
if (account.getStatus() == Account.STATUS_ONLINE if (account.getStatus() == Account.State.ONLINE
&& account.getXmppConnection() != null) { && account.getXmppConnection() != null) {
if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE) { if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE) {
if (message.getCounterpart() != null) { if (message.getCounterpart() != null) {
@ -614,8 +614,8 @@ public class XmppConnectionService extends Service {
} else if (conv.hasValidOtrSession() } else if (conv.hasValidOtrSession()
&& conv.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) { && conv.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) {
mJingleConnectionManager mJingleConnectionManager
.createNewConnection(message); .createNewConnection(message);
} }
} else { } else {
mJingleConnectionManager.createNewConnection(message); mJingleConnectionManager.createNewConnection(message);
} }
@ -656,7 +656,7 @@ public class XmppConnectionService extends Service {
if (!account.getXmppConnection().getFeatures().sm() if (!account.getXmppConnection().getFeatures().sm()
&& conv.getMode() != Conversation.MODE_MULTI) { && conv.getMode() != Conversation.MODE_MULTI) {
message.setStatus(Message.STATUS_SEND); message.setStatus(Message.STATUS_SEND);
} }
} else { } else {
message.setStatus(Message.STATUS_WAITING); message.setStatus(Message.STATUS_WAITING);
if (message.getType() == Message.TYPE_TEXT) { if (message.getType() == Message.TYPE_TEXT) {
@ -673,7 +673,7 @@ public class XmppConnectionService extends Service {
if (!conv.hasValidOtrSession() if (!conv.hasValidOtrSession()
&& message.getCounterpart() != null) { && message.getCounterpart() != null) {
conv.startOtrSession(this, message.getCounterpart().getResourcepart(), false); conv.startOtrSession(this, message.getCounterpart().getResourcepart(), false);
} }
} }
} }
@ -683,7 +683,7 @@ public class XmppConnectionService extends Service {
if (message.getEncryption() == Message.ENCRYPTION_NONE if (message.getEncryption() == Message.ENCRYPTION_NONE
|| saveEncryptedMessages()) { || saveEncryptedMessages()) {
databaseBackend.createMessage(message); databaseBackend.createMessage(message);
} }
} }
if ((send) && (packet != null)) { if ((send) && (packet != null)) {
sendMessagePacket(account, packet); sendMessagePacket(account, packet);
@ -705,7 +705,7 @@ public class XmppConnectionService extends Service {
MessagePacket packet = null; MessagePacket packet = null;
if (message.getEncryption() == Message.ENCRYPTION_OTR) { if (message.getEncryption() == Message.ENCRYPTION_OTR) {
Presences presences = message.getConversation().getContact() Presences presences = message.getConversation().getContact()
.getPresences(); .getPresences();
if (!message.getConversation().hasValidOtrSession()) { if (!message.getConversation().hasValidOtrSession()) {
if ((message.getCounterpart() != null) if ((message.getCounterpart() != null)
&& (presences.has(message.getCounterpart().getResourcepart()))) { && (presences.has(message.getCounterpart().getResourcepart()))) {
@ -732,7 +732,7 @@ public class XmppConnectionService extends Service {
} catch (InvalidJidException e) { } catch (InvalidJidException e) {
} }
} }
} }
} else if (message.getType() == Message.TYPE_TEXT) { } else if (message.getType() == Message.TYPE_TEXT) {
if (message.getEncryption() == Message.ENCRYPTION_NONE) { if (message.getEncryption() == Message.ENCRYPTION_NONE) {
@ -740,7 +740,7 @@ public class XmppConnectionService extends Service {
} else if ((message.getEncryption() == Message.ENCRYPTION_DECRYPTED) } else if ((message.getEncryption() == Message.ENCRYPTION_DECRYPTED)
|| (message.getEncryption() == Message.ENCRYPTION_PGP)) { || (message.getEncryption() == Message.ENCRYPTION_PGP)) {
packet = mMessageGenerator.generatePgpChat(message, true); packet = mMessageGenerator.generatePgpChat(message, true);
} }
} else if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE) { } else if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE) {
Contact contact = message.getConversation().getContact(); Contact contact = message.getConversation().getContact();
Presences presences = contact.getPresences(); Presences presences = contact.getPresences();
@ -787,7 +787,7 @@ public class XmppConnectionService extends Service {
@Override @Override
public void onIqPacketReceived(final Account account, public void onIqPacketReceived(final Account account,
IqPacket packet) { IqPacket packet) {
Element query = packet.findChild("query"); Element query = packet.findChild("query");
if (query != null) { if (query != null) {
account.getRoster().markAllAsNotInRoster(); account.getRoster().markAllAsNotInRoster();
@ -863,11 +863,11 @@ public class XmppConnectionService extends Service {
break; break;
} }
final Contact contact = account.getRoster() final Contact contact = account.getRoster()
.getContact(jid); .getContact(jid);
String systemAccount = phoneContact String systemAccount = phoneContact
.getInt("phoneid") .getInt("phoneid")
+ "#" + "#"
+ phoneContact.getString("lookup"); + phoneContact.getString("lookup");
contact.setSystemAccount(systemAccount); contact.setSystemAccount(systemAccount);
contact.setPhotoUri(phoneContact contact.setPhotoUri(phoneContact
.getString("photouri")); .getString("photouri"));
@ -887,7 +887,7 @@ public class XmppConnectionService extends Service {
accountLookupTable.put(account.getUuid(), account); accountLookupTable.put(account.getUuid(), account);
} }
this.conversations = databaseBackend this.conversations = databaseBackend
.getConversations(Conversation.STATUS_AVAILABLE); .getConversations(Conversation.STATUS_AVAILABLE);
for (Conversation conv : this.conversations) { for (Conversation conv : this.conversations) {
Account account = accountLookupTable.get(conv.getAccountUuid()); Account account = accountLookupTable.get(conv.getAccountUuid());
conv.setAccount(account); conv.setAccount(account);
@ -905,7 +905,7 @@ public class XmppConnectionService extends Service {
if (!getFileBackend().isFileAvailable(message)) { if (!getFileBackend().isFileAvailable(message)) {
message.setDownloadable(new DownloadablePlaceholder(Downloadable.STATUS_DELETED)); message.setDownloadable(new DownloadablePlaceholder(Downloadable.STATUS_DELETED));
} }
} }
} }
} }
@ -920,7 +920,7 @@ public class XmppConnectionService extends Service {
updateConversationUi(); updateConversationUi();
} }
return; return;
} }
} }
} }
} }
@ -930,7 +930,7 @@ public class XmppConnectionService extends Service {
} }
public void populateWithOrderedConversations(List<Conversation> list, public void populateWithOrderedConversations(List<Conversation> list,
boolean includeConferences) { boolean includeConferences) {
list.clear(); list.clear();
if (includeConferences) { if (includeConferences) {
list.addAll(getConversations()); list.addAll(getConversations());
@ -981,19 +981,19 @@ public class XmppConnectionService extends Service {
} }
public Conversation find(final List<Conversation> haystack, public Conversation find(final List<Conversation> haystack,
final Account account, final Account account,
final Jid jid) { final Jid jid) {
for (Conversation conversation : haystack) { for (Conversation conversation : haystack) {
if ((account == null || conversation.getAccount() == account) if ((account == null || conversation.getAccount() == account)
&& (conversation.getContactJid().toBareJid().equals(jid.toBareJid()))) { && (conversation.getContactJid().toBareJid().equals(jid.toBareJid()))) {
return conversation; return conversation;
} }
} }
return null; return null;
} }
public Conversation findOrCreateConversation(final Account account, final Jid jid, public Conversation findOrCreateConversation(final Account account, final Jid jid,
final boolean muc) { final boolean muc) {
Conversation conversation = find(account, jid); Conversation conversation = find(account, jid);
if (conversation != null) { if (conversation != null) {
return conversation; return conversation;
@ -1008,7 +1008,7 @@ public class XmppConnectionService extends Service {
conversation.setMode(Conversation.MODE_SINGLE); conversation.setMode(Conversation.MODE_SINGLE);
} }
conversation.setMessages(databaseBackend.getMessages(conversation, conversation.setMessages(databaseBackend.getMessages(conversation,
50)); 50));
this.databaseBackend.updateConversation(conversation); this.databaseBackend.updateConversation(conversation);
} else { } else {
String conversationName; String conversationName;
@ -1034,7 +1034,7 @@ public class XmppConnectionService extends Service {
public void archiveConversation(Conversation conversation) { public void archiveConversation(Conversation conversation) {
if (conversation.getMode() == Conversation.MODE_MULTI) { if (conversation.getMode() == Conversation.MODE_MULTI) {
if (conversation.getAccount().getStatus() == Account.STATUS_ONLINE) { if (conversation.getAccount().getStatus() == Account.State.ONLINE) {
Bookmark bookmark = conversation.getBookmark(); Bookmark bookmark = conversation.getBookmark();
if (bookmark != null && bookmark.autojoin()) { if (bookmark != null && bookmark.autojoin()) {
bookmark.setAutojoin(false); bookmark.setAutojoin(false);
@ -1139,9 +1139,9 @@ public class XmppConnectionService extends Service {
OnConversationUpdate listener) { OnConversationUpdate listener) {
/*if (!isScreenOn()) { /*if (!isScreenOn()) {
Log.d(Config.LOGTAG, Log.d(Config.LOGTAG,
"ignoring setOnConversationListChangedListener"); "ignoring setOnConversationListChangedListener");
return; return;
}*/ }*/
synchronized (this.convChangedListenerCount) { synchronized (this.convChangedListenerCount) {
if (checkListeners()) { if (checkListeners()) {
switchToForeground(); switchToForeground();
@ -1150,7 +1150,7 @@ public class XmppConnectionService extends Service {
this.mNotificationService.setIsInForeground(true); this.mNotificationService.setIsInForeground(true);
this.convChangedListenerCount++; this.convChangedListenerCount++;
} }
} }
public void removeOnConversationListChangedListener() { public void removeOnConversationListChangedListener() {
synchronized (this.convChangedListenerCount) { synchronized (this.convChangedListenerCount) {
@ -1170,7 +1170,7 @@ public class XmppConnectionService extends Service {
/*if (!isScreenOn()) { /*if (!isScreenOn()) {
Log.d(Config.LOGTAG, "ignoring setOnAccountListChangedListener"); Log.d(Config.LOGTAG, "ignoring setOnAccountListChangedListener");
return; return;
}*/ }*/
synchronized (this.accountChangedListenerCount) { synchronized (this.accountChangedListenerCount) {
if (checkListeners()) { if (checkListeners()) {
switchToForeground(); switchToForeground();
@ -1197,7 +1197,7 @@ public class XmppConnectionService extends Service {
/*if (!isScreenOn()) { /*if (!isScreenOn()) {
Log.d(Config.LOGTAG, "ignoring setOnRosterUpdateListener"); Log.d(Config.LOGTAG, "ignoring setOnRosterUpdateListener");
return; return;
}*/ }*/
synchronized (this.rosterChangedListenerCount) { synchronized (this.rosterChangedListenerCount) {
if (checkListeners()) { if (checkListeners()) {
switchToForeground(); switchToForeground();
@ -1227,7 +1227,7 @@ public class XmppConnectionService extends Service {
private void switchToForeground() { private void switchToForeground() {
for (Account account : getAccounts()) { for (Account account : getAccounts()) {
if (account.getStatus() == Account.STATUS_ONLINE) { if (account.getStatus() == Account.State.ONLINE) {
XmppConnection connection = account.getXmppConnection(); XmppConnection connection = account.getXmppConnection();
if (connection != null && connection.getFeatures().csi()) { if (connection != null && connection.getFeatures().csi()) {
connection.sendActive(); connection.sendActive();
@ -1239,7 +1239,7 @@ public class XmppConnectionService extends Service {
private void switchToBackground() { private void switchToBackground() {
for (Account account : getAccounts()) { for (Account account : getAccounts()) {
if (account.getStatus() == Account.STATUS_ONLINE) { if (account.getStatus() == Account.State.ONLINE) {
XmppConnection connection = account.getXmppConnection(); XmppConnection connection = account.getXmppConnection();
if (connection != null && connection.getFeatures().csi()) { if (connection != null && connection.getFeatures().csi()) {
connection.sendInactive(); connection.sendInactive();
@ -1252,7 +1252,7 @@ public class XmppConnectionService extends Service {
private boolean isScreenOn() { private boolean isScreenOn() {
PowerManager pm = (PowerManager) this PowerManager pm = (PowerManager) this
.getSystemService(Context.POWER_SERVICE); .getSystemService(Context.POWER_SERVICE);
return pm.isScreenOn(); return pm.isScreenOn();
} }
@ -1262,7 +1262,7 @@ public class XmppConnectionService extends Service {
if ((conversation.getMode() == Conversation.MODE_MULTI) if ((conversation.getMode() == Conversation.MODE_MULTI)
&& (conversation.getAccount() == account)) { && (conversation.getAccount() == account)) {
joinMuc(conversation); joinMuc(conversation);
} }
} }
} }
@ -1270,7 +1270,7 @@ public class XmppConnectionService extends Service {
Account account = conversation.getAccount(); Account account = conversation.getAccount();
account.pendingConferenceJoins.remove(conversation); account.pendingConferenceJoins.remove(conversation);
account.pendingConferenceLeaves.remove(conversation); account.pendingConferenceLeaves.remove(conversation);
if (account.getStatus() == Account.STATUS_ONLINE) { if (account.getStatus() == Account.State.ONLINE) {
Log.d(Config.LOGTAG, Log.d(Config.LOGTAG,
"joining conversation " + conversation.getContactJid()); "joining conversation " + conversation.getContactJid());
String nick = conversation.getMucOptions().getProposedNick(); String nick = conversation.getMucOptions().getProposedNick();
@ -1363,7 +1363,7 @@ public class XmppConnectionService extends Service {
} else { } else {
conversation.setContactJid(options.getJoinJid()); conversation.setContactJid(options.getJoinJid());
databaseBackend.updateConversation(conversation); databaseBackend.updateConversation(conversation);
if (conversation.getAccount().getStatus() == Account.STATUS_ONLINE) { if (conversation.getAccount().getStatus() == Account.State.ONLINE) {
Bookmark bookmark = conversation.getBookmark(); Bookmark bookmark = conversation.getBookmark();
if (bookmark != null) { if (bookmark != null) {
bookmark.setNick(nick); bookmark.setNick(nick);
@ -1378,7 +1378,7 @@ public class XmppConnectionService extends Service {
Account account = conversation.getAccount(); Account account = conversation.getAccount();
account.pendingConferenceJoins.remove(conversation); account.pendingConferenceJoins.remove(conversation);
account.pendingConferenceLeaves.remove(conversation); account.pendingConferenceLeaves.remove(conversation);
if (account.getStatus() == Account.STATUS_ONLINE) { if (account.getStatus() == Account.State.ONLINE) {
PresencePacket packet = new PresencePacket(); PresencePacket packet = new PresencePacket();
packet.setTo(conversation.getMucOptions().getJoinJid()); packet.setTo(conversation.getMucOptions().getJoinJid());
packet.setFrom(conversation.getAccount().getJid()); packet.setFrom(conversation.getAccount().getJid());
@ -1394,8 +1394,8 @@ public class XmppConnectionService extends Service {
} }
public void disconnect(Account account, boolean force) { public void disconnect(Account account, boolean force) {
if ((account.getStatus() == Account.STATUS_ONLINE) if ((account.getStatus() == Account.State.ONLINE)
|| (account.getStatus() == Account.STATUS_DISABLED)) { || (account.getStatus() == Account.State.DISABLED)) {
if (!force) { if (!force) {
List<Conversation> conversations = getConversations(); List<Conversation> conversations = getConversations();
for (Conversation conversation : conversations) { for (Conversation conversation : conversations) {
@ -1413,7 +1413,7 @@ public class XmppConnectionService extends Service {
} }
} }
account.getXmppConnection().disconnect(force); account.getXmppConnection().disconnect(force);
} }
} }
@Override @Override
@ -1453,8 +1453,8 @@ public class XmppConnectionService extends Service {
Session otrSession = conversation.getOtrSession(); Session otrSession = conversation.getOtrSession();
Log.d(Config.LOGTAG, Log.d(Config.LOGTAG,
account.getJid().toBareJid() + " otr session established with " account.getJid().toBareJid() + " otr session established with "
+ conversation.getContactJid() + "/" + conversation.getContactJid() + "/"
+ otrSession.getSessionID().getUserID()); + otrSession.getSessionID().getUserID());
for (Message msg : messages) { for (Message msg : messages) {
if ((msg.getStatus() == Message.STATUS_UNSEND || msg.getStatus() == Message.STATUS_WAITING) if ((msg.getStatus() == Message.STATUS_UNSEND || msg.getStatus() == Message.STATUS_WAITING)
&& (msg.getEncryption() == Message.ENCRYPTION_OTR)) { && (msg.getEncryption() == Message.ENCRYPTION_OTR)) {
@ -1466,7 +1466,7 @@ public class XmppConnectionService extends Service {
} }
if (msg.getType() == Message.TYPE_TEXT) { if (msg.getType() == Message.TYPE_TEXT) {
MessagePacket outPacket = mMessageGenerator MessagePacket outPacket = mMessageGenerator
.generateOtrChat(msg, true); .generateOtrChat(msg, true);
if (outPacket != null) { if (outPacket != null) {
msg.setStatus(Message.STATUS_SEND); msg.setStatus(Message.STATUS_SEND);
databaseBackend.updateMessage(msg); databaseBackend.updateMessage(msg);
@ -1475,7 +1475,7 @@ public class XmppConnectionService extends Service {
} else if (msg.getType() == Message.TYPE_IMAGE || msg.getType() == Message.TYPE_FILE) { } else if (msg.getType() == Message.TYPE_IMAGE || msg.getType() == Message.TYPE_FILE) {
mJingleConnectionManager.createNewConnection(msg); mJingleConnectionManager.createNewConnection(msg);
} }
} }
} }
updateConversationUi(); updateConversationUi();
} }
@ -1496,7 +1496,7 @@ public class XmppConnectionService extends Service {
try { try {
packet.setBody(otrSession packet.setBody(otrSession
.transformSending(CryptoHelper.FILETRANSFER .transformSending(CryptoHelper.FILETRANSFER
+ CryptoHelper.bytesToHex(symmetricKey))); + CryptoHelper.bytesToHex(symmetricKey)));
sendMessagePacket(account, packet); sendMessagePacket(account, packet);
conversation.setSymmetricKey(symmetricKey); conversation.setSymmetricKey(symmetricKey);
return true; return true;
@ -1511,11 +1511,11 @@ public class XmppConnectionService extends Service {
contact.resetOption(Contact.Options.DIRTY_DELETE); contact.resetOption(Contact.Options.DIRTY_DELETE);
contact.setOption(Contact.Options.DIRTY_PUSH); contact.setOption(Contact.Options.DIRTY_PUSH);
Account account = contact.getAccount(); Account account = contact.getAccount();
if (account.getStatus() == Account.STATUS_ONLINE) { if (account.getStatus() == Account.State.ONLINE) {
boolean ask = contact.getOption(Contact.Options.ASKING); boolean ask = contact.getOption(Contact.Options.ASKING);
boolean sendUpdates = contact boolean sendUpdates = contact
.getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST) .getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)
&& contact.getOption(Contact.Options.PREEMPTIVE_GRANT); && contact.getOption(Contact.Options.PREEMPTIVE_GRANT);
IqPacket iq = new IqPacket(IqPacket.TYPE_SET); IqPacket iq = new IqPacket(IqPacket.TYPE_SET);
iq.query("jabber:iq:roster").addChild(contact.asElement()); iq.query("jabber:iq:roster").addChild(contact.asElement());
account.getXmppConnection().sendIqPacket(iq, null); account.getXmppConnection().sendIqPacket(iq, null);
@ -1531,11 +1531,11 @@ public class XmppConnectionService extends Service {
} }
public void publishAvatar(Account account, Uri image, public void publishAvatar(Account account, Uri image,
final UiCallback<Avatar> callback) { final UiCallback<Avatar> callback) {
final Bitmap.CompressFormat format = Config.AVATAR_FORMAT; final Bitmap.CompressFormat format = Config.AVATAR_FORMAT;
final int size = Config.AVATAR_SIZE; final int size = Config.AVATAR_SIZE;
final Avatar avatar = getFileBackend() final Avatar avatar = getFileBackend()
.getPepAvatar(image, size, format); .getPepAvatar(image, size, format);
if (avatar != null) { if (avatar != null) {
avatar.height = size; avatar.height = size;
avatar.width = size; avatar.width = size;
@ -1557,12 +1557,12 @@ public class XmppConnectionService extends Service {
public void onIqPacketReceived(Account account, IqPacket result) { public void onIqPacketReceived(Account account, IqPacket result) {
if (result.getType() == IqPacket.TYPE_RESULT) { if (result.getType() == IqPacket.TYPE_RESULT) {
IqPacket packet = XmppConnectionService.this.mIqGenerator IqPacket packet = XmppConnectionService.this.mIqGenerator
.publishAvatarMetadata(avatar); .publishAvatarMetadata(avatar);
sendIqPacket(account, packet, new OnIqPacketReceived() { sendIqPacket(account, packet, new OnIqPacketReceived() {
@Override @Override
public void onIqPacketReceived(Account account, public void onIqPacketReceived(Account account,
IqPacket result) { IqPacket result) {
if (result.getType() == IqPacket.TYPE_RESULT) { if (result.getType() == IqPacket.TYPE_RESULT) {
if (account.setAvatar(avatar.getFilename())) { if (account.setAvatar(avatar.getFilename())) {
databaseBackend.updateAccount(account); databaseBackend.updateAccount(account);
@ -1592,14 +1592,14 @@ public class XmppConnectionService extends Service {
} }
public void fetchAvatar(Account account, final Avatar avatar, public void fetchAvatar(Account account, final Avatar avatar,
final UiCallback<Avatar> callback) { final UiCallback<Avatar> callback) {
IqPacket packet = this.mIqGenerator.retrieveAvatar(avatar); IqPacket packet = this.mIqGenerator.retrieveAvatar(avatar);
sendIqPacket(account, packet, new OnIqPacketReceived() { sendIqPacket(account, packet, new OnIqPacketReceived() {
@Override @Override
public void onIqPacketReceived(Account account, IqPacket result) { public void onIqPacketReceived(Account account, IqPacket result) {
final String ERROR = account.getJid().toBareJid() final String ERROR = account.getJid().toBareJid()
+ ": fetching avatar for " + avatar.owner + " failed "; + ": fetching avatar for " + avatar.owner + " failed ";
if (result.getType() == IqPacket.TYPE_RESULT) { if (result.getType() == IqPacket.TYPE_RESULT) {
avatar.image = mIqParser.avatarData(result); avatar.image = mIqParser.avatarData(result);
if (avatar.image != null) { if (avatar.image != null) {
@ -1613,7 +1613,7 @@ public class XmppConnectionService extends Service {
updateAccountUi(); updateAccountUi();
} else { } else {
Contact contact = account.getRoster() Contact contact = account.getRoster()
.getContact(avatar.owner); .getContact(avatar.owner);
contact.setAvatar(avatar.getFilename()); contact.setAvatar(avatar.getFilename());
getAvatarService().clear(contact); getAvatarService().clear(contact);
updateConversationUi(); updateConversationUi();
@ -1648,7 +1648,7 @@ public class XmppConnectionService extends Service {
} }
public void checkForAvatar(Account account, public void checkForAvatar(Account account,
final UiCallback<Avatar> callback) { final UiCallback<Avatar> callback) {
IqPacket packet = this.mIqGenerator.retrieveAvatarMetaData(null); IqPacket packet = this.mIqGenerator.retrieveAvatarMetaData(null);
this.sendIqPacket(account, packet, new OnIqPacketReceived() { this.sendIqPacket(account, packet, new OnIqPacketReceived() {
@ -1687,7 +1687,7 @@ public class XmppConnectionService extends Service {
contact.resetOption(Contact.Options.DIRTY_PUSH); contact.resetOption(Contact.Options.DIRTY_PUSH);
contact.setOption(Contact.Options.DIRTY_DELETE); contact.setOption(Contact.Options.DIRTY_DELETE);
Account account = contact.getAccount(); Account account = contact.getAccount();
if (account.getStatus() == Account.STATUS_ONLINE) { if (account.getStatus() == Account.State.ONLINE) {
IqPacket iq = new IqPacket(IqPacket.TYPE_SET); IqPacket iq = new IqPacket(IqPacket.TYPE_SET);
Element item = iq.query("jabber:iq:roster").addChild("item"); Element item = iq.query("jabber:iq:roster").addChild("item");
item.setAttribute("jid", contact.getJid().toString()); item.setAttribute("jid", contact.getJid().toString());
@ -1736,14 +1736,14 @@ public class XmppConnectionService extends Service {
if (message.getType() != Message.TYPE_IMAGE if (message.getType() != Message.TYPE_IMAGE
&& message.getStatus() == Message.STATUS_UNSEND) { && message.getStatus() == Message.STATUS_UNSEND) {
markMessage(message, Message.STATUS_WAITING); markMessage(message, Message.STATUS_WAITING);
} }
} }
} }
} }
} }
public boolean markMessage(final Account account, final Jid recipient, final String uuid, public boolean markMessage(final Account account, final Jid recipient, final String uuid,
final int status) { final int status) {
if (uuid == null) { if (uuid == null) {
return false; return false;
} else { } else {
@ -1751,24 +1751,24 @@ public class XmppConnectionService extends Service {
if (conversation.getContactJid().equals(recipient) if (conversation.getContactJid().equals(recipient)
&& conversation.getAccount().equals(account)) { && conversation.getAccount().equals(account)) {
return markMessage(conversation, uuid, status); return markMessage(conversation, uuid, status);
} }
} }
return false; return false;
} }
} }
public boolean markMessage(Conversation conversation, String uuid, public boolean markMessage(Conversation conversation, String uuid,
int status) { int status) {
if (uuid == null) { if (uuid == null) {
return false; return false;
} else { } else {
for (Message message : conversation.getMessages()) { for (Message message : conversation.getMessages()) {
if (uuid.equals(message.getUuid()) if (uuid.equals(message.getUuid())
|| (message.getStatus() >= Message.STATUS_SEND && uuid || (message.getStatus() >= Message.STATUS_SEND && uuid
.equals(message.getRemoteMsgId()))) { .equals(message.getRemoteMsgId()))) {
markMessage(message, status); markMessage(message, status);
return true; return true;
} }
} }
return false; return false;
} }
@ -1777,9 +1777,9 @@ public class XmppConnectionService extends Service {
public void markMessage(Message message, int status) { public void markMessage(Message message, int status) {
if (status == Message.STATUS_SEND_FAILED if (status == Message.STATUS_SEND_FAILED
&& (message.getStatus() == Message.STATUS_SEND_RECEIVED || message && (message.getStatus() == Message.STATUS_SEND_RECEIVED || message
.getStatus() == Message.STATUS_SEND_DISPLAYED)) { .getStatus() == Message.STATUS_SEND_DISPLAYED)) {
return; return;
} }
message.setStatus(status); message.setStatus(status);
databaseBackend.updateMessage(message); databaseBackend.updateMessage(message);
updateConversationUi(); updateConversationUi();
@ -1787,7 +1787,7 @@ public class XmppConnectionService extends Service {
public SharedPreferences getPreferences() { public SharedPreferences getPreferences() {
return PreferenceManager return PreferenceManager
.getDefaultSharedPreferences(getApplicationContext()); .getDefaultSharedPreferences(getApplicationContext());
} }
public boolean forceEncryption() { public boolean forceEncryption() {
@ -1864,7 +1864,7 @@ public class XmppConnectionService extends Service {
if (message.getEncryption() == Message.ENCRYPTION_OTR if (message.getEncryption() == Message.ENCRYPTION_OTR
&& message.getStatus() == Message.STATUS_WAITING) { && message.getStatus() == Message.STATUS_WAITING) {
markMessage(message, Message.STATUS_SEND_FAILED); markMessage(message, Message.STATUS_SEND_FAILED);
} }
} }
} }
@ -1885,9 +1885,9 @@ public class XmppConnectionService extends Service {
} }
public void replyWithNotAcceptable(Account account, MessagePacket packet) { public void replyWithNotAcceptable(Account account, MessagePacket packet) {
if (account.getStatus() == Account.STATUS_ONLINE) { if (account.getStatus() == Account.State.ONLINE) {
MessagePacket error = this.mMessageGenerator MessagePacket error = this.mMessageGenerator
.generateNotAcceptable(packet); .generateNotAcceptable(packet);
sendMessagePacket(account, error); sendMessagePacket(account, error);
} }
} }
@ -1949,7 +1949,7 @@ public class XmppConnectionService extends Service {
} }
public void sendIqPacket(Account account, IqPacket packet, public void sendIqPacket(Account account, IqPacket packet,
OnIqPacketReceived callback) { OnIqPacketReceived callback) {
XmppConnection connection = account.getXmppConnection(); XmppConnection connection = account.getXmppConnection();
if (connection != null) { if (connection != null) {
connection.sendIqPacket(packet, callback); connection.sendIqPacket(packet, callback);

View file

@ -130,7 +130,7 @@ public class ChooseContactActivity extends XmppActivity {
protected void filterContacts(String needle) { protected void filterContacts(String needle) {
this.contacts.clear(); this.contacts.clear();
for (Account account : xmppConnectionService.getAccounts()) { for (Account account : xmppConnectionService.getAccounts()) {
if (account.getStatus() != Account.STATUS_DISABLED) { if (account.getStatus() != Account.State.DISABLED) {
for (Contact contact : account.getRoster().getContacts()) { for (Contact contact : account.getRoster().getContacts()) {
if (contact.showInRoster() && contact.match(needle)) { if (contact.showInRoster() && contact.match(needle)) {
this.contacts.add(contact); this.contacts.add(contact);

View file

@ -266,7 +266,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
receive.setChecked(false); receive.setChecked(false);
} }
} }
if (contact.getAccount().getStatus() == Account.STATUS_ONLINE) { if (contact.getAccount().getStatus() == Account.State.ONLINE) {
receive.setEnabled(true); receive.setEnabled(true);
send.setEnabled(true); send.setEnabled(true);
} else { } else {

View file

@ -544,7 +544,7 @@ public class ConversationFragment extends Fragment {
} else if (conversation.getMode() == Conversation.MODE_SINGLE) { } else if (conversation.getMode() == Conversation.MODE_SINGLE) {
makeFingerprintWarning(); makeFingerprintWarning();
} else if (!conversation.getMucOptions().online() } else if (!conversation.getMucOptions().online()
&& conversation.getAccount().getStatus() == Account.STATUS_ONLINE) { && conversation.getAccount().getStatus() == Account.State.ONLINE) {
int error = conversation.getMucOptions().getError(); int error = conversation.getMucOptions().getError();
switch (error) { switch (error) {
case MucOptions.ERROR_NICK_IN_USE: case MucOptions.ERROR_NICK_IN_USE:
@ -648,7 +648,7 @@ public class ConversationFragment extends Fragment {
public void updateSendButton() { public void updateSendButton() {
Conversation c = this.conversation; Conversation c = this.conversation;
if (activity.useSendButtonToIndicateStatus() && c != null if (activity.useSendButtonToIndicateStatus() && c != null
&& c.getAccount().getStatus() == Account.STATUS_ONLINE) { && c.getAccount().getStatus() == Account.State.ONLINE) {
if (c.getMode() == Conversation.MODE_SINGLE) { if (c.getMode() == Conversation.MODE_SINGLE) {
switch (c.getContact().getMostAvailableStatus()) { switch (c.getContact().getMostAvailableStatus()) {
case Presences.CHAT: case Presences.CHAT:

View file

@ -62,7 +62,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if (mAccount != null if (mAccount != null
&& mAccount.getStatus() == Account.STATUS_DISABLED) { && mAccount.getStatus() == Account.State.DISABLED) {
mAccount.setOption(Account.OPTION_DISABLED, false); mAccount.setOption(Account.OPTION_DISABLED, false);
xmppConnectionService.updateAccount(mAccount); xmppConnectionService.updateAccount(mAccount);
return; return;
@ -139,13 +139,13 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
@Override @Override
public void run() { public void run() {
if (mAccount != null if (mAccount != null
&& mAccount.getStatus() != Account.STATUS_ONLINE && mAccount.getStatus() != Account.State.ONLINE
&& mFetchingAvatar) { && mFetchingAvatar) {
startActivity(new Intent(getApplicationContext(), startActivity(new Intent(getApplicationContext(),
ManageAccountActivity.class)); ManageAccountActivity.class));
finish(); finish();
} else if (jidToEdit == null && mAccount != null } else if (jidToEdit == null && mAccount != null
&& mAccount.getStatus() == Account.STATUS_ONLINE) { && mAccount.getStatus() == Account.State.ONLINE) {
if (!mFetchingAvatar) { if (!mFetchingAvatar) {
mFetchingAvatar = true; mFetchingAvatar = true;
xmppConnectionService.checkForAvatar(mAccount, xmppConnectionService.checkForAvatar(mAccount,
@ -231,12 +231,12 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
protected void updateSaveButton() { protected void updateSaveButton() {
if (mAccount != null if (mAccount != null
&& mAccount.getStatus() == Account.STATUS_CONNECTING) { && mAccount.getStatus() == Account.State.CONNECTING) {
this.mSaveButton.setEnabled(false); this.mSaveButton.setEnabled(false);
this.mSaveButton.setTextColor(getSecondaryTextColor()); this.mSaveButton.setTextColor(getSecondaryTextColor());
this.mSaveButton.setText(R.string.account_status_connecting); this.mSaveButton.setText(R.string.account_status_connecting);
} else if (mAccount != null } else if (mAccount != null
&& mAccount.getStatus() == Account.STATUS_DISABLED) { && mAccount.getStatus() == Account.State.DISABLED) {
this.mSaveButton.setEnabled(true); this.mSaveButton.setEnabled(true);
this.mSaveButton.setTextColor(getPrimaryTextColor()); this.mSaveButton.setTextColor(getPrimaryTextColor());
this.mSaveButton.setText(R.string.enable); this.mSaveButton.setText(R.string.enable);
@ -245,7 +245,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
this.mSaveButton.setTextColor(getPrimaryTextColor()); this.mSaveButton.setTextColor(getPrimaryTextColor());
if (jidToEdit != null) { if (jidToEdit != null) {
if (mAccount != null if (mAccount != null
&& mAccount.getStatus() == Account.STATUS_ONLINE) { && mAccount.getStatus() == Account.State.ONLINE) {
this.mSaveButton.setText(R.string.save); this.mSaveButton.setText(R.string.save);
if (!accountInfoEdited()) { if (!accountInfoEdited()) {
this.mSaveButton.setEnabled(false); this.mSaveButton.setEnabled(false);
@ -379,7 +379,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
this.mRegisterNew.setVisibility(View.GONE); this.mRegisterNew.setVisibility(View.GONE);
this.mRegisterNew.setChecked(false); this.mRegisterNew.setChecked(false);
} }
if (this.mAccount.getStatus() == Account.STATUS_ONLINE if (this.mAccount.getStatus() == Account.State.ONLINE
&& !this.mFetchingAvatar) { && !this.mFetchingAvatar) {
this.mStats.setVisibility(View.VISIBLE); this.mStats.setVisibility(View.VISIBLE);
this.mSessionEst.setText(UIHelper.readableTimeDifference( this.mSessionEst.setText(UIHelper.readableTimeDifference(
@ -428,8 +428,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
} }
} else { } else {
if (this.mAccount.errorStatus()) { if (this.mAccount.errorStatus()) {
this.mAccountJid.setError(getString(this.mAccount this.mAccountJid.setError(getString(this.mAccount.getStatus().getReadableId()));
.getReadableStatusId()));
this.mAccountJid.requestFocus(); this.mAccountJid.requestFocus();
} }
this.mStats.setVisibility(View.GONE); this.mStats.setVisibility(View.GONE);

View file

@ -555,7 +555,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
protected void onBackendConnected() { protected void onBackendConnected() {
this.mActivatedAccounts.clear(); this.mActivatedAccounts.clear();
for (Account account : xmppConnectionService.getAccounts()) { for (Account account : xmppConnectionService.getAccounts()) {
if (account.getStatus() != Account.STATUS_DISABLED) { if (account.getStatus() != Account.State.DISABLED) {
this.mActivatedAccounts.add(account.getJid().toBareJid().toString()); this.mActivatedAccounts.add(account.getJid().toBareJid().toString());
} }
} }
@ -646,7 +646,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
protected void filterContacts(String needle) { protected void filterContacts(String needle) {
this.contacts.clear(); this.contacts.clear();
for (Account account : xmppConnectionService.getAccounts()) { for (Account account : xmppConnectionService.getAccounts()) {
if (account.getStatus() != Account.STATUS_DISABLED) { if (account.getStatus() != Account.State.DISABLED) {
for (Contact contact : account.getRoster().getContacts()) { for (Contact contact : account.getRoster().getContacts()) {
if (contact.showInRoster() && contact.match(needle)) { if (contact.showInRoster() && contact.match(needle)) {
this.contacts.add(contact); this.contacts.add(contact);
@ -661,7 +661,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
protected void filterConferences(String needle) { protected void filterConferences(String needle) {
this.conferences.clear(); this.conferences.clear();
for (Account account : xmppConnectionService.getAccounts()) { for (Account account : xmppConnectionService.getAccounts()) {
if (account.getStatus() != Account.STATUS_DISABLED) { if (account.getStatus() != Account.State.DISABLED) {
for (Bookmark bookmark : account.getBookmarks()) { for (Bookmark bookmark : account.getBookmarks()) {
if (bookmark.match(needle)) { if (bookmark.match(needle)) {
this.conferences.add(bookmark); this.conferences.add(bookmark);

View file

@ -143,7 +143,7 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer
} }
protected boolean isAccountOnline() { protected boolean isAccountOnline() {
if (this.mAccount.getStatus() != Account.STATUS_ONLINE) { if (this.mAccount.getStatus() != Account.State.ONLINE) {
Toast.makeText(this,R.string.not_connected_try_again,Toast.LENGTH_SHORT).show(); Toast.makeText(this,R.string.not_connected_try_again,Toast.LENGTH_SHORT).show();
return false; return false;
} else { } else {

View file

@ -517,7 +517,7 @@ public abstract class XmppActivity extends Activity {
if (presences.size() == 0) { if (presences.size() == 0) {
if (!contact.getOption(Contact.Options.TO) if (!contact.getOption(Contact.Options.TO)
&& !contact.getOption(Contact.Options.ASKING) && !contact.getOption(Contact.Options.ASKING)
&& contact.getAccount().getStatus() == Account.STATUS_ONLINE) { && contact.getAccount().getStatus() == Account.State.ONLINE) {
showAskForPresenceDialog(contact); showAskForPresenceDialog(contact);
} else if (!contact.getOption(Contact.Options.TO) } else if (!contact.getOption(Contact.Options.TO)
|| !contact.getOption(Contact.Options.FROM)) { || !contact.getOption(Contact.Options.FROM)) {

View file

@ -36,67 +36,19 @@ public class AccountAdapter extends ArrayAdapter<Account> {
ImageView imageView = (ImageView) view.findViewById(R.id.account_image); ImageView imageView = (ImageView) view.findViewById(R.id.account_image);
imageView.setImageBitmap(activity.avatarService().get(account, imageView.setImageBitmap(activity.avatarService().get(account,
activity.getPixel(48))); activity.getPixel(48)));
switch (account.getStatus()) { statusView.setText(getContext().getString(account.getStatus().getReadableId()));
case Account.STATUS_DISABLED: switch (account.getStatus()) {
statusView.setText(getContext().getString( case ONLINE:
R.string.account_status_disabled)); statusView.setTextColor(activity.getPrimaryColor());
statusView.setTextColor(activity.getSecondaryTextColor()); break;
break; case DISABLED:
case Account.STATUS_ONLINE: case CONNECTING:
statusView.setText(getContext().getString( statusView.setTextColor(activity.getSecondaryTextColor());
R.string.account_status_online)); break;
statusView.setTextColor(activity.getPrimaryColor()); default:
break; statusView.setTextColor(activity.getWarningTextColor());
case Account.STATUS_CONNECTING: break;
statusView.setText(getContext().getString( }
R.string.account_status_connecting));
statusView.setTextColor(activity.getSecondaryTextColor());
break;
case Account.STATUS_OFFLINE:
statusView.setText(getContext().getString(
R.string.account_status_offline));
statusView.setTextColor(activity.getWarningTextColor());
break;
case Account.STATUS_UNAUTHORIZED:
statusView.setText(getContext().getString(
R.string.account_status_unauthorized));
statusView.setTextColor(activity.getWarningTextColor());
break;
case Account.STATUS_SERVER_NOT_FOUND:
statusView.setText(getContext().getString(
R.string.account_status_not_found));
statusView.setTextColor(activity.getWarningTextColor());
break;
case Account.STATUS_NO_INTERNET:
statusView.setText(getContext().getString(
R.string.account_status_no_internet));
statusView.setTextColor(activity.getWarningTextColor());
break;
case Account.STATUS_REGISTRATION_FAILED:
statusView.setText(getContext().getString(
R.string.account_status_regis_fail));
statusView.setTextColor(activity.getWarningTextColor());
break;
case Account.STATUS_REGISTRATION_CONFLICT:
statusView.setText(getContext().getString(
R.string.account_status_regis_conflict));
statusView.setTextColor(activity.getWarningTextColor());
break;
case Account.STATUS_REGISTRATION_SUCCESSFULL:
statusView.setText(getContext().getString(
R.string.account_status_regis_success));
statusView.setTextColor(activity.getSecondaryTextColor());
break;
case Account.STATUS_REGISTRATION_NOT_SUPPORTED:
statusView.setText(getContext().getString(
R.string.account_status_regis_not_sup));
statusView.setTextColor(activity.getWarningTextColor());
break;
default:
statusView.setText("");
break;
}
return view; return view;
} }
} }

View file

@ -12,6 +12,8 @@ import android.util.Log;
import android.util.SparseArray; import android.util.SparseArray;
import org.apache.http.conn.ssl.StrictHostnameVerifier; import org.apache.http.conn.ssl.StrictHostnameVerifier;
import org.json.JSONException;
import org.json.JSONObject;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException; import java.io.IOException;
@ -120,15 +122,15 @@ public class XmppConnection implements Runnable {
applicationContext = service.getApplicationContext(); applicationContext = service.getApplicationContext();
} }
protected void changeStatus(int nextStatus) { protected void changeStatus(final Account.State nextStatus) {
if (account.getStatus() != nextStatus) { if (account.getStatus() != nextStatus) {
if ((nextStatus == Account.STATUS_OFFLINE) if ((nextStatus == Account.State.OFFLINE)
&& (account.getStatus() != Account.STATUS_CONNECTING) && (account.getStatus() != Account.State.CONNECTING)
&& (account.getStatus() != Account.STATUS_ONLINE) && (account.getStatus() != Account.State.ONLINE)
&& (account.getStatus() != Account.STATUS_DISABLED)) { && (account.getStatus() != Account.State.DISABLED)) {
return; return;
} }
if (nextStatus == Account.STATUS_ONLINE) { if (nextStatus == Account.State.ONLINE) {
this.attempt = 0; this.attempt = 0;
} }
account.setStatus(nextStatus); account.setStatus(nextStatus);
@ -151,12 +153,12 @@ public class XmppConnection implements Runnable {
tagReader = new XmlReader(wakeLock); tagReader = new XmlReader(wakeLock);
tagWriter = new TagWriter(); tagWriter = new TagWriter();
packetCallbacks.clear(); packetCallbacks.clear();
this.changeStatus(Account.STATUS_CONNECTING); this.changeStatus(Account.State.CONNECTING);
Bundle result = DNSHelper.getSRVRecord(account.getServer()); Bundle result = DNSHelper.getSRVRecord(account.getServer());
ArrayList<Parcelable> values = result.getParcelableArrayList("values"); ArrayList<Parcelable> values = result.getParcelableArrayList("values");
if ("timeout".equals(result.getString("error"))) { if ("timeout".equals(result.getString("error"))) {
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": dns timeout"); Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": dns timeout");
this.changeStatus(Account.STATUS_OFFLINE); this.changeStatus(Account.State.OFFLINE);
return; return;
} else if (values != null) { } else if (values != null) {
int i = 0; int i = 0;
@ -197,7 +199,7 @@ public class XmppConnection implements Runnable {
} }
} }
if (socketError) { if (socketError) {
this.changeStatus(Account.STATUS_SERVER_NOT_FOUND); this.changeStatus(Account.State.SERVER_NOT_FOUND);
if (wakeLock.isHeld()) { if (wakeLock.isHeld()) {
try { try {
wakeLock.release(); wakeLock.release();
@ -212,7 +214,7 @@ public class XmppConnection implements Runnable {
} else { } else {
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
+ ": timeout in DNS resolution"); + ": timeout in DNS resolution");
changeStatus(Account.STATUS_OFFLINE); changeStatus(Account.State.OFFLINE);
return; return;
} }
OutputStream out = socket.getOutputStream(); OutputStream out = socket.getOutputStream();
@ -236,7 +238,7 @@ public class XmppConnection implements Runnable {
socket.close(); socket.close();
} }
} catch (UnknownHostException e) { } catch (UnknownHostException e) {
this.changeStatus(Account.STATUS_SERVER_NOT_FOUND); this.changeStatus(Account.State.SERVER_NOT_FOUND);
if (wakeLock.isHeld()) { if (wakeLock.isHeld()) {
try { try {
wakeLock.release(); wakeLock.release();
@ -245,7 +247,7 @@ public class XmppConnection implements Runnable {
} }
} catch (final IOException | XmlPullParserException e) { } catch (final IOException | XmlPullParserException e) {
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage()); Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage());
this.changeStatus(Account.STATUS_OFFLINE); this.changeStatus(Account.State.OFFLINE);
if (wakeLock.isHeld()) { if (wakeLock.isHeld()) {
try { try {
wakeLock.release(); wakeLock.release();
@ -254,7 +256,7 @@ public class XmppConnection implements Runnable {
} }
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage()); Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage());
this.changeStatus(Account.STATUS_OFFLINE); this.changeStatus(Account.State.OFFLINE);
Log.d(Config.LOGTAG, "compression exception " + e.getMessage()); Log.d(Config.LOGTAG, "compression exception " + e.getMessage());
if (wakeLock.isHeld()) { if (wakeLock.isHeld()) {
try { try {
@ -293,13 +295,15 @@ public class XmppConnection implements Runnable {
Log.e(Config.LOGTAG, String.valueOf(e)); Log.e(Config.LOGTAG, String.valueOf(e));
} }
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": logged in"); Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": logged in");
account.setKey(Account.PINNED_MECHANISM_KEY,
String.valueOf(saslMechanism.getPriority()));
tagReader.reset(); tagReader.reset();
sendStartStream(); sendStartStream();
processStream(tagReader.readTag()); processStream(tagReader.readTag());
break; break;
} else if (nextTag.isStart("failure")) { } else if (nextTag.isStart("failure")) {
tagReader.readElement(nextTag); tagReader.readElement(nextTag);
changeStatus(Account.STATUS_UNAUTHORIZED); changeStatus(Account.State.UNAUTHORIZED);
} else if (nextTag.isStart("challenge")) { } else if (nextTag.isStart("challenge")) {
final String challenge = tagReader.readElement(nextTag).getContent(); final String challenge = tagReader.readElement(nextTag).getContent();
final Element response = new Element("response"); final Element response = new Element("response");
@ -376,7 +380,7 @@ public class XmppConnection implements Runnable {
tagReader.readElement(nextTag); tagReader.readElement(nextTag);
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": resumption failed"); Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": resumption failed");
streamId = null; streamId = null;
if (account.getStatus() != Account.STATUS_ONLINE) { if (account.getStatus() != Account.State.ONLINE) {
sendBindRequest(); sendBindRequest();
} }
} else if (nextTag.isStart("iq")) { } else if (nextTag.isStart("iq")) {
@ -388,8 +392,8 @@ public class XmppConnection implements Runnable {
} }
nextTag = tagReader.readTag(); nextTag = tagReader.readTag();
} }
if (account.getStatus() == Account.STATUS_ONLINE) { if (account.getStatus() == Account.State.ONLINE) {
account. setStatus(Account.STATUS_OFFLINE); account. setStatus(Account.State.OFFLINE);
if (statusListener != null) { if (statusListener != null) {
statusListener.onStatusChanged(account); statusListener.onStatusChanged(account);
} }
@ -407,7 +411,7 @@ public class XmppConnection implements Runnable {
public void onIqPacketReceived(Account account, IqPacket packet) { public void onIqPacketReceived(Account account, IqPacket packet) {
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
+ ": online with resource " + account.getResource()); + ": online with resource " + account.getResource());
changeStatus(Account.STATUS_ONLINE); changeStatus(Account.State.ONLINE);
} }
}); });
} }
@ -592,12 +596,13 @@ public class XmppConnection implements Runnable {
} }
sslSocket.setEnabledProtocols(supportProtocols); sslSocket.setEnabledProtocols(supportProtocols);
if (verifier != null if (verifier != null
&& !verifier.verify(account.getServer().getDomainpart(), && !verifier.verify(account.getServer().getDomainpart(),
sslSocket.getSession())) { sslSocket.getSession())) {
sslSocket.close(); account.setStatus(Account.State.SECURITY_ERROR);
throw new IOException("host mismatch in TLS connection"); sslSocket.close();
} throw new IOException("Host mismatch in TLS connection");
}
tagReader.setInputStream(sslSocket.getInputStream()); tagReader.setInputStream(sslSocket.getInputStream());
tagWriter.setOutputStream(sslSocket.getOutputStream()); tagWriter.setOutputStream(sslSocket.getOutputStream());
sendStartStream(); sendStartStream();
@ -624,7 +629,7 @@ public class XmppConnection implements Runnable {
sendRegistryRequest(); sendRegistryRequest();
} else if (!this.streamFeatures.hasChild("register") } else if (!this.streamFeatures.hasChild("register")
&& account.isOptionSet(Account.OPTION_REGISTER)) { && account.isOptionSet(Account.OPTION_REGISTER)) {
changeStatus(Account.STATUS_REGISTRATION_NOT_SUPPORTED); changeStatus(Account.State.REGISTRATION_NOT_SUPPORTED);
disconnect(true); disconnect(true);
} else if (this.streamFeatures.hasChild("mechanisms") } else if (this.streamFeatures.hasChild("mechanisms")
&& shouldAuthenticate && enabledEncryption) { && shouldAuthenticate && enabledEncryption) {
@ -632,23 +637,33 @@ public class XmppConnection implements Runnable {
.findChild("mechanisms")); .findChild("mechanisms"));
final Element auth = new Element("auth"); final Element auth = new Element("auth");
auth.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-sasl"); auth.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-sasl");
if (mechanisms.contains(ScramSha1.getMechanism())) { if (mechanisms.contains("SCRAM-SHA-1")) {
saslMechanism = new ScramSha1(tagWriter, account, mXmppConnectionService.getRNG()); saslMechanism = new ScramSha1(tagWriter, account, mXmppConnectionService.getRNG());
Log.d(Config.LOGTAG, "Authenticating with " + ScramSha1.getMechanism()); } else if (mechanisms.contains("DIGEST-MD5")) {
auth.setAttribute("mechanism", ScramSha1.getMechanism());
} else if (mechanisms.contains(DigestMd5.getMechanism())) {
Log.d(Config.LOGTAG, "Authenticating with " + DigestMd5.getMechanism());
saslMechanism = new DigestMd5(tagWriter, account, mXmppConnectionService.getRNG()); saslMechanism = new DigestMd5(tagWriter, account, mXmppConnectionService.getRNG());
auth.setAttribute("mechanism", DigestMd5.getMechanism()); } else if (mechanisms.contains("PLAIN")) {
} else if (mechanisms.contains(Plain.getMechanism())) {
Log.d(Config.LOGTAG, "Authenticating with " + Plain.getMechanism());
saslMechanism = new Plain(tagWriter, account); saslMechanism = new Plain(tagWriter, account);
auth.setAttribute("mechanism", Plain.getMechanism());
} }
if (!saslMechanism.getClientFirstMessage().isEmpty()) { final JSONObject keys = account.getKeys();
auth.setContent(saslMechanism.getClientFirstMessage()); try {
} if (keys.has(Account.PINNED_MECHANISM_KEY) &&
tagWriter.writeElement(auth); keys.getInt(Account.PINNED_MECHANISM_KEY) > saslMechanism.getPriority() ) {
Log.e(Config.LOGTAG, "Auth failed. Authentication mechanism " + saslMechanism.getMechanism() +
" has lower priority (" + String.valueOf(saslMechanism.getPriority()) +
") than pinned priority (" + keys.getInt(Account.PINNED_MECHANISM_KEY) +
"). Possible downgrade attack?");
disconnect(true);
account.setStatus(Account.State.SECURITY_ERROR);
}
} catch (final JSONException e) {
Log.d(Config.LOGTAG, "Parse error while checking pinned auth mechanism");
}
Log.d(Config.LOGTAG, "Authenticating with " + saslMechanism.getMechanism());
auth.setAttribute("mechanism", saslMechanism.getMechanism());
if (!saslMechanism.getClientFirstMessage().isEmpty()) {
auth.setContent(saslMechanism.getClientFirstMessage());
}
tagWriter.writeElement(auth);
} else if (this.streamFeatures.hasChild("sm", "urn:xmpp:sm:" } else if (this.streamFeatures.hasChild("sm", "urn:xmpp:sm:"
+ smVersion) + smVersion)
&& streamId != null) { && streamId != null) {
@ -658,6 +673,7 @@ public class XmppConnection implements Runnable {
} else if (this.streamFeatures.hasChild("bind") && shouldBind) { } else if (this.streamFeatures.hasChild("bind") && shouldBind) {
sendBindRequest(); sendBindRequest();
} else { } else {
account.setStatus(Account.State.INCOMPATIBLE_SERVER);
Log.d(Config.LOGTAG, account.getJid().toBareJid() Log.d(Config.LOGTAG, account.getJid().toBareJid()
+ ": incompatible server. disconnecting"); + ": incompatible server. disconnecting");
disconnect(true); disconnect(true);
@ -721,20 +737,20 @@ public class XmppConnection implements Runnable {
if (packet.getType() == IqPacket.TYPE_RESULT) { if (packet.getType() == IqPacket.TYPE_RESULT) {
account.setOption(Account.OPTION_REGISTER, account.setOption(Account.OPTION_REGISTER,
false); false);
changeStatus(Account.STATUS_REGISTRATION_SUCCESSFULL); changeStatus(Account.State.REGISTRATION_SUCCESSFUL);
} else if (packet.hasChild("error") } else if (packet.hasChild("error")
&& (packet.findChild("error") && (packet.findChild("error")
.hasChild("conflict"))) { .hasChild("conflict"))) {
changeStatus(Account.STATUS_REGISTRATION_CONFLICT); changeStatus(Account.State.REGISTRATION_CONFLICT);
} else { } else {
changeStatus(Account.STATUS_REGISTRATION_FAILED); changeStatus(Account.State.REGISTRATION_FAILED);
Log.d(Config.LOGTAG, packet.toString()); Log.d(Config.LOGTAG, packet.toString());
} }
disconnect(true); disconnect(true);
} }
}); });
} else { } else {
changeStatus(Account.STATUS_REGISTRATION_FAILED); changeStatus(Account.State.REGISTRATION_FAILED);
disconnect(true); disconnect(true);
Log.d(Config.LOGTAG, account.getJid().toBareJid() Log.d(Config.LOGTAG, account.getJid().toBareJid()
+ ": could not register. instructions are" + ": could not register. instructions are"

View file

@ -917,7 +917,7 @@ public class JingleConnection implements Downloadable {
} }
public boolean start() { public boolean start() {
if (account.getStatus() == Account.STATUS_ONLINE) { if (account.getStatus() == Account.State.ONLINE) {
if (mJingleStatus == JINGLE_STATUS_INITIATED) { if (mJingleStatus == JINGLE_STATUS_INITIATED) {
new Thread(new Runnable() { new Thread(new Runnable() {

View file

@ -141,6 +141,8 @@
<string name="account_status_regis_conflict">Username already in use</string> <string name="account_status_regis_conflict">Username already in use</string>
<string name="account_status_regis_success">Registration completed</string> <string name="account_status_regis_success">Registration completed</string>
<string name="account_status_regis_not_sup">Server does not support registration</string> <string name="account_status_regis_not_sup">Server does not support registration</string>
<string name="account_status_security_error">Security error</string>
<string name="account_status_incompatible_server">Incompatible server</string>
<string name="encryption_choice_none">Plain text</string> <string name="encryption_choice_none">Plain text</string>
<string name="encryption_choice_otr">OTR</string> <string name="encryption_choice_otr">OTR</string>
<string name="encryption_choice_pgp">OpenPGP</string> <string name="encryption_choice_pgp">OpenPGP</string>