Commit 9deaf399 authored by Matthias Andree's avatar Matthias Andree

In-depth fix for to64frombits() BASE64 encoder buffer sizing.

parent 3a363944
......@@ -27,23 +27,27 @@ static const char base64val[] = {
};
#define DECODE64(c) (isascii((unsigned char)(c)) ? base64val[c] : BAD)
void to64frombits(char *out, const void *in_, int inlen)
int to64frombits(char *out, const void *in_, int inlen, size_t outlen)
/* raw bytes in quasi-big-endian order to base 64 string (NUL-terminated) */
{
int rc = 0;
const unsigned char *in = (const unsigned char *)in_;
for (; inlen >= 3; inlen -= 3)
{
if (outlen < 5) { rc = -1; goto fail; } /* buffer too small */
*out++ = base64digits[in[0] >> 2];
*out++ = base64digits[((in[0] << 4) & 0x30) | (in[1] >> 4)];
*out++ = base64digits[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
*out++ = base64digits[in[2] & 0x3f];
in += 3;
outlen -= 4;
}
if (inlen > 0)
{
unsigned char fragment;
if (outlen < 5) { rc = -1; goto fail; } /* buffer too small */
*out++ = base64digits[in[0] >> 2];
fragment = (in[0] << 4) & 0x30;
if (inlen > 1)
......@@ -52,7 +56,9 @@ void to64frombits(char *out, const void *in_, int inlen)
*out++ = (inlen < 2) ? '=' : base64digits[(in[1] << 2) & 0x3c];
*out++ = '=';
}
fail:
*out = '\0';
return rc;
}
int from64tobits(void *out_, const char *in, int maxlen)
......@@ -103,7 +109,7 @@ int from64tobits(void *out_, const char *in, int maxlen)
} while
(*in && *in != '\r' && digit4 != '=');
return (len);
return len;
}
/* base64.c ends here */
......@@ -122,7 +122,7 @@ int do_cram_md5 (int sock, const char *command, struct query *ctl, const char *s
response[8], response[9], response[10], response[11],
response[12], response[13], response[14], response[15]);
to64frombits (buf1, reply, strlen(reply));
to64frombits (buf1, reply, strlen(reply), sizeof buf1);
/* ship the authentication back, accept the server's responses */
/* PMDF5.2 IMAP has a bug that requires this to be a single write */
......
......@@ -640,8 +640,8 @@ int prc_parse_file(const char *, const flag);
int prc_filecheck(const char *, const flag);
/* base64.c */
void to64frombits(char *, const void *, int);
int from64tobits(void *, const char *, int maxlen);
int to64frombits(char *, const void *, int inlen, size_t outlen);
int from64tobits(void *, const char *, int mxoutlen);
/* unmime.c */
/* Bit-mask returned by MimeBodyType */
......
......@@ -202,7 +202,7 @@ cancelfail:
return result;
return PS_AUTHFAIL;
}
to64frombits(buf1, send_token.value, send_token.length);
to64frombits(buf1, send_token.value, send_token.length, sizeof buf1);
gss_release_buffer(&min_stat, &send_token);
suppress_tags = TRUE;
......@@ -286,7 +286,7 @@ cancelfail:
report(stderr, GT_("GSSAPI send_token too large (%lu) while sending username.\n"), (unsigned long)send_token.length);
goto cancelfail;
}
to64frombits(buf1, send_token.value, send_token.length);
to64frombits(buf1, send_token.value, send_token.length, sizeof buf1);
suppress_tags = TRUE;
result = gen_transact(sock, "%s", buf1);
......
......@@ -392,7 +392,7 @@ static int do_authcert (int sock, const char *command, const char *name)
{
size_t len = strlen(name);
if ((len / 3) + ((len % 3) ? 4 : 0) < sizeof(buf))
to64frombits (buf, name, strlen(name));
to64frombits (buf, name, strlen(name), sizeof buf);
else
return PS_AUTHFAIL; /* buffer too small. */
}
......
......@@ -44,7 +44,7 @@ int ntlm_helper(int sock, struct query *ctl, const char *proto)
dumpSmbNtlmAuthRequest(stdout, &request);
memset(msgbuf,0,sizeof msgbuf);
to64frombits (msgbuf, &request, SmbLength(&request));
to64frombits (msgbuf, &request, SmbLength(&request), sizeof msgbuf);
if (outlevel >= O_MONITOR)
report(stdout, "%s> %s\n", proto, msgbuf);
......@@ -95,7 +95,7 @@ int ntlm_helper(int sock, struct query *ctl, const char *proto)
dumpSmbNtlmAuthResponse(stdout, &response);
memset(msgbuf,0,sizeof msgbuf);
to64frombits (msgbuf, &response, SmbLength(&response));
to64frombits (msgbuf, &response, SmbLength(&response), sizeof msgbuf);
if (outlevel >= O_MONITOR)
report(stdout, "%s> %s\n", proto, msgbuf);
......
......@@ -106,7 +106,7 @@ static void SMTP_auth(int sock, char smtp_mode, char *username, char *password,
digest[9], digest[10], digest[11], digest[12], digest[13],
digest[14], digest[15]);
to64frombits(b64buf, tmp, strlen(tmp));
to64frombits(b64buf, tmp, strlen(tmp), sizeof b64buf);
SockPrintf(sock, "%s\r\n", b64buf);
SMTP_ok(sock, smtp_mode, TIMEOUT_DEFAULT);
}
......@@ -122,7 +122,7 @@ static void SMTP_auth(int sock, char smtp_mode, char *username, char *password,
if (tmp[c] == '^')
tmp[c] = '\0';
}
to64frombits(b64buf, tmp, len);
to64frombits(b64buf, tmp, len, sizeof b64buf);
SockPrintf(sock, "AUTH PLAIN %s\r\n", b64buf);
SMTP_ok(sock, smtp_mode, TIMEOUT_DEFAULT);
}
......@@ -144,7 +144,7 @@ static void SMTP_auth(int sock, char smtp_mode, char *username, char *password,
SMTP_auth_error(sock, GT_("Bad base64 reply from server.\n"));
return;
}
to64frombits(b64buf, username, strlen(username));
to64frombits(b64buf, username, strlen(username), sizeof b64buf);
SockPrintf(sock, "%s\r\n", b64buf);
SockRead(sock, smtp_response, sizeof(smtp_response) - 1);
strlcpy(tmp, smtp_response, sizeof(tmp));
......@@ -159,7 +159,7 @@ static void SMTP_auth(int sock, char smtp_mode, char *username, char *password,
SMTP_auth_error(sock, GT_("Bad base64 reply from server.\n"));
return;
}
to64frombits(b64buf, password, strlen(password));
to64frombits(b64buf, password, strlen(password), sizeof b64buf);
SockPrintf(sock, "%s\r\n", b64buf);
SMTP_ok(sock, smtp_mode, TIMEOUT_DEFAULT);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment