diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java index 6bde0fe78..f8fe76a2f 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java +++ b/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) { diff --git a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java index 2d371ab6f..dcf5b9a50 100644 --- a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java +++ b/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; + } } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 0c49b9e75..912f5db3f 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/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 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(); diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java index 8bcbe998b..606f5cc0d 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ b/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 diff --git a/src/main/java/eu/siacs/conversations/xmpp/forms/Data.java b/src/main/java/eu/siacs/conversations/xmpp/forms/Data.java index c81c5a1f3..e22eeada5 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/forms/Data.java +++ b/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"); } + }