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