mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-31 22:35:25 +00:00
Fix base64 decoder.
This commit is contained in:
121
common/parse.c
121
common/parse.c
@@ -43,7 +43,7 @@
|
|||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char copyright[] =
|
static char copyright[] =
|
||||||
"$Id: parse.c,v 1.81 2000/08/28 21:22:34 neild Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
|
"$Id: parse.c,v 1.82 2000/09/01 23:07:35 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include "dhcpd.h"
|
#include "dhcpd.h"
|
||||||
@@ -1137,7 +1137,7 @@ int parse_base64 (data, cfile)
|
|||||||
{
|
{
|
||||||
enum dhcp_token token;
|
enum dhcp_token token;
|
||||||
const char *val;
|
const char *val;
|
||||||
int i, j;
|
int i, j, k;
|
||||||
unsigned acc = 0;
|
unsigned acc = 0;
|
||||||
static unsigned char
|
static unsigned char
|
||||||
from64 [] = {64, 64, 64, 64, 64, 64, 64, 64, /* \"#$%&' */
|
from64 [] = {64, 64, 64, 64, 64, 64, 64, 64, /* \"#$%&' */
|
||||||
@@ -1152,9 +1152,15 @@ int parse_base64 (data, cfile)
|
|||||||
33, 34, 35, 36, 37, 38, 39, 40, /* hijklmno */
|
33, 34, 35, 36, 37, 38, 39, 40, /* hijklmno */
|
||||||
41, 42, 43, 44, 45, 46, 47, 48, /* pqrstuvw */
|
41, 42, 43, 44, 45, 46, 47, 48, /* pqrstuvw */
|
||||||
59, 50, 51, 64, 64, 64, 64, 64}; /* xyz{|}~ */
|
59, 50, 51, 64, 64, 64, 64, 64}; /* xyz{|}~ */
|
||||||
|
struct string_list *bufs = (struct string_list *)0,
|
||||||
|
*last = (struct string_list *)0,
|
||||||
|
*t;
|
||||||
|
int cc = 0;
|
||||||
|
int terminated = 0;
|
||||||
|
|
||||||
token = next_token (&val, cfile);
|
token = peek_token (&val, cfile);
|
||||||
if (token == STRING) {
|
if (token == STRING) {
|
||||||
|
token = next_token (&val, cfile);
|
||||||
data -> len = strlen (val) + 1;
|
data -> len = strlen (val) + 1;
|
||||||
if (!buffer_allocate (&data -> buffer, data -> len, MDL)) {
|
if (!buffer_allocate (&data -> buffer, data -> len, MDL)) {
|
||||||
parse_warn (cfile, "can't allocate string buffer");
|
parse_warn (cfile, "can't allocate string buffer");
|
||||||
@@ -1166,7 +1172,30 @@ int parse_base64 (data, cfile)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
data -> len = strlen (val);
|
/* It's possible for a + or a / to cause a base64 quantity to be
|
||||||
|
tokenized into more than one token, so we have to parse them all
|
||||||
|
in before decoding. */
|
||||||
|
do {
|
||||||
|
int l;
|
||||||
|
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
l = strlen (val);
|
||||||
|
t = dmalloc (l + sizeof *t, MDL);
|
||||||
|
if (!t)
|
||||||
|
log_fatal ("no memory for base64 buffer.");
|
||||||
|
memset (t, 0, (sizeof *t) - 1);
|
||||||
|
strcpy (t -> string, val);
|
||||||
|
cc += l;
|
||||||
|
if (last)
|
||||||
|
last -> next = t;
|
||||||
|
else
|
||||||
|
bufs = t;
|
||||||
|
last = t;
|
||||||
|
token = peek_token (&val, cfile);
|
||||||
|
} while (token == NUMBER_OR_NAME || token == NAME || token == EQUAL ||
|
||||||
|
token == NUMBER || token == PLUS || token == SLASH);
|
||||||
|
|
||||||
|
data -> len = cc;
|
||||||
data -> len = (data -> len * 3) / 4;
|
data -> len = (data -> len * 3) / 4;
|
||||||
if (!buffer_allocate (&data -> buffer, data -> len, MDL)) {
|
if (!buffer_allocate (&data -> buffer, data -> len, MDL)) {
|
||||||
parse_warn (cfile, "can't allocate buffer for base64 data.");
|
parse_warn (cfile, "can't allocate buffer for base64 data.");
|
||||||
@@ -1175,43 +1204,71 @@ int parse_base64 (data, cfile)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
j = 0;
|
j = k = 0;
|
||||||
for (i = 0; val [i] != '=' && val [i]; i++) {
|
for (t = bufs; t; t = t -> next) {
|
||||||
unsigned foo = val [i];
|
for (i = 0; t -> string [i]; i++) {
|
||||||
|
unsigned foo = t -> string [i];
|
||||||
|
if (terminated && foo != '=') {
|
||||||
|
parse_warn (cfile,
|
||||||
|
"stuff after base64 '=' terminator: %s.",
|
||||||
|
&t -> string [i]);
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
if (foo < ' ' || foo > 'z') {
|
if (foo < ' ' || foo > 'z') {
|
||||||
bad64:
|
bad64:
|
||||||
parse_warn (cfile,
|
parse_warn (cfile,
|
||||||
"invalid base64 character %d.", val [i]);
|
"invalid base64 character %d.",
|
||||||
|
t -> string [i]);
|
||||||
|
bad:
|
||||||
data_string_forget (data, MDL);
|
data_string_forget (data, MDL);
|
||||||
return 0;
|
goto out;
|
||||||
}
|
}
|
||||||
foo = from64 [foo - ' '];
|
if (foo == '=')
|
||||||
if (foo == 64)
|
terminated = 1;
|
||||||
goto bad64;
|
else {
|
||||||
acc = (acc << 6) + foo;
|
foo = from64 [foo - ' '];
|
||||||
switch (i % 4) {
|
if (foo == 64)
|
||||||
case 0:
|
goto bad64;
|
||||||
break;
|
acc = (acc << 6) + foo;
|
||||||
case 1:
|
switch (k % 4) {
|
||||||
data -> buffer -> data [j++] = (acc >> 4);
|
case 0:
|
||||||
acc = acc & 0x0f;
|
break;
|
||||||
break;
|
case 1:
|
||||||
|
data -> buffer -> data [j++] = (acc >> 4);
|
||||||
case 2:
|
acc = acc & 0x0f;
|
||||||
data -> buffer -> data [j++] = (acc >> 2);
|
break;
|
||||||
acc = acc & 0x03;
|
|
||||||
break;
|
case 2:
|
||||||
case 3:
|
data -> buffer -> data [j++] = (acc >> 2);
|
||||||
data -> buffer -> data [j++] = acc;
|
acc = acc & 0x03;
|
||||||
acc = 0;
|
break;
|
||||||
break;
|
case 3:
|
||||||
|
data -> buffer -> data [j++] = acc;
|
||||||
|
acc = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (k % 4) {
|
||||||
|
if (acc) {
|
||||||
|
parse_warn (cfile,
|
||||||
|
"partial base64 value left over: %d.",
|
||||||
|
acc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i % 4)
|
|
||||||
parse_warn (cfile, "partial base64 value left over: %d.", acc);
|
|
||||||
data -> len = j;
|
data -> len = j;
|
||||||
data -> data = data -> buffer -> data;
|
data -> data = data -> buffer -> data;
|
||||||
return 1;
|
out:
|
||||||
|
for (t = bufs; t; t = last) {
|
||||||
|
last = t -> next;
|
||||||
|
dfree (t, MDL);
|
||||||
|
}
|
||||||
|
if (data -> len)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user