summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkrw <krw@openbsd.org>2013-12-18 00:37:59 +0000
committerkrw <krw@openbsd.org>2013-12-18 00:37:59 +0000
commit8d2bd14bc4b8b892b7002f8103dd519957ebea2d (patch)
treecd86a2c66297a6efd68c2fe4b16e1689e885d326
parentmention mac address being in lowercase hex (diff)
downloadwireguard-openbsd-8d2bd14bc4b8b892b7002f8103dd519957ebea2d.tar.xz
wireguard-openbsd-8d2bd14bc4b8b892b7002f8103dd519957ebea2d.zip
Code existed to print non-printable characters in strings written
to the leases file. No code existed to correctly read back the strings so written. Redo both sides and use vis()/strnunvis() instead of handrolling more parsing. As a side-effect allow embedded NUL characters rather than skipping them.
-rw-r--r--sbin/dhclient/conflex.c32
-rw-r--r--sbin/dhclient/options.c21
2 files changed, 31 insertions, 22 deletions
diff --git a/sbin/dhclient/conflex.c b/sbin/dhclient/conflex.c
index 5cccce5098d..9eedf051dd4 100644
--- a/sbin/dhclient/conflex.c
+++ b/sbin/dhclient/conflex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conflex.c,v 1.25 2013/12/05 22:31:35 krw Exp $ */
+/* $OpenBSD: conflex.c,v 1.26 2013/12/18 00:37:59 krw Exp $ */
/* Lexical scanner for dhclient config file. */
@@ -43,6 +43,8 @@
#include "dhcpd.h"
#include "dhctoken.h"
+#include <vis.h>
+
int lexline;
int lexchar;
char *token_line;
@@ -60,6 +62,7 @@ static int token;
static int ugflag;
static char *tval;
static char tokbuf[1500];
+static char visbuf[1500];
static int get_char(FILE *);
static int get_token(FILE *);
@@ -235,25 +238,34 @@ read_string(FILE *cfile)
{
int i, c, bs;
+ /*
+ * Read in characters until an un-escaped '"' is encountered. And
+ * then unvis the data that was read.
+ */
bs = i = 0;
- do {
- c = get_char(cfile);
+ memset(visbuf, 0, sizeof(visbuf));
+ while ((c = get_char(cfile)) != EOF) {
+ if (c == '"' && bs == 0)
+ break;
+
+ visbuf[i++] = c;
if (bs)
bs = 0;
else if (c == '\\')
bs = 1;
- if (c != '"' && c != EOF && bs == 0)
- tokbuf[i++] = c;
-
- } while (i < (sizeof(tokbuf) - 1) && c != EOF && c != '"');
+ if (i == sizeof(visbuf) - 1)
+ break;
+ }
+ if (bs == 1)
+ visbuf[--i] = '\0';
+ i = strnunvis(tokbuf, visbuf, sizeof(tokbuf));
if (c == EOF)
parse_warn("eof in string constant");
- else if (c != '"')
- parse_warn("string constant larger than internal buffer");
+ else if (i == -1 || i >= sizeof(tokbuf))
+ parse_warn("string constant too long");
- tokbuf[i] = 0;
tval = tokbuf;
return (TOK_STRING);
diff --git a/sbin/dhclient/options.c b/sbin/dhclient/options.c
index b105f298bb7..59b0c2b4aed 100644
--- a/sbin/dhclient/options.c
+++ b/sbin/dhclient/options.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: options.c,v 1.60 2013/12/14 16:06:42 krw Exp $ */
+/* $OpenBSD: options.c,v 1.61 2013/12/18 00:37:59 krw Exp $ */
/* DHCP options parsing and reassembly. */
@@ -42,6 +42,8 @@
#include "dhcpd.h"
+#include <vis.h>
+
int parse_option_buffer(struct option_data *, unsigned char *, int);
/*
@@ -197,7 +199,7 @@ pretty_print_option(unsigned int code, struct option_data *option,
{
static char optbuf[32768]; /* XXX */
int hunksize = 0, numhunk = -1, numelem = 0;
- char fmtbuf[32], *op = optbuf;
+ char fmtbuf[32], visbuf[5], *op = optbuf;
int i, j, k, opleft = sizeof(optbuf);
unsigned char *data = option->data;
unsigned char *dp = data;
@@ -327,19 +329,14 @@ pretty_print_option(unsigned int code, struct option_data *option,
op += opcount;
}
for (; dp < data + len; dp++) {
- if (!isascii(*dp) || !isprint(*dp)) {
- opcount = snprintf(op, opleft,
- "\\%03o", *dp);
- } else if (*dp == '"' ||
- *dp == '\'' ||
- *dp == '$' ||
- *dp == '`' ||
- *dp == '\\') {
+ if (*dp && strchr("\"'$`\\", *dp))
opcount = snprintf(op, opleft,
"\\%c", *dp);
- } else {
+ else {
+ vis(visbuf, *dp, VIS_OCTAL,
+ *dp+1);
opcount = snprintf(op, opleft,
- "%c", *dp);
+ "%s", visbuf);
}
if (opcount >= opleft || opcount == -1)
goto toobig;