1 /*
2  * Copyright (c) 1983 Eric P. Allman
3  * Copyright (c) 1988 Regents of the University of California.
4  * All rights reserved.
5  *
6  * %sccs.include.redist.c%
7  */
8 
9 # include "sendmail.h"
10 
11 #ifndef lint
12 #ifdef SMTP
13 static char sccsid[] = "@(#)usersmtp.c	6.30 (Berkeley) 05/12/93 (with SMTP)";
14 #else
15 static char sccsid[] = "@(#)usersmtp.c	6.30 (Berkeley) 05/12/93 (without SMTP)";
16 #endif
17 #endif /* not lint */
18 
19 # include <sysexits.h>
20 # include <errno.h>
21 
22 # ifdef SMTP
23 
24 /*
25 **  USERSMTP -- run SMTP protocol from the user end.
26 **
27 **	This protocol is described in RFC821.
28 */
29 
30 #define REPLYTYPE(r)	((r) / 100)		/* first digit of reply code */
31 #define REPLYCLASS(r)	(((r) / 10) % 10)	/* second digit of reply code */
32 #define SMTPCLOSING	421			/* "Service Shutting Down" */
33 
34 char	SmtpMsgBuffer[MAXLINE];		/* buffer for commands */
35 char	SmtpReplyBuffer[MAXLINE];	/* buffer for replies */
36 char	SmtpError[MAXLINE] = "";	/* save failure error messages */
37 int	SmtpPid;			/* pid of mailer */
38 
39 #ifdef __STDC__
40 extern	smtpmessage(char *f, MAILER *m, MCI *mci, ...);
41 #endif
42 /*
43 **  SMTPINIT -- initialize SMTP.
44 **
45 **	Opens the connection and sends the initial protocol.
46 **
47 **	Parameters:
48 **		m -- mailer to create connection to.
49 **		pvp -- pointer to parameter vector to pass to
50 **			the mailer.
51 **
52 **	Returns:
53 **		none.
54 **
55 **	Side Effects:
56 **		creates connection and sends initial protocol.
57 */
58 
59 smtpinit(m, mci, e)
60 	struct mailer *m;
61 	register MCI *mci;
62 	ENVELOPE *e;
63 {
64 	register int r;
65 	register char *p;
66 	extern STAB *stab();
67 	extern void helo_options();
68 
69 	if (tTd(17, 1))
70 	{
71 		printf("smtpinit ");
72 		mci_dump(mci);
73 	}
74 
75 	/*
76 	**  Open the connection to the mailer.
77 	*/
78 
79 	SmtpError[0] = '\0';
80 	CurHostName = mci->mci_host;		/* XXX UGLY XXX */
81 	switch (mci->mci_state)
82 	{
83 	  case MCIS_ACTIVE:
84 		/* need to clear old information */
85 		smtprset(m, mci, e);
86 		/* fall through */
87 
88 	  case MCIS_OPEN:
89 		return;
90 
91 	  case MCIS_ERROR:
92 	  case MCIS_SSD:
93 		/* shouldn't happen */
94 		smtpquit(m, mci, e);
95 		/* fall through */
96 
97 	  case MCIS_CLOSED:
98 		syserr("451 smtpinit: state CLOSED");
99 		return;
100 
101 	  case MCIS_OPENING:
102 		break;
103 	}
104 
105 	mci->mci_state = MCIS_OPENING;
106 
107 	/*
108 	**  Get the greeting message.
109 	**	This should appear spontaneously.  Give it five minutes to
110 	**	happen.
111 	*/
112 
113 	SmtpPhase = mci->mci_phase = "greeting wait";
114 	setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
115 	r = reply(m, mci, e, TimeOuts.to_initial, NULL);
116 	if (r < 0 || REPLYTYPE(r) != 2)
117 		goto tempfail1;
118 
119 	/*
120 	**  Send the HELO command.
121 	**	My mother taught me to always introduce myself.
122 	*/
123 
124 	if (bitnset(M_ESMTP, m->m_flags))
125 		mci->mci_flags |= MCIF_ESMTP;
126 
127 tryhelo:
128 	if (bitset(MCIF_ESMTP, mci->mci_flags))
129 	{
130 		smtpmessage("EHLO %s", m, mci, MyHostName);
131 		SmtpPhase = mci->mci_phase = "EHLO wait";
132 	}
133 	else
134 	{
135 		smtpmessage("HELO %s", m, mci, MyHostName);
136 		SmtpPhase = mci->mci_phase = "HELO wait";
137 	}
138 	setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
139 	r = reply(m, mci, e, TimeOuts.to_helo, helo_options);
140 	if (r < 0)
141 		goto tempfail1;
142 	else if (REPLYTYPE(r) == 5)
143 	{
144 		if (bitset(MCIF_ESMTP, mci->mci_flags))
145 		{
146 			/* try old SMTP instead */
147 			mci->mci_flags &= ~MCIF_ESMTP;
148 			goto tryhelo;
149 		}
150 		goto unavailable;
151 	}
152 	else if (REPLYTYPE(r) != 2)
153 		goto tempfail1;
154 
155 	/*
156 	**  Check to see if we actually ended up talking to ourself.
157 	**  This means we didn't know about an alias or MX, or we managed
158 	**  to connect to an echo server.
159 	*/
160 
161 	p = strchr(&SmtpReplyBuffer[4], ' ');
162 	if (p != NULL)
163 		*p == '\0';
164 	if (strcasecmp(&SmtpReplyBuffer[4], MyHostName) == 0)
165 	{
166 		syserr("553 %s config error: mail loops back to myself",
167 			MyHostName);
168 		mci->mci_exitstat = EX_CONFIG;
169 		mci->mci_errno = 0;
170 		smtpquit(m, mci, e);
171 		return;
172 	}
173 
174 	/*
175 	**  If this is expected to be another sendmail, send some internal
176 	**  commands.
177 	*/
178 
179 	if (bitnset(M_INTERNAL, m->m_flags))
180 	{
181 		/* tell it to be verbose */
182 		smtpmessage("VERB", m, mci);
183 		r = reply(m, mci, e, TimeOuts.to_miscshort, NULL);
184 		if (r < 0)
185 			goto tempfail2;
186 	}
187 
188 	mci->mci_state = MCIS_OPEN;
189 	return;
190 
191   tempfail1:
192   tempfail2:
193 	mci->mci_exitstat = EX_TEMPFAIL;
194 	if (mci->mci_errno == 0)
195 		mci->mci_errno = errno;
196 	if (mci->mci_state != MCIS_CLOSED)
197 		smtpquit(m, mci, e);
198 	return;
199 
200   unavailable:
201 	mci->mci_exitstat = EX_UNAVAILABLE;
202 	mci->mci_errno = errno;
203 	smtpquit(m, mci, e);
204 	return;
205 }
206 /*
207 **  HELO_OPTIONS -- process the options on a HELO line.
208 **
209 **	Parameters:
210 **		line -- the response line.
211 **		m -- the mailer.
212 **		mci -- the mailer connection info.
213 **		e -- the envelope.
214 **
215 **	Returns:
216 **		none.
217 */
218 
219 void
220 helo_options(line, m, mci, e)
221 	char *line;
222 	MAILER *m;
223 	register MCI *mci;
224 	ENVELOPE *e;
225 {
226 	register char *p;
227 
228 	if (strlen(line) < 5)
229 		return;
230 	line += 4;
231 	p = strchr(line, ' ');
232 	if (p != NULL)
233 		*p++ = '\0';
234 	if (strcasecmp(line, "size") == 0)
235 	{
236 		mci->mci_flags |= MCIF_SIZE;
237 		if (p != NULL)
238 			mci->mci_maxsize = atol(p);
239 	}
240 	else if (strcasecmp(line, "8bitmime") == 0)
241 		mci->mci_flags |= MCIF_8BITMIME;
242 	else if (strcasecmp(line, "expn") == 0)
243 		mci->mci_flags |= MCIF_EXPN;
244 }
245 /*
246 **  SMTPMAILFROM -- send MAIL command
247 **
248 **	Parameters:
249 **		m -- the mailer.
250 **		mci -- the mailer connection structure.
251 **		e -- the envelope (including the sender to specify).
252 */
253 
254 smtpmailfrom(m, mci, e)
255 	struct mailer *m;
256 	MCI *mci;
257 	ENVELOPE *e;
258 {
259 	int r;
260 	char buf[MAXNAME];
261 	char optbuf[MAXLINE];
262 
263 	if (tTd(17, 2))
264 		printf("smtpmailfrom: CurHost=%s\n", CurHostName);
265 
266 	/* set up appropriate options to include */
267 	if (bitset(MCIF_SIZE, mci->mci_flags))
268 		sprintf(optbuf, " SIZE=%ld", e->e_msgsize);
269 	else
270 		strcpy(optbuf, "");
271 
272 	/*
273 	**  Send the MAIL command.
274 	**	Designates the sender.
275 	*/
276 
277 	mci->mci_state = MCIS_ACTIVE;
278 
279 	if (bitset(EF_RESPONSE, e->e_flags) &&
280 	    !bitnset(M_NO_NULL_FROM, m->m_flags))
281 		(void) strcpy(buf, "");
282 	else
283 		expand("\201g", buf, &buf[sizeof buf - 1], e);
284 	if (e->e_from.q_mailer == LocalMailer ||
285 	    !bitnset(M_FROMPATH, m->m_flags))
286 	{
287 		smtpmessage("MAIL From:<%s>%s", m, mci, buf, optbuf);
288 	}
289 	else
290 	{
291 		smtpmessage("MAIL From:<@%s%c%s>%s", m, mci, MyHostName,
292 			buf[0] == '@' ? ',' : ':', buf, optbuf);
293 	}
294 	SmtpPhase = mci->mci_phase = "MAIL wait";
295 	setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
296 	r = reply(m, mci, e, TimeOuts.to_mail, NULL);
297 	if (r < 0 || REPLYTYPE(r) == 4)
298 	{
299 		mci->mci_exitstat = EX_TEMPFAIL;
300 		mci->mci_errno = errno;
301 		smtpquit(m, mci, e);
302 		return EX_TEMPFAIL;
303 	}
304 	else if (r == 250)
305 	{
306 		mci->mci_exitstat = EX_OK;
307 		return EX_OK;
308 	}
309 	else if (r == 552)
310 	{
311 		/* signal service unavailable */
312 		mci->mci_exitstat = EX_UNAVAILABLE;
313 		smtpquit(m, mci, e);
314 		return EX_UNAVAILABLE;
315 	}
316 
317 #ifdef LOG
318 	if (LogLevel > 1)
319 	{
320 		syslog(LOG_CRIT, "%s: SMTP MAIL protocol error: %s",
321 			e->e_id, SmtpReplyBuffer);
322 	}
323 #endif
324 
325 	/* protocol error -- close up */
326 	smtpquit(m, mci, e);
327 	mci->mci_exitstat = EX_PROTOCOL;
328 	return EX_PROTOCOL;
329 }
330 /*
331 **  SMTPRCPT -- designate recipient.
332 **
333 **	Parameters:
334 **		to -- address of recipient.
335 **		m -- the mailer we are sending to.
336 **		mci -- the connection info for this transaction.
337 **		e -- the envelope for this transaction.
338 **
339 **	Returns:
340 **		exit status corresponding to recipient status.
341 **
342 **	Side Effects:
343 **		Sends the mail via SMTP.
344 */
345 
346 smtprcpt(to, m, mci, e)
347 	ADDRESS *to;
348 	register MAILER *m;
349 	MCI *mci;
350 	ENVELOPE *e;
351 {
352 	register int r;
353 
354 	smtpmessage("RCPT To:<%s>", m, mci, to->q_user);
355 
356 	SmtpPhase = mci->mci_phase = "RCPT wait";
357 	setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
358 	r = reply(m, mci, e, TimeOuts.to_rcpt, NULL);
359 	if (r < 0 || REPLYTYPE(r) == 4)
360 		return (EX_TEMPFAIL);
361 	else if (REPLYTYPE(r) == 2)
362 		return (EX_OK);
363 	else if (r == 550 || r == 551 || r == 553)
364 		return (EX_NOUSER);
365 	else if (r == 552 || r == 554)
366 		return (EX_UNAVAILABLE);
367 
368 #ifdef LOG
369 	if (LogLevel > 1)
370 	{
371 		syslog(LOG_CRIT, "%s: SMTP RCPT protocol error: %s",
372 			e->e_id, SmtpReplyBuffer);
373 	}
374 #endif
375 
376 	return (EX_PROTOCOL);
377 }
378 /*
379 **  SMTPDATA -- send the data and clean up the transaction.
380 **
381 **	Parameters:
382 **		m -- mailer being sent to.
383 **		e -- the envelope for this message.
384 **
385 **	Returns:
386 **		exit status corresponding to DATA command.
387 **
388 **	Side Effects:
389 **		none.
390 */
391 
392 smtpdata(m, mci, e)
393 	struct mailer *m;
394 	register MCI *mci;
395 	register ENVELOPE *e;
396 {
397 	register int r;
398 
399 	/*
400 	**  Send the data.
401 	**	First send the command and check that it is ok.
402 	**	Then send the data.
403 	**	Follow it up with a dot to terminate.
404 	**	Finally get the results of the transaction.
405 	*/
406 
407 	/* send the command and check ok to proceed */
408 	smtpmessage("DATA", m, mci);
409 	SmtpPhase = mci->mci_phase = "DATA wait";
410 	setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
411 	r = reply(m, mci, e, TimeOuts.to_datainit, NULL);
412 	if (r < 0 || REPLYTYPE(r) == 4)
413 	{
414 		smtpquit(m, mci, e);
415 		return (EX_TEMPFAIL);
416 	}
417 	else if (r == 554)
418 	{
419 		smtprset(m, mci, e);
420 		return (EX_UNAVAILABLE);
421 	}
422 	else if (r != 354)
423 	{
424 #ifdef LOG
425 		if (LogLevel > 1)
426 		{
427 			syslog(LOG_CRIT, "%s: SMTP DATA-1 protocol error: %s",
428 				e->e_id, SmtpReplyBuffer);
429 		}
430 #endif
431 		smtprset(m, mci, e);
432 		return (EX_PROTOCOL);
433 	}
434 
435 	/* now output the actual message */
436 	(*e->e_puthdr)(mci->mci_out, m, e);
437 	putline("\n", mci->mci_out, m);
438 	(*e->e_putbody)(mci->mci_out, m, e, NULL);
439 
440 	/* terminate the message */
441 	fprintf(mci->mci_out, ".%s", m->m_eol);
442 	if (Verbose)
443 		nmessage(">>> .");
444 
445 	/* check for the results of the transaction */
446 	SmtpPhase = mci->mci_phase = "result wait";
447 	setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
448 	r = reply(m, mci, e, TimeOuts.to_datafinal, NULL);
449 	if (r < 0)
450 	{
451 		smtpquit(m, mci, e);
452 		return (EX_TEMPFAIL);
453 	}
454 	mci->mci_state = MCIS_OPEN;
455 	e->e_statmsg = newstr(&SmtpReplyBuffer[4]);
456 	if (REPLYTYPE(r) == 4)
457 		return (EX_TEMPFAIL);
458 	else if (r == 250)
459 		return (EX_OK);
460 	else if (r == 552 || r == 554)
461 		return (EX_UNAVAILABLE);
462 #ifdef LOG
463 	if (LogLevel > 1)
464 	{
465 		syslog(LOG_CRIT, "%s: SMTP DATA-2 protocol error: %s",
466 			e->e_id, SmtpReplyBuffer);
467 	}
468 #endif
469 	return (EX_PROTOCOL);
470 }
471 /*
472 **  SMTPQUIT -- close the SMTP connection.
473 **
474 **	Parameters:
475 **		m -- a pointer to the mailer.
476 **
477 **	Returns:
478 **		none.
479 **
480 **	Side Effects:
481 **		sends the final protocol and closes the connection.
482 */
483 
484 smtpquit(m, mci, e)
485 	register MAILER *m;
486 	register MCI *mci;
487 	ENVELOPE *e;
488 {
489 	int i;
490 
491 	/* send the quit message if we haven't gotten I/O error */
492 	if (mci->mci_state != MCIS_ERROR)
493 	{
494 		smtpmessage("QUIT", m, mci);
495 		(void) reply(m, mci, e, TimeOuts.to_quit, NULL);
496 		if (mci->mci_state == MCIS_CLOSED)
497 			return;
498 	}
499 
500 	/* now actually close the connection and pick up the zombie */
501 	i = endmailer(mci, e, m->m_argv);
502 	if (i != EX_OK)
503 		syserr("451 smtpquit %s: stat %d", m->m_argv[0], i);
504 }
505 /*
506 **  SMTPRSET -- send a RSET (reset) command
507 */
508 
509 smtprset(m, mci, e)
510 	register MAILER *m;
511 	register MCI *mci;
512 	ENVELOPE *e;
513 {
514 	int r;
515 
516 	smtpmessage("RSET", m, mci);
517 	r = reply(m, mci, e, TimeOuts.to_rset, NULL);
518 	if (r < 0)
519 		mci->mci_state = MCIS_ERROR;
520 	else if (REPLYTYPE(r) == 2)
521 	{
522 		mci->mci_state = MCIS_OPEN;
523 		return;
524 	}
525 	smtpquit(m, mci, e);
526 }
527 /*
528 **  SMTPPROBE -- check the connection state
529 */
530 
531 smtpprobe(mci)
532 	register MCI *mci;
533 {
534 	int r;
535 	MAILER *m = mci->mci_mailer;
536 	extern ENVELOPE BlankEnvelope;
537 	ENVELOPE *e = &BlankEnvelope;
538 
539 	smtpmessage("RSET", m, mci);
540 	r = reply(m, mci, e, TimeOuts.to_miscshort, NULL);
541 	if (r < 0 || REPLYTYPE(r) != 2)
542 		smtpquit(m, mci, e);
543 	return r;
544 }
545 /*
546 **  REPLY -- read arpanet reply
547 **
548 **	Parameters:
549 **		m -- the mailer we are reading the reply from.
550 **		mci -- the mailer connection info structure.
551 **		e -- the current envelope.
552 **		timeout -- the timeout for reads.
553 **		pfunc -- processing function for second and subsequent
554 **			lines of response -- if null, no special
555 **			processing is done.
556 **
557 **	Returns:
558 **		reply code it reads.
559 **
560 **	Side Effects:
561 **		flushes the mail file.
562 */
563 
564 reply(m, mci, e, timeout, pfunc)
565 	MAILER *m;
566 	MCI *mci;
567 	ENVELOPE *e;
568 	time_t timeout;
569 	void (*pfunc)();
570 {
571 	register char *bufp;
572 	register int r;
573 	bool firstline = TRUE;
574 	char junkbuf[MAXLINE];
575 
576 	if (mci->mci_out != NULL)
577 		(void) fflush(mci->mci_out);
578 
579 	if (tTd(18, 1))
580 		printf("reply\n");
581 
582 	/*
583 	**  Read the input line, being careful not to hang.
584 	*/
585 
586 	for (bufp = SmtpReplyBuffer;; bufp = junkbuf)
587 	{
588 		register char *p;
589 		extern time_t curtime();
590 
591 		/* actually do the read */
592 		if (e->e_xfp != NULL)
593 			(void) fflush(e->e_xfp);	/* for debugging */
594 
595 		/* if we are in the process of closing just give the code */
596 		if (mci->mci_state == MCIS_CLOSED)
597 			return (SMTPCLOSING);
598 
599 		if (mci->mci_out != NULL)
600 			fflush(mci->mci_out);
601 
602 		/* get the line from the other side */
603 		p = sfgets(bufp, MAXLINE, mci->mci_in, timeout);
604 		mci->mci_lastuse = curtime();
605 
606 		if (p == NULL)
607 		{
608 			extern char MsgBuf[];		/* err.c */
609 
610 			/* if the remote end closed early, fake an error */
611 			if (errno == 0)
612 # ifdef ECONNRESET
613 				errno = ECONNRESET;
614 # else /* ECONNRESET */
615 				errno = EPIPE;
616 # endif /* ECONNRESET */
617 
618 			mci->mci_errno = errno;
619 			mci->mci_exitstat = EX_TEMPFAIL;
620 			message("451 %s: reply: read error from %s",
621 				e->e_id == NULL ? "NOQUEUE" : e->e_id,
622 				mci->mci_host);
623 			/* if debugging, pause so we can see state */
624 			if (tTd(18, 100))
625 				pause();
626 # ifdef LOG
627 			if (LogLevel > 1)
628 				syslog(LOG_INFO, "%s", &MsgBuf[4]);
629 # endif /* LOG */
630 			mci->mci_state = MCIS_ERROR;
631 			smtpquit(m, mci, e);
632 			return (-1);
633 		}
634 		fixcrlf(bufp, TRUE);
635 
636 		if (e->e_xfp != NULL && strchr("45", bufp[0]) != NULL)
637 		{
638 			/* serious error -- log the previous command */
639 			if (SmtpMsgBuffer[0] != '\0')
640 				fprintf(e->e_xfp, ">>> %s\n", SmtpMsgBuffer);
641 			SmtpMsgBuffer[0] = '\0';
642 
643 			/* now log the message as from the other side */
644 			fprintf(e->e_xfp, "<<< %s\n", bufp);
645 		}
646 
647 		/* display the input for verbose mode */
648 		if (Verbose)
649 			nmessage("050 %s", bufp);
650 
651 		/* process the line */
652 		if (pfunc != NULL && !firstline)
653 			(*pfunc)(bufp, m, mci, e);
654 
655 		firstline = FALSE;
656 
657 		/* if continuation is required, we can go on */
658 		if (bufp[3] == '-')
659 			continue;
660 
661 		/* ignore improperly formated input */
662 		if (!(isascii(bufp[0]) && isdigit(bufp[0])))
663 			continue;
664 
665 		/* decode the reply code */
666 		r = atoi(bufp);
667 
668 		/* extra semantics: 0xx codes are "informational" */
669 		if (r >= 100)
670 			break;
671 	}
672 
673 	/*
674 	**  Now look at SmtpReplyBuffer -- only care about the first
675 	**  line of the response from here on out.
676 	*/
677 
678 	/* save temporary failure messages for posterity */
679 	if (SmtpReplyBuffer[0] == '4' && SmtpError[0] == '\0')
680 		(void) strcpy(SmtpError, SmtpReplyBuffer);
681 
682 	/* reply code 421 is "Service Shutting Down" */
683 	if (r == SMTPCLOSING && mci->mci_state != MCIS_SSD)
684 	{
685 		/* send the quit protocol */
686 		mci->mci_state = MCIS_SSD;
687 		smtpquit(m, mci, e);
688 	}
689 
690 	return (r);
691 }
692 /*
693 **  SMTPMESSAGE -- send message to server
694 **
695 **	Parameters:
696 **		f -- format
697 **		m -- the mailer to control formatting.
698 **		a, b, c -- parameters
699 **
700 **	Returns:
701 **		none.
702 **
703 **	Side Effects:
704 **		writes message to mci->mci_out.
705 */
706 
707 /*VARARGS1*/
708 #ifdef __STDC__
709 smtpmessage(char *f, MAILER *m, MCI *mci, ...)
710 #else
711 smtpmessage(f, m, mci, va_alist)
712 	char *f;
713 	MAILER *m;
714 	MCI *mci;
715 	va_dcl
716 #endif
717 {
718 	VA_LOCAL_DECL
719 
720 	VA_START(mci);
721 	(void) vsprintf(SmtpMsgBuffer, f, ap);
722 	VA_END;
723 
724 	if (tTd(18, 1) || Verbose)
725 		nmessage(">>> %s", SmtpMsgBuffer);
726 	if (mci->mci_out != NULL)
727 	{
728 		fprintf(mci->mci_out, "%s%s", SmtpMsgBuffer,
729 			m == NULL ? "\r\n" : m->m_eol);
730 	}
731 	else if (tTd(18, 1))
732 	{
733 		printf("smtpmessage: NULL mci_out\n");
734 	}
735 }
736 
737 # endif /* SMTP */
738