1
/*
2
 * pop3.c -- POP3 protocol methods
3
 *
4
 * Copyright 1998 by Eric S. Raymond.
5
 * For license terms, see the file COPYING in this directory.
6
 */
7
8
#include  "config.h"
9
#ifdef POP3_ENABLE
10
#include  <stdio.h>
11
#include  <string.h>
12
#include  <ctype.h>
13
#if defined(HAVE_UNISTD_H)
14
#include <unistd.h>
15
#endif
16
#if defined(STDC_HEADERS)
17
#include  <stdlib.h>
18
#endif
19
#include  <errno.h>
20
21
#include  "fetchmail.h"
22
#include  "socket.h"
23
#include  "i18n.h"
24
25
#ifdef OPIE_ENABLE
26
#ifdef __cplusplus
27
extern "C" {
28
#endif
29
#include <opie.h>
30
#ifdef __cplusplus
31
}
32
#endif
33
#endif /* OPIE_ENABLE */
34
35
/* global variables: please reinitialize them explicitly for proper
36
 * working in daemon mode */
37
38
/* TODO: session variables to be initialized before server greeting */
39
#ifdef OPIE_ENABLE
40
static char lastok[POPBUFSIZE+1];
41
#endif /* OPIE_ENABLE */
42
43
/* session variables initialized in capa_probe() or pop3_getauth() */
44
flag done_capa = FALSE;
45
#if defined(GSSAPI)
46
flag has_gssapi = FALSE;
47
#endif /* defined(GSSAPI) */
48
#if defined(KERBEROS_V4) || defined(KERBEROS_V5)
49
flag has_kerberos = FALSE;
50
#endif /* defined(KERBEROS_V4) || defined(KERBEROS_V5) */
51
static flag has_cram = FALSE;
52
#ifdef OPIE_ENABLE
53
flag has_otp = FALSE;
54
#endif /* OPIE_ENABLE */
55
#ifdef NTLM_ENABLE
56
flag has_ntlm = FALSE;
57
#endif /* NTLM_ENABLE */
58
#ifdef SSL_ENABLE
59
static flag has_stls = FALSE;
60
#endif /* SSL_ENABLE */
61
62
/* mailbox variables initialized in pop3_getrange() */
63
static int last;
64
65
/* mail variables initialized in pop3_fetch() */
66
#ifdef SDPS_ENABLE
67
char *sdps_envfrom;
68
char *sdps_envto;
69
#endif /* SDPS_ENABLE */
70
71
#ifdef NTLM_ENABLE
72
#include "ntlm.h"
73
74
/*
75
 * NTLM support by Grant Edwards.
76
 *
77
 * Handle MS-Exchange NTLM authentication method.  This is the same
78
 * as the NTLM auth used by Samba for SMB related services. We just
79
 * encode the packets in base64 instead of sending them out via a
80
 * network interface.
81
 * 
82
 * Much source (ntlm.h, smb*.c smb*.h) was borrowed from Samba.
83
 */
84
85
static int do_pop3_ntlm(int sock, struct query *ctl,
86
	int msn_instead /** if true, send AUTH MSN, else send AUTH NTLM */)
87
{
88
    char msgbuf[POPBUFSIZE+1];
89
    int result;
90
91
    gen_send(sock, msn_instead ? "AUTH MSN" : "AUTH NTLM");
92
93
    if ((result = ntlm_helper(sock, ctl, "POP3")))
94
	return result;
95
96
    if ((result = gen_recv (sock, msgbuf, sizeof msgbuf)))
97
	return result;
98
99
    if (strstr (msgbuf, "OK"))
100
	return PS_SUCCESS;
101
    else
102
	return PS_AUTHFAIL;
103
}
104
#endif /* NTLM */
105
106
107
#define DOTLINE(s)	(s[0] == '.' && (s[1]=='\r'||s[1]=='\n'||s[1]=='\0'))
108
109
static int pop3_ok (int sock, char *argbuf)
110
/* parse command response */
111
{
112
    int ok;
113
    char buf [POPBUFSIZE+1];
114
    char *bufp;
115
116
    if ((ok = gen_recv(sock, buf, sizeof(buf))) == 0)
117
    {	bufp = buf;
118
	if (*bufp == '+' || *bufp == '-')
119
	    bufp++;
120
	else
121
	    return(PS_PROTOCOL);
122
123
	while (isalpha((unsigned char)*bufp))
124
	    bufp++;
125
126
	if (*bufp)
127
	  *(bufp++) = '\0';
128
129
	if (strcmp(buf,"+OK") == 0)
130
	{
131
#ifdef OPIE_ENABLE
132
	    strcpy(lastok, bufp);
133
#endif /* OPIE_ENABLE */
134
	    ok = 0;
135
	}
136
	else if (strncmp(buf,"-ERR", 4) == 0)
137
	{
138
	    if (stage == STAGE_FETCH)
139
		ok = PS_TRANSIENT;
140
	    else if (stage > STAGE_GETAUTH)
141
		ok = PS_PROTOCOL;
142
	    /*
143
	     * We're checking for "lock busy", "unable to lock", 
144
	     * "already locked", "wait a few minutes" etc. here. 
145
	     * This indicates that we have to wait for the server to
146
	     * unwedge itself before we can poll again.
147
	     *
148
	     * PS_LOCKBUSY check empirically verified with two recent
149
	     * versions of the Berkeley popper; QPOP (version 2.2)  and
150
	     * QUALCOMM Pop server derived from UCB (version 2.1.4-R3)
151
	     * These are caught by the case-indifferent "lock" check.
152
	     * The "wait" catches "mail storage services unavailable,
153
	     * wait a few minutes and try again" on the InterMail server.
154
	     *
155
	     * If these aren't picked up on correctly, fetchmail will 
156
	     * think there is an authentication failure and wedge the
157
	     * connection in order to prevent futile polls.
158
	     *
159
	     * Gad, what a kluge.
160
	     */
161
	    else if (strstr(bufp,"lock")
162
		     || strstr(bufp,"Lock")
163
		     || strstr(bufp,"LOCK")
164
		     || strstr(bufp,"wait")
165
		     /* these are blessed by RFC 2449 */
166
		     || strstr(bufp,"[IN-USE]")||strstr(bufp,"[LOGIN-DELAY]"))
167
		ok = PS_LOCKBUSY;
168
	    else if ((strstr(bufp,"Service")
169
		     || strstr(bufp,"service"))
170
			 && (strstr(bufp,"unavailable")))
171
		ok = PS_SERVBUSY;
172
	    else
173
		ok = PS_AUTHFAIL;
174
	    /*
175
	     * We always want to pass the user lock-busy messages, because
176
	     * they're red flags.  Other stuff (like AUTH failures on non-
177
	     * RFC1734 servers) only if we're debugging.
178
	     */
179
	    if (*bufp && (ok == PS_LOCKBUSY || outlevel >= O_MONITOR))
180
	      report(stderr, "%s\n", bufp);
181
	}
182
	else
183
	    ok = PS_PROTOCOL;
184
185
#if POPBUFSIZE > MSGBUFSIZE
186
#error "POPBUFSIZE must not be larger than MSGBUFSIZE"
187
#endif
188
	if (argbuf != NULL)
189
	    strcpy(argbuf,bufp);
190
    }
191
192
    return(ok);
193
}
194
195
196
197
static int capa_probe(int sock)
198
/* probe the capabilities of the remote server */
199
{
200
    int	ok;
201
202
    if (done_capa) {
203
	return PS_SUCCESS;
204
    }
205
#if defined(GSSAPI)
206
    has_gssapi = FALSE;
207
#endif /* defined(GSSAPI) */
208
#if defined(KERBEROS_V4) || defined(KERBEROS_V5)
209
    has_kerberos = FALSE;
210
#endif /* defined(KERBEROS_V4) || defined(KERBEROS_V5) */
211
    has_cram = FALSE;
212
#ifdef OPIE_ENABLE
213
    has_otp = FALSE;
214
#endif /* OPIE_ENABLE */
215
#ifdef NTLM_ENABLE
216
    has_ntlm = FALSE;
217
#endif /* NTLM_ENABLE */
218
219
    ok = gen_transact(sock, "CAPA");
220
    if (ok == PS_SUCCESS)
221
    {
222
	char buffer[64];
223
224
	/* determine what authentication methods we have available */
225
	while ((ok = gen_recv(sock, buffer, sizeof(buffer))) == 0)
226
	{
227
	    if (DOTLINE(buffer))
228
		break;
229
230
#ifdef SSL_ENABLE
231
	    if (strstr(buffer, "STLS"))
232
		has_stls = TRUE;
233
#endif /* SSL_ENABLE */
234
235
#if defined(GSSAPI)
236
	    if (strstr(buffer, "GSSAPI"))
237
		has_gssapi = TRUE;
238
#endif /* defined(GSSAPI) */
239
240
#if defined(KERBEROS_V4)
241
	    if (strstr(buffer, "KERBEROS_V4"))
242
		has_kerberos = TRUE;
243
#endif /* defined(KERBEROS_V4)  */
244
245
#ifdef OPIE_ENABLE
246
	    if (strstr(buffer, "X-OTP"))
247
		has_otp = TRUE;
248
#endif /* OPIE_ENABLE */
249
250
#ifdef NTLM_ENABLE
251
	    if (strstr(buffer, "NTLM"))
252
		has_ntlm = TRUE;
253
#endif /* NTLM_ENABLE */
254
255
	    if (strstr(buffer, "CRAM-MD5"))
256
		has_cram = TRUE;
257
	}
258
    }
259
    done_capa = TRUE;
260
    return(ok);
261
}
262
263
static void set_peek_capable(struct query *ctl)
264
{
265
    /* we're peek-capable means that the use of TOP is enabled,
266
     * see pop3_fetch for details - short story, we can use TOP if
267
     * we have a means of reliably tracking which mail we need to
268
     * refetch should the connection abort in the middle.
269
     * fetchall forces RETR, as does keep without UIDL */
270
    peek_capable = !ctl->fetchall && (!ctl->keep || ctl->server.uidl);
271
}
272
273
static int pop3_getauth(int sock, struct query *ctl, char *greeting)
274
/* apply for connection authorization */
275
{
276
    int ok;
277
    char *start,*end;
278
    char *msg;
279
#ifdef OPIE_ENABLE
280
    char *challenge;
281
#endif /* OPIE_ENABLE */
282
#ifdef SSL_ENABLE
283
    flag connection_may_have_tls_errors = FALSE;
284
#endif /* SSL_ENABLE */
285
286
    done_capa = FALSE;
287
#if defined(GSSAPI)
288
    has_gssapi = FALSE;
289
#endif /* defined(GSSAPI) */
290
#if defined(KERBEROS_V4) || defined(KERBEROS_V5)
291
    has_kerberos = FALSE;
292
#endif /* defined(KERBEROS_V4) || defined(KERBEROS_V5) */
293
    has_cram = FALSE;
294
#ifdef OPIE_ENABLE
295
    has_otp = FALSE;
296
#endif /* OPIE_ENABLE */
297
#ifdef SSL_ENABLE
298
    has_stls = FALSE;
299
#endif /* SSL_ENABLE */
300
301
    /* Set this up before authentication quits early. */
302
    set_peek_capable(ctl);
303
304
    /* Hack: allow user to force RETR. */
305
    if (peek_capable && getenv("FETCHMAIL_POP3_FORCE_RETR")) {
306
	peek_capable = 0;
307
    }
308
309
    /*
310
     * The "Maillennium POP3/PROXY server" deliberately truncates
311
     * TOP replies after c. 64 or 80 kByte (we have varying reports), so
312
     * disable TOP. Comcast once spewed marketing babble to the extent
313
     * of protecting Outlook -- pretty overzealous to break a protocol
314
     * for that that Microsoft could have read, too. Comcast aren't
315
     * alone in using this software though.
316
     * <http://lists.ccil.org/pipermail/fetchmail-friends/2004-April/008523.html>
317
     * (Thanks to Ed Wilts for reminding me of that.)
318
     *
319
     * The warning is printed once per server, until fetchmail exits.
320
     * It will be suppressed when --fetchall or other circumstances make
321
     * us use RETR anyhow.
322
     *
323
     * Matthias Andree
324
     */
325
    if (peek_capable && strstr(greeting, "Maillennium POP3/PROXY server")) {
326
	if ((ctl->server.workarounds & WKA_TOP) == 0) {
327
	    report(stdout, GT_("Warning: \"Maillennium POP3/PROXY server\" found, using RETR command instead of TOP.\n"));
328
	    ctl->server.workarounds |= WKA_TOP;
329
	}
330
	peek_capable = 0;
331
    }
332
    if (ctl->server.authenticate == A_SSH) {
333
        return PS_SUCCESS;
334
    }
335
336
#ifdef SDPS_ENABLE
337
    /*
338
     * This needs to catch both demon.co.uk and demon.net.
339
     * If we see either, and we're in multidrop mode, try to use
340
     * the SDPS *ENV extension.
341
     */
342
    if (!(ctl->server.sdps) && MULTIDROP(ctl) && strstr(greeting, "demon."))
343
        ctl->server.sdps = TRUE;
344
#endif /* SDPS_ENABLE */
345
346
   switch (ctl->server.protocol) {
347
    case P_POP3:
348
#ifdef RPA_ENABLE
349
	/* XXX FIXME: AUTH probing (RFC1734) should become global */
350
	/* CompuServe POP3 Servers as of 990730 want AUTH first for RPA */
351
	if (strstr(ctl->remotename, "@compuserve.com"))
352
	{
353
	    /* AUTH command should return a list of available mechanisms */
354
	    if (gen_transact(sock, "AUTH") == 0)
355
	    {
356
		char buffer[10];
357
		flag has_rpa = FALSE;
358
359
		while ((ok = gen_recv(sock, buffer, sizeof(buffer))) == 0)
360
		{
361
		    if (DOTLINE(buffer))
362
			break;
363
		    if (strncasecmp(buffer, "rpa", 3) == 0)
364
			has_rpa = TRUE;
365
		}
366
		if (has_rpa && !POP3_auth_rpa(ctl->remotename, 
367
					      ctl->password, sock))
368
		    return(PS_SUCCESS);
369
	    }
370
371
	    return(PS_AUTHFAIL);
372
	}
373
#endif /* RPA_ENABLE */
374
375
	/*
376
	 * CAPA command may return a list including available
377
	 * authentication mechanisms and STLS capability.
378
	 *
379
	 * If it doesn't, no harm done, we just fall back to a plain
380
	 * login -- if the user allows it.
381
	 *
382
	 * Note that this code latches the server's authentication type,
383
	 * so that in daemon mode the CAPA check only needs to be done
384
	 * once at start of run.
385
	 *
386
	 * If CAPA fails, then force the authentication method to
387
	 * PASSWORD, switch off opportunistic and repoll immediately.
388
	 * If TLS is mandatory, fail up front.
389
	 */
390
	if ((ctl->server.authenticate == A_ANY) ||
391
		(ctl->server.authenticate == A_GSSAPI) ||
392
		(ctl->server.authenticate == A_KERBEROS_V4) ||
393
		(ctl->server.authenticate == A_KERBEROS_V5) ||
394
		(ctl->server.authenticate == A_OTP) ||
395
		(ctl->server.authenticate == A_CRAM_MD5) ||
396
		maybe_tls(ctl))
397
	{
398
	    if ((ok = capa_probe(sock)) != PS_SUCCESS)
399
		/* we are in STAGE_GETAUTH => failure is PS_AUTHFAIL! */
400
		if (ok == PS_AUTHFAIL ||
401
		    /* Some servers directly close the socket. However, if we
402
		     * have already authenticated before, then a previous CAPA
403
		     * must have succeeded. In that case, treat this as a
404
		     * genuine socket error and do not change the auth method.
405
		     */
406
		    (ok == PS_SOCKET && !ctl->wehaveauthed))
407
		{
408
#ifdef SSL_ENABLE
409
		    if (must_tls(ctl)) {
410
			/* fail with mandatory STLS without repoll */
411
			report(stderr, GT_("TLS is mandatory for this session, but server refused CAPA command.\n"));
412
			report(stderr, GT_("The CAPA command is however necessary for TLS.\n"));
413
			return ok;
414
		    } else if (maybe_tls(ctl)) {
415
			/* defeat opportunistic STLS */
416
			xfree(ctl->sslproto);
417
			ctl->sslproto = xstrdup("");
418
		    }
419
#endif
420
		    /* If strong authentication was opportunistic, retry without, else fail. */
421
		    switch (ctl->server.authenticate) {
422
			case A_ANY:
423
			    ctl->server.authenticate = A_PASSWORD;
424
			    /* FALLTHROUGH */
425
			case A_PASSWORD: /* this should only happen with TLS enabled */
426
			    return PS_REPOLL;
427
			default:
428
			    return PS_AUTHFAIL;
429
		    }
430
		}
431
	}
432
433
#ifdef SSL_ENABLE
434
	if (maybe_tls(ctl)) {
435
	    char *commonname;
436
437
	    commonname = ctl->server.pollname;
438
	    if (ctl->server.via)
439
		commonname = ctl->server.via;
440
	    if (ctl->sslcommonname)
441
		commonname = ctl->sslcommonname;
442
443
	   if (has_stls
444
		   || must_tls(ctl)) /* if TLS is mandatory, ignore capabilities */
445
	   {
446
	       /* Use "tls1" rather than ctl->sslproto because tls1 is the only
447
		* protocol that will work with STARTTLS.  Don't need to worry
448
		* whether TLS is mandatory or opportunistic unless SSLOpen() fails
449
		* (see below). */
450
	       if (gen_transact(sock, "STLS") == PS_SUCCESS
451
		       && (set_timeout(mytimeout), SSLOpen(sock, ctl->sslcert, ctl->sslkey, "tls1", ctl->sslcertck,
452
			   ctl->sslcertfile, ctl->sslcertpath, ctl->sslfingerprint, commonname,
453
			   ctl->server.pollname, &ctl->remotename)) != -1)
454
	       {
455
		   /*
456
		    * RFC 2595 says this:
457
		    *
458
		    * "Once TLS has been started, the client MUST discard cached
459
		    * information about server capabilities and SHOULD re-issue the
460
		    * CAPABILITY command.  This is necessary to protect against
461
		    * man-in-the-middle attacks which alter the capabilities list prior
462
		    * to STARTTLS.  The server MAY advertise different capabilities
463
		    * after STARTTLS."
464
		    *
465
		    * Now that we're confident in our TLS connection we can
466
		    * guarantee a secure capability re-probe.
467
		    */
468
		   set_timeout(0);
469
		   done_capa = FALSE;
470
		   ok = capa_probe(sock);
471
		   if (ok != PS_SUCCESS) {
472
		       return ok;
473
		   }
474
		   if (outlevel >= O_VERBOSE)
475
		   {
476
		       report(stdout, GT_("%s: upgrade to TLS succeeded.\n"), commonname);
477
		   }
478
	       } else if (must_tls(ctl)) {
479
		   /* Config required TLS but we couldn't guarantee it, so we must
480
		    * stop. */
481
		   set_timeout(0);
482
		   report(stderr, GT_("%s: upgrade to TLS failed.\n"), commonname);
483
		   return PS_SOCKET;
484
	       } else {
485
		   /* We don't know whether the connection is usable, and there's
486
		    * no command we can reasonably issue to test it (NOOP isn't
487
		    * allowed til post-authentication), so leave it in an unknown
488
		    * state, mark it as such, and check more carefully if things
489
		    * go wrong when we try to authenticate. */
490
		   set_timeout(0);
491
		   connection_may_have_tls_errors = TRUE;
492
		   if (outlevel >= O_VERBOSE)
493
		   {
494
		       report(stdout, GT_("%s: opportunistic upgrade to TLS failed, trying to continue.\n"), commonname);
495
		   }
496
	       }
497
	   }
498
	} /* maybe_tls() */
499
#endif /* SSL_ENABLE */
500
501
	/*
502
	 * OK, we have an authentication type now.
503
	 */
504
#if defined(KERBEROS_V4)
505
	/* 
506
	 * Servers doing KPOP have to go through a dummy login sequence
507
	 * rather than doing SASL.
508
	 */
509
	if (has_kerberos &&
510
	    ctl->server.service && (strcmp(ctl->server.service, KPOP_PORT)!=0)
511
	    && (ctl->server.authenticate == A_KERBEROS_V4
512
	     || ctl->server.authenticate == A_KERBEROS_V5
513
	     || ctl->server.authenticate == A_ANY))
514
	{
515
	    ok = do_rfc1731(sock, "AUTH", ctl->server.truename);
516
	    if (ok == PS_SUCCESS || ctl->server.authenticate != A_ANY)
517
		break;
518
	}
519
#endif /* defined(KERBEROS_V4) || defined(KERBEROS_V5) */
520
521
#if defined(GSSAPI)
522
	if (has_gssapi &&
523
	    (ctl->server.authenticate == A_GSSAPI ||
524
	    (ctl->server.authenticate == A_ANY
525
	     && check_gss_creds("pop", ctl->server.truename) == PS_SUCCESS)))
526
	{
527
	    ok = do_gssauth(sock,"AUTH","pop",ctl->server.truename,ctl->remotename);
528
	    if (ok == PS_SUCCESS || ctl->server.authenticate != A_ANY)
529
		break;
530
	}
531
#endif /* defined(GSSAPI) */
532
533
#ifdef OPIE_ENABLE
534
	if (has_otp &&
535
	    (ctl->server.authenticate == A_OTP ||
536
	     ctl->server.authenticate == A_ANY))
537
	{
538
	    ok = do_otp(sock, "AUTH", ctl);
539
	    if (ok == PS_SUCCESS || ctl->server.authenticate != A_ANY)
540
		break;
541
	}
542
#endif /* OPIE_ENABLE */
543
544
#ifdef NTLM_ENABLE
545
    /* MSN servers require the use of NTLM (MSN) authentication */
546
    if (!strcasecmp(ctl->server.pollname, "pop3.email.msn.com") ||
547
	    ctl->server.authenticate == A_MSN)
548
	return (do_pop3_ntlm(sock, ctl, 1) == 0) ? PS_SUCCESS : PS_AUTHFAIL;
549
    if (ctl->server.authenticate == A_NTLM || (has_ntlm && ctl->server.authenticate == A_ANY)) {
550
	ok = do_pop3_ntlm(sock, ctl, 0);
551
        if (ok == 0 || ctl->server.authenticate != A_ANY)
552
	    break;
553
    }
554
#else
555
    if (ctl->server.authenticate == A_NTLM || ctl->server.authenticate == A_MSN)
556
    {
557
	report(stderr,
558
	   GT_("Required NTLM capability not compiled into fetchmail\n"));
559
    }
560
#endif
561
562
 	if (ctl->server.authenticate == A_CRAM_MD5 || 
563
	    (has_cram && ctl->server.authenticate == A_ANY))
564
	{
565
	    ok = do_cram_md5(sock, "AUTH", ctl, NULL);
566
	    if (ok == PS_SUCCESS || ctl->server.authenticate != A_ANY)
567
		break;
568
	}
569
570
	/* ordinary validation, no one-time password or RPA */ 
571
	if ((ok = gen_transact(sock, "USER %s", ctl->remotename)))
572
	    break;
573
574
#ifdef OPIE_ENABLE
575
	/* see RFC1938: A One-Time Password System */
576
	if ((challenge = strstr(lastok, "otp-"))) {
577
	  char response[OPIE_RESPONSE_MAX+1];
578
	  int i;
579
	  char *n = xstrdup("");
580
581
	  i = opiegenerator(challenge, !strcmp(ctl->password, "opie") ? n : ctl->password, response);
582
	  free(n);
583
	  if ((i == -2) && !run.poll_interval) {
584
	    char secret[OPIE_SECRET_MAX+1];
585
	    fprintf(stderr, GT_("Secret pass phrase: "));
586
	    if (opiereadpass(secret, sizeof(secret), 0))
587
	      i = opiegenerator(challenge,  secret, response);
588
	    memset(secret, 0, sizeof(secret));
589
	  };
590
591
	  if (i) {
592
	    ok = PS_ERROR;
593
	    break;
594
	  };
595
596
	  ok = gen_transact(sock, "PASS %s", response);
597
	  break;
598
	}
599
#endif /* OPIE_ENABLE */
600
601
	/* KPOP uses out-of-band authentication and does not check what
602
	 * we send here, so send some random fixed string, to avoid
603
	 * users switching *to* KPOP accidentally revealing their
604
	 * password */
605
	if ((ctl->server.authenticate == A_ANY
606
		    || ctl->server.authenticate == A_KERBEROS_V4
607
		    || ctl->server.authenticate == A_KERBEROS_V5)
608
		&& (ctl->server.service != NULL
609
		    && strcmp(ctl->server.service, KPOP_PORT) == 0))
610
	{
611
	    ok = gen_transact(sock, "PASS krb_ticket");
612
	    break;
613
	}
614
615
	/* check if we are actually allowed to send the password */
616
	if (ctl->server.authenticate == A_ANY
617
		|| ctl->server.authenticate == A_PASSWORD) {
618
	    strlcpy(shroud, ctl->password, sizeof(shroud));
619
	    ok = gen_transact(sock, "PASS %s", ctl->password);
620
	} else {
621
	    report(stderr, GT_("We've run out of allowed authenticators and cannot continue.\n"));
622
	    ok = PS_AUTHFAIL;
623
	}
624
	memset(shroud, 0x55, sizeof(shroud));
625
	shroud[0] = '\0';
626
	break;
627
628
    case P_APOP:
629
	/* build MD5 digest from greeting timestamp + password */
630
	/* find start of timestamp */
631
	for (start = greeting;  *start != 0 && *start != '<';  start++)
632
	    continue;
633
	if (*start == 0) {
634
	    report(stderr,
635
		   GT_("Required APOP timestamp not found in greeting\n"));
636
	    return(PS_AUTHFAIL);
637
	}
638
639
	/* find end of timestamp */
640
	for (end = start;  *end != 0  && *end != '>';  end++)
641
	    continue;
642
	if (*end == 0 || end == start + 1) {
643
	    report(stderr, 
644
		   GT_("Timestamp syntax error in greeting\n"));
645
	    return(PS_AUTHFAIL);
646
	}
647
	else
648
	    *++end = '\0';
649
650
	/* SECURITY: 2007-03-17
651
	 * Strictly validating the presented challenge for RFC-822
652
	 * conformity (it must be a msg-id in terms of that standard) is
653
	 * supposed to make attacks against the MD5 implementation
654
	 * harder[1]
655
	 *
656
	 * [1] "Security vulnerability in APOP authentication",
657
	 *     Gaëtan Leurent, fetchmail-devel, 2007-03-17 */
658
	if (!rfc822_valid_msgid((unsigned char *)start)) {
659
	    report(stderr,
660
		    GT_("Invalid APOP timestamp.\n"));
661
	    return PS_AUTHFAIL;
662
	}
663
664
	/* copy timestamp and password into digestion buffer */
665
	msg = (char *)xmalloc((end-start+1) + strlen(ctl->password) + 1);
666
	strcpy(msg,start);
667
	strcat(msg,ctl->password);
668
	strcpy((char *)ctl->digest, MD5Digest((unsigned char *)msg));
669
	free(msg);
670
671
	ok = gen_transact(sock, "APOP %s %s", ctl->remotename, (char *)ctl->digest);
672
	break;
673
674
    case P_RPOP:
675
	if ((ok = gen_transact(sock,"USER %s", ctl->remotename)) == 0) {
676
	    strlcpy(shroud, ctl->password, sizeof(shroud));
677
	    ok = gen_transact(sock, "RPOP %s", ctl->password);
678
	    memset(shroud, 0x55, sizeof(shroud));
679
	    shroud[0] = '\0';
680
	}
681
	break;
682
683
    default:
684
	report(stderr, GT_("Undefined protocol request in POP3_auth\n"));
685
	ok = PS_ERROR;
686
    }
687
688
#ifdef SSL_ENABLE
689
    /* this is for servers which claim to support TLS, but actually
690
     * don't! */
691
    if (connection_may_have_tls_errors
692
		    && (ok == PS_SOCKET || ok == PS_PROTOCOL))
693
    {
694
	xfree(ctl->sslproto);
695
	ctl->sslproto = xstrdup("");
696
	/* repoll immediately without TLS */
697
	ok = PS_REPOLL;
698
    }
699
#endif
700
701
    if (ok != 0)
702
    {
703
	/* maybe we detected a lock-busy condition? */
704
        if (ok == PS_LOCKBUSY)
705
	    report(stderr, GT_("lock busy!  Is another session active?\n")); 
706
707
	return(ok);
708
    }
709
710
/* Disable the sleep. Based on patch by Brian Candler 2004-04-19/2004-11-08,
711
 * accepted by Matthias Andree.
712
 *
713
 * Rationale: the server must have locked the spool before returning +OK;
714
 * this sleep just wastes time and hence, for modem and GSM CSD users, money. */
715
#ifdef WANT_BOGUS
716
    /*
717
     * Empirical experience shows some server/OS combinations
718
     * may need a brief pause even after any lockfiles on the
719
     * server are released, to give the server time to finish
720
     * copying back very large mailfolders from the temp-file...
721
     * this is only ever an issue with extremely large mailboxes.
722
     */
723
    sleep(3); /* to be _really_ safe, probably need sleep(5)! */
724
#endif
725
726
    /* we're approved */
727
    return(PS_SUCCESS);
728
}
729
730
/* cut off C string at first POSIX space */
731
static void trim(char *s) {
732
    s += strcspn(s, POSIX_space);
733
    s[0] = '\0';
734
}
735
736
/* XXX FIXME: using the Message-ID is unsafe, some messages (spam,
737
 * broken messages) do not have Message-ID headers, and messages without
738
 * those appear to break this code and cause fetchmail (at least version
739
 * 6.2.3) to not delete such messages properly after retrieval.
740
 * See Sourceforge Bug #780933.
741
 *
742
 * The other problem is that the TOP command itself is optional, too... */
743
static int pop3_gettopid(int sock, int num , char *id, size_t idsize)
744
{
745
    int ok;
746
    int got_it;
747
    char buf [POPBUFSIZE+1];
748
    snprintf(buf, sizeof(buf), "TOP %d 1", num);
749
    if ((ok = gen_transact(sock, "%s", buf)) != 0)
750
       return ok;
751
    got_it = 0;
752
    while (gen_recv(sock, buf, sizeof(buf)) == 0)
753
    {
754
	if (DOTLINE(buf))
755
	    break;
756
	if (!got_it && 0 == strncasecmp("Message-Id:", buf, 11)) {
757
	    char *p = buf + 11;
758
	    got_it = 1;
759
	    p += strspn(p, POSIX_space);
760
	    strlcpy(id, p, idsize);
761
	    trim(id);
762
	}
763
    }
764
    /* XXX FIXME: do not return success here if no Message-ID header was
765
     * found. */
766
    return 0;
767
}
768
769
/** Parse the UID response (leading +OK must have been
770
 * stripped off) in buf, store the number in gotnum, and store the ID
771
 * into the caller-provided buffer "id" of size "idsize".
772
 * Returns PS_SUCCESS or PS_PROTOCOL for failure. */
773
static int parseuid(const char *buf, unsigned long *gotnum, char *id, size_t idsize)
774
{
775
    const char *i;
776
    char *j;
777
778
    /* skip leading blanks ourselves */
779
    i = buf;
780
    i += strspn(i, POSIX_space);
781
    errno = 0;
782
    *gotnum = strtoul(i, &j, 10);
783
    if (j == i || !*j || errno || NULL == strchr(POSIX_space, *j)) {
784
	report(stderr, GT_("Cannot handle UIDL response from upstream server.\n"));
785
	return PS_PROTOCOL;
786
    }
787
    j += strspn(j, POSIX_space);
788
    strlcpy(id, j, idsize);
789
    trim(id);
790
    return PS_SUCCESS;
791
}
792
793
/** request UIDL for single message \a num and stuff the result into the
794
 * buffer \a id which can hold \a idsize bytes */
795
static int pop3_getuidl(int sock, int num, char *id /** output */, size_t idsize)
796
{
797
    int ok;
798
    char buf [POPBUFSIZE+1];
799
    unsigned long gotnum;
800
801
    gen_send(sock, "UIDL %d", num);
802
    if ((ok = pop3_ok(sock, buf)) != 0)
803
	return(ok);
804
    if ((ok = parseuid(buf, &gotnum, id, idsize)))
805
	return ok;
806
    if (gotnum != (unsigned long)num) {
807
	report(stderr, GT_("Server responded with UID for wrong message.\n"));
808
	return PS_PROTOCOL;
809
    }
810
    return(PS_SUCCESS);
811
}
812
813
static int pop3_fastuidl( int sock,  struct query *ctl, unsigned int count, int *newp)
814
{
815
    int ok;
816
    unsigned int first_nr, last_nr, try_nr;
817
    char id [IDLEN+1];
818
    struct idlist *savep = NULL; /** pointer to cache save_str result, speeds up saves */
819
820
    first_nr = 0;
821
    last_nr = count + 1;
822
    while (first_nr < last_nr - 1)
823
    {
824
	struct idlist	*newl;
825
826
	try_nr = (first_nr + last_nr) / 2;
827
	if ((ok = pop3_getuidl(sock, try_nr, id, sizeof(id))) != 0)
828
	    return ok;
829
	if ((newl = str_in_list(&ctl->oldsaved, id, FALSE)))
830
	{
831
	    flag mark = newl->val.status.mark;
832
	    if (mark == UID_DELETED || mark == UID_EXPUNGED)
833
	    {
834
		if (outlevel >= O_VERBOSE)
835
		    report(stderr, GT_("id=%s (num=%u) was deleted, but is still present!\n"), id, try_nr);
836
		/* just mark it as seen now! */
837
		newl->val.status.mark = mark = UID_SEEN;
838
	    }
839
840
	    /* narrow the search region! */
841
	    if (mark == UID_UNSEEN)
842
	    {
843
		if (outlevel >= O_DEBUG)
844
		    report(stdout, GT_("%u is unseen\n"), try_nr);
845
		last_nr = try_nr;
846
	    }
847
	    else
848
		first_nr = try_nr;
849
850
	    /* save the number */
851
	    newl->val.status.num = try_nr;
852
	}
853
	else
854
	{
855
	    if (outlevel >= O_DEBUG)
856
		report(stdout, GT_("%u is unseen\n"), try_nr);
857
	    last_nr = try_nr;
858
859
	    /* save it */
860
	    savep = save_str(savep ? &savep : &ctl->oldsaved, id, UID_UNSEEN);
861
	    savep->val.status.num = try_nr;
862
	}
863
    }
864
    if (outlevel >= O_DEBUG && last_nr <= count)
865
	report(stdout, GT_("%u is first unseen\n"), last_nr);
866
867
    /* update last! */
868
    *newp = count - first_nr;
869
    last = first_nr;
870
    return 0;
871
}
872
873
static int pop3_slowuidl( int sock,  struct query *ctl, int *countp, int *newp)
874
{
875
    /* XXX FIXME: this code is severely broken. A Cc:d mailing list
876
     * message will arrive twice with the same Message-ID, so this
877
     * slowuidl code will break. Same goes for messages without
878
     * Message-ID headers at all. This code would best be removed. */
879
    /* This approach tries to get the message headers from the
880
     * remote hosts and compares the message-id to the already known
881
     * ones:
882
     *  + if the first message containes a new id, all messages on
883
     *    the server will be new
884
     *  + if the first is known, try to estimate the last known message
885
     *    on the server and check. If this works you know the total number
886
     *    of messages to get.
887
     *  + Otherwise run a binary search to determine the last known message
888
     */
889
    int ok, nolinear = 0;
890
    int first_nr, list_len, try_id, try_nr, add_id;
891
    int num;
892
    char id [IDLEN+1];
893
894
    if ((ok = pop3_gettopid(sock, 1, id, sizeof(id))) != 0)
895
	return ok;
896
897
    if( ( first_nr = str_nr_in_list(&ctl->oldsaved, id) ) == -1 ) {
898
	/* the first message is unknown -> all messages are new */
899
	*newp = *countp;	
900
	return 0;
901
    }
902
903
    /* check where we expect the latest known message */
904
    list_len = count_list( &ctl->oldsaved );
905
    try_id = list_len  - first_nr; /* -1 + 1 */
906
    if( try_id > 1 ) {
907
	if( try_id <= *countp ) {
908
	    if ((ok = pop3_gettopid(sock, try_id, id, sizeof(id))) != 0)
909
		return ok;
910
    
911
	    try_nr = str_nr_last_in_list(&ctl->oldsaved, id);
912
	} else {
913
	    try_id = *countp+1;
914
	    try_nr = -1;
915
	}
916
	if( try_nr != list_len -1 ) {
917
	    /* some messages inbetween have been deleted... */
918
	    if( try_nr == -1 ) {
919
		nolinear = 1;
920
921
		for( add_id = 1<<30; add_id > try_id-1; add_id >>= 1 )
922
		    ;
923
		for( ; add_id; add_id >>= 1 ) {
924
		    if( try_nr == -1 ) {
925
			if( try_id - add_id <= 1 ) {
926
			    continue;
927
			}
928
			try_id -= add_id;
929
		    } else 
930
			try_id += add_id;
931
		    
932
		    if ((ok = pop3_gettopid(sock, try_id, id, sizeof(id))) != 0)
933
			return ok;
934
		    try_nr = str_nr_in_list(&ctl->oldsaved, id);
935
		}
936
		if( try_nr == -1 ) {
937
		    try_id--;
938
		}
939
	    } else {
940
		report(stderr, 
941
		       GT_("Messages inserted into list on server. Cannot handle this.\n"));
942
		return -1;
943
	    }
944
	} 
945
    }
946
    /* the first try_id messages are known -> copy them to the newsaved list */
947
    for( num = first_nr; num < list_len; num++ )
948
    {
949
	struct idlist	*newl = save_str(&ctl->newsaved, 
950
				str_from_nr_list(&ctl->oldsaved, num),
951
				UID_UNSEEN);
952
	newl->val.status.num = num - first_nr + 1;
953
    }
954
955
    if( nolinear ) {
956
	free_str_list(&ctl->oldsaved);
957
	ctl->oldsaved = 0;
958
	last = try_id;
959
    }
960
961
    *newp = *countp - try_id;
962
    return 0;
963
}
964
965
static int pop3_getrange(int sock, 
966
			 struct query *ctl,
967
			 const char *folder,
968
			 int *countp, int *newp, int *bytes)
969
/* get range of messages to be fetched */
970
{
971
    int ok;
972
    char buf [POPBUFSIZE+1];
973
974
    (void)folder;
975
    /* Ensure that the new list is properly empty */
976
    ctl->newsaved = (struct idlist *)NULL;
977
978
#ifdef MBOX
979
    /* Alain Knaff suggests this, but it's not RFC standard */
980
    if (folder)
981
	if ((ok = gen_transact(sock, "MBOX %s", folder)))
982
	    return ok;
983
#endif /* MBOX */
984
985
    /* get the total message count */
986
    gen_send(sock, "STAT");
987
    ok = pop3_ok(sock, buf);
988
    if (ok == 0) {
989
	int asgn;
990
991
	asgn = sscanf(buf,"%d %d", countp, bytes);
992
	if (asgn != 2)
993
		return PS_PROTOCOL;
994
    } else
995
	return(ok);
996
997
    /*
998
     * Newer, RFC-1725/1939-conformant POP servers may not have the LAST
999
     * command.  We work as hard as possible to hide this, but it makes
1000
     * counting new messages intrinsically quadratic in the worst case.
1001
     */
1002
    last = 0;
1003
    *newp = -1;
1004
    /* if there are messages, and UIDL is desired, use UIDL
1005
     * also use UIDL if fetchall is unset */
1006
    if (*countp > 0 && (!ctl->fetchall || ctl->server.uidl))
1007
    {
1008
	int fastuidl;
1009
	char id [IDLEN+1];
1010
1011
	/* should we do fast uidl this time? */
1012
	fastuidl = ctl->fastuidl;
1013
	if (*countp > 7 &&		/* linear search is better if there are few mails! */
1014
	    !ctl->fetchall &&		/* with fetchall, all uids are required */
1015
	    !ctl->flush &&		/* with flush, it is safer to disable fastuidl */
1016
	    NUM_NONZERO (fastuidl))
1017
	{
1018
	    if (fastuidl == 1)
1019
		dofastuidl = 1;
1020
	    else
1021
		dofastuidl = ctl->fastuidlcount != 0;
1022
	}
1023
	else
1024
	    dofastuidl = 0;
1025
1026
	if (!ctl->server.uidl) {
1027
	    gen_send(sock, "LAST");
1028
	    ok = pop3_ok(sock, buf);
1029
	} else
1030
	    ok = 1;
1031
1032
	if (ok == 0)
1033
	{
1034
	    /* scan LAST reply */
1035
	    if (sscanf(buf, "%d", &last) == 0)
1036
	    {
1037
		report(stderr, GT_("protocol error\n"));
1038
		return(PS_ERROR);
1039
	    }
1040
	    *newp = (*countp - last);
1041
	}
1042
	else
1043
	{
1044
	    /* do UIDL */
1045
	    if (dofastuidl)
1046
		return(pop3_fastuidl( sock, ctl, *countp, newp));
1047
	    /* grab the mailbox's UID list */
1048
	    if (gen_transact(sock, "UIDL") != 0)
1049
	    {
1050
		/* don't worry, yet! do it the slow way */
1051
		if (pop3_slowuidl(sock, ctl, countp, newp))
1052
		{
1053
		    report(stderr, GT_("protocol error while fetching UIDLs\n"));
1054
		    return(PS_ERROR);
1055
		}
1056
	    }
1057
	    else
1058
	    {
1059
		/* UIDL worked - parse reply */
1060
		unsigned long unum;
1061
		struct idlist *newl = NULL;
1062
1063
		*newp = 0;
1064
		while (gen_recv(sock, buf, sizeof(buf)) == PS_SUCCESS)
1065
		{
1066
		    if (DOTLINE(buf))
1067
			break;
1068
1069
		    if (parseuid(buf, &unum, id, sizeof(id)) == PS_SUCCESS)
1070
		    {
1071
			struct idlist	*old;
1072
1073
			newl = save_str(newl ? &newl : &ctl->newsaved, id, UID_UNSEEN);
1074
			newl->val.status.num = unum;
1075
1076
			if ((old = str_in_list(&ctl->oldsaved, id, FALSE)))
1077
			{
1078
			    flag mark = old->val.status.mark;
1079
			    if (mark == UID_DELETED || mark == UID_EXPUNGED)
1080
			    {
1081
				/* XXX FIXME: switch 3 occurrences from
1082
				 * (int)unum or (unsigned int)unum to
1083
				 * remove the cast and use %lu - not now
1084
				 * though, time for new release */
1085
				if (outlevel >= O_VERBOSE)
1086
				    report(stderr, GT_("id=%s (num=%d) was deleted, but is still present!\n"), id, (int)unum);
1087
				/* just mark it as seen now! */
1088
				old->val.status.mark = mark = UID_SEEN;
1089
			    }
1090
			    newl->val.status.mark = mark;
1091
			    if (mark == UID_UNSEEN)
1092
			    {
1093
				(*newp)++;
1094
				if (outlevel >= O_DEBUG)
1095
				    report(stdout, GT_("%u is unseen\n"), (unsigned int)unum);
1096
			    }
1097
			}
1098
			else
1099
			{
1100
			    (*newp)++;
1101
			    if (outlevel >= O_DEBUG)
1102
				report(stdout, GT_("%u is unseen\n"), (unsigned int)unum);
1103
			    /* add it to oldsaved also! In case, we do not
1104
			     * swap the lists (say, due to socket error),
1105
			     * the same mail will not be downloaded again.
1106
			     */
1107
			    old = save_str(&ctl->oldsaved, id, UID_UNSEEN);
1108
			}
1109
			/* save the number */
1110
			old->val.status.num = unum;
1111
		    } else
1112
			return PS_ERROR;
1113
		} /* multi-line loop for UIDL reply */
1114
	    } /* UIDL parser */
1115
	} /* do UIDL */
1116
    }
1117
1118
    return(PS_SUCCESS);
1119
}
1120
1121
static int pop3_getpartialsizes(int sock, int first, int last, int *sizes)
1122
/* capture the size of message #first */
1123
{
1124
    int	ok = 0, i, num;
1125
    char buf [POPBUFSIZE+1];
1126
    unsigned int size;
1127
1128
    for (i = first; i <= last; i++) {
1129
	gen_send(sock, "LIST %d", i);
1130
	if ((ok = pop3_ok(sock, buf)) != 0)
1131
	    return(ok);
1132
	if (sscanf(buf, "%d %u", &num, &size) == 2) {
1133
	    if (num == i)
1134
		sizes[i - first] = size;
1135
	    else
1136
		/* warn about possible attempt to induce buffer overrun
1137
		 *
1138
		 * we expect server reply message number and requested
1139
		 * message number to match */
1140
		report(stderr, "Warning: ignoring bogus data for message sizes returned by server.\n");
1141
	}
1142
    }
1143
    return(ok);
1144
}
1145
1146
static int pop3_getsizes(int sock, int count, int *sizes)
1147
/* capture the sizes of all messages */
1148
{
1149
    int	ok;
1150
1151
    if ((ok = gen_transact(sock, "LIST")) != 0)
1152
	return(ok);
1153
    else
1154
    {
1155
	char buf [POPBUFSIZE+1];
1156
1157
	while ((ok = gen_recv(sock, buf, sizeof(buf))) == 0)
1158
	{
1159
	    unsigned int num, size;
1160
1161
	    if (DOTLINE(buf))
1162
		break;
1163
	    else if (sscanf(buf, "%u %u", &num, &size) == 2) {
1164
		if (num > 0 && num <= (unsigned)count)
1165
		    sizes[num - 1] = size;
1166
		else
1167
		    /* warn about possible attempt to induce buffer overrun */
1168
		    report(stderr, "Warning: ignoring bogus data for message sizes returned by server.\n");
1169
	    }
1170
	}
1171
1172
	return(ok);
1173
    }
1174
}
1175
1176
static int pop3_is_old(int sock, struct query *ctl, int num)
1177
/* is the given message old? */
1178
{
1179
    struct idlist *newl;
1180
    if (!ctl->oldsaved)
1181
	return (num <= last);
1182
    else if (dofastuidl)
1183
    {
1184
	char id [IDLEN+1];
1185
1186
	if (num <= last)
1187
	    return(TRUE);
1188
1189
	/* in fast uidl, we manipulate the old list only! */
1190
1191
	if ((newl = id_find(&ctl->oldsaved, num)))
1192
	{
1193
	    /* we already have the id! */
1194
	    return(newl->val.status.mark != UID_UNSEEN);
1195
	}
1196
1197
	/* get the uidl first! */
1198
	if (pop3_getuidl(sock, num, id, sizeof(id)) != PS_SUCCESS)
1199
	    return(TRUE);
1200
1201
	if ((newl = str_in_list(&ctl->oldsaved, id, FALSE))) {
1202
	    /* we already have the id! */
1203
	    newl->val.status.num = num;
1204
	    return(newl->val.status.mark != UID_UNSEEN);
1205
	}
1206
1207
	/* save it */
1208
	newl = save_str(&ctl->oldsaved, id, UID_UNSEEN);
1209
	newl->val.status.num = num;
1210
	return(FALSE);
1211
    }
1212
    else
1213
        return ((newl = id_find(&ctl->newsaved, num)) != NULL &&
1214
	    newl->val.status.mark != UID_UNSEEN);
1215
}
1216
1217
#ifdef UNUSED
1218
/*
1219
 * We could use this to fetch headers only as we do for IMAP.  The trouble 
1220
 * is that there's no way to fetch the body only.  So the following RETR 
1221
 * would have to re-fetch the header.  Enough messages have longer headers
1222
 * than bodies to make this a net loss.
1223
 */
1224
static int pop_fetch_headers(int sock, struct query *ctl,int number,int *lenp)
1225
/* request headers of nth message */
1226
{
1227
    int ok;
1228
    char buf[POPBUFSIZE+1];
1229
1230
    gen_send(sock, "TOP %d 0", number);
1231
    if ((ok = pop3_ok(sock, buf)) != 0)
1232
	return(ok);
1233
1234
    *lenp = -1;		/* we got sizes from the LIST response */
1235
1236
    return(PS_SUCCESS);
1237
}
1238
#endif /* UNUSED */
1239
1240
static int pop3_fetch(int sock, struct query *ctl, int number, int *lenp)
1241
/* request nth message */
1242
{
1243
    int ok;
1244
    char buf[POPBUFSIZE+1];
1245
1246
#ifdef SDPS_ENABLE
1247
    /*
1248
     * See http://www.demon.net/helpdesk/producthelp/mail/sdps-tech.html/
1249
     * for a description of what we're parsing here.
1250
     * -- updated 2006-02-22
1251
     */
1252
    if (ctl->server.sdps)
1253
    {
1254
	int	linecount = 0;
1255
1256
	sdps_envfrom = (char *)NULL;
1257
	sdps_envto = (char *)NULL;
1258
	gen_send(sock, "*ENV %d", number);
1259
	do {
1260
	    if (gen_recv(sock, buf, sizeof(buf)))
1261
            {
1262
                break;
1263
            }
1264
            linecount++;
1265
	    switch (linecount) {
1266
	    case 4:
1267
		/* No need to wrap envelope from address */
1268
		/* FIXME: some parts of fetchmail don't handle null
1269
		 * envelope senders, so use <> to mark null sender
1270
		 * as a workaround. */
1271
		if (strspn(buf, " \t") == strlen(buf))
1272
		    strcpy(buf, "<>");
1273
		sdps_envfrom = (char *)xmalloc(strlen(buf)+1);
1274
		strcpy(sdps_envfrom,buf);
1275
		break;
1276
	    case 5:
1277
                /* Wrap address with To: <> so nxtaddr() likes it */
1278
                sdps_envto = (char *)xmalloc(strlen(buf)+7);
1279
                sprintf(sdps_envto,"To: <%s>",buf);
1280
		break;
1281
            }
1282
	} while
1283
	    (!(buf[0] == '.' && (buf[1] == '\r' || buf[1] == '\n' || buf[1] == '\0')));
1284
    }
1285
#else
1286
    (void)ctl;
1287
#endif /* SDPS_ENABLE */
1288
1289
    /*
1290
     * Though the POP RFCs don't document this fact, on almost every
1291
     * POP3 server I know of messages are marked "seen" only at the
1292
     * time the OK response to a RETR is issued.
1293
     *
1294
     * This means we can use TOP to fetch the message without setting its
1295
     * seen flag.  This is good!  It means that if the protocol exchange
1296
     * craps out during the message, it will still be marked `unseen' on
1297
     * the server.  (Exception: in early 1999 SpryNet's POP3 servers were
1298
     * reported to mark messages seen on a TOP fetch.)
1299
     *
1300
     * However...*don't* do this if we're using keep to suppress deletion!
1301
     * In that case, marking the seen flag is the only way to prevent the
1302
     * message from being re-fetched on subsequent runs.
1303
     *
1304
     * Also use RETR (that means no TOP, no peek) if fetchall is on.
1305
     * This gives us a workaround for servers like usa.net's that bungle
1306
     * TOP.  It's pretty harmless because fetchall guarantees that any
1307
     * message dropped by an interrupted RETR will be picked up on the
1308
     * next poll of the site.
1309
     *
1310
     * We take advantage here of the fact that, according to all the
1311
     * POP RFCs, "if the number of lines requested by the POP3 client
1312
     * is greater than than the number of lines in the body, then the
1313
     * POP3 server sends the entire message.").
1314
     *
1315
     * The line count passed (99999999) is the maximum value CompuServe will
1316
     * accept; it's much lower than the natural value 2147483646 (the maximum
1317
     * twos-complement signed 32-bit integer minus 1) */
1318
    if (!peek_capable)
1319
	gen_send(sock, "RETR %d", number);
1320
    else
1321
	gen_send(sock, "TOP %d 99999999", number);
1322
    if ((ok = pop3_ok(sock, buf)) != 0)
1323
	return(ok);
1324
1325
    *lenp = -1;		/* we got sizes from the LIST response */
1326
1327
    return(PS_SUCCESS);
1328
}
1329
1330
static void mark_uid_seen(struct query *ctl, int number)
1331
/* Tell the UID code we've seen this. */
1332
{
1333
    struct idlist	*sdp;
1334
1335
    if ((sdp = id_find(&ctl->newsaved, number)))
1336
	sdp->val.status.mark = UID_SEEN;
1337
    /* mark it as seen in oldsaved also! In case, we do not swap the lists
1338
     * (say, due to socket error), the same mail will not be downloaded
1339
     * again.
1340
     */
1341
    if ((sdp = id_find(&ctl->oldsaved, number)))
1342
	sdp->val.status.mark = UID_SEEN;
1343
}
1344
1345
static int pop3_delete(int sock, struct query *ctl, int number)
1346
/* delete a given message */
1347
{
1348
    int ok;
1349
    mark_uid_seen(ctl, number);
1350
    /* actually, mark for deletion -- doesn't happen until QUIT time */
1351
    ok = gen_transact(sock, "DELE %d", number);
1352
    if (ok != PS_SUCCESS)
1353
	return(ok);
1354
    delete_str(dofastuidl ? &ctl->oldsaved : &ctl->newsaved, number);
1355
    return(PS_SUCCESS);
1356
}
1357
1358
static int pop3_mark_seen(int sock, struct query *ctl, int number)
1359
/* mark a given message as seen */
1360
{
1361
    (void)sock;
1362
    mark_uid_seen(ctl, number);
1363
    return(PS_SUCCESS);
1364
}
1365
1366
static int pop3_logout(int sock, struct query *ctl)
1367
/* send logout command */
1368
{
1369
    int ok;
1370
1371
#ifdef __UNUSED__
1372
    /*
1373
     * We used to do this in case the server marks messages deleted when seen.
1374
     * (Yes, this has been reported, in the MercuryP/NLM server.
1375
     * It's even legal under RFC 1939 (section 8) as a site policy.)
1376
     * It interacted badly with UIDL, though.  Thomas Zajic wrote:
1377
     * "Running 'fetchmail -F -v' and checking the logs, I found out
1378
     * that fetchmail did in fact flush my mailbox properly, but sent
1379
     * a RSET just before sending QUIT to log off.  This caused the
1380
     * POP3 server to undo/forget about the previous DELEs, resetting
1381
     * my mailbox to its original (ie.  unflushed) state. The
1382
     * ~/.fetchids file did get flushed though, so the next time
1383
     * fetchmail was run it saw all the old messages as new ones ..."
1384
     */
1385
     if (ctl->keep)
1386
	gen_transact(sock, "RSET");
1387
#endif /* __UNUSED__ */
1388
1389
    ok = gen_transact(sock, "QUIT");
1390
    if (!ok)
1391
	expunge_uids(ctl);
1392
1393
    return(ok);
1394
}
1395
1396
static const struct method pop3 =
1397
{
1398
    "POP3",		/* Post Office Protocol v3 */
1399
    "pop3",		/* port for plain and TLS POP3 */
1400
    "pop3s",		/* port for SSL POP3 */
1401
    FALSE,		/* this is not a tagged protocol */
1402
    TRUE,		/* this uses a message delimiter */
1403
    pop3_ok,		/* parse command response */
1404
    pop3_getauth,	/* get authorization */
1405
    pop3_getrange,	/* query range of messages */
1406
    pop3_getsizes,	/* we can get a list of sizes */
1407
    pop3_getpartialsizes,	/* we can get the size of 1 mail */
1408
    pop3_is_old,	/* how do we tell a message is old? */
1409
    pop3_fetch,		/* request given message */
1410
    NULL,		/* no way to fetch body alone */
1411
    NULL,		/* no message trailer */
1412
    pop3_delete,	/* how to delete a message */
1413
    pop3_mark_seen,	/* how to mark a message as seen */
1414
    NULL,		/* no action at end of mailbox */
1415
    pop3_logout,	/* log out, we're done */
1416
    FALSE,		/* no, we can't re-poll */
1417
};
1418
1419
int doPOP3 (struct query *ctl)
1420
/* retrieve messages using POP3 */
1421
{
1422
#ifndef MBOX
1423
    if (ctl->mailboxes->id) {
1424
	fprintf(stderr,GT_("Option --folder is not supported with POP3\n"));
1425
	return(PS_SYNTAX);
1426
    }
1427
#endif /* MBOX */
1428
1429
    return(do_protocol(ctl, &pop3));
1430
}
1431
#endif /* POP3_ENABLE */
1432
1433
/* pop3.c ends here */