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

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