File: sendmail-8.14.3.connect.diff

package info (click to toggle)
mailfromd 9.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 11,512 kB
  • sloc: ansic: 56,882; sh: 22,979; yacc: 4,130; lex: 1,428; makefile: 928; lisp: 488; awk: 393; perl: 319; sed: 25
file content (103 lines) | stat: -rw-r--r-- 3,465 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
diff -pur orig/sendmail-8.14.3/sendmail/milter.c sendmail-8.14.3/sendmail/milter.c
--- orig/sendmail-8.14.3/sendmail/milter.c	2007-06-06 20:26:12.000000000 +0300
+++ sendmail-8.14.3/sendmail/milter.c	2009-08-31 11:49:59.750070622 +0300
@@ -3951,29 +3951,30 @@ milter_connect(hostname, addr, e, state)
 		milter_per_connection_check(e);
 
 	/*
+	*  There used to be the following comment here:
+	*
 	**  SMFIR_REPLYCODE can't work with connect due to
 	**  the requirements of SMTP.  Therefore, ignore the
 	**  reply code text but keep the state it would reflect.
+	*
+	*  However, this is wrong.  RFC2821, section 3.9 states, that:
+	*
+	* "An SMTP server MUST NOT intentionally close the connection except:
+	* [...]
+	* -  After detecting the need to shut down the SMTP service and
+	* returning a 421 response code.  This response code can be issued
+	* after the server receives any command or, if necessary,
+	* asynchronously from command receipt (on the assumption that the
+	* client will receive it after the next command is issued)."
+	*
+	* I see no reason why a milter cannot supply its own textual
+	* explanation in xxfi_connect.  So, instead of blindly filtering
+	* out the user-supllied response, I return it to smtp().  The latter
+	* is crafted so that it will graciously abort the connection, if
+	* the response begins with 421, giving the user-supplied textual
+	* message, and will proceed with nullserver otherwise.
+	*              --gray
 	*/
-
-	if (*state == SMFIR_REPLYCODE)
-	{
-		if (response != NULL &&
-		    *response == '4')
-		{
-			if (strncmp(response, "421 ", 4) == 0)
-				*state = SMFIR_SHUTDOWN;
-			else
-				*state = SMFIR_TEMPFAIL;
-		}
-		else
-			*state = SMFIR_REJECT;
-		if (response != NULL)
-		{
-			sm_free(response); /* XXX */
-			response = NULL;
-		}
-	}
 	return response;
 }
 
diff -pur orig/sendmail-8.14.3/sendmail/srvrsmtp.c sendmail-8.14.3/sendmail/srvrsmtp.c
--- orig/sendmail-8.14.3/sendmail/srvrsmtp.c	2008-03-31 19:32:13.000000000 +0300
+++ sendmail-8.14.3/sendmail/srvrsmtp.c	2009-09-23 16:07:56.604677429 +0300
@@ -957,6 +957,8 @@ smtp(nullserver, d_flags, e)
 	{
 		char state;
 		char *response;
+ 		static char greetcodebuf[4];
+ 		size_t len;
 
 		q = macvalue(macid("{client_name}"), e);
 		SM_ASSERT(q != NULL || OpMode == MD_SMTP);
@@ -965,7 +967,36 @@ smtp(nullserver, d_flags, e)
 		response = milter_connect(q, RealHostAddr, e, &state);
 		switch (state)
 		{
-		  case SMFIR_REPLYCODE:	/* REPLYCODE shouldn't happen */
+		  case SMFIR_REPLYCODE:	
+ 			if (MilterLogLevel > 3)
+ 				sm_syslog(LOG_INFO, e->e_id,
+ 					  "Milter: connect: host=%s, addr=%s, reject=%s",
+ 					  peerhostname,
+ 					  anynet_ntoa(&RealHostAddr),
+ 					  response);
+ 			len = strlen(response);
+ 			if (len >= 3) {
+ 				/* RFC 2821, Section 3.9 */
+				nullserver = newstr(response);
+ 				if (memcmp(response, "421", 3) == 0) {
+ 					message(response);
+ 					/* arrange to ignore send list */
+ 					e->e_sendqueue = NULL;
+ 				        sm_syslog(LOG_INFO, e->e_id,
+ 					          "host=%s, addr=%s, reject=%s",
+ 					          peerhostname,
+ 					          anynet_ntoa(&RealHostAddr),
+ 					          response);
+ 					goto doquit;
+ 				} else {
+ 					memcpy(greetcodebuf, response, 3);
+ 					greetcodebuf[3] = 0;
+ 					greetcode = greetcodebuf;
+ 					break;
+ 				}
+ 			}
+ 			/* FALL THROUGH */	
+ 
 		  case SMFIR_REJECT:
 			if (MilterLogLevel > 3)
 				sm_syslog(LOG_INFO, e->e_id,