/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.accounts;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerInternal;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
import android.util.PackageUtils;
import android.util.Pair;
import android.util.Slog;
import android.util.Xml;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.content.PackageMonitor;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.XmlUtils;
import com.android.server.accounts.AccountsDb.DeDatabaseHelper;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * Helper class for backup and restore of account access grants.
 */
public final class AccountManagerBackupHelper {
    private static final String TAG = "AccountManagerBackupHelper";

    private static final long PENDING_RESTORE_TIMEOUT_MILLIS = 60 * 60 * 1000; // 1 hour

    private static final String TAG_PERMISSIONS = "permissions";
    private static final String TAG_PERMISSION = "permission";
    private static final String ATTR_ACCOUNT_SHA_256 = "account-sha-256";
    private static final String ATTR_PACKAGE = "package";
    private static final String ATTR_DIGEST = "digest";

    private final Object mLock = new Object();

    private final AccountManagerService mAccountManagerService;
    private final AccountManagerInternal mAccountManagerInternal;

    @GuardedBy("mLock")
    private List<PendingAppPermission> mRestorePendingAppPermissions;

    @GuardedBy("mLock")
    private RestorePackageMonitor mRestorePackageMonitor;

    @GuardedBy("mLock")
    private Runnable mRestoreCancelCommand;

    public AccountManagerBackupHelper(AccountManagerService accountManagerService,
            AccountManagerInternal accountManagerInternal) {
        mAccountManagerService = accountManagerService;
        mAccountManagerInternal = accountManagerInternal;
    }

    private final class PendingAppPermission {
        private final @NonNull String accountDigest;
        private final @NonNull String packageName;
        private final @NonNull String certDigest;
        private final @IntRange(from = 0) int userId;

        public PendingAppPermission(String accountDigest, String packageName,
                String certDigest, int userId) {
            this.accountDigest = accountDigest;
            this.packageName = packageName;
            this.certDigest = certDigest;
            this.userId = userId;
        }

        public boolean apply(PackageManager packageManager) {
            Account account = null;
            AccountManagerService.UserAccounts accounts = mAccountManagerService
                    .getUserAccounts(userId);
            synchronized (accounts.dbLock) {
                synchronized (accounts.cacheLock) {
                    for (Account[] accountsPerType : accounts.accountCache.values()) {
                        for (Account accountPerType : accountsPerType) {
                            if (accountDigest.equals(PackageUtils.computeSha256Digest(
                                    accountPerType.name.getBytes()))) {
                                account = accountPerType;
                                break;
                            }
                        }
                        if (account != null) {
                            break;
                        }
                    }
                }
            }
            if (account == null) {
                return false;
            }
            final PackageInfo packageInfo;
            try {
                packageInfo = packageManager.getPackageInfoAsUser(packageName,
                        PackageManager.GET_SIGNATURES, userId);
            } catch (PackageManager.NameNotFoundException e) {
                return false;
            }

            // Before we used only the first signature to compute the SHA 256 but some
            // apps could be singed by multiple certs and the cert order is undefined.
            // We prefer the modern computation procedure where all certs are taken
            // into account but also allow the value from the old computation to allow
            // restoring backed up grants on an older platform version.
            final String[] signaturesSha256Digests = PackageUtils.computeSignaturesSha256Digests(
                    packageInfo.signatures);
            final String signaturesSha256Digest = PackageUtils.computeSignaturesSha256Digest(
                    signaturesSha256Digests);
            if (!certDigest.equals(signaturesSha256Digest) && (packageInfo.signatures.length <= 1
                    || !certDigest.equals(signaturesSha256Digests[0]))) {
                return false;
            }
            final int uid = packageInfo.applicationInfo.uid;
            if (!mAccountManagerInternal.hasAccountAccess(account, uid)) {
                mAccountManagerService.grantAppPermission(account,
                        AccountManager.ACCOUNT_ACCESS_TOKEN_TYPE, uid);
            }
            return true;
        }
    }

    public byte[] backupAccountAccessPermissions(int userId) {
        final AccountManagerService.UserAccounts accounts = mAccountManagerService
                .getUserAccounts(userId);
        synchronized (accounts.dbLock) {
            synchronized (accounts.cacheLock) {
                List<Pair<String, Integer>> allAccountGrants = accounts.accountsDb
                        .findAllAccountGrants();
                if (allAccountGrants.isEmpty()) {
                    return null;
                }
                try {
                    ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
                    final XmlSerializer serializer = new FastXmlSerializer();
                    serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
                    serializer.startDocument(null, true);
                    serializer.startTag(null, TAG_PERMISSIONS);

                    PackageManager packageManager = mAccountManagerService.mContext
                            .getPackageManager();
                    for (Pair<String, Integer> grant : allAccountGrants) {
                        final String accountName = grant.first;
                        final int uid = grant.second;

                        final String[] packageNames = packageManager.getPackagesForUid(uid);
                        if (packageNames == null) {
                            continue;
                        }

                        for (String packageName : packageNames) {
                            final PackageInfo packageInfo;
                            try {
                                packageInfo = packageManager.getPackageInfoAsUser(packageName,
                                        PackageManager.GET_SIGNATURES, userId);
                            } catch (PackageManager.NameNotFoundException e) {
                                Slog.i(TAG, "Skipping backup of account access grant for"
                                        + " non-existing package: " + packageName);
                                continue;
                            }
                            final String digest = PackageUtils.computeSignaturesSha256Digest(
                                    packageInfo.signatures);
                            if (digest != null) {
                                serializer.startTag(null, TAG_PERMISSION);
                                serializer.attribute(null, ATTR_ACCOUNT_SHA_256,
                                        PackageUtils.computeSha256Digest(accountName.getBytes()));
                                serializer.attribute(null, ATTR_PACKAGE, packageName);
                                serializer.attribute(null, ATTR_DIGEST, digest);
                                serializer.endTag(null, TAG_PERMISSION);
                            }
                        }
                    }
                    serializer.endTag(null, TAG_PERMISSIONS);
                    serializer.endDocument();
                    serializer.flush();
                    return dataStream.toByteArray();
                } catch (IOException e) {
                    Log.e(TAG, "Error backing up account access grants", e);
                    return null;
                }
            }
        }
    }

    public void restoreAccountAccessPermissions(byte[] data, int userId) {
        try {
            ByteArrayInputStream dataStream = new ByteArrayInputStream(data);
            XmlPullParser parser = Xml.newPullParser();
            parser.setInput(dataStream, StandardCharsets.UTF_8.name());
            PackageManager packageManager = mAccountManagerService.mContext.getPackageManager();

            final int permissionsOuterDepth = parser.getDepth();
            while (XmlUtils.nextElementWithin(parser, permissionsOuterDepth)) {
                if (!TAG_PERMISSIONS.equals(parser.getName())) {
                    continue;
                }
                final int permissionOuterDepth = parser.getDepth();
                while (XmlUtils.nextElementWithin(parser, permissionOuterDepth)) {
                    if (!TAG_PERMISSION.equals(parser.getName())) {
                        continue;
                    }
                    String accountDigest = parser.getAttributeValue(null, ATTR_ACCOUNT_SHA_256);
                    if (TextUtils.isEmpty(accountDigest)) {
                        XmlUtils.skipCurrentTag(parser);
                    }
                    String packageName = parser.getAttributeValue(null, ATTR_PACKAGE);
                    if (TextUtils.isEmpty(packageName)) {
                        XmlUtils.skipCurrentTag(parser);
                    }
                    String digest =  parser.getAttributeValue(null, ATTR_DIGEST);
                    if (TextUtils.isEmpty(digest)) {
                        XmlUtils.skipCurrentTag(parser);
                    }

                    PendingAppPermission pendingAppPermission = new PendingAppPermission(
                            accountDigest, packageName, digest, userId);

                    if (!pendingAppPermission.apply(packageManager)) {
                        synchronized (mLock) {
                            // Start watching before add pending to avoid a missed signal
                            if (mRestorePackageMonitor == null) {
                                mRestorePackageMonitor = new RestorePackageMonitor();
                                mRestorePackageMonitor.register(mAccountManagerService.mContext,
                                        mAccountManagerService.mHandler.getLooper(), true);
                            }
                            if (mRestorePendingAppPermissions == null) {
                                mRestorePendingAppPermissions = new ArrayList<>();
                            }
                            mRestorePendingAppPermissions.add(pendingAppPermission);
                        }
                    }
                }
            }

            // Make sure we eventually prune the in-memory pending restores
            mRestoreCancelCommand = new CancelRestoreCommand();
            mAccountManagerService.mHandler.postDelayed(mRestoreCancelCommand,
                    PENDING_RESTORE_TIMEOUT_MILLIS);
        } catch (XmlPullParserException | IOException e) {
            Log.e(TAG, "Error restoring app permissions", e);
        }
    }

    private final class RestorePackageMonitor extends PackageMonitor {
        @Override
        public void onPackageAdded(String packageName, int uid) {
            synchronized (mLock) {
                if (mRestorePendingAppPermissions == null) {
                    return;
                }
                if (UserHandle.getUserId(uid) != UserHandle.USER_SYSTEM) {
                    return;
                }
                final int count = mRestorePendingAppPermissions.size();
                for (int i = count - 1; i >= 0; i--) {
                    PendingAppPermission pendingAppPermission =
                            mRestorePendingAppPermissions.get(i);
                    if (!pendingAppPermission.packageName.equals(packageName)) {
                        continue;
                    }
                    if (pendingAppPermission.apply(
                            mAccountManagerService.mContext.getPackageManager())) {
                        mRestorePendingAppPermissions.remove(i);
                    }
                }
                if (mRestorePendingAppPermissions.isEmpty()
                        && mRestoreCancelCommand != null) {
                    mAccountManagerService.mHandler.removeCallbacks(mRestoreCancelCommand);
                    mRestoreCancelCommand.run();
                    mRestoreCancelCommand = null;
                }
            }
        }
    }

    private final class CancelRestoreCommand implements Runnable {
        @Override
        public void run() {
            synchronized (mLock) {
                mRestorePendingAppPermissions = null;
                if (mRestorePackageMonitor != null) {
                    mRestorePackageMonitor.unregister();
                    mRestorePackageMonitor = null;
                }
            }
        }
    }
}
