16 |
{ |
{ |
17 |
const char *msg = command(fmt, param); |
const char *msg = command(fmt, param); |
18 |
char *answer = xmalloc_fgetline(stdin); |
char *answer = xmalloc_fgetline(stdin); |
19 |
if (answer && '+' == *answer) { |
if (answer && '+' == answer[0]) { |
20 |
if (timeout) |
if (timeout) |
21 |
alarm(0); |
alarm(0); |
22 |
if (ret) |
if (ret) { |
23 |
*ret = answer+4; // skip "+OK " |
// skip "+OK " |
24 |
else if (ENABLE_FEATURE_CLEAN_UP) |
memmove(answer, answer + 4, strlen(answer) - 4); |
25 |
|
*ret = answer; |
26 |
|
} else |
27 |
free(answer); |
free(answer); |
28 |
return; |
return; |
29 |
} |
} |
73 |
// parse options |
// parse options |
74 |
opt_complementary = "-1:dd:t+:R+:L+:H+"; |
opt_complementary = "-1:dd:t+:R+:L+:H+"; |
75 |
opts = getopt32(argv, |
opts = getopt32(argv, |
76 |
"bdmVcasTkt:" "R:Z:L:H:" USE_FEATURE_POPMAILDIR_DELIVERY("M:F:"), |
"bdmVcasTkt:" "R:Z:L:H:" IF_FEATURE_POPMAILDIR_DELIVERY("M:F:"), |
77 |
&timeout, NULL, NULL, NULL, &opt_nlines |
&timeout, NULL, NULL, NULL, &opt_nlines |
78 |
USE_FEATURE_POPMAILDIR_DELIVERY(, &delivery, &delivery) // we treat -M and -F the same |
IF_FEATURE_POPMAILDIR_DELIVERY(, &delivery, &delivery) // we treat -M and -F the same |
79 |
); |
); |
80 |
//argc -= optind; |
//argc -= optind; |
81 |
argv += optind; |
argv += optind; |
96 |
|
|
97 |
// authenticate (if no -s given) |
// authenticate (if no -s given) |
98 |
if (!(opts & OPT_s)) { |
if (!(opts & OPT_s)) { |
99 |
// server supports APOP and we want it? -> use it |
// server supports APOP and we want it? |
100 |
if ('<' == *buf && (opts & OPT_a)) { |
if ('<' == buf[0] && (opts & OPT_a)) { |
101 |
md5_ctx_t md5; |
union { // save a bit of stack |
102 |
// yes! compose <stamp><password> |
md5_ctx_t ctx; |
103 |
|
char hex[16 * 2 + 1]; |
104 |
|
} md5; |
105 |
|
uint32_t res[16 / 4]; |
106 |
|
|
107 |
char *s = strchr(buf, '>'); |
char *s = strchr(buf, '>'); |
108 |
if (s) |
if (s) |
109 |
strcpy(s+1, G.pass); |
s[1] = '\0'; |
110 |
s = buf; |
// get md5 sum of "<stamp>password" string |
111 |
// get md5 sum of <stamp><password> |
md5_begin(&md5.ctx); |
112 |
md5_begin(&md5); |
md5_hash(buf, strlen(buf), &md5.ctx); |
113 |
md5_hash(s, strlen(s), &md5); |
md5_hash(G.pass, strlen(G.pass), &md5.ctx); |
114 |
md5_end(s, &md5); |
md5_end(res, &md5.ctx); |
115 |
// 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'; |
|
116 |
// APOP |
// APOP |
117 |
s = xasprintf("%s %s", G.user, md5_hex); |
s = xasprintf("%s %s", G.user, md5.hex); |
|
#undef md5_hex |
|
118 |
pop3_check("APOP %s", s); |
pop3_check("APOP %s", s); |
119 |
if (ENABLE_FEATURE_CLEAN_UP) { |
free(s); |
120 |
free(s); |
free(buf); |
|
free(buf-4); // buf is "+OK " away from malloc'ed string |
|
|
} |
|
121 |
// server ignores APOP -> use simple text authentication |
// server ignores APOP -> use simple text authentication |
122 |
} else { |
} else { |
123 |
// USER |
// USER |
140 |
// if atoi fails to convert buf into number it returns 0 |
// if atoi fails to convert buf into number it returns 0 |
141 |
// in this case the following loop simply will not be executed |
// in this case the following loop simply will not be executed |
142 |
nmsg = atoi(buf); |
nmsg = atoi(buf); |
143 |
if (ENABLE_FEATURE_CLEAN_UP) |
free(buf); |
|
free(buf-4); // buf is "+OK " away from malloc'ed string |
|
144 |
|
|
145 |
// loop through messages |
// loop through messages |
146 |
retr = (opts & OPT_T) ? xasprintf("TOP %%u %u", opt_nlines) : "RETR %u"; |
retr = (opts & OPT_T) ? xasprintf("TOP %%u %u", opt_nlines) : "RETR %u"; |