/* SPDX-License-Identifier: BSD-3-Clause */
/*
 * swtpm_localca_utils.c: Utility functions
 *
 * Author: Stefan Berger, stefanb@linux.ibm.com
 *
 * Copyright (c) IBM Corporation, 2021
 */

#include "config.h"

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <regex.h>
#include <errno.h>
#include <sys/file.h>

#include "swtpm_utils.h"
#include "swtpm_localca.h"
#include "swtpm_localca_utils.h"

/* Create a directory pat (and all its predecessors) if it doesn't exist */
int makedir(const char *dirname, const char *purpose)
{
    struct stat statbuf;

    if (stat(dirname, &statbuf) != 0) {
        logit(gl_LOGFILE, "Creating swtpm-localca dir '%s'.\n", dirname);
        if (g_mkdir_with_parents(dirname, S_IRWXU | S_IRWXG | S_IXGRP | S_IRGRP) == -1) {
            logerr(gl_LOGFILE, "Could not create directory for '%s': %s\n",
                   purpose, strerror(errno));
            return 1;
        }
    }
    return 0;
}

/* Get a configuration value given its name */
gchar *get_config_value(gchar **config_file_lines, const gchar *configname, const gchar *fallback)
{
    g_autofree gchar *regex = g_strdup_printf("^%s[[:space:]]*=[[:space:]]*([^#\n]*).*", configname);
    gchar *result = NULL;
    regex_t preg;
    size_t idx;
    regmatch_t pmatch[2];

    if (regcomp(&preg, regex, REG_EXTENDED) != 0) {
        logerr(gl_LOGFILE, "Internal error: Could not compile regex\n");
        goto error;
    }

    for (idx = 0; config_file_lines[idx] != NULL; idx++) {
        const gchar *line = config_file_lines[idx];
        if (regexec(&preg, line, 2, pmatch, 0) == 0) {
            g_autofree gchar *tmp = NULL;

            tmp = g_strndup(&line[pmatch[1].rm_so],
                            pmatch[1].rm_eo - pmatch[1].rm_so);
            g_strchomp(tmp);
            result = resolve_string(tmp);
            break;
        }
    }
    regfree(&preg);

error:
    if (result == NULL)
        result = g_strdup(fallback);
    //printf("Found match for %s: |%s|\n", configname, result);

    return result;
}

/* Extract all environment variables from the config file and add them to
 * the given environent.
 * Environment variable lines must start with 'env:' and must not contain
 * trailing spaces or a comment starting with '#'
 */
int get_config_envvars(gchar **config_file_lines, gchar ***env)
{
    const char *regex = "^env:([a-zA-Z_][a-zA-Z_0-9]*)[[:space:]]*=[[:space:]]*([^\n]*)";
    regex_t preg;
    size_t idx;
    regmatch_t pmatch[3];

    if (regcomp(&preg, regex, REG_EXTENDED) != 0) {
        logerr(gl_LOGFILE, "Internal error: Could not compile regex\n");
        return 1;
    }

    for (idx = 0; config_file_lines[idx] != NULL; idx++) {
        const gchar *line = config_file_lines[idx];
        if (regexec(&preg, line, 3, pmatch, 0) == 0) {
            g_autofree gchar *key = NULL, *value = NULL;

            key = g_strndup(&line[pmatch[1].rm_so],
                            pmatch[1].rm_eo - pmatch[1].rm_so);
            value = g_strndup(&line[pmatch[2].rm_so],
                              pmatch[2].rm_eo - pmatch[2].rm_so);
            *env = g_environ_setenv(*env, key, value, TRUE);
        }
    }

    regfree(&preg);

    return 0;
}

/* flock a file; the file descriptor for the file to unlock later on is returned */
int lock_file(const gchar *lockfile)
{
    int lockfd;
    mode_t mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;

    lockfd = open(lockfile, O_RDWR | O_CREAT, mode);
    if (lockfd < 0) {
        logerr(gl_LOGFILE, "Could not open lockfile %s: %s\n", lockfile, strerror(errno));
        return -1;
    }

    if (flock(lockfd, LOCK_EX) < 0) {
        logerr(gl_LOGFILE, "Could not lock file %s: %s\n", lockfile, strerror(errno));
        close(lockfd);
        return -1;
    }
    return lockfd;
}

/* unlock a file previously locked using lock_file */
void unlock_file(int lockfd) {
    if (lockfd >= 0) {
        flock(lockfd, LOCK_UN);
        close(lockfd);
    }
}

/* Replace a few characters in vmid so it can be used by CommonName in cert */
void vmid_replacechars(char *vmid) {
    size_t i = 0;
    char c;

    while ((c = vmid[i])) {
        switch (c) {
        case '+':
            // https://github.com/gnutls/gnutls/blob/gnutls_3_6_x/lib/x509/x509_dn.c#L167
            if (i == 0 || vmid[i - 1] != '\\')
                vmid[i] = '_';
            break;
        case ',':
            // no commas allowed
            vmid[i] = '_';
            break;
        }
        i++;
    }
}
