• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stefanberger / swtpm / #2827

13 May 2025 12:48PM UTC coverage: 73.203% (-0.09%) from 73.293%
#2827

push

travis-ci

web-flow
Merge c4cda135b into 29d533fbf

7149 of 9766 relevant lines covered (73.2%)

14116.95 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

22.22
/src/swtpm_setup/swtpm_setup_utils.c
1
/* SPDX-License-Identifier: BSD-3-Clause */
2
/*
3
 * swtpm_setup_utils.c: Utility functions for swtpm_setup
4
 *
5
 * Author: Stefan Berger, stefanb@linux.ibm.com
6
 *
7
 * Copyright (c) IBM Corporation, 2021
8
 */
9

10
#include "config.h"
11

12
#include <errno.h>
13
#include <regex.h>
14
#include <stdio.h>
15
#include <stdlib.h>
16
#include <string.h>
17
#include <sys/utsname.h>
18
#include <unistd.h>
19

20
#include <glib.h>
21

22
#include "swtpm_conf.h"
23
#include "swtpm_utils.h"
24
#include "swtpm_setup_utils.h"
25

26
/* Get a configuration value given its name */
27
gchar *get_config_value(gchar **config_file_lines, const gchar *configname)
289✔
28
{
29
    g_autofree gchar *regex = g_strdup_printf("^%s[[:space:]]*=[[:space:]]*([^#\n]*).*",
289✔
30
                                              configname);
31
    gchar *result = NULL;
289✔
32
    regmatch_t pmatch[2];
289✔
33
    regex_t preg;
289✔
34
    size_t idx;
289✔
35

36
    if (regcomp(&preg, regex, REG_EXTENDED) != 0) {
289✔
37
        logerr(gl_LOGFILE, "Internal error: Could not compile regex\n");
×
38
        return NULL;
×
39
    }
40

41
    for (idx = 0; config_file_lines[idx] != NULL; idx++) {
858✔
42
        const gchar *line = config_file_lines[idx];
687✔
43
        if (regexec(&preg, line, 2, pmatch, 0) == 0) {
687✔
44
            g_autofree gchar *tmp = NULL;
118✔
45

46
            tmp = g_strndup(&line[pmatch[1].rm_so],
236✔
47
                            pmatch[1].rm_eo - pmatch[1].rm_so);
118✔
48
            g_strchomp(tmp);
118✔
49
            result = resolve_string(tmp);
118✔
50
            break;
118✔
51
        }
52
    }
53

54
    regfree(&preg);
289✔
55

56
    return result;
289✔
57
}
58

59
/* Create swtpm_setup and swtpm-localca config files for a user
60
 *
61
 * @overwrite: TRUE:  overwrite any existing config files
62
 *             FALSE: return error if any file exists
63
 * @root_flag: TRUE:  create the config files under root's home
64
 *                    directory shadowing any existing config files in /etc/
65
 *             FALSE: refuse to create config files as root
66
 * @skip_if_exist: TRUE  if any one config files exists return with no error
67
 *
68
 */
69
int create_config_files(gboolean overwrite, gboolean root_flag,
×
70
                        gboolean skip_if_exist)
71
{
72
    enum {
×
73
        SWTPM_SETUP_CONF = 0,
74
        SWTPM_LOCALCA_CONF = 1,
75
        SWTPM_LOCALCA_OPTIONS = 2,
76
        NUM_FILES = 3,
77
    };
78
    const gchar *filenames[NUM_FILES] = {
×
79
        "swtpm_setup.conf",
80
        "swtpm-localca.conf",
81
        "swtpm-localca.options"
82
    };
83
    const gchar *configdir = g_get_user_config_dir();
×
84
    g_autofree gchar *create_certs_tool = NULL;
×
85
    g_autofree gchar *swtpm_localca_dir = NULL;
×
86
    g_autofree gchar *signkey = NULL;
×
87
    g_autofree gchar *issuercert = NULL;
×
88
    g_autofree gchar *certserial = NULL;
×
89
    g_autofree gchar *platform_manufacturer = NULL;
×
90
    g_autofree gchar *platform_version = NULL;
×
91
    g_autofree gchar *platform_model = NULL;
×
92
    g_autoptr(GError) error = NULL;
×
93
    gboolean delete_files = FALSE;
×
94
    g_auto(GStrv) configfiles = NULL;
×
95
    g_auto(GStrv) filedata = NULL;
×
96
    struct utsname utsname;
×
97
    int ret = 1;
×
98
    size_t i;
×
99

100
    if (getuid() == 0 && !root_flag) {
×
101
        fprintf(stderr, "Requiring the 'root' flag since the configuration "
×
102
                        "files will shadow those in %s.\n", SYSCONFDIR);
103
        goto error;
×
104
    }
105

106
    configfiles = g_new0(gchar *, NUM_FILES + 1);
×
107
    for (i = 0; i < NUM_FILES; i++) {
×
108
        configfiles[i] = g_build_filename(configdir, filenames[i], NULL);
×
109
        if (!overwrite && g_file_test(configfiles[i], G_FILE_TEST_EXISTS)) {
×
110
            if (skip_if_exist) {
×
111
                ret = 0;
112
            } else {
113
                fprintf(stderr, "File %s already exists. Refusing to overwrite.\n",
×
114
                        configfiles[i]);
115
            }
116
            goto out;
×
117
        }
118
    }
119

120
    swtpm_localca_dir = g_build_filename(configdir,
×
121
                                         "var", "lib", "swtpm-localca", NULL);
122
    if (g_mkdir_with_parents(swtpm_localca_dir, 0775) < 0) {
×
123
        fprintf(stderr, "Could not create %s: %s\n",
×
124
                swtpm_localca_dir, strerror(errno));
×
125
        goto error;
×
126
    }
127

128
    filedata = g_new0(gchar *, NUM_FILES + 1);
×
129

130
    /* setpm_setup.conf */
131
    create_certs_tool = g_build_filename(BINDIR,
×
132
                                         "swtpm_localca", NULL);
133
    filedata[SWTPM_SETUP_CONF] = g_strdup_printf(
×
134
        "create_certs_tool = %s\n"
135
        "create_certs_tool_config = %s\n"
136
        "create_certs_tool_options = %s\n"
137
        "# Comma-separated list (no spaces) of PCR banks to activate by default\n"
138
        "active_pcr_banks = %s\n",
139
        create_certs_tool,
140
        configfiles[SWTPM_LOCALCA_CONF],
141
        configfiles[SWTPM_LOCALCA_OPTIONS],
142
        DEFAULT_PCR_BANKS
143
    );
144

145
    /* swtpm-localca.conf */
146
    signkey = g_build_filename(swtpm_localca_dir, "signkey.pem", NULL);
×
147
    issuercert = g_build_filename(swtpm_localca_dir, "issuercert.pem", NULL);
×
148
    certserial = g_build_filename(swtpm_localca_dir, "certserial", NULL);
×
149
    filedata[SWTPM_LOCALCA_CONF] = g_strdup_printf(
×
150
        "statedir = %s\n"
151
        "signingkey = %s\n"
152
        "issuercert = %s\n"
153
        "certserial = %s\n",
154
        swtpm_localca_dir,
155
        signkey,
156
        issuercert,
157
        certserial
158
    );
159

160
    /* swtpm-localca.options */
161
    if (uname(&utsname) < 0) {
×
162
        fprintf(stderr, "uname failed: %s\n", strerror(errno));
×
163
        goto error;
×
164
    }
165

166
    platform_manufacturer = str_replace(utsname.sysname, " ", "_");
×
167
    platform_version = str_replace(utsname.version, " ", "_");
×
168
    platform_model = str_replace(utsname.sysname, " ", "_");
×
169

170
    filedata[SWTPM_LOCALCA_OPTIONS] = g_strdup_printf(
×
171
        "--platform-manufacturer %s\n"
172
        "--platform-version %s\n"
173
        "--platform-model %s\n",
174
        platform_manufacturer,
175
        platform_version,
176
        platform_model
177
    );
178

179
    for (i = 0; i < NUM_FILES; i++) {
×
180
        fprintf(stdout, "Writing %s.\n", configfiles[i]);
×
181
        if (!g_file_set_contents(configfiles[i], filedata[i], -1, &error)) {
×
182
            fprintf(stderr,
×
183
                    "Could not write to %s: %s\n",
184
                    configfiles[i], strerror(errno));
×
185
            delete_files = TRUE;
×
186
            goto error;
×
187
        }
188
    }
189

190
    ret = 0;
191

192
error:
×
193
    if (delete_files) {
×
194
        for (i = 0; i < NUM_FILES; i++)
×
195
            unlink(configfiles[i]);
×
196
    }
197

198
out:
×
199
    return ret;
×
200
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc