/*
 * Copyright (C) 2010 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 android.tests.getinfo;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Pattern;

/** Crawls /proc to find processes that are running as root. */
class RootProcessScanner {

    /** Processes that are allowed to run as root. */
    private static final Pattern ROOT_PROCESS_WHITELIST_PATTERN = getRootProcessWhitelistPattern(
            "debuggerd",
            "init",
            "installd",
            "servicemanager",
            "vold",
            "zygote"
    );

    /** Combine the individual patterns into one super pattern. */
    private static Pattern getRootProcessWhitelistPattern(String... patterns) {
        StringBuilder rootProcessPattern = new StringBuilder();
        for (int i = 0; i < patterns.length; i++) {
            rootProcessPattern.append(patterns[i]);
            if (i + 1 < patterns.length) {
                rootProcessPattern.append('|');
            }
        }
        return Pattern.compile(rootProcessPattern.toString());
    }

    /** Test that there are no unapproved root processes running on the system. */
    public static String[] getRootProcesses()
            throws FileNotFoundException, MalformedStatMException {
        List<File> rootProcessDirs = getRootProcessDirs();
        String[] rootProcessNames = new String[rootProcessDirs.size()];
        for (int i = 0; i < rootProcessNames.length; i++) {
            rootProcessNames[i] = getProcessName(rootProcessDirs.get(i));
        }
        return rootProcessNames;
    }

    private static List<File> getRootProcessDirs()
            throws FileNotFoundException, MalformedStatMException {
        File proc = new File("/proc");
        if (!proc.exists()) {
            throw new FileNotFoundException(proc + " is missing (man 5 proc)");
        }

        List<File> rootProcesses = new ArrayList<File>();
        File[] processDirs = proc.listFiles();
        if (processDirs != null && processDirs.length > 0) {
            for (File processDir : processDirs) {
                if (isUnapprovedRootProcess(processDir)) {
                    rootProcesses.add(processDir);
                }
            }
        }
        return rootProcesses;
    }

    /**
     * Filters out processes in /proc that are not approved.
     * @throws FileNotFoundException
     * @throws MalformedStatMException
     */
    private static boolean isUnapprovedRootProcess(File pathname)
            throws FileNotFoundException, MalformedStatMException {
        return isPidDirectory(pathname)
                && !isKernelProcess(pathname)
                && isRootProcess(pathname);
    }

    private static boolean isPidDirectory(File pathname) {
        return pathname.isDirectory() && Pattern.matches("\\d+", pathname.getName());
    }

    private static boolean isKernelProcess(File processDir)
            throws FileNotFoundException, MalformedStatMException {
        File statm = getProcessStatM(processDir);
        Scanner scanner = null;
        try {
            scanner = new Scanner(statm);

            boolean allZero = true;
            for (int i = 0; i < 7; i++) {
                if (scanner.nextInt() != 0) {
                    allZero = false;
                }
            }

            if (scanner.hasNext()) {
                throw new MalformedStatMException(processDir
                        + " statm expected to have 7 integers (man 5 proc)");
            }

            return allZero;
        } finally {
            if (scanner != null) {
                scanner.close();
            }
        }
    }

    private static File getProcessStatM(File processDir) {
        return new File(processDir, "statm");
    }

    public static class MalformedStatMException extends Exception {
        MalformedStatMException(String detailMessage) {
            super(detailMessage);
        }
    }

    /**
     * Return whether or not this process is running as root without being approved.
     *
     * @param processDir with the status file
     * @return whether or not it is a unwhitelisted root process
     * @throws FileNotFoundException
     */
    private static boolean isRootProcess(File processDir) throws FileNotFoundException {
        File status = getProcessStatus(processDir);
        Scanner scanner = null;
        try {
            scanner = new Scanner(status);

            scanner = findToken(scanner, "Name:");
            String name = scanner.next();

            scanner = findToken(scanner, "Uid:");
            boolean rootUid = hasRootId(scanner);

            scanner = findToken(scanner, "Gid:");
            boolean rootGid = hasRootId(scanner);

            return !ROOT_PROCESS_WHITELIST_PATTERN.matcher(name).matches()
                    && (rootUid || rootGid);
        } finally {
            if (scanner != null) {
                scanner.close();
            }
        }
    }

    /**
     * Get the status {@link File} that has name:value pairs.
     * <pre>
     * Name:   init
     * ...
     * Uid:    0       0       0       0
     * Gid:    0       0       0       0
     * </pre>
     */
    private static File getProcessStatus(File processDir) {
        return new File(processDir, "status");
    }

    /**
     * Convenience method to move the scanner's position to the point after the given token.
     *
     * @param scanner to call next() until the token is found
     * @param token to find like "Name:"
     * @return scanner after finding token
     */
    private static Scanner findToken(Scanner scanner, String token) {
        while (true) {
            String next = scanner.next();
            if (next.equals(token)) {
                return scanner;
            }
        }

        // Scanner will exhaust input and throw an exception before getting here.
    }

    /**
     * Uid and Gid lines have four values: "Uid:    0       0       0       0"
     *
     * @param scanner that has just processed the "Uid:" or "Gid:" token
     * @return whether or not any of the ids are root
     */
    private static boolean hasRootId(Scanner scanner) {
        int realUid = scanner.nextInt();
        int effectiveUid = scanner.nextInt();
        int savedSetUid = scanner.nextInt();
        int fileSystemUid = scanner.nextInt();
        return realUid == 0 || effectiveUid == 0 || savedSetUid == 0 || fileSystemUid == 0;
    }

    /** Returns the name of the process corresponding to its process directory in /proc. */
    private static String getProcessName(File processDir) throws FileNotFoundException {
        File status = getProcessStatus(processDir);
        Scanner scanner = new Scanner(status);
        try {
            scanner = findToken(scanner, "Name:");
            return scanner.next();
        } finally {
            scanner.close();
        }
    }
}
