Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8a8f0b25 authored by daquexian's avatar daquexian Committed by Vincent Breitmoser
Browse files

Add 'guessing' in autoconfigure

parent 3f69ae1f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -78,7 +78,7 @@ public class AutoConfigureAutodiscover implements AutoConfigure {
    private ProviderInfo findProviderInfoByUrl(String url, String email, boolean followRedirects) {
        ProviderInfo providerInfo = null;
        try {
            Document document = Jsoup.connect(url).requestBody(String.format(AUTODISCOVER_POST_BODY, email))
            Document document = Jsoup.connect(url).timeout(5000).requestBody(String.format(AUTODISCOVER_POST_BODY, email))
                    .followRedirects(followRedirects).post();
            Element account = document.select("Account").first();
            if (account == null) {
+0 −103
Original line number Diff line number Diff line
package com.fsck.k9.mail.autoconfiguration;


import java.io.IOException;

import android.support.annotation.Nullable;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import timber.log.Timber;


/**
 * Search in ISPDB
 */

public class AutoconfigureISPDB implements AutoConfigure {
    private static final String ISPDB_URL = "https://autoconfig.thunderbird.net/v1.1/%s";

    @Nullable
    public ProviderInfo parse(Document document) {
        ProviderInfo providerInfo = new ProviderInfo();

        Element incomingElement = document.select("incomingServer").first();
        if (incomingElement == null) return null;
        Element incomingHostnameElement = incomingElement.select("hostname").first();
        if (incomingHostnameElement == null) return null;
        providerInfo.incomingAddr = incomingHostnameElement.text();
        providerInfo.incomingType = incomingElement.attr("type").toLowerCase();
        Element incomingPortElement = incomingElement.select("port").first();
        if (incomingPortElement != null) providerInfo.incomingPort = Integer.valueOf(incomingPortElement.text());
        Element incomingSocketTypeElement = incomingElement.select("socketType").first();
        String incomingSocketType = incomingSocketTypeElement != null ?
                incomingSocketTypeElement.text().toLowerCase() :
                "";
        switch (incomingSocketType) {
            case "ssl":
                providerInfo.incomingSocketType = ProviderInfo.SOCKET_TYPE_SSL_OR_TLS;
                break;
            case "starttls":
                providerInfo.incomingSocketType = ProviderInfo.SOCKET_TYPE_STARTTLS;
                break;
            default:
                providerInfo.incomingSocketType = "";
                break;
        }
        final Element usernameElement = incomingElement.select("username").first();
        if (usernameElement == null) return null;
        final String incomingUsername = usernameElement.text();
        // "\\" to escape '$'
        providerInfo.incomingUsernameTemplate = incomingUsername
                .replaceAll("%EMAILDOMAIN%", "\\" + ProviderInfo.USERNAME_TEMPLATE_DOMAIN)
                .replaceAll("%EMAILADDRESS%", "\\" + ProviderInfo.USERNAME_TEMPLATE_EMAIL)
                .replaceAll("%EMAILLOCALPART%", "\\" + ProviderInfo.USERNAME_TEMPLATE_USER);

        Element outgoingElement = document.select("outgoingServer").first();
        final Element outgoingHostnameElement = outgoingElement.select("hostname").first();
        if (outgoingHostnameElement == null) return null;
        providerInfo.outgoingAddr = outgoingHostnameElement.text();
        providerInfo.outgoingType = outgoingElement.attr("type").toLowerCase();
        Element outgoingPortElement = outgoingElement.select("port").first();
        if (outgoingPortElement != null) providerInfo.outgoingPort = Integer.valueOf(outgoingPortElement.text());
        final String outgoingSocketType = outgoingElement.select("socketType").first().text().toLowerCase();
        switch (outgoingSocketType) {
            case "ssl":
                providerInfo.outgoingSocketType = ProviderInfo.SOCKET_TYPE_SSL_OR_TLS;
                break;
            case "starttls":
                providerInfo.outgoingSocketType = ProviderInfo.SOCKET_TYPE_STARTTLS;
                break;
            default:
                providerInfo.outgoingSocketType = "";
                break;
        }
        final Element outgoingUsernameElement = outgoingElement.select("username").first();
        if (outgoingUsernameElement != null) {
            providerInfo.outgoingUsernameTemplate = outgoingUsernameElement.text()
                    .replaceAll("%EMAILDOMAIN%", "\\" + ProviderInfo.USERNAME_TEMPLATE_DOMAIN)
                    .replaceAll("%EMAILADDRESS%", "\\" + ProviderInfo.USERNAME_TEMPLATE_EMAIL)
                    .replaceAll("%EMAILLOCALPART%", "\\" + ProviderInfo.USERNAME_TEMPLATE_USER);
        }
        return providerInfo;
    }

    @Override
    public ProviderInfo findProviderInfo(String email) {
        String[] parts = email.split("@");
        if (parts.length < 2) return null;
        String domain = parts[1];

        try {
            String url = String.format(ISPDB_URL, domain);
            Document document = Jsoup.connect(url).get();

            return parse(document);
        } catch (IOException e) {
            Timber.w(e, "No information in ISPDB");
            return null;
        }
    }
}
+85 −27
Original line number Diff line number Diff line
package com.fsck.k9.mail.autoconfiguration;


import java.net.UnknownHostException;
import java.io.IOException;

import org.xbill.DNS.MXRecord;
import org.xbill.DNS.TextParseException;
import android.support.annotation.Nullable;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import timber.log.Timber;


/**
 * Search in ISPDB
 */

public class AutoconfigureMozilla implements AutoConfigure {
    @Override
    public ProviderInfo findProviderInfo(String email) {
        String[] parts = email.split("@");
        if (parts.length < 2) return null;
        String domain = parts[1];
    private static final String ISPDB_URL = "https://autoconfig.thunderbird.net/v1.1/%s";

        DNSOperation dnsOperation = new DNSOperation();
    @Nullable
    public ProviderInfo parse(Document document) {
        ProviderInfo providerInfo = new ProviderInfo();

        AutoconfigureISPDB autoconfigureISPDB = new AutoconfigureISPDB();
        ProviderInfo providerInfo = autoconfigureISPDB.findProviderInfo(email);
        Element incomingElement = document.select("incomingServer").first();
        if (incomingElement == null) return null;
        Element incomingHostnameElement = incomingElement.select("hostname").first();
        if (incomingHostnameElement == null) return null;
        providerInfo.incomingAddr = incomingHostnameElement.text();
        providerInfo.incomingType = incomingElement.attr("type").toLowerCase();
        Element incomingPortElement = incomingElement.select("port").first();
        if (incomingPortElement != null) providerInfo.incomingPort = Integer.valueOf(incomingPortElement.text());
        Element incomingSocketTypeElement = incomingElement.select("socketType").first();
        String incomingSocketType = incomingSocketTypeElement != null ?
                incomingSocketTypeElement.text().toLowerCase() :
                "";
        switch (incomingSocketType) {
            case "ssl":
                providerInfo.incomingSocketType = ProviderInfo.SOCKET_TYPE_SSL_OR_TLS;
                break;
            case "starttls":
                providerInfo.incomingSocketType = ProviderInfo.SOCKET_TYPE_STARTTLS;
                break;
            default:
                providerInfo.incomingSocketType = "";
                break;
        }
        final Element usernameElement = incomingElement.select("username").first();
        if (usernameElement == null) return null;
        final String incomingUsername = usernameElement.text();
        // "\\" to escape '$'
        providerInfo.incomingUsernameTemplate = incomingUsername
                .replaceAll("%EMAILDOMAIN%", "\\" + ProviderInfo.USERNAME_TEMPLATE_DOMAIN)
                .replaceAll("%EMAILADDRESS%", "\\" + ProviderInfo.USERNAME_TEMPLATE_EMAIL)
                .replaceAll("%EMAILLOCALPART%", "\\" + ProviderInfo.USERNAME_TEMPLATE_USER);

        if (providerInfo != null) {
        Element outgoingElement = document.select("outgoingServer").first();
        final Element outgoingHostnameElement = outgoingElement.select("hostname").first();
        if (outgoingHostnameElement == null) return null;
        providerInfo.outgoingAddr = outgoingHostnameElement.text();
        providerInfo.outgoingType = outgoingElement.attr("type").toLowerCase();
        Element outgoingPortElement = outgoingElement.select("port").first();
        if (outgoingPortElement != null) providerInfo.outgoingPort = Integer.valueOf(outgoingPortElement.text());
        final String outgoingSocketType = outgoingElement.select("socketType").first().text().toLowerCase();
        switch (outgoingSocketType) {
            case "ssl":
                providerInfo.outgoingSocketType = ProviderInfo.SOCKET_TYPE_SSL_OR_TLS;
                break;
            case "starttls":
                providerInfo.outgoingSocketType = ProviderInfo.SOCKET_TYPE_STARTTLS;
                break;
            default:
                providerInfo.outgoingSocketType = "";
                break;
        }
        final Element outgoingUsernameElement = outgoingElement.select("username").first();
        if (outgoingUsernameElement != null) {
            providerInfo.outgoingUsernameTemplate = outgoingUsernameElement.text()
                    .replaceAll("%EMAILDOMAIN%", "\\" + ProviderInfo.USERNAME_TEMPLATE_DOMAIN)
                    .replaceAll("%EMAILADDRESS%", "\\" + ProviderInfo.USERNAME_TEMPLATE_EMAIL)
                    .replaceAll("%EMAILLOCALPART%", "\\" + ProviderInfo.USERNAME_TEMPLATE_USER);
        }
        return providerInfo;
    }

        try {
            MXRecord mxRecord = dnsOperation.mxLookup(domain);
            if (mxRecord != null) {
                final String target = mxRecord.getTarget().toString(true);
                final String[] targetParts = target.split("\\.");
    @Override
    public ProviderInfo findProviderInfo(String email) {
        String[] parts = email.split("@");
        if (parts.length < 2) return null;
        String domain = parts[1];

                String newDomain = targetParts[targetParts.length - 2] + "." + targetParts[targetParts.length - 1];
        try {
            String url = String.format(ISPDB_URL, domain);
            Document document = Jsoup.connect(url).timeout(5000).get();

                if (!newDomain.equals(domain)) {
                    providerInfo = autoconfigureISPDB.findProviderInfo(newDomain);
                }
            }
        } catch (TextParseException | UnknownHostException e) {
            Timber.e(e, "Error while trying to run MX lookup");
            return parse(document);
        } catch (IOException e) {
            Timber.w(e, "No information in ISPDB");
            return null;
        }

        return providerInfo;
    }
}
+22 −0
Original line number Diff line number Diff line
package com.fsck.k9.mail.autoconfiguration;


import java.net.UnknownHostException;

import org.xbill.DNS.MXRecord;
import org.xbill.DNS.TextParseException;


public class DNSHelper {
    public static String getMXDomain(String domain) throws TextParseException, UnknownHostException {
        DNSOperation dnsOperation = new DNSOperation();
        MXRecord mxRecord = dnsOperation.mxLookup(domain);
        if (mxRecord != null) {
            final String target = mxRecord.getTarget().toString(true);
            final String[] targetParts = target.split("\\.");

            return targetParts[targetParts.length - 2] + "." + targetParts[targetParts.length - 1];
        }
        return null;
    }
}
+16 −16
Original line number Diff line number Diff line
@@ -36,8 +36,8 @@ public class ISPDBTest {

        Document document = Jsoup.parse(xml);

        AutoconfigureISPDB autoconfigureISPDB = new AutoconfigureISPDB();
        ProviderInfo actual = autoconfigureISPDB.parse(document).fillDefaultPorts();
        AutoconfigureMozilla autoconfigureMozilla = new AutoconfigureMozilla();
        ProviderInfo actual = autoconfigureMozilla.parse(document).fillDefaultPorts();
        ProviderInfo expected = new ProviderInfo();
        expected.incomingType = ProviderInfo.INCOMING_TYPE_IMAP;
        expected.incomingSocketType = ProviderInfo.SOCKET_TYPE_SSL_OR_TLS;
@@ -97,8 +97,8 @@ public class ISPDBTest {

        Document document = Jsoup.parse(xml);

        AutoconfigureISPDB autoconfigureISPDB = new AutoconfigureISPDB();
        ProviderInfo actual = autoconfigureISPDB.parse(document).fillDefaultPorts();
        AutoconfigureMozilla autoconfigureMozilla = new AutoconfigureMozilla();
        ProviderInfo actual = autoconfigureMozilla.parse(document).fillDefaultPorts();
        ProviderInfo expected = new ProviderInfo();
        expected.incomingType = ProviderInfo.INCOMING_TYPE_POP3;
        expected.incomingSocketType = ProviderInfo.SOCKET_TYPE_SSL_OR_TLS;
@@ -165,8 +165,8 @@ public class ISPDBTest {

        Document document = Jsoup.parse(xml);

        AutoconfigureISPDB autoconfigureISPDB = new AutoconfigureISPDB();
        ProviderInfo actual = autoconfigureISPDB.parse(document).fillDefaultPorts();
        AutoconfigureMozilla autoconfigureMozilla = new AutoconfigureMozilla();
        ProviderInfo actual = autoconfigureMozilla.parse(document).fillDefaultPorts();
        ProviderInfo expected = new ProviderInfo();
        expected.incomingType = ProviderInfo.INCOMING_TYPE_IMAP;
        expected.incomingSocketType = ProviderInfo.SOCKET_TYPE_SSL_OR_TLS;
@@ -207,8 +207,8 @@ public class ISPDBTest {

        Document document = Jsoup.parse(xml);

        AutoconfigureISPDB autoconfigureISPDB = new AutoconfigureISPDB();
        ProviderInfo actual = autoconfigureISPDB.parse(document).fillDefaultPorts();
        AutoconfigureMozilla autoconfigureMozilla = new AutoconfigureMozilla();
        ProviderInfo actual = autoconfigureMozilla.parse(document).fillDefaultPorts();
        ProviderInfo expected = new ProviderInfo();
        expected.incomingType = ProviderInfo.INCOMING_TYPE_POP3;
        expected.incomingSocketType = "";
@@ -249,8 +249,8 @@ public class ISPDBTest {

        Document document = Jsoup.parse(xml);

        AutoconfigureISPDB autoconfigureISPDB = new AutoconfigureISPDB();
        ProviderInfo actual = autoconfigureISPDB.parse(document).fillDefaultPorts();
        AutoconfigureMozilla autoconfigureMozilla = new AutoconfigureMozilla();
        ProviderInfo actual = autoconfigureMozilla.parse(document).fillDefaultPorts();
        ProviderInfo expected = new ProviderInfo();
        expected.incomingType = ProviderInfo.INCOMING_TYPE_POP3;
        expected.incomingSocketType = ProviderInfo.SOCKET_TYPE_STARTTLS;
@@ -294,8 +294,8 @@ public class ISPDBTest {

        Document document = Jsoup.parse(xml);

        AutoconfigureISPDB autoconfigureISPDB = new AutoconfigureISPDB();
        ProviderInfo actual = autoconfigureISPDB.parse(document).fillDefaultPorts();
        AutoconfigureMozilla autoconfigureMozilla = new AutoconfigureMozilla();
        ProviderInfo actual = autoconfigureMozilla.parse(document).fillDefaultPorts();
        ProviderInfo expected = new ProviderInfo();
        expected.incomingType = ProviderInfo.INCOMING_TYPE_IMAP;
        expected.incomingSocketType = ProviderInfo.SOCKET_TYPE_SSL_OR_TLS;
@@ -330,8 +330,8 @@ public class ISPDBTest {

        Document document = Jsoup.parse(xml);

        AutoconfigureISPDB autoconfigureISPDB = new AutoconfigureISPDB();
        ProviderInfo actual = autoconfigureISPDB.parse(document);
        AutoconfigureMozilla autoconfigureMozilla = new AutoconfigureMozilla();
        ProviderInfo actual = autoconfigureMozilla.parse(document);

        Assert.assertNull(actual);
    }
@@ -361,8 +361,8 @@ public class ISPDBTest {

        Document document = Jsoup.parse(xml);

        AutoconfigureISPDB autoconfigureISPDB = new AutoconfigureISPDB();
        ProviderInfo actual = autoconfigureISPDB.parse(document);
        AutoconfigureMozilla autoconfigureMozilla = new AutoconfigureMozilla();
        ProviderInfo actual = autoconfigureMozilla.parse(document);

        Assert.assertNull(actual);
    }
Loading