popmaildir: fix several grave bugs with using memory past end of malloc block

This commit is contained in:
Denis Vlasenko 2009-03-12 15:35:26 +00:00
parent dec37b3232
commit 4abaec50a2

View File

@ -16,12 +16,14 @@ static void pop3_checkr(const char *fmt, const char *param, char **ret)
{ {
const char *msg = command(fmt, param); const char *msg = command(fmt, param);
char *answer = xmalloc_fgetline(stdin); char *answer = xmalloc_fgetline(stdin);
if (answer && '+' == *answer) { if (answer && '+' == answer[0]) {
if (timeout) if (timeout)
alarm(0); alarm(0);
if (ret) if (ret) {
*ret = answer+4; // skip "+OK " // skip "+OK "
else if (ENABLE_FEATURE_CLEAN_UP) memmove(answer, answer + 4, strlen(answer) - 4);
*ret = answer;
} else
free(answer); free(answer);
return; return;
} }
@ -94,31 +96,28 @@ int popmaildir_main(int argc UNUSED_PARAM, char **argv)
// authenticate (if no -s given) // authenticate (if no -s given)
if (!(opts & OPT_s)) { if (!(opts & OPT_s)) {
// server supports APOP and we want it? -> use it // server supports APOP and we want it?
if ('<' == *buf && (opts & OPT_a)) { if ('<' == buf[0] && (opts & OPT_a)) {
md5_ctx_t md5; union { // save a bit of stack
// yes! compose <stamp><password> md5_ctx_t ctx;
char hex[16 * 2 + 1];
} md5;
uint32_t res[16 / 4];
char *s = strchr(buf, '>'); char *s = strchr(buf, '>');
if (s) if (s)
strcpy(s+1, G.pass); s[1] = '\0';
s = buf; // get md5 sum of "<stamp>password" string
// get md5 sum of <stamp><password> md5_begin(&md5.ctx);
md5_begin(&md5); md5_hash(buf, strlen(buf), &md5.ctx);
md5_hash(s, strlen(s), &md5); md5_hash(G.pass, strlen(G.pass), &md5.ctx);
md5_end(s, &md5); md5_end(res, &md5.ctx);
// NOTE: md5 struct contains enough space *bin2hex(md5.hex, (char*)res, 16) = '\0';
// so we reuse md5 space instead of xzalloc(16*2+1)
#define md5_hex ((uint8_t *)&md5)
// uint8_t *md5_hex = (uint8_t *)&md5;
*bin2hex((char *)md5_hex, s, 16) = '\0';
// APOP // APOP
s = xasprintf("%s %s", G.user, md5_hex); s = xasprintf("%s %s", G.user, md5.hex);
#undef md5_hex
pop3_check("APOP %s", s); pop3_check("APOP %s", s);
if (ENABLE_FEATURE_CLEAN_UP) {
free(s); free(s);
free(buf-4); // buf is "+OK " away from malloc'ed string free(buf);
}
// server ignores APOP -> use simple text authentication // server ignores APOP -> use simple text authentication
} else { } else {
// USER // USER
@ -141,8 +140,7 @@ int popmaildir_main(int argc UNUSED_PARAM, char **argv)
// if atoi fails to convert buf into number it returns 0 // if atoi fails to convert buf into number it returns 0
// in this case the following loop simply will not be executed // in this case the following loop simply will not be executed
nmsg = atoi(buf); nmsg = atoi(buf);
if (ENABLE_FEATURE_CLEAN_UP) free(buf);
free(buf-4); // buf is "+OK " away from malloc'ed string
// loop through messages // loop through messages
retr = (opts & OPT_T) ? xasprintf("TOP %%u %u", opt_nlines) : "RETR %u"; retr = (opts & OPT_T) ? xasprintf("TOP %%u %u", opt_nlines) : "RETR %u";