aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/eu/siacs/conversations/crypto/OtrService.java40
-rw-r--r--src/main/java/eu/siacs/conversations/entities/Account.java89
-rw-r--r--src/main/java/eu/siacs/conversations/entities/MucOptions.java1
-rw-r--r--src/main/java/eu/siacs/conversations/generator/MessageGenerator.java4
-rw-r--r--src/main/java/eu/siacs/conversations/parser/MessageParser.java39
-rw-r--r--src/main/java/eu/siacs/conversations/services/XmppConnectionService.java6
-rw-r--r--src/main/java/eu/siacs/conversations/ui/WelcomeActivity.java6
-rw-r--r--src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java19
8 files changed, 109 insertions, 95 deletions
diff --git a/src/main/java/eu/siacs/conversations/crypto/OtrService.java b/src/main/java/eu/siacs/conversations/crypto/OtrService.java
index af11756f..3663cd3b 100644
--- a/src/main/java/eu/siacs/conversations/crypto/OtrService.java
+++ b/src/main/java/eu/siacs/conversations/crypto/OtrService.java
@@ -53,28 +53,30 @@ public class OtrService extends OtrCryptoEngineImpl implements OtrEngineHost {
this.mXmppConnectionService = service;
}
- private KeyPair loadKey(JSONObject keys) {
+ private KeyPair loadKey(final JSONObject keys) {
if (keys == null) {
return null;
}
- try {
- BigInteger x = new BigInteger(keys.getString("otr_x"), 16);
- BigInteger y = new BigInteger(keys.getString("otr_y"), 16);
- BigInteger p = new BigInteger(keys.getString("otr_p"), 16);
- BigInteger q = new BigInteger(keys.getString("otr_q"), 16);
- BigInteger g = new BigInteger(keys.getString("otr_g"), 16);
- KeyFactory keyFactory = KeyFactory.getInstance("DSA");
- DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(y, p, q, g);
- DSAPrivateKeySpec privateKeySpec = new DSAPrivateKeySpec(x, p, q, g);
- PublicKey publicKey = keyFactory.generatePublic(pubKeySpec);
- PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
- return new KeyPair(publicKey, privateKey);
- } catch (JSONException e) {
- return null;
- } catch (NoSuchAlgorithmException e) {
- return null;
- } catch (InvalidKeySpecException e) {
- return null;
+ synchronized (keys) {
+ try {
+ BigInteger x = new BigInteger(keys.getString("otr_x"), 16);
+ BigInteger y = new BigInteger(keys.getString("otr_y"), 16);
+ BigInteger p = new BigInteger(keys.getString("otr_p"), 16);
+ BigInteger q = new BigInteger(keys.getString("otr_q"), 16);
+ BigInteger g = new BigInteger(keys.getString("otr_g"), 16);
+ KeyFactory keyFactory = KeyFactory.getInstance("DSA");
+ DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(y, p, q, g);
+ DSAPrivateKeySpec privateKeySpec = new DSAPrivateKeySpec(x, p, q, g);
+ PublicKey publicKey = keyFactory.generatePublic(pubKeySpec);
+ PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
+ return new KeyPair(publicKey, privateKey);
+ } catch (JSONException e) {
+ return null;
+ } catch (NoSuchAlgorithmException e) {
+ return null;
+ } catch (InvalidKeySpecException e) {
+ return null;
+ }
}
}
diff --git a/src/main/java/eu/siacs/conversations/entities/Account.java b/src/main/java/eu/siacs/conversations/entities/Account.java
index 9218e524..7d60dcf7 100644
--- a/src/main/java/eu/siacs/conversations/entities/Account.java
+++ b/src/main/java/eu/siacs/conversations/entities/Account.java
@@ -203,7 +203,7 @@ public class Account extends AbstractEntity {
protected int options = 0;
protected String rosterVersion;
protected State status = State.OFFLINE;
- protected JSONObject keys = new JSONObject();
+ protected final JSONObject keys;
protected String avatar;
protected String displayName = null;
protected String hostname = null;
@@ -238,11 +238,13 @@ public class Account extends AbstractEntity {
this.password = password;
this.options = options;
this.rosterVersion = rosterVersion;
+ JSONObject tmp;
try {
- this.keys = new JSONObject(keys);
- } catch (final JSONException ignored) {
- this.keys = new JSONObject();
+ tmp = new JSONObject(keys);
+ } catch(JSONException e) {
+ tmp = new JSONObject();
}
+ this.keys = tmp;
this.avatar = avatar;
this.displayName = displayName;
this.hostname = hostname;
@@ -391,15 +393,28 @@ public class Account extends AbstractEntity {
}
public String getKey(final String name) {
- return this.keys.optString(name, null);
+ synchronized (this.keys) {
+ return this.keys.optString(name, null);
+ }
}
- public boolean setKey(final String keyName, final String keyValue) {
+ public int getKeyAsInt(final String name, int defaultValue) {
+ String key = getKey(name);
try {
- this.keys.put(keyName, keyValue);
- return true;
- } catch (final JSONException e) {
- return false;
+ return key == null ? defaultValue : Integer.parseInt(key);
+ } catch (NumberFormatException e) {
+ return defaultValue;
+ }
+ }
+
+ public boolean setKey(final String keyName, final String keyValue) {
+ synchronized (this.keys) {
+ try {
+ this.keys.put(keyName, keyValue);
+ return true;
+ } catch (final JSONException e) {
+ return false;
+ }
}
}
@@ -419,7 +434,9 @@ public class Account extends AbstractEntity {
values.put(SERVER, jid.getDomainpart());
values.put(PASSWORD, password);
values.put(OPTIONS, options);
- values.put(KEYS, this.keys.toString());
+ synchronized (this.keys) {
+ values.put(KEYS, this.keys.toString());
+ }
values.put(ROSTERVERSION, rosterVersion);
values.put(AVATAR, avatar);
values.put(DISPLAY_NAME, displayName);
@@ -496,54 +513,42 @@ public class Account extends AbstractEntity {
}
public String getPgpSignature() {
- try {
- if (keys.has(KEY_PGP_SIGNATURE) && !"null".equals(keys.getString(KEY_PGP_SIGNATURE))) {
- return keys.getString(KEY_PGP_SIGNATURE);
- } else {
- return null;
- }
- } catch (final JSONException e) {
- return null;
- }
+ return getKey(KEY_PGP_SIGNATURE);
}
public boolean setPgpSignature(String signature) {
- try {
- keys.put(KEY_PGP_SIGNATURE, signature);
- } catch (JSONException e) {
- return false;
- }
- return true;
+ return setKey(KEY_PGP_SIGNATURE, signature);
}
public boolean unsetPgpSignature() {
- try {
- keys.put(KEY_PGP_SIGNATURE, JSONObject.NULL);
- } catch (JSONException e) {
- return false;
+ synchronized (this.keys) {
+ return keys.remove(KEY_PGP_SIGNATURE) != null;
}
- return true;
}
public long getPgpId() {
- if (keys.has(KEY_PGP_ID)) {
- try {
- return keys.getLong(KEY_PGP_ID);
- } catch (JSONException e) {
+ synchronized (this.keys) {
+ if (keys.has(KEY_PGP_ID)) {
+ try {
+ return keys.getLong(KEY_PGP_ID);
+ } catch (JSONException e) {
+ return 0;
+ }
+ } else {
return 0;
}
- } else {
- return 0;
}
}
public boolean setPgpSignId(long pgpID) {
- try {
- keys.put(KEY_PGP_ID, pgpID);
- } catch (JSONException e) {
- return false;
+ synchronized (this.keys) {
+ try {
+ keys.put(KEY_PGP_ID, pgpID);
+ } catch (JSONException e) {
+ return false;
+ }
+ return true;
}
- return true;
}
public Roster getRoster() {
diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java
index 9d54a86d..fa6afcfa 100644
--- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java
+++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java
@@ -127,7 +127,6 @@ public class MucOptions {
UNKNOWN
}
- public static final String STATUS_CODE_ROOM_CONFIG_CHANGED = "104";
public static final String STATUS_CODE_SELF_PRESENCE = "110";
public static final String STATUS_CODE_ROOM_CREATED = "201";
public static final String STATUS_CODE_BANNED = "301";
diff --git a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java
index 5ef47a33..f5c701cc 100644
--- a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java
+++ b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java
@@ -183,6 +183,10 @@ public class MessageGenerator extends AbstractGenerator {
packet.setFrom(conversation.getAccount().getJid());
Element x = packet.addChild("x", "jabber:x:conference");
x.setAttribute("jid", conversation.getJid().toBareJid().toString());
+ String password = conversation.getMucOptions().getPassword();
+ if (password != null) {
+ x.setAttribute("password",password);
+ }
return packet;
}
diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java
index b4553012..81b68ed9 100644
--- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java
+++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java
@@ -587,26 +587,27 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
}
}
if (conversation != null && mucUserElement != null && from.isBareJid()) {
- if (mucUserElement.hasChild("status")) {
- for (Element child : mucUserElement.getChildren()) {
- if (child.getName().equals("status")
- && MucOptions.STATUS_CODE_ROOM_CONFIG_CHANGED.equals(child.getAttribute("code"))) {
- mXmppConnectionService.fetchConferenceConfiguration(conversation);
- }
- }
- } else if (mucUserElement.hasChild("item")) {
- for(Element child : mucUserElement.getChildren()) {
- if ("item".equals(child.getName())) {
- MucOptions.User user = AbstractParser.parseItem(conversation,child);
- Log.d(Config.LOGTAG,account.getJid()+": changing affiliation for "
- +user.getRealJid()+" to "+user.getAffiliation()+" in "
- +conversation.getJid().toBareJid());
- if (!user.realJidMatchesAccount()) {
- conversation.getMucOptions().addUser(user);
- mXmppConnectionService.getAvatarService().clear(conversation);
- mXmppConnectionService.updateMucRosterUi();
- mXmppConnectionService.updateConversationUi();
+ for (Element child : mucUserElement.getChildren()) {
+ if ("status".equals(child.getName())) {
+ try {
+ int code = Integer.parseInt(child.getAttribute("code"));
+ if ((code >= 170 && code <= 174) || (code >= 102 && code <= 104)) {
+ mXmppConnectionService.fetchConferenceConfiguration(conversation);
+ break;
}
+ } catch (Exception e) {
+ //ignored
+ }
+ } else if ("item".equals(child.getName())) {
+ MucOptions.User user = AbstractParser.parseItem(conversation,child);
+ Log.d(Config.LOGTAG,account.getJid()+": changing affiliation for "
+ +user.getRealJid()+" to "+user.getAffiliation()+" in "
+ +conversation.getJid().toBareJid());
+ if (!user.realJidMatchesAccount()) {
+ conversation.getMucOptions().addUser(user);
+ mXmppConnectionService.getAvatarService().clear(conversation);
+ mXmppConnectionService.updateMucRosterUi();
+ mXmppConnectionService.updateConversationUi();
}
}
}
diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
index f6298ea2..5650b894 100644
--- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
+++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
@@ -1135,7 +1135,8 @@ public class XmppConnectionService extends Service {
}
if (packet != null) {
- if (account.getXmppConnection().getFeatures().sm() || conversation.getMode() == Conversation.MODE_MULTI) {
+ if (account.getXmppConnection().getFeatures().sm()
+ || (conversation.getMode() == Conversation.MODE_MULTI && message.getCounterpart().isBareJid())) {
message.setStatus(Message.STATUS_UNSEND);
} else {
message.setStatus(Message.STATUS_SEND);
@@ -1177,7 +1178,8 @@ public class XmppConnectionService extends Service {
if (resend) {
if (packet != null && addToConversation) {
- if (account.getXmppConnection().getFeatures().sm() || conversation.getMode() == Conversation.MODE_MULTI) {
+ if (account.getXmppConnection().getFeatures().sm()
+ || (conversation.getMode() == Conversation.MODE_MULTI && message.getCounterpart().isBareJid())) {
markMessage(message, Message.STATUS_UNSEND);
} else {
markMessage(message, Message.STATUS_SEND);
diff --git a/src/main/java/eu/siacs/conversations/ui/WelcomeActivity.java b/src/main/java/eu/siacs/conversations/ui/WelcomeActivity.java
index 3c837b94..59d58db5 100644
--- a/src/main/java/eu/siacs/conversations/ui/WelcomeActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/WelcomeActivity.java
@@ -1,5 +1,6 @@
package eu.siacs.conversations.ui;
+import android.app.ActionBar;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -16,6 +17,11 @@ public class WelcomeActivity extends Activity {
if (getResources().getBoolean(R.bool.portrait_only)) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
+ final ActionBar ab = getActionBar();
+ if (ab != null) {
+ ab.setDisplayShowHomeEnabled(false);
+ ab.setDisplayHomeAsUpEnabled(false);
+ }
super.onCreate(savedInstanceState);
setContentView(R.layout.welcome);
final Button createAccount = (Button) findViewById(R.id.create_account);
diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
index ab92535a..383e990d 100644
--- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
+++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
@@ -852,18 +852,13 @@ public class XmppConnection implements Runnable {
saslMechanism = new Anonymous(tagWriter, account, mXmppConnectionService.getRNG());
}
if (saslMechanism != null) {
- final JSONObject keys = account.getKeys();
- try {
- if (keys.has(Account.PINNED_MECHANISM_KEY) &&
- 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?");
- throw new SecurityException();
- }
- } catch (final JSONException e) {
- Log.d(Config.LOGTAG, "Parse error while checking pinned auth mechanism");
+ final int pinnedMechanism = account.getKeyAsInt(Account.PINNED_MECHANISM_KEY, -1);
+ if (pinnedMechanism > saslMechanism.getPriority()) {
+ Log.e(Config.LOGTAG, "Auth failed. Authentication mechanism " + saslMechanism.getMechanism() +
+ " has lower priority (" + String.valueOf(saslMechanism.getPriority()) +
+ ") than pinned priority (" + pinnedMechanism +
+ "). Possible downgrade attack?");
+ throw new SecurityException();
}
Log.d(Config.LOGTAG, account.getJid().toString() + ": Authenticating with " + saslMechanism.getMechanism());
auth.setAttribute("mechanism", saslMechanism.getMechanism());