/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "seccomon.h"
#include "prio.h"
#include "prprf.h"
#include "plhash.h"
#include "prenv.h"

/*
 * The following provides a default example for operating systems to set up
 * and manage applications loading NSS on their OS globally.
 *
 * This code hooks in to the system pkcs11.txt, which controls all the loading
 * of pkcs11 modules common to all applications.
 */

/*
 * OS Specific function to get where the NSS user database should reside.
 */

#ifdef XP_UNIX
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>

static int
testdir(char *dir)
{
    struct stat buf;
    memset(&buf, 0, sizeof(buf));

    if (stat(dir, &buf) < 0) {
        return 0;
    }

    return S_ISDIR(buf.st_mode);
}

#define NSS_USER_PATH1 "/.pki"
#define NSS_USER_PATH2 "/nssdb"
static char *
getUserDB(void)
{
    char *userdir = PR_GetEnvSecure("HOME");
    char *nssdir = NULL;

    if (userdir == NULL) {
        return NULL;
    }

    nssdir = PORT_Alloc(strlen(userdir) + sizeof(NSS_USER_PATH1) + sizeof(NSS_USER_PATH2));
    if (nssdir == NULL) {
        return NULL;
    }
    PORT_Strcpy(nssdir, userdir);
    /* verify it exists */
    if (!testdir(nssdir)) {
        PORT_Free(nssdir);
        return NULL;
    }
    PORT_Strcat(nssdir, NSS_USER_PATH1);
    if (!testdir(nssdir) && mkdir(nssdir, 0760)) {
        PORT_Free(nssdir);
        return NULL;
    }
    PORT_Strcat(nssdir, NSS_USER_PATH2);
    if (!testdir(nssdir) && mkdir(nssdir, 0760)) {
        PORT_Free(nssdir);
        return NULL;
    }
    return nssdir;
}

#define NSS_DEFAULT_SYSTEM "/etc/pki/nssdb"
static char *
getSystemDB(void)
{
    return PORT_Strdup(NSS_DEFAULT_SYSTEM);
}

static PRBool
userIsRoot()
{
    /* this works for linux and all unixes that we know off
       though it isn't stated as such in POSIX documentation */
    return getuid() == 0;
}

static PRBool
userCanModifySystemDB()
{
    return (access(NSS_DEFAULT_SYSTEM, W_OK) == 0);
}

#else
#ifdef XP_WIN
static char *
getUserDB(void)
{
    /* use the registry to find the user's NSS_DIR. if no entry exists, create
     * one in the users Appdir location */
    return NULL;
}

static char *
getSystemDB(void)
{
    /* use the registry to find the system's NSS_DIR. if no entry exists, create
     * one based on the windows system data area */
    return NULL;
}

static PRBool
userIsRoot()
{
    /* use the registry to find if the user is the system administrator. */
    return PR_FALSE;
}

static PRBool
userCanModifySystemDB()
{
    /* use the registry to find if the user has administrative privilege
    * to modify the system's nss database. */
    return PR_FALSE;
}

#else
#error "Need to write getUserDB, SystemDB, userIsRoot, and userCanModifySystemDB functions"
#endif
#endif

static PRBool
getFIPSEnv(void)
{
    char *fipsEnv = PR_GetEnvSecure("NSS_FIPS");
    if (!fipsEnv) {
        return PR_FALSE;
    }
    if ((strcasecmp(fipsEnv, "fips") == 0) ||
        (strcasecmp(fipsEnv, "true") == 0) ||
        (strcasecmp(fipsEnv, "on") == 0) ||
        (strcasecmp(fipsEnv, "1") == 0)) {
        return PR_TRUE;
    }
    return PR_FALSE;
}
#ifdef XP_LINUX

static PRBool
getFIPSMode(void)
{
    FILE *f;
    char d;
    size_t size;

    f = fopen("/proc/sys/crypto/fips_enabled", "r");
    if (!f) {
        /* if we don't have a proc flag, fall back to the
     * environment variable */
        return getFIPSEnv();
    }

    size = fread(&d, 1, 1, f);
    fclose(f);
    if (size != 1)
        return PR_FALSE;
    if (d != '1')
        return PR_FALSE;
    return PR_TRUE;
}

#else
static PRBool
getFIPSMode(void)
{
    return getFIPSEnv();
}
#endif

#define NSS_DEFAULT_FLAGS "flags=readonly"

/* configuration flags according to
 * https://developer.mozilla.org/en/PKCS11_Module_Specs
 * As stated there the slotParams start with a slot name which is a slotID
 * Slots 1 through 3 are reserved for the nss internal modules as follows:
 * 1 for crypto operations slot non-fips,
 * 2 for the key slot, and
 * 3 for the crypto operations slot fips
 */
#define CIPHER_ORDER_FLAGS "cipherOrder=100"
#define SLOT_FLAGS                                                  \
    "[slotFlags=RSA,RC4,RC2,DES,DH,SHA1,MD5,MD2,SSL,TLS,AES,RANDOM" \
    " askpw=any timeout=30 ]"

static const char *nssDefaultFlags =
    CIPHER_ORDER_FLAGS " slotParams={0x00000001=" SLOT_FLAGS " }  ";

static const char *nssDefaultFIPSFlags =
    CIPHER_ORDER_FLAGS " slotParams={0x00000003=" SLOT_FLAGS " }  ";

/*
 * This function builds the list of databases and modules to load, and sets
 * their configuration. For the sample we have a fixed set.
 *  1. We load the user's home nss database.
 *  2. We load the user's custom PKCS #11 modules.
 *  3. We load the system nss database readonly.
 *
 * Any space allocated in get_list must be freed in release_list.
 * This function can use whatever information is available to the application.
 * it is running in the process of the application for which it is making
 * decisions, so it's possible to acquire the application name as part of
 * the decision making process.
 *
 */
static char **
get_list(char *filename, char *stripped_parameters)
{
    char **module_list = PORT_ZNewArray(char *, 5);
    char *userdb, *sysdb;
    int isFIPS = getFIPSMode();
    const char *nssflags = isFIPS ? nssDefaultFIPSFlags : nssDefaultFlags;
    int next = 0;

    /* can't get any space */
    if (module_list == NULL) {
        return NULL;
    }

    sysdb = getSystemDB();
    userdb = getUserDB();

    /* Don't open root's user DB */
    if (userdb != NULL && !userIsRoot()) {
        /* return a list of databases to open. First the user Database */
        module_list[next++] = PR_smprintf(
            "library= "
            "module=\"NSS User database\" "
            "parameters=\"configdir='sql:%s' %s tokenDescription='NSS user database'\" "
            "NSS=\"trustOrder=75 %sflags=internal%s\"",
            userdb, stripped_parameters, nssflags,
            isFIPS ? ",FIPS" : "");

        /* now open the user's defined PKCS #11 modules */
        /* skip the local user DB entry */
        module_list[next++] = PR_smprintf(
            "library= "
            "module=\"NSS User database\" "
            "parameters=\"configdir='sql:%s' %s\" "
            "NSS=\"flags=internal,moduleDBOnly,defaultModDB,skipFirst\"",
            userdb, stripped_parameters);
    }

    /* now the system database (always read only unless it's root) */
    if (sysdb) {
        const char *readonly = userCanModifySystemDB() ? "" : "flags=readonly";
        module_list[next++] = PR_smprintf(
            "library= "
            "module=\"NSS system database\" "
            "parameters=\"configdir='sql:%s' tokenDescription='NSS system database' %s\" "
            "NSS=\"trustOrder=80 %sflags=internal,critical\"",
            sysdb, readonly, nssflags);
    }

    /* that was the last module */
    module_list[next] = 0;

    PORT_Free(userdb);
    PORT_Free(sysdb);

    return module_list;
}

static char **
release_list(char **arg)
{
    static char *success = "Success";
    int next;

    for (next = 0; arg[next]; next++) {
        free(arg[next]);
    }
    PORT_Free(arg);
    return &success;
}

#include "utilpars.h"

#define TARGET_SPEC_COPY(new, start, end) \
    if (end > start) {                    \
        int _cnt = end - start;           \
        PORT_Memcpy(new, start, _cnt);    \
        new += _cnt;                      \
    }

/*
 * According the strcpy man page:
 *
 * The strings  may  not overlap, and the destination string dest must be
 * large enough to receive the copy.
 *
 * This implementation allows target to overlap with src.
 * It does not allow the src to overlap the target.
 *  example: overlapstrcpy(string, string+4) is fine
 *           overlapstrcpy(string+4, string) is not.
 */
static void
overlapstrcpy(char *target, char *src)
{
    while (*src) {
        *target++ = *src++;
    }
    *target = 0;
}

/* determine what options the user was trying to open this database with */
/* filename is the directory pointed to by configdir= */
/* stripped is the rest of the parameters with configdir= stripped out */
static SECStatus
parse_parameters(const char *parameters, char **filename, char **stripped)
{
    const char *sourcePrev;
    const char *sourceCurr;
    char *targetCurr;
    char *newStripped;
    *filename = NULL;
    *stripped = NULL;

    newStripped = PORT_Alloc(PORT_Strlen(parameters) + 2);
    targetCurr = newStripped;
    sourcePrev = parameters;
    sourceCurr = NSSUTIL_ArgStrip(parameters);
    TARGET_SPEC_COPY(targetCurr, sourcePrev, sourceCurr);

    while (*sourceCurr) {
        int next;
        sourcePrev = sourceCurr;
        NSSUTIL_HANDLE_STRING_ARG(sourceCurr, *filename, "configdir=",
                                  sourcePrev = sourceCurr;)
        NSSUTIL_HANDLE_FINAL_ARG(sourceCurr);
        TARGET_SPEC_COPY(targetCurr, sourcePrev, sourceCurr);
    }
    *targetCurr = 0;
    if (*filename == NULL) {
        PORT_Free(newStripped);
        return SECFailure;
    }
    /* strip off any directives from the filename */
    if (strncmp("sql:", *filename, 4) == 0) {
        overlapstrcpy(*filename, (*filename) + 4);
    } else if (strncmp("dbm:", *filename, 4) == 0) {
        overlapstrcpy(*filename, (*filename) + 4);
    } else if (strncmp("extern:", *filename, 7) == 0) {
        overlapstrcpy(*filename, (*filename) + 7);
    }
    *stripped = newStripped;
    return SECSuccess;
}

/* entry point */
char **
NSS_ReturnModuleSpecData(unsigned long function, char *parameters, void *args)
{
    char *filename = NULL;
    char *stripped = NULL;
    char **retString = NULL;
    SECStatus rv;

    rv = parse_parameters(parameters, &filename, &stripped);
    if (rv != SECSuccess) {
        /* use defaults */
        filename = getSystemDB();
        if (!filename) {
            return NULL;
        }
        stripped = PORT_Strdup(NSS_DEFAULT_FLAGS);
        if (!stripped) {
            free(filename);
            return NULL;
        }
    }
    switch (function) {
        case SECMOD_MODULE_DB_FUNCTION_FIND:
            retString = get_list(filename, stripped);
            break;
        case SECMOD_MODULE_DB_FUNCTION_RELEASE:
            retString = release_list((char **)args);
            break;
        /* can't add or delete from this module DB */
        case SECMOD_MODULE_DB_FUNCTION_ADD:
        case SECMOD_MODULE_DB_FUNCTION_DEL:
            retString = NULL;
            break;
        default:
            retString = NULL;
            break;
    }

    PORT_Free(filename);
    PORT_Free(stripped);
    return retString;
}
