GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/acme-client/chngproc.c Lines: 0 60 0.0 %
Date: 2017-11-07 Branches: 0 42 0.0 %

Line Branch Exec Source
1
/*	$Id: chngproc.c,v 1.12 2017/01/24 13:32:55 jsing Exp $ */
2
/*
3
 * Copyright (c) 2016 Kristaps Dzonsons <kristaps@bsd.lv>
4
 *
5
 * Permission to use, copy, modify, and distribute this software for any
6
 * purpose with or without fee is hereby granted, provided that the above
7
 * copyright notice and this permission notice appear in all copies.
8
 *
9
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
10
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
12
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
 */
17
18
#include <assert.h>
19
#include <err.h>
20
#include <errno.h>
21
#include <fcntl.h>
22
#include <stdio.h>
23
#include <stdlib.h>
24
#include <string.h>
25
#include <unistd.h>
26
27
#include "extern.h"
28
29
int
30
chngproc(int netsock, const char *root)
31
{
32
	char		 *tok = NULL, *th = NULL, *fmt = NULL, **fs = NULL;
33
	size_t		  i, fsz = 0;
34
	int		  rc = 0, fd = -1, cc;
35
	long		  lval;
36
	enum chngop	  op;
37
	void		 *pp;
38
39
	if (chroot(root) == -1) {
40
		warn("chroot");
41
		goto out;
42
	}
43
	if (chdir("/") == -1) {
44
		warn("chdir");
45
		goto out;
46
	}
47
	if (pledge("stdio cpath wpath flock rpath", NULL) == -1) {
48
		warn("pledge");
49
		goto out;
50
	}
51
52
	/*
53
	 * Loop while we wait to get a thumbprint and token.
54
	 * We'll get this for each SAN request.
55
	 */
56
57
	for (;;) {
58
		op = CHNG__MAX;
59
		if ((lval = readop(netsock, COMM_CHNG_OP)) == 0)
60
			op = CHNG_STOP;
61
		else if (lval == CHNG_SYN)
62
			op = lval;
63
64
		if (op == CHNG__MAX) {
65
			warnx("unknown operation from netproc");
66
			goto out;
67
		} else if (op == CHNG_STOP)
68
			break;
69
70
		assert(op == CHNG_SYN);
71
72
		/*
73
		 * Read the thumbprint and token.
74
		 * The token is the filename, so store that in a vector
75
		 * of tokens that we'll later clean up.
76
		 */
77
78
		if ((th = readstr(netsock, COMM_THUMB)) == NULL)
79
			goto out;
80
		else if ((tok = readstr(netsock, COMM_TOK)) == NULL)
81
			goto out;
82
83
		/* Vector appending... */
84
85
		pp = reallocarray(fs, (fsz + 1), sizeof(char *));
86
		if (pp == NULL) {
87
			warn("realloc");
88
			goto out;
89
		}
90
		fs = pp;
91
		fs[fsz] = tok;
92
		tok = NULL;
93
		fsz++;
94
95
		if (asprintf(&fmt, "%s.%s", fs[fsz - 1], th) == -1) {
96
			warn("asprintf");
97
			goto out;
98
		}
99
100
		/*
101
		 * Create and write to our challenge file.
102
		 * Note: we use file descriptors instead of FILE
103
		 * because we want to minimise our pledges.
104
		 */
105
		fd = open(fs[fsz - 1], O_WRONLY|O_EXCL|O_CREAT, 0444);
106
		if (fd == -1) {
107
			warn("%s", fs[fsz - 1]);
108
			goto out;
109
		} if (write(fd, fmt, strlen(fmt)) == -1) {
110
			warn("%s", fs[fsz - 1]);
111
			goto out;
112
		} else if (close(fd) == -1) {
113
			warn("%s", fs[fsz - 1]);
114
			goto out;
115
		}
116
		fd = -1;
117
118
		free(th);
119
		free(fmt);
120
		th = fmt = NULL;
121
122
		dodbg("%s/%s: created", root, fs[fsz - 1]);
123
124
		/*
125
		 * Write our acknowledgement.
126
		 * Ignore reader failure.
127
		 */
128
129
		cc = writeop(netsock, COMM_CHNG_ACK, CHNG_ACK);
130
		if (cc == 0)
131
			break;
132
		if (cc < 0)
133
			goto out;
134
	}
135
136
	rc = 1;
137
out:
138
	close(netsock);
139
	if (fd != -1)
140
		close(fd);
141
	for (i = 0; i < fsz; i++) {
142
		if (unlink(fs[i]) == -1 && errno != ENOENT)
143
			warn("%s", fs[i]);
144
		free(fs[i]);
145
	}
146
	free(fs);
147
	free(fmt);
148
	free(th);
149
	free(tok);
150
	return rc;
151
}