From 0408d06dd199703d9b88fc15cfbeeca9e93a72af Mon Sep 17 00:00:00 2001 From: Christian Schneppe Date: Mon, 1 Oct 2018 14:48:54 +0200 Subject: introduced error code for server not opening stream after auth or starttls --- .../java/de/pixart/messenger/entities/Account.java | 387 +++++++++++---------- .../de/pixart/messenger/xmpp/XmppConnection.java | 7 +- src/main/res/values/strings.xml | 1 + 3 files changed, 200 insertions(+), 195 deletions(-) (limited to 'src/main') diff --git a/src/main/java/de/pixart/messenger/entities/Account.java b/src/main/java/de/pixart/messenger/entities/Account.java index 6fd4c1c05..9e3711535 100644 --- a/src/main/java/de/pixart/messenger/entities/Account.java +++ b/src/main/java/de/pixart/messenger/entities/Account.java @@ -59,197 +59,34 @@ public class Account extends AbstractEntity { public static final int OPTION_USECOMPRESSION = 3; public static final int OPTION_MAGIC_CREATE = 4; public static final int OPTION_REQUIRES_ACCESS_MODE_CHANGE = 5; - public static final int OPTION_LOGGED_IN_SUCCESSFULLY = 6; + public static final int OPTION_LOGGED_IN_SUCCESSFULLY = 6; public static final int OPTION_HTTP_UPLOAD_AVAILABLE = 7; + private static final String KEY_PGP_SIGNATURE = "pgp_signature"; + private static final String KEY_PGP_ID = "pgp_id"; public final HashSet> inProgressDiscoFetches = new HashSet<>(); - - public boolean httpUploadAvailable(long filesize) { - return xmppConnection != null && (xmppConnection.getFeatures().httpUpload(filesize) || xmppConnection.getFeatures().p1S3FileTransfer()); - } - - public boolean httpUploadAvailable() { - return isOptionSet(OPTION_HTTP_UPLOAD_AVAILABLE) || httpUploadAvailable(0); - } - - public void setDisplayName(String displayName) { - this.displayName = displayName; - } - - public String getDisplayName() { - return displayName; - } - - public XmppConnection.Identity getServerIdentity() { - if (xmppConnection == null) { - return XmppConnection.Identity.UNKNOWN; - } else { - return xmppConnection.getServerIdentity(); - } - } - - public Contact getSelfContact() { - return getRoster().getContact(jid); - } - - public boolean hasPendingPgpIntent(Conversation conversation) { - return pgpDecryptionService != null && pgpDecryptionService.hasPendingIntent(conversation); - } - - public boolean isPgpDecryptionServiceConnected() { - return pgpDecryptionService != null && pgpDecryptionService.isConnected(); - } - - public boolean setShowErrorNotification(boolean newValue) { - boolean oldValue = showErrorNotification(); - setKey("show_error", Boolean.toString(newValue)); - return newValue != oldValue; - } - - public boolean showErrorNotification() { - String key = getKey("show_error"); - return key == null || Boolean.parseBoolean(key); - } - - public boolean isEnabled() { - return !isOptionSet(Account.OPTION_DISABLED); - } - - public enum State { - DISABLED(false, false), - OFFLINE(false), - CONNECTING(false), - ONLINE(false), - NO_INTERNET(false), - UNAUTHORIZED, - SERVER_NOT_FOUND, - REGISTRATION_SUCCESSFUL(false), - REGISTRATION_FAILED(true, false), - REGISTRATION_WEB(true, false), - REGISTRATION_CONFLICT(true, false), - REGISTRATION_NOT_SUPPORTED(true, false), - REGISTRATION_PLEASE_WAIT(true, false), - REGISTRATION_PASSWORD_TOO_WEAK(true, false), - TLS_ERROR, - INCOMPATIBLE_SERVER, - TOR_NOT_AVAILABLE, - DOWNGRADE_ATTACK, - SESSION_FAILURE, - BIND_FAILURE, - HOST_UNKNOWN, - STREAM_ERROR, - POLICY_VIOLATION, - PAYMENT_REQUIRED, - MISSING_INTERNET_PERMISSION(false); - - private final boolean isError; - private final boolean attemptReconnect; - - public boolean isError() { - return this.isError; - } - - public boolean isAttemptReconnect() { - return this.attemptReconnect; - } - - State(final boolean isError) { - this(isError, true); - } - - State(final boolean isError, final boolean reconnect) { - this.isError = isError; - this.attemptReconnect = reconnect; - } - - State() { - this(true, true); - } - - public int getReadableId() { - switch (this) { - case DISABLED: - return R.string.account_status_disabled; - case ONLINE: - return R.string.account_status_online; - case CONNECTING: - return R.string.account_status_connecting; - case OFFLINE: - return R.string.account_status_offline; - case UNAUTHORIZED: - return R.string.account_status_unauthorized; - case SERVER_NOT_FOUND: - return R.string.account_status_not_found; - case NO_INTERNET: - return R.string.account_status_no_internet; - case REGISTRATION_FAILED: - return R.string.account_status_regis_fail; - case REGISTRATION_WEB: - return R.string.account_status_regis_web; - case REGISTRATION_CONFLICT: - return R.string.account_status_regis_conflict; - case REGISTRATION_SUCCESSFUL: - return R.string.account_status_regis_success; - case REGISTRATION_NOT_SUPPORTED: - return R.string.account_status_regis_not_sup; - 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.sasl_downgrade; - case HOST_UNKNOWN: - return R.string.account_status_host_unknown; - case POLICY_VIOLATION: - return R.string.account_status_policy_violation; - case REGISTRATION_PLEASE_WAIT: - return R.string.registration_please_wait; - case REGISTRATION_PASSWORD_TOO_WEAK: - return R.string.registration_password_too_weak; - case STREAM_ERROR: - return R.string.account_status_stream_error; - case PAYMENT_REQUIRED: - return R.string.payment_required; - case MISSING_INTERNET_PERMISSION: - return R.string.missing_internet_permission; - default: - return R.string.account_status_unknown; - } - } - } - + protected final JSONObject keys; + private final Roster roster = new Roster(this); + private final Collection blocklist = new CopyOnWriteArraySet<>(); public List pendingConferenceJoins = new CopyOnWriteArrayList<>(); public List pendingConferenceLeaves = new CopyOnWriteArrayList<>(); - - private static final String KEY_PGP_SIGNATURE = "pgp_signature"; - private static final String KEY_PGP_ID = "pgp_id"; - protected Jid jid; protected String password; protected int options = 0; - private String rosterVersion; protected State status = State.OFFLINE; - protected final JSONObject keys; protected String resource; protected String avatar; - protected String displayName = null; protected String hostname = null; protected int port = 5222; protected boolean online = false; private OtrService mOtrService = null; + private String rosterVersion; + private String displayName = null; private AxolotlService axolotlService = null; private PgpDecryptionService pgpDecryptionService = null; private XmppConnection xmppConnection = null; private long mEndGracePeriod = 0L; private String otrFingerprint; - private final Roster roster = new Roster(this); private List bookmarks = new CopyOnWriteArrayList<>(); - private final Collection blocklist = new CopyOnWriteArraySet<>(); private Presence.Status presenceStatus = Presence.Status.ONLINE; private String presenceStatusMessage = null; @@ -308,6 +145,57 @@ public class Account extends AbstractEntity { cursor.getString(cursor.getColumnIndex(STATUS_MESSAGE))); } + public boolean httpUploadAvailable(long filesize) { + return xmppConnection != null && (xmppConnection.getFeatures().httpUpload(filesize) || xmppConnection.getFeatures().p1S3FileTransfer()); + } + + public boolean httpUploadAvailable() { + return isOptionSet(OPTION_HTTP_UPLOAD_AVAILABLE) || httpUploadAvailable(0); + } + + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public XmppConnection.Identity getServerIdentity() { + if (xmppConnection == null) { + return XmppConnection.Identity.UNKNOWN; + } else { + return xmppConnection.getServerIdentity(); + } + } + + public Contact getSelfContact() { + return getRoster().getContact(jid); + } + + public boolean hasPendingPgpIntent(Conversation conversation) { + return pgpDecryptionService != null && pgpDecryptionService.hasPendingIntent(conversation); + } + + public boolean isPgpDecryptionServiceConnected() { + return pgpDecryptionService != null && pgpDecryptionService.isConnected(); + } + + public boolean setShowErrorNotification(boolean newValue) { + boolean oldValue = showErrorNotification(); + setKey("show_error", Boolean.toString(newValue)); + return newValue != oldValue; + } + + public boolean showErrorNotification() { + String key = getKey("show_error"); + return key == null || Boolean.parseBoolean(key); + } + + public boolean isEnabled() { + return !isOptionSet(Account.OPTION_DISABLED); + } + public boolean isOptionSet(final int option) { return ((options & (1 << option)) != 0); } @@ -354,27 +242,27 @@ public class Account extends AbstractEntity { this.password = password; } - public void setHostname(String hostname) { - this.hostname = hostname; - } - public String getHostname() { return this.hostname == null ? "" : this.hostname; } + public void setHostname(String hostname) { + this.hostname = hostname; + } + public boolean isOnion() { final String server = getServer(); return server != null && server.endsWith(".onion"); } - public void setPort(int port) { - this.port = port; - } - public int getPort() { return this.port; } + public void setPort(int port) { + this.port = port; + } + public State getStatus() { if (isOptionSet(OPTION_DISABLED)) { return State.DISABLED; @@ -383,14 +271,14 @@ public class Account extends AbstractEntity { } } - public State getTrueStatus() { - return this.status; - } - public void setStatus(final State status) { this.status = status; } + public State getTrueStatus() { + return this.status; + } + public boolean errorStatus() { return getStatus().isError(); } @@ -401,22 +289,22 @@ public class Account extends AbstractEntity { && getXmppConnection().getAttempt() >= 3; } - public void setPresenceStatus(Presence.Status status) { - this.presenceStatus = status; - } - public Presence.Status getPresenceStatus() { return this.presenceStatus; } - public void setPresenceStatusMessage(String message) { - this.presenceStatusMessage = message; + public void setPresenceStatus(Presence.Status status) { + this.presenceStatus = status; } public String getPresenceStatusMessage() { return this.presenceStatusMessage; } + public void setPresenceStatusMessage(String message) { + this.presenceStatusMessage = message; + } + public String getResource() { return jid.getResource(); } @@ -613,7 +501,7 @@ public class Account extends AbstractEntity { return getBookmark(conferenceJid) != null; } - public Bookmark getBookmark(final Jid jid) { + Bookmark getBookmark(final Jid jid) { for (final Bookmark bookmark : this.bookmarks) { if (bookmark.getJid() != null && jid.asBareJid().equals(bookmark.getJid().asBareJid())) { return bookmark; @@ -653,16 +541,17 @@ public class Account extends AbstractEntity { List fingerprints = this.getFingerprints(); String uri = "xmpp:" + this.getJid().asBareJid().toEscapedString(); if (fingerprints.size() > 0) { - return XmppUri.getFingerprintUri(uri,fingerprints,';'); + return XmppUri.getFingerprintUri(uri, fingerprints, ';'); } else { return uri; } } + public String getShareableLink() { List fingerprints = this.getFingerprints(); String uri = Config.inviteUserURL + XmppUri.lameUrlEncode(this.getJid().asBareJid().toEscapedString()); if (fingerprints.size() > 0) { - return XmppUri.getFingerprintUri(uri,fingerprints,'&'); + return XmppUri.getFingerprintUri(uri, fingerprints, '&'); } else { return uri; } @@ -706,4 +595,116 @@ public class Account extends AbstractEntity { public boolean isOnlineAndConnected() { return this.getStatus() == State.ONLINE && this.getXmppConnection() != null; } -} + + public enum State { + DISABLED(false, false), + OFFLINE(false), + CONNECTING(false), + ONLINE(false), + NO_INTERNET(false), + UNAUTHORIZED, + SERVER_NOT_FOUND, + REGISTRATION_SUCCESSFUL(false), + REGISTRATION_FAILED(true, false), + REGISTRATION_WEB(true, false), + REGISTRATION_CONFLICT(true, false), + REGISTRATION_NOT_SUPPORTED(true, false), + REGISTRATION_PLEASE_WAIT(true, false), + REGISTRATION_PASSWORD_TOO_WEAK(true, false), + TLS_ERROR, + INCOMPATIBLE_SERVER, + TOR_NOT_AVAILABLE, + DOWNGRADE_ATTACK, + SESSION_FAILURE, + BIND_FAILURE, + HOST_UNKNOWN, + STREAM_ERROR, + STREAM_OPENING_ERROR, + POLICY_VIOLATION, + PAYMENT_REQUIRED, + MISSING_INTERNET_PERMISSION(false); + + private final boolean isError; + private final boolean attemptReconnect; + + State(final boolean isError) { + this(isError, true); + } + + State(final boolean isError, final boolean reconnect) { + this.isError = isError; + this.attemptReconnect = reconnect; + } + + State() { + this(true, true); + } + + public boolean isError() { + return this.isError; + } + + public boolean isAttemptReconnect() { + return this.attemptReconnect; + } + + public int getReadableId() { + switch (this) { + case DISABLED: + return R.string.account_status_disabled; + case ONLINE: + return R.string.account_status_online; + case CONNECTING: + return R.string.account_status_connecting; + case OFFLINE: + return R.string.account_status_offline; + case UNAUTHORIZED: + return R.string.account_status_unauthorized; + case SERVER_NOT_FOUND: + return R.string.account_status_not_found; + case NO_INTERNET: + return R.string.account_status_no_internet; + case REGISTRATION_FAILED: + return R.string.account_status_regis_fail; + case REGISTRATION_WEB: + return R.string.account_status_regis_web; + case REGISTRATION_CONFLICT: + return R.string.account_status_regis_conflict; + case REGISTRATION_SUCCESSFUL: + return R.string.account_status_regis_success; + case REGISTRATION_NOT_SUPPORTED: + return R.string.account_status_regis_not_sup; + 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.sasl_downgrade; + case HOST_UNKNOWN: + return R.string.account_status_host_unknown; + case POLICY_VIOLATION: + return R.string.account_status_policy_violation; + case REGISTRATION_PLEASE_WAIT: + return R.string.registration_please_wait; + case REGISTRATION_PASSWORD_TOO_WEAK: + return R.string.registration_password_too_weak; + case STREAM_ERROR: + return R.string.account_status_stream_error; + case STREAM_OPENING_ERROR: + return R.string.account_status_stream_opening_error; + case PAYMENT_REQUIRED: + return R.string.payment_required; + case MISSING_INTERNET_PERMISSION: + return R.string.missing_internet_permission; + default: + return R.string.account_status_unknown; + } + } + } +} \ No newline at end of file diff --git a/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java b/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java index ee5f91e2f..bb4edda5c 100644 --- a/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java +++ b/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java @@ -423,6 +423,9 @@ public class XmppConnection implements Runnable { break; // successfully connected to server that speaks xmpp } else { localSocket.close(); + if (!iterator.hasNext()) { + throw new StateChangingException(Account.State.STREAM_OPENING_ERROR); + } } } catch (final StateChangingException e) { throw e; @@ -545,7 +548,7 @@ public class XmppConnection implements Runnable { if (tag != null && tag.isStart("stream")) { processStream(); } else { - throw new IOException("server didn't restart stream after successful auth"); + throw new StateChangingException(Account.State.STREAM_OPENING_ERROR); } break; } else if (nextTag.isStart("failure")) { @@ -887,7 +890,7 @@ public class XmppConnection implements Runnable { SSLSocketHelper.log(account, sslSocket); processStream(); } else { - throw new IOException("server didn't restart stream after STARTTLS"); + throw new StateChangingException(Account.State.STREAM_OPENING_ERROR); } sslSocket.close(); } catch (final NoSuchAlgorithmException | KeyManagementException e1) { diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 62b415cf3..d3f9eeb0c 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -826,4 +826,5 @@ Group details View media Media browser + Stream opening error -- cgit v1.2.3