explicitly search for namespaces when processing stream features
This commit is contained in:
parent
b792563fad
commit
a717917b3d
|
@ -66,4 +66,8 @@ public abstract class SaslMechanism {
|
||||||
public String getResponse(final String challenge) throws AuthenticationException {
|
public String getResponse(final String challenge) throws AuthenticationException {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum Version {
|
||||||
|
SASL, SASL_2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ public final class Namespace {
|
||||||
public static final String BLOCKING = "urn:xmpp:blocking";
|
public static final String BLOCKING = "urn:xmpp:blocking";
|
||||||
public static final String ROSTER = "jabber:iq:roster";
|
public static final String ROSTER = "jabber:iq:roster";
|
||||||
public static final String REGISTER = "jabber:iq:register";
|
public static final String REGISTER = "jabber:iq:register";
|
||||||
|
public static final String REGISTER_STREAM_FEATURE = "http://jabber.org/features/iq-register";
|
||||||
public static final String BYTE_STREAMS = "http://jabber.org/protocol/bytestreams";
|
public static final String BYTE_STREAMS = "http://jabber.org/protocol/bytestreams";
|
||||||
public static final String HTTP_UPLOAD = "urn:xmpp:http:upload:0";
|
public static final String HTTP_UPLOAD = "urn:xmpp:http:upload:0";
|
||||||
public static final String HTTP_UPLOAD_LEGACY = "urn:xmpp:http:upload";
|
public static final String HTTP_UPLOAD_LEGACY = "urn:xmpp:http:upload";
|
||||||
|
@ -15,6 +16,7 @@ public final class Namespace {
|
||||||
public static final String DATA = "jabber:x:data";
|
public static final String DATA = "jabber:x:data";
|
||||||
public static final String OOB = "jabber:x:oob";
|
public static final String OOB = "jabber:x:oob";
|
||||||
public static final String SASL = "urn:ietf:params:xml:ns:xmpp-sasl";
|
public static final String SASL = "urn:ietf:params:xml:ns:xmpp-sasl";
|
||||||
|
public static final String SASL_2 = "urn:xmpp:sasl:1";
|
||||||
public static final String TLS = "urn:ietf:params:xml:ns:xmpp-tls";
|
public static final String TLS = "urn:ietf:params:xml:ns:xmpp-tls";
|
||||||
public static final String PUBSUB = "http://jabber.org/protocol/pubsub";
|
public static final String PUBSUB = "http://jabber.org/protocol/pubsub";
|
||||||
public static final String PUBSUB_PUBLISH_OPTIONS = PUBSUB + "#publish-options";
|
public static final String PUBSUB_PUBLISH_OPTIONS = PUBSUB + "#publish-options";
|
||||||
|
|
|
@ -848,40 +848,64 @@ public class XmppConnection implements Runnable {
|
||||||
|
|
||||||
private void processStreamFeatures(final Tag currentTag) throws IOException {
|
private void processStreamFeatures(final Tag currentTag) throws IOException {
|
||||||
this.streamFeatures = tagReader.readElement(currentTag);
|
this.streamFeatures = tagReader.readElement(currentTag);
|
||||||
final boolean isSecure = features.encryptionEnabled || Config.ALLOW_NON_TLS_CONNECTIONS || account.isOnion();
|
Log.d(Config.LOGTAG, this.streamFeatures.toString());
|
||||||
|
final boolean isSecure =
|
||||||
|
features.encryptionEnabled || Config.ALLOW_NON_TLS_CONNECTIONS || account.isOnion();
|
||||||
final boolean needsBinding = !isBound && !account.isOptionSet(Account.OPTION_REGISTER);
|
final boolean needsBinding = !isBound && !account.isOptionSet(Account.OPTION_REGISTER);
|
||||||
if (this.streamFeatures.hasChild("starttls") && !features.encryptionEnabled) {
|
if (this.streamFeatures.hasChild("starttls", Namespace.TLS)
|
||||||
|
&& !features.encryptionEnabled) {
|
||||||
sendStartTLS();
|
sendStartTLS();
|
||||||
} else if (this.streamFeatures.hasChild("register") && account.isOptionSet(Account.OPTION_REGISTER)) {
|
} else if (this.streamFeatures.hasChild("register", Namespace.REGISTER_STREAM_FEATURE)
|
||||||
|
&& account.isOptionSet(Account.OPTION_REGISTER)) {
|
||||||
if (isSecure) {
|
if (isSecure) {
|
||||||
register();
|
register();
|
||||||
} else {
|
} else {
|
||||||
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": unable to find STARTTLS for registration process " + XmlHelper.printElementNames(this.streamFeatures));
|
Log.d(
|
||||||
|
Config.LOGTAG,
|
||||||
|
account.getJid().asBareJid()
|
||||||
|
+ ": unable to find STARTTLS for registration process "
|
||||||
|
+ XmlHelper.printElementNames(this.streamFeatures));
|
||||||
throw new StateChangingException(Account.State.INCOMPATIBLE_SERVER);
|
throw new StateChangingException(Account.State.INCOMPATIBLE_SERVER);
|
||||||
}
|
}
|
||||||
} else if (!this.streamFeatures.hasChild("register") && account.isOptionSet(Account.OPTION_REGISTER)) {
|
} else if (!this.streamFeatures.hasChild("register", Namespace.REGISTER_STREAM_FEATURE)
|
||||||
|
&& account.isOptionSet(Account.OPTION_REGISTER)) {
|
||||||
throw new StateChangingException(Account.State.REGISTRATION_NOT_SUPPORTED);
|
throw new StateChangingException(Account.State.REGISTRATION_NOT_SUPPORTED);
|
||||||
} else if (this.streamFeatures.hasChild("mechanisms") && shouldAuthenticate && isSecure) {
|
} else if (this.streamFeatures.hasChild("mechanisms", Namespace.SASL_2)
|
||||||
authenticate();
|
&& shouldAuthenticate
|
||||||
} else if (this.streamFeatures.hasChild("sm", "urn:xmpp:sm:" + smVersion) && streamId != null) {
|
&& isSecure) {
|
||||||
|
authenticate(SaslMechanism.Version.SASL_2);
|
||||||
|
} else if (this.streamFeatures.hasChild("mechanisms", Namespace.SASL)
|
||||||
|
&& shouldAuthenticate
|
||||||
|
&& isSecure) {
|
||||||
|
authenticate(SaslMechanism.Version.SASL);
|
||||||
|
} else if (this.streamFeatures.hasChild("sm", "urn:xmpp:sm:" + smVersion)
|
||||||
|
&& streamId != null) {
|
||||||
if (Config.EXTENDED_SM_LOGGING) {
|
if (Config.EXTENDED_SM_LOGGING) {
|
||||||
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": resuming after stanza #" + stanzasReceived);
|
Log.d(
|
||||||
|
Config.LOGTAG,
|
||||||
|
account.getJid().asBareJid()
|
||||||
|
+ ": resuming after stanza #"
|
||||||
|
+ stanzasReceived);
|
||||||
}
|
}
|
||||||
final ResumePacket resume = new ResumePacket(this.streamId, stanzasReceived, smVersion);
|
final ResumePacket resume = new ResumePacket(this.streamId, stanzasReceived, smVersion);
|
||||||
this.mSmCatchupMessageCounter.set(0);
|
this.mSmCatchupMessageCounter.set(0);
|
||||||
this.mWaitingForSmCatchup.set(true);
|
this.mWaitingForSmCatchup.set(true);
|
||||||
this.tagWriter.writeStanzaAsync(resume);
|
this.tagWriter.writeStanzaAsync(resume);
|
||||||
} else if (needsBinding) {
|
} else if (needsBinding) {
|
||||||
if (this.streamFeatures.hasChild("bind") && isSecure) {
|
if (this.streamFeatures.hasChild("bind", Namespace.BIND) && isSecure) {
|
||||||
sendBindRequest();
|
sendBindRequest();
|
||||||
} else {
|
} else {
|
||||||
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": unable to find bind feature " + XmlHelper.printElementNames(this.streamFeatures));
|
Log.d(
|
||||||
|
Config.LOGTAG,
|
||||||
|
account.getJid().asBareJid()
|
||||||
|
+ ": unable to find bind feature "
|
||||||
|
+ XmlHelper.printElementNames(this.streamFeatures));
|
||||||
throw new StateChangingException(Account.State.INCOMPATIBLE_SERVER);
|
throw new StateChangingException(Account.State.INCOMPATIBLE_SERVER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void authenticate() throws IOException {
|
private void authenticate(final SaslMechanism.Version version) throws IOException {
|
||||||
final List<String> mechanisms = extractMechanisms(streamFeatures.findChild("mechanisms"));
|
final List<String> mechanisms = extractMechanisms(streamFeatures.findChild("mechanisms"));
|
||||||
final Element auth = new Element("auth", Namespace.SASL);
|
final Element auth = new Element("auth", Namespace.SASL);
|
||||||
if (mechanisms.contains(External.MECHANISM) && account.getPrivateKeyAlias() != null) {
|
if (mechanisms.contains(External.MECHANISM) && account.getPrivateKeyAlias() != null) {
|
||||||
|
|
Loading…
Reference in a new issue