add some extra hostname validation

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/xmpp/Jid.java | 17 ++++++++++++---
src/main/res/values/strings.xml                    |  1 
2 files changed, 14 insertions(+), 4 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/xmpp/Jid.java 🔗

@@ -1,9 +1,10 @@
 package eu.siacs.conversations.xmpp;
 
 import androidx.annotation.NonNull;
-import com.google.common.base.CharMatcher;
+import eu.siacs.conversations.utils.IP;
 import im.conversations.android.xmpp.model.stanza.Stanza;
 import java.io.Serializable;
+import java.util.regex.Pattern;
 import org.jxmpp.jid.impl.JidCreate;
 import org.jxmpp.jid.parts.Domainpart;
 import org.jxmpp.jid.parts.Localpart;
@@ -12,6 +13,10 @@ import org.jxmpp.stringprep.XmppStringprepException;
 
 public abstract class Jid implements Comparable<Jid>, Serializable, CharSequence {
 
+    private static final Pattern HOSTNAME_PATTERN =
+            Pattern.compile(
+                    "^(?=.{1,253}$)(?=.{1,253}$)(?!-)(?!.*--)(?!.*-$)[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)*$");
+
     public static Jid of(
             final CharSequence local, final CharSequence domain, final CharSequence resource) {
         if (local == null) {
@@ -77,10 +82,14 @@ public abstract class Jid implements Comparable<Jid>, Serializable, CharSequence
 
     public static Jid ofUserInput(final CharSequence input) {
         final var jid = of(input);
-        if (CharMatcher.is('@').matchesAnyOf(jid.getDomain())) {
-            throw new IllegalArgumentException("Domain should not contain @");
+        final var domain = jid.getDomain().toString();
+        if (domain.isEmpty()) {
+            throw new IllegalArgumentException("Domain can not be empty");
+        }
+        if (HOSTNAME_PATTERN.matcher(domain).matches() || IP.matches(domain)) {
+            return jid;
         }
-        return jid;
+        throw new IllegalArgumentException("Invalid hostname");
     }
 
     public static Jid ofOrInvalid(final String input) {

src/main/res/values/strings.xml 🔗

@@ -171,6 +171,7 @@
     <string name="account_status_incompatible_client">Incompatible client</string>
     <string name="account_status_stream_error">Stream error</string>
     <string name="account_status_stream_opening_error">Stream opening error</string>
+    <string name="account_status_channel_binding">Channel binding unavailable</string>
     <string name="encryption_choice_unencrypted">Clear text</string>
     <string name="encryption_choice_otr">OTR</string>
     <string name="encryption_choice_pgp">OpenPGP</string>