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

Commit 448a80e9 authored by cketti's avatar cketti
Browse files

Merge branch 'cert_validation'

parents b500047e cedcd7e4
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -27,11 +27,13 @@ android {
      manifest.srcFile 'AndroidManifest.xml'
      java.srcDirs = ['src']
      res.srcDirs = ['res']
      assets.srcDirs = ['assets']
    }

    instrumentTest {
      manifest.srcFile 'tests/AndroidManifest.xml'
      java.srcDirs = ['tests/src']
      assets.srcDirs = ['tests/assets']
    }
  }
}
+57 −0
Original line number Diff line number Diff line

package com.fsck.k9;

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
@@ -22,6 +24,7 @@ import android.net.ConnectivityManager;
import android.net.Uri;
import android.util.Log;

import com.fsck.k9.activity.setup.AccountSetupCheckSettings.CheckDirection;
import com.fsck.k9.crypto.Apg;
import com.fsck.k9.crypto.CryptoProvider;
import com.fsck.k9.helper.Utility;
@@ -40,6 +43,7 @@ import com.fsck.k9.search.SqlQueryBuilder;
import com.fsck.k9.search.SearchSpecification.Attribute;
import com.fsck.k9.search.SearchSpecification.SearchCondition;
import com.fsck.k9.search.SearchSpecification.Searchfield;
import com.fsck.k9.security.LocalKeyStore;
import com.fsck.k9.view.ColorChip;
import com.larswerkman.colorpicker.ColorPicker;

@@ -1865,4 +1869,57 @@ public class Account implements BaseAccount {
            search.and(Searchfield.FOLDER, folderName, Attribute.NOT_EQUALS);
        }
    }

    /**
     * Add a new certificate for the incoming or outgoing server to the local key store.
     */
    public void addCertificate(CheckDirection direction,
            X509Certificate certificate) throws CertificateException {
        Uri uri;
        if (direction.equals(CheckDirection.INCOMING)) {
            uri = Uri.parse(getStoreUri());
        } else {
            uri = Uri.parse(getTransportUri());
        }
        LocalKeyStore localKeyStore = LocalKeyStore.getInstance();
        localKeyStore.addCertificate(uri.getHost(), uri.getPort(), certificate);
    }

    /**
     * Examine the existing settings for an account.  If the old host/port is different from the
     * new host/port, then try and delete any (possibly non-existent) certificate stored for the
     * old host/port.
     */
    public void deleteCertificate(String newHost, int newPort,
            CheckDirection direction) {
        Uri uri;
        if (direction.equals(CheckDirection.INCOMING)) {
            uri = Uri.parse(getStoreUri());
        } else {
            uri = Uri.parse(getTransportUri());
        }
        String oldHost = uri.getHost();
        int oldPort = uri.getPort();
        if (oldPort == -1) {
            // This occurs when a new account is created
            return;
        }
        if (!newHost.equals(oldHost) || newPort != oldPort) {
            LocalKeyStore localKeyStore = LocalKeyStore.getInstance();
            localKeyStore.deleteCertificate(oldHost, oldPort);
        }
    }

    /**
     * Examine the settings for the account and attempt to delete (possibly non-existent)
     * certificates for the incoming and outgoing servers.
     */
    public void deleteCertificates() {
        LocalKeyStore localKeyStore = LocalKeyStore.getInstance();

        Uri uri = Uri.parse(getStoreUri());
        localKeyStore.deleteCertificate(uri.getHost(), uri.getPort());
        uri = Uri.parse(getTransportUri());
        localKeyStore.deleteCertificate(uri.getHost(), uri.getPort());
    }
}
+32 −11
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.internet.BinaryTempFileBody;
import com.fsck.k9.mail.store.LocalStore;
import com.fsck.k9.provider.UnreadWidgetProvider;
import com.fsck.k9.security.LocalKeyStore;
import com.fsck.k9.service.BootReceiver;
import com.fsck.k9.service.MailService;
import com.fsck.k9.service.ShutdownReceiver;
@@ -59,7 +60,7 @@ public class K9 extends Application {
         *            The application instance. Never <code>null</code>.
         * @throws Exception
         */
        void initializeComponent(K9 application);
        void initializeComponent(Application application);
    }

    public static Application app = null;
@@ -91,6 +92,15 @@ public class K9 extends Application {
     */
    private static List<ApplicationAware> observers = new ArrayList<ApplicationAware>();

    /**
     * This will be {@code true} once the initialization is complete and {@link #notifyObservers()}
     * was called.
     * Afterwards calls to {@link #registerApplicationAware(com.fsck.k9.K9.ApplicationAware)} will
     * immediately call {@link com.fsck.k9.K9.ApplicationAware#initializeComponent(K9)} for the
     * supplied argument.
     */
    private static boolean sInitialized = false;

    public enum BACKGROUND_OPS {
        WHEN_CHECKED, ALWAYS, NEVER, WHEN_CHECKED_AUTO_SYNC
    }
@@ -581,6 +591,8 @@ public class K9 extends Application {
         */
        BinaryTempFileBody.setTempDirectory(getCacheDir());

        LocalKeyStore.setKeyStoreLocation(getDir("KeyStore", MODE_PRIVATE).toString());

        /*
         * Enable background sync of messages
         */
@@ -829,6 +841,7 @@ public class K9 extends Application {
     * component that the application is available and ready
     */
    protected void notifyObservers() {
        synchronized (observers) {
            for (final ApplicationAware aware : observers) {
                if (K9.DEBUG) {
                    Log.v(K9.LOG_TAG, "Initializing observer: " + aware);
@@ -839,6 +852,10 @@ public class K9 extends Application {
                    Log.w(K9.LOG_TAG, "Failure when notifying " + aware, e);
                }
            }

            sInitialized = true;
            observers.clear();
        }
    }

    /**
@@ -848,10 +865,14 @@ public class K9 extends Application {
     *            Never <code>null</code>.
     */
    public static void registerApplicationAware(final ApplicationAware component) {
        if (!observers.contains(component)) {
        synchronized (observers) {
            if (sInitialized) {
                component.initializeComponent(K9.app);
            } else if (!observers.contains(component)) {
                observers.add(component);
            }
        }
    }

    public static String getK9Language() {
        return language;
+1 −0
Original line number Diff line number Diff line
@@ -127,6 +127,7 @@ public class Preferences {

        Store.removeAccount(account);

        account.deleteCertificates();
        account.delete(this);

        if (newAccount == account) {
+36 −16
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ import android.widget.Button;
import android.widget.EditText;
import com.fsck.k9.*;
import com.fsck.k9.activity.K9Activity;
import com.fsck.k9.activity.setup.AccountSetupCheckSettings.CheckDirection;
import com.fsck.k9.helper.Utility;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
@@ -37,6 +38,8 @@ public class AccountSetupBasics extends K9Activity
    private final static int DIALOG_NOTE = 1;
    private final static String STATE_KEY_PROVIDER =
            "com.fsck.k9.AccountSetupBasics.provider";
    private final static String STATE_KEY_CHECKED_INCOMING =
            "com.fsck.k9.AccountSetupBasics.checkedIncoming";

    private EditText mEmailView;
    private EditText mPasswordView;
@@ -46,6 +49,7 @@ public class AccountSetupBasics extends K9Activity
    private Provider mProvider;

    private EmailAddressValidator mEmailValidator = new EmailAddressValidator();
    private boolean mCheckedIncoming = false;

    public static void actionNewAccount(Context context) {
        Intent i = new Intent(context, AccountSetupBasics.class);
@@ -66,15 +70,6 @@ public class AccountSetupBasics extends K9Activity

        mEmailView.addTextChangedListener(this);
        mPasswordView.addTextChangedListener(this);

        if (savedInstanceState != null && savedInstanceState.containsKey(EXTRA_ACCOUNT)) {
            String accountUuid = savedInstanceState.getString(EXTRA_ACCOUNT);
            mAccount = Preferences.getPreferences(this).getAccount(accountUuid);
        }

        if (savedInstanceState != null && savedInstanceState.containsKey(STATE_KEY_PROVIDER)) {
            mProvider = (Provider)savedInstanceState.getSerializable(STATE_KEY_PROVIDER);
        }
    }

    @Override
@@ -92,6 +87,23 @@ public class AccountSetupBasics extends K9Activity
        if (mProvider != null) {
            outState.putSerializable(STATE_KEY_PROVIDER, mProvider);
        }
        outState.putBoolean(STATE_KEY_CHECKED_INCOMING, mCheckedIncoming);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);

        if (savedInstanceState.containsKey(EXTRA_ACCOUNT)) {
            String accountUuid = savedInstanceState.getString(EXTRA_ACCOUNT);
            mAccount = Preferences.getPreferences(this).getAccount(accountUuid);
        }

        if (savedInstanceState.containsKey(STATE_KEY_PROVIDER)) {
            mProvider = (Provider) savedInstanceState.getSerializable(STATE_KEY_PROVIDER);
        }

        mCheckedIncoming = savedInstanceState.getBoolean(STATE_KEY_CHECKED_INCOMING);
    }

    public void afterTextChanged(Editable s) {
@@ -229,7 +241,8 @@ public class AccountSetupBasics extends K9Activity
            } else if (incomingUri.toString().startsWith("pop3")) {
                mAccount.setDeletePolicy(Account.DELETE_POLICY_NEVER);
            }
            AccountSetupCheckSettings.actionCheckSettings(this, mAccount, true, true);
            // Check incoming here.  Then check outgoing in onActivityResult()
            AccountSetupCheckSettings.actionCheckSettings(this, mAccount, CheckDirection.INCOMING);
        } catch (UnsupportedEncodingException enc) {
            // This really shouldn't happen since the encoding is hardcoded to UTF-8
            Log.e(K9.LOG_TAG, "Couldn't urlencode username or password.", enc);
@@ -266,6 +279,12 @@ public class AccountSetupBasics extends K9Activity
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            if (!mCheckedIncoming) {
                //We've successfully checked incoming.  Now check outgoing.
                mCheckedIncoming = true;
                AccountSetupCheckSettings.actionCheckSettings(this, mAccount, CheckDirection.OUTGOING);
            } else {
                //We've successfully checked outgoing as well.
                mAccount.setDescription(mAccount.getEmail());
                mAccount.save(Preferences.getPreferences(this));
                K9.setServicesEnabled(this);
@@ -273,6 +292,7 @@ public class AccountSetupBasics extends K9Activity
                finish();
            }
        }
    }

    private void onManualSetup() {
        String email = mEmailView.getText().toString();
Loading