check sasl success message no response

This commit is contained in:
Daniel Gultsch 2024-02-10 10:20:40 +01:00
parent 75f42d680d
commit 6ce052a337
No known key found for this signature in database
GPG key ID: F43D18AD2A0982C2

View file

@ -623,6 +623,8 @@ public class XmppConnection implements Runnable {
} else if (nextTag.isStart("challenge")) { } else if (nextTag.isStart("challenge")) {
final Element challenge = tagReader.readElement(nextTag); final Element challenge = tagReader.readElement(nextTag);
processChallenge(challenge); processChallenge(challenge);
} else if (!LoginInfo.isSuccess(this.loginInfo)) {
throw new StateChangingException(Account.State.INCOMPATIBLE_SERVER);
} else if (this.streamId != null } else if (this.streamId != null
&& nextTag.isStart("resumed", Namespace.STREAM_MANAGEMENT)) { && nextTag.isStart("resumed", Namespace.STREAM_MANAGEMENT)) {
final Element resumed = tagReader.readElement(nextTag); final Element resumed = tagReader.readElement(nextTag);
@ -730,9 +732,13 @@ public class XmppConnection implements Runnable {
} else { } else {
throw new AssertionError("Missing implementation for " + version); throw new AssertionError("Missing implementation for " + version);
} }
final LoginInfo currentLoginInfo = this.loginInfo;
if (currentLoginInfo == null || LoginInfo.isSuccess(currentLoginInfo)) {
throw new StateChangingException(Account.State.INCOMPATIBLE_SERVER);
}
try { try {
response.setContent( response.setContent(
this.loginInfo.saslMechanism.getResponse( currentLoginInfo.saslMechanism.getResponse(
challenge.getContent(), sslSocketOrNull(socket))); challenge.getContent(), sslSocketOrNull(socket)));
} catch (final SaslMechanism.AuthenticationException e) { } catch (final SaslMechanism.AuthenticationException e) {
// TODO: Send auth abort tag. // TODO: Send auth abort tag.
@ -764,9 +770,9 @@ public class XmppConnection implements Runnable {
throw new AssertionError("Missing implementation for " + version); throw new AssertionError("Missing implementation for " + version);
} }
try { try {
currentSaslMechanism.getResponse(challenge, sslSocketOrNull(socket)); currentLoginInfo.success(challenge, sslSocketOrNull(socket));
} catch (final SaslMechanism.AuthenticationException e) { } catch (final SaslMechanism.AuthenticationException e) {
Log.e(Config.LOGTAG, String.valueOf(e)); Log.e(Config.LOGTAG, account.getJid().asBareJid() + ": authentication failure ", e);
throw new StateChangingException(Account.State.UNAUTHORIZED); throw new StateChangingException(Account.State.UNAUTHORIZED);
} }
Log.d( Log.d(
@ -1481,7 +1487,7 @@ public class XmppConnection implements Runnable {
authenticate(SaslMechanism.Version.SASL); authenticate(SaslMechanism.Version.SASL);
} else if (this.streamFeatures.hasChild("sm", Namespace.STREAM_MANAGEMENT) } else if (this.streamFeatures.hasChild("sm", Namespace.STREAM_MANAGEMENT)
&& isSecure && isSecure
&& loginInfo != null && LoginInfo.isSuccess(loginInfo)
&& streamId != null && streamId != null
&& !inSmacksSession) { && !inSmacksSession) {
if (Config.EXTENDED_SM_LOGGING) { if (Config.EXTENDED_SM_LOGGING) {
@ -1498,7 +1504,7 @@ public class XmppConnection implements Runnable {
} else if (needsBinding) { } else if (needsBinding) {
if (this.streamFeatures.hasChild("bind", Namespace.BIND) if (this.streamFeatures.hasChild("bind", Namespace.BIND)
&& isSecure && isSecure
&& loginInfo != null) { && LoginInfo.isSuccess(loginInfo)) {
sendBindRequest(); sendBindRequest();
} else { } else {
Log.d( Log.d(
@ -2767,6 +2773,7 @@ public class XmppConnection implements Runnable {
public final SaslMechanism saslMechanism; public final SaslMechanism saslMechanism;
public final SaslMechanism.Version saslVersion; public final SaslMechanism.Version saslVersion;
public final List<String> inlineBindFeatures; public final List<String> inlineBindFeatures;
public final AtomicBoolean success = new AtomicBoolean(false);
private LoginInfo( private LoginInfo(
final SaslMechanism saslMechanism, final SaslMechanism saslMechanism,
@ -2785,6 +2792,23 @@ public class XmppConnection implements Runnable {
public static SaslMechanism mechanism(final LoginInfo loginInfo) { public static SaslMechanism mechanism(final LoginInfo loginInfo) {
return loginInfo == null ? null : loginInfo.saslMechanism; return loginInfo == null ? null : loginInfo.saslMechanism;
} }
public void success(final String challenge, final SSLSocket sslSocket)
throws SaslMechanism.AuthenticationException {
final var response = this.saslMechanism.getResponse(challenge, sslSocket);
if (!Strings.isNullOrEmpty(response)) {
throw new SaslMechanism.AuthenticationException(
"processing success yielded another response");
}
if (this.success.compareAndSet(false, true)) {
return;
}
throw new SaslMechanism.AuthenticationException("Process 'success' twice");
}
public static boolean isSuccess(final LoginInfo loginInfo) {
return loginInfo != null && loginInfo.success.get();
}
} }
private static class StreamId { private static class StreamId {