wg: stricter key file reading
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
		
							parent
							
								
									fabb6eca2b
								
							
						
					
					
						commit
						067ebe2cb9
					
				
					 1 changed files with 40 additions and 31 deletions
				
			
		
							
								
								
									
										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;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							/* If we're at the end and we didn't read anything, we're /dev/null. */
 | 
				
			||||||
 | 
							if (!ferror(f) && feof(f) && !ftell(f)) {
 | 
				
			||||||
 | 
								ret = 1;
 | 
				
			||||||
 | 
								goto out;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							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);
 | 
						fclose(f);
 | 
				
			||||||
	n = strlen(*dst);
 | 
						return ret;
 | 
				
			||||||
	if (!n)
 | 
					 | 
				
			||||||
		return 1;
 | 
					 | 
				
			||||||
	while (--n) {
 | 
					 | 
				
			||||||
		if (isspace((*dst)[n]))
 | 
					 | 
				
			||||||
			(*dst)[n] = '\0';
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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