make x509 verification node world readable

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java  | 21 
src/main/java/eu/siacs/conversations/generator/IqGenerator.java          | 19 
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java | 49 
src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java   |  2 
src/main/java/eu/siacs/conversations/xmpp/forms/Data.java                | 12 
5 files changed, 88 insertions(+), 15 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java 🔗

@@ -533,8 +533,23 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
 			Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + ": publish verification for device "+getOwnDeviceId());
 			mXmppConnectionService.sendIqPacket(account, packet, new OnIqPacketReceived() {
 				@Override
-				public void onIqPacketReceived(Account account, IqPacket packet) {
-					publishDeviceBundle(signedPreKeyRecord, preKeyRecords, announceAfter, wipe);
+				public void onIqPacketReceived(final Account account, IqPacket packet) {
+					String node = AxolotlService.PEP_VERIFICATION+":"+getOwnDeviceId();
+					Bundle pubsubOptions = new Bundle();
+					pubsubOptions.putString("pubsub#access_model","open");
+					mXmppConnectionService.pushNodeConfiguration(account, account.getJid().toBareJid(), node, pubsubOptions, new XmppConnectionService.OnConfigurationPushed() {
+						@Override
+						public void onPushSucceeded() {
+							Log.d(Config.LOGTAG,getLogprefix(account) + "configured verification node to be world readable");
+							publishDeviceBundle(signedPreKeyRecord, preKeyRecords, announceAfter, wipe);
+						}
+
+						@Override
+						public void onPushFailed() {
+							Log.d(Config.LOGTAG,getLogprefix(account) + "unable to set access model on verification node");
+							publishDeviceBundle(signedPreKeyRecord, preKeyRecords, announceAfter, wipe);
+						}
+					});
 				}
 			});
 		} catch (Exception  e) {
@@ -661,7 +676,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
 		IqPacket publish = mXmppConnectionService.getIqGenerator().publishBundles(
 				signedPreKeyRecord, axolotlStore.getIdentityKeyPair().getPublicKey(),
 				preKeyRecords, getOwnDeviceId());
-		Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + ": Bundle " + getOwnDeviceId() + " in PEP not current. Publishing: " + publish);
+		Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + ": Bundle " + getOwnDeviceId() + " in PEP not current. Publishing...");
 		mXmppConnectionService.sendIqPacket(account, publish, new OnIqPacketReceived() {
 			@Override
 			public void onIqPacketReceived(Account account, IqPacket packet) {

src/main/java/eu/siacs/conversations/generator/IqGenerator.java 🔗

@@ -396,4 +396,23 @@ public class IqGenerator extends AbstractGenerator {
 		options.putString("muc#roomconfig_whois", "anyone");
 		return options;
 	}
+
+	public IqPacket requestPubsubConfiguration(Jid jid, String node) {
+		return pubsubConfiguration(jid, node, null);
+	}
+
+	public IqPacket publishPubsubConfiguration(Jid jid, String node, Data data) {
+		return pubsubConfiguration(jid,node,data);
+	}
+
+	private IqPacket pubsubConfiguration(Jid jid, String node, Data data) {
+		IqPacket packet = new IqPacket(data == null ? IqPacket.TYPE.GET : IqPacket.TYPE.SET);
+		packet.setTo(jid);
+		Element pubsub = packet.addChild("pubsub","http://jabber.org/protocol/pubsub#owner");
+		Element configure = pubsub.addChild("configure").setAttribute("node",node);
+		if (data != null) {
+			configure.addChild(data);
+		}
+		return packet;
+	}
 }

src/main/java/eu/siacs/conversations/services/XmppConnectionService.java 🔗

@@ -1831,9 +1831,10 @@ public class XmppConnectionService extends Service {
 	}
 
 	public void updateKeyInAccount(final Account account, final String alias) {
-		Log.d(Config.LOGTAG, "update key in account " + alias);
+		Log.d(Config.LOGTAG, account.getJid().toBareJid()+": update key in account " + alias);
 		try {
 			X509Certificate[] chain = KeyChain.getCertificateChain(XmppConnectionService.this, alias);
+			Log.d(Config.LOGTAG,account.getJid().toBareJid()+" loaded certificate chain");
 			Pair<Jid, String> info = CryptoHelper.extractJidAndName(chain[0]);
 			if (account.getJid().toBareJid().equals(info.first)) {
 				account.setPrivateKeyAlias(alias);
@@ -1841,7 +1842,7 @@ public class XmppConnectionService extends Service {
 				databaseBackend.updateAccount(account);
 				if (Config.X509_VERIFICATION) {
 					try {
-						getMemorizingTrustManager().getNonInteractive(account.getJid().getDomainpart()).checkClientTrusted(chain, "RSA");
+						getMemorizingTrustManager().getNonInteractive().checkClientTrusted(chain, "RSA");
 					} catch (CertificateException e) {
 						showErrorToastInUi(R.string.certificate_chain_is_not_trusted);
 					}
@@ -2454,7 +2455,7 @@ public class XmppConnectionService extends Service {
 				joinMuc(conversation, new OnConferenceJoined() {
 					@Override
 					public void onConferenceJoined(final Conversation conversation) {
-						pushConferenceConfiguration(conversation, IqGenerator.defaultRoomConfiguration(), new OnConferenceOptionsPushed() {
+						pushConferenceConfiguration(conversation, IqGenerator.defaultRoomConfiguration(), new OnConfigurationPushed() {
 							@Override
 							public void onPushSucceeded() {
 								if (subject != null && !subject.trim().isEmpty()) {
@@ -2538,7 +2539,38 @@ public class XmppConnectionService extends Service {
 		});
 	}
 
-	public void pushConferenceConfiguration(final Conversation conversation, final Bundle options, final OnConferenceOptionsPushed callback) {
+	public void pushNodeConfiguration(Account account, final Jid jid, final String node, final Bundle options, final OnConfigurationPushed callback) {
+		sendIqPacket(account, mIqGenerator.requestPubsubConfiguration(jid,node), new OnIqPacketReceived() {
+			@Override
+			public void onIqPacketReceived(Account account, IqPacket packet) {
+				if (packet.getType() == IqPacket.TYPE.RESULT) {
+					Element pubsub = packet.findChild("pubsub","http://jabber.org/protocol/pubsub#owner");
+					Element configuration = pubsub == null ? null : pubsub.findChild("configure");
+					Element x = configuration == null ? null : configuration.findChild("x","jabber:x:data");
+					if (x != null) {
+						Data data = Data.parse(x);
+						data.submit(options);
+						sendIqPacket(account, mIqGenerator.publishPubsubConfiguration(jid, node, data), new OnIqPacketReceived() {
+							@Override
+							public void onIqPacketReceived(Account account, IqPacket packet) {
+								if (packet.getType() == IqPacket.TYPE.RESULT) {
+									callback.onPushSucceeded();
+								} else {
+									Log.d(Config.LOGTAG,packet.toString());
+								}
+							}
+						});
+					} else {
+						callback.onPushFailed();
+					}
+				} else {
+					callback.onPushFailed();
+				}
+			}
+		});
+	}
+
+	public void pushConferenceConfiguration(final Conversation conversation, final Bundle options, final OnConfigurationPushed callback) {
 		IqPacket request = new IqPacket(IqPacket.TYPE.GET);
 		request.setTo(conversation.getJid().toBareJid());
 		request.query("http://jabber.org/protocol/muc#owner");
@@ -2547,12 +2579,7 @@ public class XmppConnectionService extends Service {
 			public void onIqPacketReceived(Account account, IqPacket packet) {
 				if (packet.getType() == IqPacket.TYPE.RESULT) {
 					Data data = Data.parse(packet.query().findChild("x", "jabber:x:data"));
-					for (Field field : data.getFields()) {
-						if (options.containsKey(field.getFieldName())) {
-							field.setValue(options.getString(field.getFieldName()));
-						}
-					}
-					data.submit();
+					data.submit(options);
 					IqPacket set = new IqPacket(IqPacket.TYPE.SET);
 					set.setTo(conversation.getJid().toBareJid());
 					set.query("http://jabber.org/protocol/muc#owner").addChild(data);
@@ -3933,7 +3960,7 @@ public class XmppConnectionService extends Service {
 		void onConferenceJoined(Conversation conversation);
 	}
 
-	public interface OnConferenceOptionsPushed {
+	public interface OnConfigurationPushed {
 		void onPushSucceeded();
 
 		void onPushFailed();

src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java 🔗

@@ -40,7 +40,7 @@ import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdat
 import eu.siacs.conversations.services.XmppConnectionService.OnMucRosterUpdate;
 import eu.siacs.conversations.xmpp.jid.Jid;
 
-public class ConferenceDetailsActivity extends XmppActivity implements OnConversationUpdate, OnMucRosterUpdate, XmppConnectionService.OnAffiliationChanged, XmppConnectionService.OnRoleChanged, XmppConnectionService.OnConferenceOptionsPushed {
+public class ConferenceDetailsActivity extends XmppActivity implements OnConversationUpdate, OnMucRosterUpdate, XmppConnectionService.OnAffiliationChanged, XmppConnectionService.OnRoleChanged, XmppConnectionService.OnConfigurationPushed {
 	public static final String ACTION_VIEW_MUC = "view_muc";
 
 	private static final float INACTIVE_ALPHA = 0.4684f; //compromise between dark and light theme

src/main/java/eu/siacs/conversations/xmpp/forms/Data.java 🔗

@@ -1,5 +1,7 @@
 package eu.siacs.conversations.xmpp.forms;
 
+import android.os.Bundle;
+
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
@@ -55,6 +57,15 @@ public class Data extends Element {
 		field.setValues(values);
 	}
 
+	public void submit(Bundle options) {
+		for (Field field : getFields()) {
+			if (options.containsKey(field.getFieldName())) {
+				field.setValue(options.getString(field.getFieldName()));
+			}
+		}
+		submit();
+	}
+
 	public void submit() {
 		this.setAttribute("type","submit");
 		removeUnnecessaryChildren();
@@ -96,4 +107,5 @@ public class Data extends Element {
 	public String getTitle() {
 		return findChildContent("title");
 	}
+
 }