/* 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/. */
/* 
 * The following code handles the storage of PKCS 11 modules used by the
 * NSS. For the rest of NSS, only one kind of database handle exists:
 *
 *     SFTKDBHandle
 *
 * There is one SFTKDBHandle for each key database and one for each cert 
 * database. These databases are opened as associated pairs, one pair per
 * slot. SFTKDBHandles are reference counted objects.
 *
 * Each SFTKDBHandle points to a low level database handle (SDB). This handle
 * represents the underlying physical database. These objects are not 
 * reference counted, and are 'owned' by their respective SFTKDBHandles.
 */

#include "prprf.h" 
#include "prsystem.h"
#include "secport.h"
#include "utilpars.h" 
#include "secerr.h"

#if defined (_WIN32)
#include <io.h>
#endif
#ifdef XP_UNIX
#include <unistd.h>
#endif

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#if defined (_WIN32)
#define os_open _open
#define os_fdopen _fdopen
#define os_stat _stat
#define os_truncate_open_flags _O_CREAT|_O_RDWR|_O_TRUNC
#define os_append_open_flags _O_CREAT|_O_RDWR|_O_APPEND
#define os_open_permissions_type int
#define os_open_permissions_default _S_IREAD | _S_IWRITE
#define os_stat_type struct _stat
#else
#define os_open open
#define os_fdopen fdopen
#define os_stat stat
#define os_truncate_open_flags O_CREAT|O_RDWR|O_TRUNC
#define os_append_open_flags O_CREAT|O_RDWR|O_APPEND
#define os_open_permissions_type mode_t
#define os_open_permissions_default 0600
#define os_stat_type struct stat
#endif

/****************************************************************
 *
 * Secmod database.
 *
 * The new secmod database is simply a text file with each of the module
 * entries in the following form:
 *
 * #
 * # This is a comment The next line is the library to load
 * library=libmypkcs11.so
 * name="My PKCS#11 module"
 * params="my library's param string"
 * nss="NSS parameters"
 * other="parameters for other libraries and applications"
 * 
 * library=libmynextpk11.so
 * name="My other PKCS#11 module"
 */


/*
 * Smart string cat functions. Automatically manage the memory.
 * The first parameter is the destination string. If it's null, we 
 * allocate memory for it. If it's not, we reallocate memory
 * so the the concanenated string fits.
 */
static char *
nssutil_DupnCat(char *baseString, const char *str, int str_len)
{
    int baseStringLen = baseString ? PORT_Strlen(baseString) : 0;
    int len = baseStringLen + 1;
    char *newString;

    len += str_len;
    newString = (char *) PORT_Realloc(baseString,len);
    if (newString == NULL) {
	PORT_Free(baseString);
	return NULL;
    }
    PORT_Memcpy(&newString[baseStringLen], str, str_len);
    newString[len - 1] = 0;
    return newString;
}

/* Same as nssutil_DupnCat except it concatenates the full string, not a
 * partial one */
static char *
nssutil_DupCat(char *baseString, const char *str)
{
    return nssutil_DupnCat(baseString, str, PORT_Strlen(str));
}

/* function to free up all the memory associated with a null terminated
 * array of module specs */
static SECStatus
nssutil_releaseSpecList(char **moduleSpecList)
{
    if (moduleSpecList) {
	char **index;
	for(index = moduleSpecList; *index; index++) {
	    PORT_Free(*index);
	}
	PORT_Free(moduleSpecList);
    }
    return SECSuccess;
}

#define SECMOD_STEP 10
static SECStatus
nssutil_growList(char ***pModuleList, int *useCount, int last)
{
    char **newModuleList;

    *useCount += SECMOD_STEP;
    newModuleList = (char **)PORT_Realloc(*pModuleList,
					  *useCount*sizeof(char *));
    if (newModuleList == NULL) {
	return SECFailure;
    }
    PORT_Memset(&newModuleList[last],0, sizeof(char *)*SECMOD_STEP);
    *pModuleList = newModuleList;
    return SECSuccess;
}

static 
char *_NSSUTIL_GetOldSecmodName(const char *dbname,const char *filename)
{
    char *file = NULL;
    char *dirPath = PORT_Strdup(dbname);
    char *sep;

    sep = PORT_Strrchr(dirPath,*NSSUTIL_PATH_SEPARATOR);
#ifdef _WIN32
    if (!sep) {
	/* utilparst.h defines NSSUTIL_PATH_SEPARATOR as "/" for all
	 * platforms. */
	sep = PORT_Strrchr(dirPath,'\\');
    }
#endif
    if (sep) {
	*sep = 0;
	file = PR_smprintf("%s"NSSUTIL_PATH_SEPARATOR"%s", dirPath, filename);
    } else {
	file = PR_smprintf("%s", filename);
    }
    PORT_Free(dirPath);
    return file;
}

static SECStatus nssutil_AddSecmodDBEntry(const char *appName,
                                          const char *filename,
                                          const char *dbname,
                                          const char *module, PRBool rw);

enum lfopen_mode { lfopen_truncate, lfopen_append };

FILE *
lfopen(const char *name, enum lfopen_mode om, os_open_permissions_type open_perms)
{
    int fd;
    FILE *file;

    fd = os_open(name,
                 (om == lfopen_truncate) ? os_truncate_open_flags : os_append_open_flags,
                 open_perms);
    if (fd < 0) {
	return NULL;
    }
    file = os_fdopen(fd, (om == lfopen_truncate) ? "w+" : "a+");
    if (!file) {
	close(fd);
    }
    /* file inherits fd */
    return file;
}

#define MAX_LINE_LENGTH 2048

/*
 * Read all the existing modules in out of the file.
 */
static char **
nssutil_ReadSecmodDB(const char *appName, 
		    const char *filename, const char *dbname, 
		    char *params, PRBool rw)
{
    FILE *fd = NULL;
    char **moduleList = NULL;
    int moduleCount = 1;
    int useCount = SECMOD_STEP;
    char line[MAX_LINE_LENGTH];
    PRBool internal = PR_FALSE;
    PRBool skipParams = PR_FALSE;
    char *moduleString = NULL;
    char *paramsValue=NULL;
    PRBool failed = PR_TRUE;

    moduleList = (char **) PORT_ZAlloc(useCount*sizeof(char *));
    if (moduleList == NULL) return NULL;

    if (dbname == NULL) {
	goto return_default;
    }

    /* do we really want to use streams here */
    fd = fopen(dbname, "r");
    if (fd == NULL) goto done;

    /*
     * the following loop takes line separated config lines and collapses
     * the lines to a single string, escaping and quoting as necessary.
     */
    /* loop state variables */
    moduleString = NULL;  /* current concatenated string */
    internal = PR_FALSE;	     /* is this an internal module */
    skipParams = PR_FALSE;	   /* did we find an override parameter block*/
    paramsValue = NULL;		   /* the current parameter block value */
    while (fgets(line, sizeof(line), fd) != NULL) { 
	int len = PORT_Strlen(line);

	/* remove the ending newline */
	if (len && line[len-1] == '\n') {
	    len--;
	    line[len] = 0;
	}
	if (*line == '#') {
	    continue;
	}
	if (*line != 0) {
	    /*
	     * The PKCS #11 group standard assumes blocks of strings
	     * separated by new lines, clumped by new lines. Internally
	     * we take strings separated by spaces, so we may need to escape
	     * certain spaces.
	     */
	    char *value = PORT_Strchr(line,'=');

	    /* there is no value, write out the stanza as is */
	    if (value == NULL || value[1] == 0) {
		if (moduleString) {
		    moduleString = nssutil_DupnCat(moduleString," ", 1);
		    if (moduleString == NULL) goto loser;
		}
	        moduleString = nssutil_DupCat(moduleString, line);
		if (moduleString == NULL) goto loser;
	    /* value is already quoted, just write it out */
	    } else if (value[1] == '"') {
		if (moduleString) {
		    moduleString = nssutil_DupnCat(moduleString," ", 1);
		    if (moduleString == NULL) goto loser;
		}
	        moduleString = nssutil_DupCat(moduleString, line);
		if (moduleString == NULL) goto loser;
		/* we have an override parameter section, remember that
		 * we found this (see following comment about why this
		 * is necessary). */
	        if (PORT_Strncasecmp(line, "parameters", 10) == 0) {
			skipParams = PR_TRUE;
		}
	    /*
	     * The internal token always overrides it's parameter block
	     * from the passed in parameters, so wait until then end
	     * before we include the parameter block in case we need to 
	     * override it. NOTE: if the parameter block is quoted with ("),
	     * this override does not happen. This allows you to override
	     * the application's parameter configuration.
	     *
	     * parameter block state is controlled by the following variables:
	     *  skipParams - Bool : set to true of we have an override param
	     *    block (all other blocks, either implicit or explicit are
	     *    ignored).
	     *  paramsValue - char * : pointer to the current param block. In
	     *    the absence of overrides, paramsValue is set to the first
	     *    parameter block we find. All subsequent blocks are ignored.
	     *    When we find an internal token, the application passed
	     *    parameters take precident.
	     */
	    } else if (PORT_Strncasecmp(line, "parameters", 10) == 0) {
		/* already have parameters */
		if (paramsValue) {
			continue;
		}
		paramsValue = NSSUTIL_Quote(&value[1], '"');
		if (paramsValue == NULL) goto loser;
		continue;
	    } else {
	    /* may need to quote */
	        char *newLine;
		if (moduleString) {
		    moduleString = nssutil_DupnCat(moduleString," ", 1);
		    if (moduleString == NULL) goto loser;
		}
		moduleString = nssutil_DupnCat(moduleString,line,value-line+1);
		if (moduleString == NULL)  goto loser;
	        newLine = NSSUTIL_Quote(&value[1],'"');
		if (newLine == NULL) goto loser;
		moduleString = nssutil_DupCat(moduleString,newLine);
	        PORT_Free(newLine);
		if (moduleString == NULL) goto loser;
	    }

	    /* check to see if it's internal? */
	    if (PORT_Strncasecmp(line, "NSS=", 4) == 0) {
		/* This should be case insensitive! reviewers make
		 * me fix it if it's not */
		if (PORT_Strstr(line,"internal")) {
		    internal = PR_TRUE;
		    /* override the parameters */
		    if (paramsValue) {
			PORT_Free(paramsValue);
		    }
		    paramsValue = NSSUTIL_Quote(params, '"');
		}
	    }
	    continue;
	}
	if ((moduleString == NULL) || (*moduleString == 0)) {
	    continue;
	}

	/* 
	 * if we are here, we have found a complete stanza. Now write out
	 * any param section we may have found.
	 */
	if (paramsValue) {
	    /* we had an override */
	    if (!skipParams) {
		moduleString = nssutil_DupnCat(moduleString," parameters=", 12);
		if (moduleString == NULL) goto loser;
		moduleString = nssutil_DupCat(moduleString, paramsValue);
		if (moduleString == NULL) goto loser;
	    }
	    PORT_Free(paramsValue);
	    paramsValue = NULL;
	}

	if ((moduleCount+1) >= useCount) {
	    SECStatus rv;
	    rv = nssutil_growList(&moduleList, &useCount,  moduleCount+1);
	    if (rv != SECSuccess) {
		goto loser;
	    }
	}

	if (internal) {
	    moduleList[0] = moduleString;
	} else {
	    moduleList[moduleCount] = moduleString;
	    moduleCount++;
	}
	moduleString = NULL;
	internal = PR_FALSE;
	skipParams = PR_FALSE;
    } 

    if (moduleString) {
	PORT_Free(moduleString);
	moduleString = NULL;
    }
done:
    /* if we couldn't open a pkcs11 database, look for the old one */
    if (fd == NULL) {
	char *olddbname = _NSSUTIL_GetOldSecmodName(dbname,filename);
	PRStatus status;

	/* couldn't get the old name */
	if (!olddbname) {
	    goto bail;
	}

	/* old one exists */
	status = PR_Access(olddbname, PR_ACCESS_EXISTS);
	if (status == PR_SUCCESS) {
	    PR_smprintf_free(olddbname);
	    PORT_ZFree(moduleList, useCount*sizeof(char *));
	    PORT_SetError(SEC_ERROR_LEGACY_DATABASE);
	    return NULL;
	}

bail:
	if (olddbname) {
	    PR_smprintf_free(olddbname);
	}
    }

return_default:
	
    if (!moduleList[0]) {
	char * newParams;
	moduleString = PORT_Strdup(NSSUTIL_DEFAULT_INTERNAL_INIT1);
	newParams = NSSUTIL_Quote(params,'"');
	if (newParams == NULL) goto loser;
	moduleString = nssutil_DupCat(moduleString, newParams);
	PORT_Free(newParams);
	if (moduleString == NULL) goto loser;
	moduleString = nssutil_DupCat(moduleString, 
					NSSUTIL_DEFAULT_INTERNAL_INIT2);
	if (moduleString == NULL) goto loser;
	moduleString = nssutil_DupCat(moduleString,
					NSSUTIL_DEFAULT_SFTKN_FLAGS);
	if (moduleString == NULL) goto loser;
	moduleString = nssutil_DupCat(moduleString, 
					NSSUTIL_DEFAULT_INTERNAL_INIT3);
	if (moduleString == NULL) goto loser;
	moduleList[0] = moduleString;
	moduleString = NULL;
    }
    failed = PR_FALSE;

loser:
    /*
     * cleanup
     */
    /* deal with trust cert db here */
    if (moduleString) {
	PORT_Free(moduleString);
	moduleString = NULL;
    }
    if (paramsValue) {
	PORT_Free(paramsValue);
	paramsValue = NULL;
    }
    if (failed || (moduleList[0] == NULL)) {
	/* This is wrong! FIXME */
	nssutil_releaseSpecList(moduleList);
	moduleList = NULL;
	failed = PR_TRUE;
    }
    if (fd != NULL) {
	fclose(fd);
    } else if (!failed && rw) {
	/* update our internal module */
	nssutil_AddSecmodDBEntry(appName, filename, dbname, moduleList[0], rw);
    }
    return moduleList;
}

static SECStatus
nssutil_ReleaseSecmodDBData(const char *appName, 
			const char *filename, const char *dbname, 
			char **moduleSpecList, PRBool rw)
{
    if (moduleSpecList) {
	nssutil_releaseSpecList(moduleSpecList);
    }
    return SECSuccess;
}


/*
 * Delete a module from the Data Base
 */
static SECStatus
nssutil_DeleteSecmodDBEntry(const char *appName,
                            const char *filename,
                            const char *dbname,
                            const char *args,
                            PRBool rw)
{
    /* SHDB_FIXME implement */
    os_stat_type stat_existing;
    os_open_permissions_type file_mode;
    FILE *fd = NULL;
    FILE *fd2 = NULL;
    char line[MAX_LINE_LENGTH];
    char *dbname2 = NULL;
    char *block = NULL;
    char *name = NULL;
    char *lib = NULL;
    int name_len = 0, lib_len = 0;
    PRBool skip = PR_FALSE;
    PRBool found = PR_FALSE;

    if (dbname == NULL) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }

    if (!rw) {
	PORT_SetError(SEC_ERROR_READ_ONLY);
	return SECFailure;
    }

    dbname2 = PORT_Strdup(dbname);
    if (dbname2 == NULL) goto loser;
    dbname2[strlen(dbname)-1]++;

    /* get the permissions of the existing file, or use the default */
    if (!os_stat(dbname, &stat_existing)) {
	file_mode = stat_existing.st_mode;
    } else {
	file_mode = os_open_permissions_default;
    }

    /* do we really want to use streams here */
    fd = fopen(dbname, "r");
    if (fd == NULL) goto loser;

    fd2 = lfopen(dbname2, lfopen_truncate, file_mode);

    if (fd2 == NULL) goto loser;

    name = NSSUTIL_ArgGetParamValue("name",args);
    if (name) {
	name_len = PORT_Strlen(name);
    }
    lib = NSSUTIL_ArgGetParamValue("library",args);
    if (lib) {
	lib_len = PORT_Strlen(lib);
    }


    /*
     * the following loop takes line separated config files and collapses
     * the lines to a single string, escaping and quoting as necessary.
     */
    /* loop state variables */
    block = NULL;
    skip = PR_FALSE;
    while (fgets(line, sizeof(line), fd) != NULL) { 
	/* If we are processing a block (we haven't hit a blank line yet */
	if (*line != '\n') {
	    /* skip means we are in the middle of a block we are deleting */
	    if (skip) {
		continue;
	    }
	    /* if we haven't found the block yet, check to see if this block
	     * matches our requirements */
	    if (!found && ((name && (PORT_Strncasecmp(line,"name=",5) == 0) &&
		 (PORT_Strncmp(line+5,name,name_len) == 0))  ||
	        (lib && (PORT_Strncasecmp(line,"library=",8) == 0) &&
		 (PORT_Strncmp(line+8,lib,lib_len) == 0)))) {

		/* yup, we don't need to save any more data, */
		PORT_Free(block);
		block=NULL;
		/* we don't need to collect more of this block */
		skip = PR_TRUE;
		/* we don't need to continue searching for the block */
		found =PR_TRUE;
		continue;
	    }
	    /* not our match, continue to collect data in this block */
	    block = nssutil_DupCat(block,line);
	    continue;
	}
	/* we've collected a block of data that wasn't the module we were
	 * looking for, write it out */
	if (block) {
	    fwrite(block, PORT_Strlen(block), 1, fd2);
	    PORT_Free(block);
	    block = NULL;
	}
	/* If we didn't just delete the this block, keep the blank line */
	if (!skip) {
	    fputs(line,fd2);
	}
	/* we are definately not in a deleted block anymore */
	skip = PR_FALSE;
    } 
    fclose(fd);
    fclose(fd2);
    if (found) {
	/* rename dbname2 to dbname */
	PR_Delete(dbname);
	PR_Rename(dbname2,dbname);
    } else {
	PR_Delete(dbname2);
    }
    PORT_Free(dbname2);
    PORT_Free(lib);
    PORT_Free(name);
    PORT_Free(block);
    return SECSuccess;

loser:
    if (fd != NULL) {
	fclose(fd);
    }
    if (fd2 != NULL) {
	fclose(fd2);
    }
    if (dbname2) {
	PR_Delete(dbname2);
	PORT_Free(dbname2);
    }
    PORT_Free(lib);
    PORT_Free(name);
    return SECFailure;
}

/*
 * Add a module to the Data base 
 */
static SECStatus
nssutil_AddSecmodDBEntry(const char *appName,
                        const char *filename, const char *dbname,
                        const char *module, PRBool rw)
{
    os_stat_type stat_existing;
    os_open_permissions_type file_mode;
    FILE *fd = NULL;
    char *block = NULL;
    PRBool libFound = PR_FALSE;

    if (dbname == NULL) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }

    /* can't write to a read only module */
    if (!rw) {
	PORT_SetError(SEC_ERROR_READ_ONLY);
	return SECFailure;
    }

    /* remove the previous version if it exists */
    (void) nssutil_DeleteSecmodDBEntry(appName, filename, dbname, module, rw);

    /* get the permissions of the existing file, or use the default */
    if (!os_stat(dbname, &stat_existing)) {
	file_mode = stat_existing.st_mode;
    } else {
	file_mode = os_open_permissions_default;
    }

    fd = lfopen(dbname, lfopen_append, file_mode);
    if (fd == NULL) {
	return SECFailure;
    }
    module = NSSUTIL_ArgStrip(module);
    while (*module) {
	int count;
	char *keyEnd = PORT_Strchr(module,'=');
	char *value;

	if (PORT_Strncmp(module, "library=", 8) == 0) {
	   libFound=PR_TRUE;
	}
	if (keyEnd == NULL) {
	    block = nssutil_DupCat(block, module);
	    break;
	}
	block = nssutil_DupnCat(block, module, keyEnd-module+1);
	if (block == NULL) { goto loser; }
	value = NSSUTIL_ArgFetchValue(&keyEnd[1], &count);
	if (value) {
	    block = nssutil_DupCat(block, NSSUTIL_ArgStrip(value));
	    PORT_Free(value);
	}
	if (block == NULL) { goto loser; }
	block = nssutil_DupnCat(block, "\n", 1);
	module = keyEnd + 1 + count;
	module = NSSUTIL_ArgStrip(module);
    }
    if (block) {
	if (!libFound) {
	    fprintf(fd,"library=\n");
	}
	fwrite(block, PORT_Strlen(block), 1, fd);
	fprintf(fd,"\n");
	PORT_Free(block);
	block = NULL;
    }
    fclose(fd);
    return SECSuccess;

loser:
    PORT_Free(block);
    fclose(fd);
    return SECFailure;
}
  

char **
NSSUTIL_DoModuleDBFunction(unsigned long function,char *parameters, void *args)
{
    char *secmod = NULL;
    char *appName = NULL;
    char *filename = NULL;
    NSSDBType dbType = NSS_DB_TYPE_NONE;
    PRBool rw;
    static char *success="Success";
    char **rvstr = NULL;


    secmod = _NSSUTIL_GetSecmodName(parameters, &dbType, &appName,
				    &filename, &rw);
    if ((dbType == NSS_DB_TYPE_LEGACY) || 
	 (dbType == NSS_DB_TYPE_MULTIACCESS)) {
	/* we can't handle the old database, only softoken can */
	PORT_SetError(SEC_ERROR_LEGACY_DATABASE);
	rvstr =  NULL;
	goto done;
    }

    switch (function) {
    case SECMOD_MODULE_DB_FUNCTION_FIND:
        rvstr = nssutil_ReadSecmodDB(appName,filename,
				     secmod,(char *)parameters,rw);
        break;
    case SECMOD_MODULE_DB_FUNCTION_ADD:
        rvstr = (nssutil_AddSecmodDBEntry(appName, filename,
                                          secmod, (char *)args, rw)
                 == SECSuccess) ? &success: NULL;
        break;
    case SECMOD_MODULE_DB_FUNCTION_DEL:
        rvstr = (nssutil_DeleteSecmodDBEntry(appName, filename,
                                             secmod, (char *)args, rw)
                 == SECSuccess) ? &success: NULL;
        break;
    case SECMOD_MODULE_DB_FUNCTION_RELEASE:
        rvstr = (nssutil_ReleaseSecmodDBData(appName, filename,
                                             secmod, (char **)args, rw)
                 == SECSuccess) ? &success: NULL;
        break;
    }
done:
    if (secmod) PR_smprintf_free(secmod);
    if (appName) PORT_Free(appName);
    if (filename) PORT_Free(filename);
    return rvstr;
}
