summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--qmail-remote.c52
1 files changed, 29 insertions, 23 deletions
diff --git a/qmail-remote.c b/qmail-remote.c
index ee2c6a8..dbeef95 100644
--- a/qmail-remote.c
+++ b/qmail-remote.c
@@ -138,6 +138,20 @@ void outhost()
138} 138}
139 139
140int flagcritical = 0; 140int flagcritical = 0;
141stralloc smtptext = {0};
142stralloc smtptextdropped = {0};
143
144void outsmtptext(stralloc *smtptext)
145{
146 int i;
147 if (smtptext->s && smtptext->len) {
148 out("Remote host said: ");
149 for (i = 0;i < smtptext->len;++i)
150 if (!smtptext->s[i]) smtptext->s[i] = '?';
151 if (substdio_put(subfdoutsmall,smtptext->s,smtptext->len) == -1) _exit(0);
152 smtptext->len = 0;
153 }
154}
141 155
142void dropped() { 156void dropped() {
143 out("ZConnected to "); 157 out("ZConnected to ");
@@ -148,6 +162,7 @@ void dropped() {
148 if (ssl_err_str) { out(ssl_err_str); out(" "); } 162 if (ssl_err_str) { out(ssl_err_str); out(" "); }
149#endif 163#endif
150 out("(#4.4.2)\n"); 164 out("(#4.4.2)\n");
165 outsmtptext(&smtptextdropped);
151 zerodie(); 166 zerodie();
152} 167}
153 168
@@ -176,7 +191,7 @@ ssize_t safewrite(fd,buf,len) int fd; char *buf; int len;
176 r = ssl_timeoutwrite(timeout, smtpfd, smtpfd, ssl, buf, len); 191 r = ssl_timeoutwrite(timeout, smtpfd, smtpfd, ssl, buf, len);
177 if (r < 0) ssl_err_str = ssl_error_str(); 192 if (r < 0) ssl_err_str = ssl_error_str();
178 } else 193 } else
179#endif 194#endif
180 r = timeoutwrite(timeout,smtpfd,buf,len); 195 r = timeoutwrite(timeout,smtpfd,buf,len);
181 if (r <= 0) dropped(); 196 if (r <= 0) dropped();
182 return r; 197 return r;
@@ -189,8 +204,6 @@ substdio smtpto = SUBSTDIO_FDBUF(safewrite,-1,smtptobuf,sizeof smtptobuf);
189char smtpfrombuf[128]; 204char smtpfrombuf[128];
190substdio smtpfrom = SUBSTDIO_FDBUF(saferead,-1,smtpfrombuf,sizeof smtpfrombuf); 205substdio smtpfrom = SUBSTDIO_FDBUF(saferead,-1,smtpfrombuf,sizeof smtpfrombuf);
191 206
192stralloc smtptext = {0};
193
194void get(ch) 207void get(ch)
195char *ch; 208char *ch;
196{ 209{
@@ -276,18 +289,6 @@ unsigned long ehlo()
276 return 250; 289 return 250;
277} 290}
278 291
279void outsmtptext()
280{
281 int i;
282 if (smtptext.s) if (smtptext.len) {
283 out("Remote host said: ");
284 for (i = 0;i < smtptext.len;++i)
285 if (!smtptext.s[i]) smtptext.s[i] = '?';
286 if (substdio_put(subfdoutsmall,smtptext.s,smtptext.len) == -1) _exit(0);
287 smtptext.len = 0;
288 }
289}
290
291void smtp_quit() 292void smtp_quit()
292{ 293{
293#ifdef TLS 294#ifdef TLS
@@ -306,7 +307,7 @@ void quit2(const char *prepend, const char *append, int flagdie)
306 outhost(); 307 outhost();
307 if (append) out(append); 308 if (append) out(append);
308 out(".\n"); 309 out(".\n");
309 outsmtptext(); 310 outsmtptext(&smtptext);
310 311
311#if defined(TLS) && defined(DEBUG) 312#if defined(TLS) && defined(DEBUG)
312 if (ssl) { 313 if (ssl) {
@@ -394,7 +395,7 @@ int verify_cb(int preverify_ok, X509_STORE_CTX *ctx) { return 1; }
394 * @return 0 ...TLS failed, continue plaintext 395 * @return 0 ...TLS failed, continue plaintext
395 * @return -1 ...skip to next MX 396 * @return -1 ...skip to next MX
396 */ 397 */
397static int tls_init(struct ip_mx *current_mx) 398static int tls_init(unsigned long code, struct ip_mx *current_mx)
398{ 399{
399 int i; 400 int i;
400 SSL *myssl; 401 SSL *myssl;
@@ -476,7 +477,9 @@ static int tls_init(struct ip_mx *current_mx)
476 if (!tls_required) return 0; 477 if (!tls_required) return 0;
477 out(failure_class); 478 out(failure_class);
478 out("TLS is required, but was not offered by host"); 479 out("TLS is required, but was not offered by host");
479 smtptext.len = 0; 480 /* only hide SMTP EHLO reply in bounce message on success */
481 if (code == 250)
482 smtptext.len = 0;
480 TLS_QUIT; 483 TLS_QUIT;
481 } 484 }
482 } 485 }
@@ -634,7 +637,7 @@ static int tls_init(struct ip_mx *current_mx)
634 637
635 /* read the responce to STARTTLS */ 638 /* read the responce to STARTTLS */
636 if (!smtps) { 639 if (!smtps) {
637 unsigned int code = smtpcode(); 640 unsigned long code = smtpcode();
638 if (code != 220) { 641 if (code != 220) {
639 SSL_free(myssl); 642 SSL_free(myssl);
640 if (!tls_required) return 0; 643 if (!tls_required) return 0;
@@ -731,7 +734,7 @@ static int tls_init(struct ip_mx *current_mx)
731 } 734 }
732 735
733 if (smtps) { 736 if (smtps) {
734 unsigned int code = smtpcode(); 737 unsigned long code = smtpcode();
735 if (code >= 500 && code < 600) quit("DTLS connected to "," but greeting failed"); 738 if (code >= 500 && code < 600) quit("DTLS connected to "," but greeting failed");
736 if (code >= 400 && code < 500) return -1; /* try next MX, see RFC-2821 */ 739 if (code >= 400 && code < 500) return -1; /* try next MX, see RFC-2821 */
737 if (code != 220) quit("ZTLS connected to "," but greeting failed"); 740 if (code != 220) quit("ZTLS connected to "," but greeting failed");
@@ -823,7 +826,7 @@ static void smtp(struct ip_mx *current_mx)
823#endif 826#endif
824 827
825#ifdef TLS 828#ifdef TLS
826 int tls = tls_init(current_mx); 829 int tls = tls_init(code, current_mx);
827 if (tls == -1) { 830 if (tls == -1) {
828 if (ssl) 831 if (ssl)
829 ssl_free(ssl); 832 ssl_free(ssl);
@@ -842,11 +845,14 @@ static void smtp(struct ip_mx *current_mx)
842 845
843 /* and if EHLO failed, use HELO */ 846 /* and if EHLO failed, use HELO */
844 } else { 847 } else {
848 /* copy EHLO reply for bounce message in case the connection has already been dropped */
849 if (!stralloc_copy(&smtptextdropped,&smtptext)) temp_nomem();
845 substdio_puts(&smtpto,"HELO "); 850 substdio_puts(&smtpto,"HELO ");
846 substdio_put(&smtpto,helohost.s,helohost.len); 851 substdio_put(&smtpto,helohost.s,helohost.len);
847 substdio_puts(&smtpto,"\r\n"); 852 substdio_puts(&smtpto,"\r\n");
848 substdio_flush(&smtpto); 853 substdio_flush(&smtpto);
849 code = smtpcode(); 854 code = smtpcode();
855 if (!stralloc_copys(&smtptextdropped,"")) temp_nomem();
850 if (code >= 500) quit("DConnected to "," but my name was rejected"); 856 if (code >= 500) quit("DConnected to "," but my name was rejected");
851 if (code != 250) quit("ZConnected to "," but my name was rejected"); 857 if (code != 250) quit("ZConnected to "," but my name was rejected");
852 } 858 }
@@ -911,12 +917,12 @@ static void smtp(struct ip_mx *current_mx)
911 if (code >= 500) { 917 if (code >= 500) {
912 out("h"); out(auth_status.s); outhost(); 918 out("h"); out(auth_status.s); outhost();
913 out(" does not like recipient.\n"); 919 out(" does not like recipient.\n");
914 outsmtptext(); zero(); 920 outsmtptext(&smtptext); zero();
915 } 921 }
916 else if (code >= 400) { 922 else if (code >= 400) {
917 out("s"); out(auth_status.s); outhost(); 923 out("s"); out(auth_status.s); outhost();
918 out(" does not like recipient.\n"); 924 out(" does not like recipient.\n");
919 outsmtptext(); zero(); 925 outsmtptext(&smtptext); zero();
920 } 926 }
921 else { 927 else {
922 /* 928 /*