From c1d2b6690ce7f2a89a477f1076be1449a414bfa6 Mon Sep 17 00:00:00 2001 From: Christian Schneppe Date: Wed, 10 May 2017 21:01:57 +0200 Subject: unified all account state exceptions --- .../java/de/pixart/messenger/entities/Account.java | 12 ++- .../pixart/messenger/xmpp/OnIqPacketReceived.java | 2 +- .../de/pixart/messenger/xmpp/XmppConnection.java | 94 +++++++--------------- src/main/res/values-de/strings.xml | 2 +- src/main/res/values/strings.xml | 4 +- 5 files changed, 45 insertions(+), 69 deletions(-) (limited to 'src') diff --git a/src/main/java/de/pixart/messenger/entities/Account.java b/src/main/java/de/pixart/messenger/entities/Account.java index 18e991367..4907d26b6 100644 --- a/src/main/java/de/pixart/messenger/entities/Account.java +++ b/src/main/java/de/pixart/messenger/entities/Account.java @@ -120,9 +120,11 @@ public class Account extends AbstractEntity { REGISTRATION_CONFLICT(true), REGISTRATION_SUCCESSFUL, REGISTRATION_NOT_SUPPORTED(true), - SECURITY_ERROR(true), + TLS_ERROR(true), INCOMPATIBLE_SERVER(true), TOR_NOT_AVAILABLE(true), + DOWNGRADE_ATTACK(true), + SESSION_FAILURE(true), BIND_FAILURE(true), HOST_UNKNOWN(true), REGISTRATION_PLEASE_WAIT(true), @@ -170,14 +172,18 @@ public class Account extends AbstractEntity { return R.string.account_status_regis_success; case REGISTRATION_NOT_SUPPORTED: return R.string.account_status_regis_not_sup; - case SECURITY_ERROR: - return R.string.account_status_security_error; + case TLS_ERROR: + return R.string.account_status_tls_error; case INCOMPATIBLE_SERVER: return R.string.account_status_incompatible_server; case TOR_NOT_AVAILABLE: return R.string.account_status_tor_unavailable; case BIND_FAILURE: return R.string.account_status_bind_failure; + case SESSION_FAILURE: + return R.string.session_failure; + case DOWNGRADE_ATTACK: + return R.string.downgrade_attack; case HOST_UNKNOWN: return R.string.account_status_host_unknown; case POLICY_VIOLATION: diff --git a/src/main/java/de/pixart/messenger/xmpp/OnIqPacketReceived.java b/src/main/java/de/pixart/messenger/xmpp/OnIqPacketReceived.java index 797eba155..2922b0226 100644 --- a/src/main/java/de/pixart/messenger/xmpp/OnIqPacketReceived.java +++ b/src/main/java/de/pixart/messenger/xmpp/OnIqPacketReceived.java @@ -4,5 +4,5 @@ import de.pixart.messenger.entities.Account; import de.pixart.messenger.xmpp.stanzas.IqPacket; public interface OnIqPacketReceived extends PacketReceived { - public void onIqPacketReceived(Account account, IqPacket packet); + void onIqPacketReceived(Account account, IqPacket packet); } diff --git a/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java b/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java index f7b826030..df690368b 100644 --- a/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java +++ b/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java @@ -327,7 +327,7 @@ public class XmppConnection implements Runnable { final SSLSession session = ((SSLSocket) localSocket).getSession(); if (!tlsFactoryVerifier.verifier.verify(account.getServer().getDomainpart(), session)) { Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": TLS certificate verification failed"); - throw new SecurityException(); + throw new StateChangingException(Account.State.TLS_ERROR); } } catch (KeyManagementException e) { features.encryptionEnabled = false; @@ -416,7 +416,7 @@ public class XmppConnection implements Runnable { if (!tlsFactoryVerifier.verifier.verify(account.getServer().getDomainpart(), ((SSLSocket) localSocket).getSession())) { Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": TLS certificate verification failed"); - throw new SecurityException(); + throw new StateChangingException(Account.State.TLS_ERROR); } } @@ -425,7 +425,7 @@ public class XmppConnection implements Runnable { } else { localSocket.close(); } - } catch (final SecurityException e) { + } catch (final StateChangingException e) { throw e; } catch (InterruptedException e) { Log.d(Config.LOGTAG,account.getJid().toBareJid()+": thread was interrupted before beginning stream"); @@ -439,28 +439,14 @@ public class XmppConnection implements Runnable { } } processStream(); - } catch (final java.lang.SecurityException e) { - this.changeStatus(Account.State.MISSING_INTERNET_PERMISSION); - } catch (final RegistrationNotSupportedException e) { - this.changeStatus(Account.State.REGISTRATION_NOT_SUPPORTED); - } catch (final IncompatibleServerException e) { - this.changeStatus(Account.State.INCOMPATIBLE_SERVER); } catch (final SecurityException e) { - this.changeStatus(Account.State.SECURITY_ERROR); - } catch (final UnauthorizedException e) { - this.changeStatus(Account.State.UNAUTHORIZED); - } catch (final PaymentRequiredException e) { - this.changeStatus(Account.State.PAYMENT_REQUIRED); + this.changeStatus(Account.State.MISSING_INTERNET_PERMISSION); + } catch (final StateChangingException e) { + this.changeStatus(e.state); } catch (final UnknownHostException | ConnectException e) { this.changeStatus(Account.State.SERVER_NOT_FOUND); } catch (final SocksSocketFactory.SocksProxyNotFoundException e) { this.changeStatus(Account.State.TOR_NOT_AVAILABLE); - } catch (final StreamErrorHostUnknown e) { - this.changeStatus(Account.State.HOST_UNKNOWN); - } catch (final StreamErrorPolicyViolation e) { - this.changeStatus(Account.State.POLICY_VIOLATION); - } catch (final StreamError e) { - this.changeStatus(Account.State.STREAM_ERROR); } catch (final IOException | XmlPullParserException | NoSuchAlgorithmException e) { Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage()); this.changeStatus(Account.State.OFFLINE); @@ -559,8 +545,8 @@ public class XmppConnection implements Runnable { try { saslMechanism.getResponse(challenge); } catch (final SaslMechanism.AuthenticationException e) { - disconnect(true); Log.e(Config.LOGTAG, String.valueOf(e)); + throw new StateChangingException(Account.State.UNAUTHORIZED); } Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": logged in"); account.setKey(Account.PINNED_MECHANISM_KEY, @@ -582,9 +568,9 @@ public class XmppConnection implements Runnable { && text.contains("renew") && Config.MAGIC_CREATE_DOMAIN != null && text.contains(Config.MAGIC_CREATE_DOMAIN)) { - throw new PaymentRequiredException(); + throw new StateChangingException(Account.State.PAYMENT_REQUIRED); } else { - throw new UnauthorizedException(); + throw new StateChangingException(Account.State.UNAUTHORIZED); } } else if (nextTag.isStart("challenge")) { final String challenge = tagReader.readElement(nextTag).getContent(); @@ -807,7 +793,7 @@ public class XmppConnection implements Runnable { } } if (callback != null) { - callback.onIqPacketReceived(account, packet); + throw new StateChangingException(Account.State.TLS_ERROR); } } } @@ -849,7 +835,7 @@ public class XmppConnection implements Runnable { if (!tlsFactoryVerifier.verifier.verify(account.getServer().getDomainpart(), sslSocket.getSession())) { Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": TLS certificate verification failed"); - throw new SecurityException(); + throw new StateChangingException(Account.State.TLS_ERROR); } tagReader.setInputStream(sslSocket.getInputStream()); tagWriter.setOutputStream(sslSocket.getOutputStream()); @@ -878,10 +864,10 @@ public class XmppConnection implements Runnable { if (features.encryptionEnabled || Config.ALLOW_NON_TLS_CONNECTIONS) { sendRegistryRequest(); } else { - throw new IncompatibleServerException(); + throw new StateChangingException(Account.State.INCOMPATIBLE_SERVER); } } else if (!this.streamFeatures.hasChild("register") && account.isOptionSet(Account.OPTION_REGISTER)) { - throw new RegistrationNotSupportedException(); + throw new StateChangingException(Account.State.REGISTRATION_NOT_SUPPORTED); } else if (this.streamFeatures.hasChild("mechanisms") && shouldAuthenticate && (features.encryptionEnabled || Config.ALLOW_NON_TLS_CONNECTIONS)) { @@ -898,7 +884,7 @@ public class XmppConnection implements Runnable { if (this.streamFeatures.hasChild("bind")) { sendBindRequest(); } else { - throw new IncompatibleServerException(); + throw new StateChangingException(Account.State.INCOMPATIBLE_SERVER); } } } @@ -928,7 +914,7 @@ public class XmppConnection implements Runnable { " has lower priority (" + String.valueOf(saslMechanism.getPriority()) + ") than pinned priority (" + pinnedMechanism + "). Possible downgrade attack?"); - throw new SecurityException(); + throw new StateChangingException(Account.State.DOWNGRADE_ATTACK); } Log.d(Config.LOGTAG, account.getJid().toString() + ": Authenticating with " + saslMechanism.getMechanism()); auth.setAttribute("mechanism", saslMechanism.getMechanism()); @@ -937,7 +923,7 @@ public class XmppConnection implements Runnable { } tagWriter.writeElement(auth); } else { - throw new IncompatibleServerException(); + throw new StateChangingException(Account.State.INCOMPATIBLE_SERVER); } } @@ -1072,8 +1058,7 @@ public class XmppConnection implements Runnable { } else { Log.d(Config.LOGTAG, account.getJid() + ": disconnecting because of bind failure (" + packet.toString()); } - forceCloseSocket(); - changeStatus(Account.State.BIND_FAILURE); + throw new StateChangingError(Account.State.BIND_FAILURE); } }); } @@ -1115,8 +1100,7 @@ public class XmppConnection implements Runnable { if (packet.getType() == IqPacket.TYPE.RESULT) { sendPostBindInitialization(); } else if (packet.getType() != IqPacket.TYPE.TIMEOUT) { - Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": could not init sessions"); - disconnect(true); + throw new StateChangingError(Account.State.SESSION_FAILURE); } } }); @@ -1296,12 +1280,12 @@ public class XmppConnection implements Runnable { + account.getResource() + ")"); throw new IOException(); } else if (streamError.hasChild("host-unknown")) { - throw new StreamErrorHostUnknown(); + throw new StateChangingException(Account.State.HOST_UNKNOWN); } else if (streamError.hasChild("policy-violation")) { - throw new StreamErrorPolicyViolation(); + throw new StateChangingException(Account.State.POLICY_VIOLATION); } else { Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": stream error " + streamError.toString()); - throw new StreamError(); + throw new StateChangingException(Account.State.STREAM_ERROR); } } @@ -1592,36 +1576,20 @@ public class XmppConnection implements Runnable { return Identity.UNKNOWN; } - private class UnauthorizedException extends IOException { - - } - - private class SecurityException extends IOException { - - } - - private class IncompatibleServerException extends IOException { - - } - - private class StreamErrorHostUnknown extends StreamError { - - } - - private class StreamErrorPolicyViolation extends StreamError { - - } - - private class StreamError extends IOException { - - } - - private class PaymentRequiredException extends IOException { + private class StateChangingError extends Error { + private final Account.State state; + public StateChangingError(Account.State state) { + this.state = state; + } } - private class RegistrationNotSupportedException extends IOException { + private class StateChangingException extends IOException { + private final Account.State state; + public StateChangingException(Account.State state) { + this.state = state; + } } public enum Identity { diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml index 0ec2bfd25..1102a95a9 100644 --- a/src/main/res/values-de/strings.xml +++ b/src/main/res/values-de/strings.xml @@ -140,7 +140,7 @@ Benutzername wird bereits verwendet Registrierung abgeschlossen Der Server unterstützt keine Registrierung - Sicherheitsfehler + TLS-Fehler Inkompatibler Server Unverschlüsselt OTR diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index ad6d67d33..375179423 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -150,7 +150,7 @@ Username already in use Registration completed Server does not support registration - Security error + TLS error Policy violation Incompatible server Stream error @@ -777,4 +777,6 @@ Show hostname and port settings when setting up an account Extended connection settings Retry decryption + Session failure + Downgrade attack -- cgit v1.2.3