package org.anhonesteffort.flock; import android.accounts.AccountManager; import android.app.Service; import android.os.Bundle; import android.util.Log; import org.anhonesteffort.flock.util.guava.Optional; import org.anhonesteffort.flock.auth.AccountAuthenticator; import org.anhonesteffort.flock.auth.DavAccount; import org.anhonesteffort.flock.crypto.InvalidMacException; import org.anhonesteffort.flock.crypto.KeyHelper; import org.anhonesteffort.flock.crypto.KeyStore; import org.anhonesteffort.flock.sync.key.DavKeyCollection; import org.anhonesteffort.flock.sync.key.DavKeyStore; import org.anhonesteffort.flock.sync.key.KeySyncScheduler; import org.anhonesteffort.flock.webdav.PropertyParseException; import org.apache.jackrabbit.webdav.DavException; import java.io.IOException; import java.security.GeneralSecurityException; import javax.net.ssl.SSLException; /** * Created by rhodey */ public abstract class ImportAccountService extends Service { private static final String TAG = "org.anhonesteffort.flock.ImportAccountService"; private void handleImportOrGenerateKeyMaterial(Bundle result, DavAccount account, String cipherPassphrase) { Optional<String[]> saltAndEncryptedKeyMaterial = Optional.absent(); KeyStore.saveMasterPassphrase(getBaseContext(), cipherPassphrase); DavAccountHelper.setAccountDavHREF(getBaseContext(), account.getDavHostHREF()); try { DavKeyStore davKeyStore = DavAccountHelper.getDavKeyStore(getBaseContext(), account); Optional<DavKeyCollection> keyCollection = davKeyStore.getCollection(); if (keyCollection.isPresent()) { if (keyCollection.get().getKeyMaterialSalt().isPresent() && keyCollection.get().getEncryptedKeyMaterial().isPresent()) { saltAndEncryptedKeyMaterial = Optional.of( new String[] { keyCollection.get().getKeyMaterialSalt().get(), keyCollection.get().getEncryptedKeyMaterial().get() } ); } } else { DavKeyStore.createCollection(getBaseContext(), account); keyCollection = davKeyStore.getCollection(); if (!keyCollection.isPresent()) { result.putInt(ErrorToaster.KEY_STATUS_CODE, ErrorToaster.CODE_DAV_SERVER_ERROR); return; } } } catch (PropertyParseException e) { ErrorToaster.handleBundleError(e, result); } catch (DavException e) { ErrorToaster.handleBundleError(e, result); } catch (SSLException e) { ErrorToaster.handleBundleError(e, result); } catch (IOException e) { ErrorToaster.handleBundleError(e, result); } try { if (saltAndEncryptedKeyMaterial.isPresent()) KeyHelper.importSaltAndEncryptedKeyMaterial(getBaseContext(), saltAndEncryptedKeyMaterial.get()); else KeyHelper.generateAndSaveSaltAndKeyMaterial(getBaseContext()); result.putInt(ErrorToaster.KEY_STATUS_CODE, ErrorToaster.CODE_SUCCESS); } catch (InvalidMacException e) { result.putInt(ErrorToaster.KEY_STATUS_CODE, ErrorToaster.CODE_INVALID_CIPHER_PASSPHRASE); } catch (GeneralSecurityException e) { ErrorToaster.handleBundleError(e, result); } catch (IOException e) { Log.e(TAG, "handleImportOrGenerateKeyMaterial()", e); result.putInt(ErrorToaster.KEY_STATUS_CODE, ErrorToaster.CODE_CRYPTO_ERROR); } } private void handleInvalidateEverything() { DavAccountHelper.invalidateAccount(getBaseContext()); KeyStore.invalidateKeyMaterial(getBaseContext()); } protected Bundle handleImportAccount(Bundle result, DavAccount account, String cipherPassphrase) { handleInvalidateEverything(); handleImportOrGenerateKeyMaterial(result, account, cipherPassphrase); if (result.getInt(ErrorToaster.KEY_STATUS_CODE) == ErrorToaster.CODE_SUCCESS) { AccountManager.get(getBaseContext()).addAccountExplicitly(account.getOsAccount(), "", null); DavAccountHelper.setAccountUsername(getBaseContext(), account.getUserId()); DavAccountHelper.setAccountPassword(getBaseContext(), account.getAuthToken()); DavAccountHelper.setAccountDavHREF(getBaseContext(), account.getDavHostHREF()); AccountAuthenticator.setAllowAccountRemoval(getBaseContext(), false); new KeySyncScheduler(getBaseContext()).requestSync(); } else handleInvalidateEverything(); return result; } }