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

stefanberger / swtpm / #2828

20 May 2025 10:46PM UTC coverage: 73.458% (+0.3%) from 73.203%
#2828

push

travis-ci

web-flow
Merge c8de77e08 into 4da66c66f

2 of 5 new or added lines in 1 file covered. (40.0%)

1670 existing lines in 25 files now uncovered.

8145 of 11088 relevant lines covered (73.46%)

13465.89 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 *const *config_file_lines, const gchar *configname)
580✔
28
{
29
    g_autofree gchar *regex = g_strdup_printf("^%s[[:space:]]*=[[:space:]]*([^#\n]*).*",
580✔
30
                                              configname);
31
    gchar *result = NULL;
580✔
32
    regmatch_t pmatch[2];
580✔
33
    regex_t preg;
580✔
34
    size_t idx;
580✔
35

36
    if (regcomp(&preg, regex, REG_EXTENDED) != 0) {
580✔
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++) {
2,130✔
42
        const gchar *line = config_file_lines[idx];
1,714✔
43
        if (regexec(&preg, line, 2, pmatch, 0) == 0) {
1,714✔
44
            g_autofree gchar *tmp = NULL;
164✔
45

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

54
    regfree(&preg);
580✔
55

56
    return result;
580✔
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
        "profile = {\"Name\":\"default-v1\"}\n"
140
        "# profile_file =\n"
141
        "local_profiles_dir = %s/etc/swtpm/profiles/\n",
142
        create_certs_tool,
143
        configfiles[SWTPM_LOCALCA_CONF],
144
        configfiles[SWTPM_LOCALCA_OPTIONS],
145
        DEFAULT_PCR_BANKS,
146
        configdir
147
    );
148

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

164
    /* swtpm-localca.options */
UNCOV
165
    if (uname(&utsname) < 0) {
×
166
        fprintf(stderr, "uname failed: %s\n", strerror(errno));
×
167
        goto error;
×
168
    }
169

170
    platform_manufacturer = str_replace(utsname.sysname, " ", "_");
×
UNCOV
171
    platform_version = str_replace(utsname.version, " ", "_");
×
UNCOV
172
    platform_model = str_replace(utsname.sysname, " ", "_");
×
173

UNCOV
174
    filedata[SWTPM_LOCALCA_OPTIONS] = g_strdup_printf(
×
175
        "--platform-manufacturer %s\n"
176
        "--platform-version %s\n"
177
        "--platform-model %s\n",
178
        platform_manufacturer,
179
        platform_version,
180
        platform_model
181
    );
182

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

194
    ret = 0;
195

UNCOV
196
error:
×
UNCOV
197
    if (delete_files) {
×
198
        for (i = 0; i < NUM_FILES; i++)
×
199
            unlink(configfiles[i]);
×
200
    }
201

UNCOV
202
out:
×
UNCOV
203
    return ret;
×
204
}
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