From 126e8ef08cb1146976da157b20947466ed3e2303 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 24 Sep 2022 14:58:49 +0200 Subject: [PATCH] refactor sasl 2 authentication code --- .../conversations/xmpp/XmppConnection.java | 84 +++++++++++-------- 1 file changed, 48 insertions(+), 36 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 5e4a6c0ed..2ff1fc406 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -1290,43 +1290,10 @@ public class XmppConnection implements Runnable { authenticate.setContent(firstMessage); } } else if (version == SaslMechanism.Version.SASL_2) { - authenticate = new Element("authenticate", Namespace.SASL_2); - if (!Strings.isNullOrEmpty(firstMessage)) { - authenticate.addChild("initial-response").setContent(firstMessage); - } - final Element userAgent = authenticate.addChild("user-agent"); - userAgent.setAttribute("id", account.getUuid()); - userAgent - .addChild("software") - .setContent(mXmppConnectionService.getString(R.string.app_name)); - if (!PhoneHelper.isEmulator()) { - userAgent - .addChild("device") - .setContent(String.format("%s %s", Build.MANUFACTURER, Build.MODEL)); - } final Element inline = authElement.findChild("inline", Namespace.SASL_2); - final boolean inlineStreamManagement = - inline != null && inline.hasChild("sm", "urn:xmpp:sm:3"); - final Element inlineBind2 = - inline != null ? inline.findChild("bind", Namespace.BIND2) : null; - final Element inlineBind2Inline = - inlineBind2 != null ? inlineBind2.findChild("inline", Namespace.BIND2) : null; - if (inlineBind2 != null) { - final Element bind = - generateBindRequest( - inlineBind2Inline == null - ? Collections.emptyList() - : Collections2.transform( - inlineBind2Inline.getChildren(), - c -> c == null ? null : c.getAttribute("var"))); - authenticate.addChild(bind); - } - if (inlineStreamManagement && streamId != null) { - final ResumePacket resume = new ResumePacket(this.streamId, stanzasReceived); - this.mSmCatchupMessageCounter.set(0); - this.mWaitingForSmCatchup.set(true); - authenticate.addChild(resume); - } + final boolean sm = inline != null && inline.hasChild("sm", "urn:xmpp:sm:3"); + final Collection bindFeatures = bindFeatures(inline); + authenticate = generateAuthenticationRequest(firstMessage, bindFeatures, sm); } else { throw new AssertionError("Missing implementation for " + version); } @@ -1342,6 +1309,51 @@ public class XmppConnection implements Runnable { tagWriter.writeElement(authenticate); } + private static Collection bindFeatures(final Element inline) { + final Element inlineBind2 = + inline != null ? inline.findChild("bind", Namespace.BIND2) : null; + final Element inlineBind2Inline = + inlineBind2 != null ? inlineBind2.findChild("inline", Namespace.BIND2) : null; + if (inlineBind2 == null) { + return null; + } + if (inlineBind2Inline == null) { + return Collections.emptyList(); + } + return Collections2.transform( + inlineBind2Inline.getChildren(), c -> c == null ? null : c.getAttribute("var")); + } + + private Element generateAuthenticationRequest( + final String firstMessage, + final Collection bind, + final boolean inlineStreamManagement) { + final Element authenticate = new Element("authenticate", Namespace.SASL_2); + if (!Strings.isNullOrEmpty(firstMessage)) { + authenticate.addChild("initial-response").setContent(firstMessage); + } + final Element userAgent = authenticate.addChild("user-agent"); + userAgent.setAttribute("id", account.getUuid()); + userAgent + .addChild("software") + .setContent(mXmppConnectionService.getString(R.string.app_name)); + if (!PhoneHelper.isEmulator()) { + userAgent + .addChild("device") + .setContent(String.format("%s %s", Build.MANUFACTURER, Build.MODEL)); + } + if (bind != null) { + authenticate.addChild(generateBindRequest(bind)); + } + if (inlineStreamManagement && streamId != null) { + final ResumePacket resume = new ResumePacket(this.streamId, stanzasReceived); + this.mSmCatchupMessageCounter.set(0); + this.mWaitingForSmCatchup.set(true); + authenticate.addChild(resume); + } + return authenticate; + } + private Element generateBindRequest(final Collection bindFeatures) { Log.d(Config.LOGTAG, "inline bind features: " + bindFeatures); final Element bind = new Element("bind", Namespace.BIND2);