process authorization id in case full jid changes

This commit is contained in:
Daniel Gultsch 2022-08-30 09:31:06 +02:00
parent 3fac7d4992
commit 4f92ba880b
2 changed files with 81 additions and 55 deletions

View file

@ -118,8 +118,7 @@ public interface Jid extends Comparable<Jid>, Serializable, CharSequence {
static Jid ofEscaped(CharSequence jid) {
try {
return new WrappedJid(JidCreate.from(jid));
} catch (XmppStringprepException e) {
e.printStackTrace();
} catch (final XmppStringprepException e) {
throw new IllegalArgumentException(e);
}
}

View file

@ -470,61 +470,10 @@ public class XmppConnection implements Runnable {
switchOverToTls();
} else if (nextTag.isStart("success")) {
final Element success = tagReader.readElement(nextTag);
final SaslMechanism.Version version;
try {
version = SaslMechanism.Version.of(success);
} catch (final IllegalArgumentException e) {
throw new StateChangingException(Account.State.INCOMPATIBLE_SERVER);
}
final String challenge;
if (version == SaslMechanism.Version.SASL) {
challenge = success.getContent();
} else if (version == SaslMechanism.Version.SASL_2) {
challenge = success.findChildContent("additional-data");
} else {
throw new AssertionError("Missing implementation for " + version);
}
try {
saslMechanism.getResponse(challenge);
} catch (final SaslMechanism.AuthenticationException e) {
Log.e(Config.LOGTAG, String.valueOf(e));
throw new StateChangingException(Account.State.UNAUTHORIZED);
}
Log.d(
Config.LOGTAG,
account.getJid().asBareJid().toString()
+ ": logged in (using "
+ version
+ ")");
account.setKey(
Account.PINNED_MECHANISM_KEY, String.valueOf(saslMechanism.getPriority()));
if (version == SaslMechanism.Version.SASL_2) {
final String authorizationIdentifier =
success.findChildContent("authorization-identifier");
Log.d(
Config.LOGTAG,
account.getJid().asBareJid()
+ ": SASL 2.0 authorization identifier was "
+ authorizationIdentifier);
final Element resumed = success.findChild("resumed", "urn:xmpp:sm:3");
final Element failed = success.findChild("failed", "urn:xmpp:sm:3");
if (resumed != null && streamId != null) {
processResumed(resumed);
} else if (failed != null) {
processFailed(failed, false); // wait for new stream features
}
}
if (version == SaslMechanism.Version.SASL) {
tagReader.reset();
sendStartStream();
final Tag tag = tagReader.readTag();
if (tag != null && tag.isStart("stream")) {
processStream();
} else {
throw new StateChangingException(Account.State.STREAM_OPENING_ERROR);
}
if (processSuccess(success)) {
break;
}
} else if (nextTag.isStart("failure", Namespace.TLS)) {
throw new StateChangingException(Account.State.TLS_ERROR);
} else if (nextTag.isStart("failure")) {
@ -679,6 +628,84 @@ public class XmppConnection implements Runnable {
}
}
private boolean processSuccess(final Element success) throws IOException, XmlPullParserException {
final SaslMechanism.Version version;
try {
version = SaslMechanism.Version.of(success);
} catch (final IllegalArgumentException e) {
throw new StateChangingException(Account.State.INCOMPATIBLE_SERVER);
}
final String challenge;
if (version == SaslMechanism.Version.SASL) {
challenge = success.getContent();
} else if (version == SaslMechanism.Version.SASL_2) {
challenge = success.findChildContent("additional-data");
} else {
throw new AssertionError("Missing implementation for " + version);
}
try {
saslMechanism.getResponse(challenge);
} catch (final SaslMechanism.AuthenticationException e) {
Log.e(Config.LOGTAG, String.valueOf(e));
throw new StateChangingException(Account.State.UNAUTHORIZED);
}
Log.d(
Config.LOGTAG,
account.getJid().asBareJid().toString()
+ ": logged in (using "
+ version
+ ")");
account.setKey(
Account.PINNED_MECHANISM_KEY, String.valueOf(saslMechanism.getPriority()));
if (version == SaslMechanism.Version.SASL_2) {
final String authorizationIdentifier =
success.findChildContent("authorization-identifier");
final Jid authorizationJid;
try {
authorizationJid = Strings.isNullOrEmpty(authorizationIdentifier) ? null : Jid.ofEscaped(authorizationIdentifier);
} catch (final IllegalArgumentException e) {
Log.d(Config.LOGTAG,account.getJid().asBareJid()+": SASL 2.0 authorization identifier was not a valid jid");
throw new StateChangingException(Account.State.BIND_FAILURE);
}
if (authorizationJid == null) {
throw new StateChangingException(Account.State.BIND_FAILURE);
}
Log.d(
Config.LOGTAG,
account.getJid().asBareJid()
+ ": SASL 2.0 authorization identifier was "
+ authorizationJid);
if (!account.getJid().getDomain().equals(authorizationJid.getDomain())) {
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": server tried to re-assign domain to " + authorizationJid.getDomain());
throw new StateChangingError(Account.State.BIND_FAILURE);
}
if (authorizationJid.isFullJid() && account.setJid(authorizationJid)) {
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": jid changed during SASL 2.0. updating database");
mXmppConnectionService.databaseBackend.updateAccount(account);
}
final Element resumed = success.findChild("resumed", "urn:xmpp:sm:3");
final Element failed = success.findChild("failed", "urn:xmpp:sm:3");
if (resumed != null && streamId != null) {
processResumed(resumed);
} else if (failed != null) {
processFailed(failed, false); // wait for new stream features
}
}
if (version == SaslMechanism.Version.SASL) {
tagReader.reset();
sendStartStream();
final Tag tag = tagReader.readTag();
if (tag != null && tag.isStart("stream")) {
processStream();
return true;
} else {
throw new StateChangingException(Account.State.STREAM_OPENING_ERROR);
}
} else {
return false;
}
}
private void processResumed(final Element resumed) throws StateChangingException {
this.inSmacksSession = true;
this.isBound = true;