/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.catalina.security;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Locale;
import java.util.Set;

import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleListener;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.res.StringManager;

public class SecurityListener implements LifecycleListener {

    private static final Log log = LogFactory.getLog(SecurityListener.class);

    private static final StringManager sm =
        StringManager.getManager(Constants.PACKAGE);

    private static final String UMASK_PROPERTY_NAME =
        Constants.PACKAGE + ".SecurityListener.UMASK";

    private static final String UMASK_FORMAT = "%04o";

    /**
     * The list of operating system users not permitted to run Tomcat.
     */
    private final Set<String> checkedOsUsers = new HashSet<>();

    /**
     * The minimum umask that must be configured for the operating system user
     * running Tomcat. The umask is handled as an octal.
     */
    private Integer minimumUmask = Integer.valueOf(7);


    public SecurityListener() {
        checkedOsUsers.add("root");
    }


    @Override
    public void lifecycleEvent(LifecycleEvent event) {
        // This is the earliest event in Lifecycle
        if (event.getType().equals(Lifecycle.BEFORE_INIT_EVENT)) {
            doChecks();
        }
    }


    /**
     * Set the list of operating system users not permitted to run Tomcat. By
     * default, only root is prevented from running Tomcat. Calling this method
     * with null or the empty string will clear the list of users and
     * effectively disables this check. User names will always be checked in a
     * case insensitive manner using the system default Locale.
     *
     * @param userNameList  A comma separated list of operating system users not
     *                      permitted to run Tomcat
     */
    public void setCheckedOsUsers(String userNameList) {
        if (userNameList == null || userNameList.length() == 0) {
            checkedOsUsers.clear();
        } else {
            String[] userNames = userNameList.split(",");
            for (String userName : userNames) {
                if (userName.length() > 0) {
                    checkedOsUsers.add(userName.toLowerCase(Locale.getDefault()));
                }
            }
        }
    }


    /**
     * Returns the current list of operating system users not permitted to run
     * Tomcat.
     *
     * @return  A comma separated list of operating system user names.
     */
    public String getCheckedOsUsers() {
        if (checkedOsUsers.size() == 0) {
            return "";
        }

        StringBuilder result = new StringBuilder();
        Iterator<String> iter = checkedOsUsers.iterator();
        result.append(iter.next());
        while (iter.hasNext()) {
            result.append(',');
            result.append(iter.next());
        }
        return result.toString();
    }


    /**
     * Set the minimum umask that must be configured before Tomcat will start.
     *
     * @param umask The 4-digit umask as returned by the OS command <i>umask</i>
     */
    public void setMinimumUmask(String umask) {
        if (umask == null || umask.length() == 0) {
            minimumUmask = Integer.valueOf(0);
        } else {
            minimumUmask = Integer.valueOf(umask, 8);
        }
    }


    /**
     * Get the minimum umask that must be configured before Tomcat will start.
     *
     * @return  The 4-digit umask as used by the OS command <i>umask</i>
     */
    public String getMinimumUmask() {
        return String.format(UMASK_FORMAT, minimumUmask);
    }


    /**
     * Execute the security checks. Each check should be in a separate method.
     */
    protected void doChecks() {
        checkOsUser();
        checkUmask();
    }


    protected void checkOsUser() {
        String userName = System.getProperty("user.name");
        if (userName != null) {
            String userNameLC = userName.toLowerCase(Locale.getDefault());

            if (checkedOsUsers.contains(userNameLC)) {
                // Have to throw Error to force start process to be aborted
                throw new Error(sm.getString(
                        "SecurityListener.checkUserWarning", userName));
            }
        }
    }


    protected void checkUmask() {
        String prop = System.getProperty(UMASK_PROPERTY_NAME);
        Integer umask = null;
        if (prop != null) {
            try {
                 umask = Integer.valueOf(prop, 8);
            } catch (NumberFormatException nfe) {
                log.warn(sm.getString("SecurityListener.checkUmaskParseFail",
                        prop));
            }
        }
        if (umask == null) {
            if (Constants.CRLF.equals(System.lineSeparator())) {
                // Probably running on Windows so no umask
                if (log.isDebugEnabled()) {
                    log.debug(sm.getString("SecurityListener.checkUmaskSkip"));
                }
                return;
            } else {
                if (minimumUmask.intValue() > 0) {
                    log.warn(sm.getString(
                            "SecurityListener.checkUmaskNone",
                            UMASK_PROPERTY_NAME, getMinimumUmask()));
                }
                return;
            }
        }

        if ((umask.intValue() & minimumUmask.intValue()) !=
                minimumUmask.intValue()) {
            throw new Error(sm.getString("SecurityListener.checkUmaskFail",
                    String.format(UMASK_FORMAT, umask), getMinimumUmask()));
        }
    }
}
