wg: stricter key file reading
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
fabb6eca2b
commit
067ebe2cb9
71
src/config.c
71
src/config.c
|
@ -424,32 +424,48 @@ err:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_line(char **dst, const char *path)
|
static int read_keyfile(char dst[WG_KEY_LEN_BASE64], const char *path)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
size_t n = 0;
|
int ret = -1, c;
|
||||||
|
|
||||||
*dst = NULL;
|
|
||||||
|
|
||||||
f = fopen(path, "r");
|
f = fopen(path, "r");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
perror("fopen");
|
perror("fopen");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (getline(dst, &n, f) < 0 && errno) {
|
|
||||||
perror("getline");
|
if (fread(dst, WG_KEY_LEN_BASE64 - 1, 1, f) != 1) {
|
||||||
fclose(f);
|
if (errno) {
|
||||||
return -1;
|
perror("fread");
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
fclose(f);
|
/* If we're at the end and we didn't read anything, we're /dev/null. */
|
||||||
n = strlen(*dst);
|
if (!ferror(f) && feof(f) && !ftell(f)) {
|
||||||
if (!n)
|
ret = 1;
|
||||||
return 1;
|
goto out;
|
||||||
while (--n) {
|
|
||||||
if (isspace((*dst)[n]))
|
|
||||||
(*dst)[n] = '\0';
|
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
fprintf(stderr, "Invalid length key in key file\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
dst[WG_KEY_LEN_BASE64 - 1] = '\0';
|
||||||
|
|
||||||
|
while ((c = getc(f)) != EOF) {
|
||||||
|
if (!isspace(c)) {
|
||||||
|
fprintf(stderr, "Found trailing character in key file: `%c`\n", c);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ferror(f) && errno) {
|
||||||
|
perror("getc");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
out:
|
||||||
|
fclose(f);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *strip_spaces(const char *in)
|
static char *strip_spaces(const char *in)
|
||||||
|
@ -492,14 +508,11 @@ bool config_read_cmd(struct wgdevice **device, char *argv[], int argc)
|
||||||
argv += 2;
|
argv += 2;
|
||||||
argc -= 2;
|
argc -= 2;
|
||||||
} else if (!strcmp(argv[0], "private-key") && argc >= 2 && !buf.dev->num_peers) {
|
} else if (!strcmp(argv[0], "private-key") && argc >= 2 && !buf.dev->num_peers) {
|
||||||
char *line;
|
char key_line[WG_KEY_LEN_BASE64];
|
||||||
int ret = read_line(&line, argv[1]);
|
int ret = read_keyfile(key_line, argv[1]);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
if (!parse_key(buf.dev->private_key, line)) {
|
if (!parse_key(buf.dev->private_key, key_line))
|
||||||
free(line);
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
free(line);
|
|
||||||
} else if (ret == 1)
|
} else if (ret == 1)
|
||||||
buf.dev->flags |= WGDEVICE_REMOVE_PRIVATE_KEY;
|
buf.dev->flags |= WGDEVICE_REMOVE_PRIVATE_KEY;
|
||||||
else
|
else
|
||||||
|
@ -544,18 +557,14 @@ bool config_read_cmd(struct wgdevice **device, char *argv[], int argc)
|
||||||
argv += 2;
|
argv += 2;
|
||||||
argc -= 2;
|
argc -= 2;
|
||||||
} else if (!strcmp(argv[0], "preshared-key") && argc >= 2 && buf.dev->num_peers) {
|
} else if (!strcmp(argv[0], "preshared-key") && argc >= 2 && buf.dev->num_peers) {
|
||||||
char *line;
|
char key_line[WG_KEY_LEN_BASE64];
|
||||||
int ret = read_line(&line, argv[1]);
|
int ret = read_keyfile(key_line, argv[1]);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
if (!parse_key(peer_from_offset(buf.dev, peer_offset)->preshared_key, line)) {
|
if (!parse_key(peer_from_offset(buf.dev, peer_offset)->preshared_key, key_line))
|
||||||
free(line);
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
} else if (ret == 1)
|
||||||
free(line);
|
|
||||||
} else if (ret == 1) {
|
|
||||||
free(line);
|
|
||||||
buf.dev->flags |= WGPEER_REMOVE_PRESHARED_KEY;
|
buf.dev->flags |= WGPEER_REMOVE_PRESHARED_KEY;
|
||||||
} else
|
else
|
||||||
goto error;
|
goto error;
|
||||||
argv += 2;
|
argv += 2;
|
||||||
argc -= 2;
|
argc -= 2;
|
||||||
|
|
Loading…
Reference in a new issue