diff options
Diffstat (limited to 'qmail-remote.c')
| -rw-r--r-- | qmail-remote.c | 52 |
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 | ||
| 140 | int flagcritical = 0; | 140 | int flagcritical = 0; |
| 141 | stralloc smtptext = {0}; | ||
| 142 | stralloc smtptextdropped = {0}; | ||
| 143 | |||
| 144 | void 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 | ||
| 142 | void dropped() { | 156 | void 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); | |||
| 189 | char smtpfrombuf[128]; | 204 | char smtpfrombuf[128]; |
| 190 | substdio smtpfrom = SUBSTDIO_FDBUF(saferead,-1,smtpfrombuf,sizeof smtpfrombuf); | 205 | substdio smtpfrom = SUBSTDIO_FDBUF(saferead,-1,smtpfrombuf,sizeof smtpfrombuf); |
| 191 | 206 | ||
| 192 | stralloc smtptext = {0}; | ||
| 193 | |||
| 194 | void get(ch) | 207 | void get(ch) |
| 195 | char *ch; | 208 | char *ch; |
| 196 | { | 209 | { |
| @@ -276,18 +289,6 @@ unsigned long ehlo() | |||
| 276 | return 250; | 289 | return 250; |
| 277 | } | 290 | } |
| 278 | 291 | ||
| 279 | void 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 | |||
| 291 | void smtp_quit() | 292 | void 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 | */ |
| 397 | static int tls_init(struct ip_mx *current_mx) | 398 | static 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 | /* |
