/*
 * Copyright (C) 2013 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.updates;

import android.content.Context;
import android.content.Intent;
import android.os.SystemProperties;
import android.provider.Settings;
import android.util.Base64;
import android.util.Slog;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import libcore.io.ErrnoException;
import libcore.io.IoUtils;
import libcore.io.Libcore;

public class SELinuxPolicyInstallReceiver extends ConfigUpdateInstallReceiver {

    private static final String TAG = "SELinuxPolicyInstallReceiver";

    private static final String sepolicyPath = "sepolicy";
    private static final String fileContextsPath = "file_contexts";
    private static final String propertyContextsPath = "property_contexts";
    private static final String seappContextsPath = "seapp_contexts";

    public SELinuxPolicyInstallReceiver() {
        super("/data/security/bundle", "sepolicy_bundle", "metadata/", "version");
    }

    private void backupContexts(File contexts) {
        new File(contexts, seappContextsPath).renameTo(
                new File(contexts, seappContextsPath + "_backup"));

        new File(contexts, propertyContextsPath).renameTo(
                new File(contexts, propertyContextsPath + "_backup"));

        new File(contexts, fileContextsPath).renameTo(
                new File(contexts, fileContextsPath + "_backup"));

        new File(contexts, sepolicyPath).renameTo(
                new File(contexts, sepolicyPath + "_backup"));
    }

    private void copyUpdate(File contexts) {
        new File(updateDir, seappContextsPath).renameTo(new File(contexts, seappContextsPath));
        new File(updateDir, propertyContextsPath).renameTo(new File(contexts, propertyContextsPath));
        new File(updateDir, fileContextsPath).renameTo(new File(contexts, fileContextsPath));
        new File(updateDir, sepolicyPath).renameTo(new File(contexts, sepolicyPath));
    }

    private int readInt(BufferedInputStream reader) throws IOException {
        int value = 0;
        for (int i=0; i < 4; i++) {
            value = (value << 8) | reader.read();
        }
        return value;
    }

    private int[] readChunkLengths(BufferedInputStream bundle) throws IOException {
        int[] chunks = new int[4];
        chunks[0] = readInt(bundle);
        chunks[1] = readInt(bundle);
        chunks[2] = readInt(bundle);
        chunks[3] = readInt(bundle);
        return chunks;
    }

    private void installFile(File destination, BufferedInputStream stream, int length)
            throws IOException {
        byte[] chunk = new byte[length];
        stream.read(chunk, 0, length);
        writeUpdate(updateDir, destination, Base64.decode(chunk, Base64.DEFAULT));
    }

    private void unpackBundle() throws IOException {
        BufferedInputStream stream = new BufferedInputStream(new FileInputStream(updateContent));
        try {
            int[] chunkLengths = readChunkLengths(stream);
            installFile(new File(updateDir, seappContextsPath), stream, chunkLengths[0]);
            installFile(new File(updateDir, propertyContextsPath), stream, chunkLengths[1]);
            installFile(new File(updateDir, fileContextsPath), stream, chunkLengths[2]);
            installFile(new File(updateDir, sepolicyPath), stream, chunkLengths[3]);
        } finally {
            IoUtils.closeQuietly(stream);
        }
    }

    private void applyUpdate() throws IOException, ErrnoException {
        Slog.i(TAG, "Applying SELinux policy");
        File contexts = new File(updateDir.getParentFile(), "contexts");
        File current = new File(updateDir.getParentFile(), "current");
        File update = new File(updateDir.getParentFile(), "update");
        File tmp = new File(updateDir.getParentFile(), "tmp");
        if (current.exists()) {
            Libcore.os.symlink(updateDir.getPath(), update.getPath());
            Libcore.os.rename(update.getPath(), current.getPath());
        } else {
            Libcore.os.symlink(updateDir.getPath(), current.getPath());
        }
        contexts.mkdirs();
        backupContexts(contexts);
        copyUpdate(contexts);
        Libcore.os.symlink(contexts.getPath(), tmp.getPath());
        Libcore.os.rename(tmp.getPath(), current.getPath());
        SystemProperties.set("selinux.reload_policy", "1");
    }

    @Override
    protected void postInstall(Context context, Intent intent) {
        try {
            unpackBundle();
            applyUpdate();
        } catch (IllegalArgumentException e) {
            Slog.e(TAG, "SELinux policy update malformed: ", e);
        } catch (IOException e) {
            Slog.e(TAG, "Could not update selinux policy: ", e);
        } catch (ErrnoException e) {
            Slog.e(TAG, "Could not update selinux policy: ", e);
        }
    }
}
