diff options
Diffstat (limited to 'qmail-remote.c')
| -rw-r--r-- | qmail-remote.c | 133 |
1 files changed, 127 insertions, 6 deletions
diff --git a/qmail-remote.c b/qmail-remote.c index dae884d..4161a7b 100644 --- a/qmail-remote.c +++ b/qmail-remote.c | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | #include <sys/types.h> | 1 | #include <sys/types.h> |
| 2 | #include <sys/stat.h> | ||
| 2 | #include <sys/socket.h> | 3 | #include <sys/socket.h> |
| 3 | #include <netinet/in.h> | 4 | #include <netinet/in.h> |
| 4 | #include <arpa/inet.h> | 5 | #include <arpa/inet.h> |
| @@ -14,6 +15,7 @@ | |||
| 14 | #include "dns.h" | 15 | #include "dns.h" |
| 15 | #include "alloc.h" | 16 | #include "alloc.h" |
| 16 | #include "quote.h" | 17 | #include "quote.h" |
| 18 | #include "fmt.h" | ||
| 17 | #include "ip.h" | 19 | #include "ip.h" |
| 18 | #include "ipalloc.h" | 20 | #include "ipalloc.h" |
| 19 | #include "ipme.h" | 21 | #include "ipme.h" |
| @@ -32,8 +34,8 @@ | |||
| 32 | 34 | ||
| 33 | #define HUGESMTPTEXT 5000 | 35 | #define HUGESMTPTEXT 5000 |
| 34 | 36 | ||
| 35 | #define PORT_SMTP 25 /* silly rabbit, /etc/services is for users */ | 37 | unsigned long smtp_port = 25; /* silly rabbit, /etc/services is for users */ |
| 36 | unsigned long port = PORT_SMTP; | 38 | unsigned long qmtp_port = 209; |
| 37 | 39 | ||
| 38 | GEN_ALLOC_typedef(saa,stralloc,sa,len,a) | 40 | GEN_ALLOC_typedef(saa,stralloc,sa,len,a) |
| 39 | GEN_ALLOC_readyplus(saa,stralloc,sa,len,a,i,n,x,10,saa_readyplus) | 41 | GEN_ALLOC_readyplus(saa,stralloc,sa,len,a,i,n,x,10,saa_readyplus) |
| @@ -87,6 +89,8 @@ void temp_chdir() { out("Z\ | |||
| 87 | Unable to switch to home directory. (#4.3.0)\n"); zerodie(); } | 89 | Unable to switch to home directory. (#4.3.0)\n"); zerodie(); } |
| 88 | void temp_control() { out("Z\ | 90 | void temp_control() { out("Z\ |
| 89 | Unable to read control files. (#4.3.0)\n"); zerodie(); } | 91 | Unable to read control files. (#4.3.0)\n"); zerodie(); } |
| 92 | void temp_proto() { out("Z\ | ||
| 93 | recipient did not talk proper QMTP (#4.3.0)\n"); zerodie(); } | ||
| 90 | void perm_partialline() { out("D\ | 94 | void perm_partialline() { out("D\ |
| 91 | SMTP cannot transfer messages with partial final lines. (#5.6.2)\n"); zerodie(); } | 95 | SMTP cannot transfer messages with partial final lines. (#5.6.2)\n"); zerodie(); } |
| 92 | void perm_usage() { out("D\ | 96 | void perm_usage() { out("D\ |
| @@ -166,9 +170,9 @@ int safewrite(fd,buf,len) int fd; char *buf; int len; | |||
| 166 | return r; | 170 | return r; |
| 167 | } | 171 | } |
| 168 | 172 | ||
| 169 | char inbuf[1024]; | 173 | char inbuf[1500]; |
| 170 | substdio ssin = SUBSTDIO_FDBUF(read,0,inbuf,sizeof inbuf); | 174 | substdio ssin = SUBSTDIO_FDBUF(read,0,inbuf,sizeof inbuf); |
| 171 | char smtptobuf[1024]; | 175 | char smtptobuf[1500]; |
| 172 | substdio smtpto = SUBSTDIO_FDBUF(safewrite,-1,smtptobuf,sizeof smtptobuf); | 176 | substdio smtpto = SUBSTDIO_FDBUF(safewrite,-1,smtptobuf,sizeof smtptobuf); |
| 173 | char smtpfrombuf[128]; | 177 | char smtpfrombuf[128]; |
| 174 | substdio smtpfrom = SUBSTDIO_FDBUF(saferead,-1,smtpfrombuf,sizeof smtpfrombuf); | 178 | substdio smtpfrom = SUBSTDIO_FDBUF(saferead,-1,smtpfrombuf,sizeof smtpfrombuf); |
| @@ -683,6 +687,113 @@ void smtp() | |||
| 683 | quit("K"," accepted message"); | 687 | quit("K"," accepted message"); |
| 684 | } | 688 | } |
| 685 | 689 | ||
| 690 | int qmtp_priority(int pref) | ||
| 691 | { | ||
| 692 | if (pref < 12800) return 0; | ||
| 693 | if (pref > 13055) return 0; | ||
| 694 | if (pref % 16 == 1) return 1; | ||
| 695 | return 0; | ||
| 696 | } | ||
| 697 | |||
| 698 | void qmtp() | ||
| 699 | { | ||
| 700 | struct stat st; | ||
| 701 | unsigned long len; | ||
| 702 | int len2; | ||
| 703 | char *x; | ||
| 704 | int i; | ||
| 705 | int n; | ||
| 706 | unsigned char ch; | ||
| 707 | char num[FMT_ULONG]; | ||
| 708 | int flagallok; | ||
| 709 | |||
| 710 | if (fstat(0,&st) == -1) quit("Z", " unable to fstat stdin"); | ||
| 711 | len = st.st_size; | ||
| 712 | |||
| 713 | /* the following code was substantially taken from serialmail'ss serialqmtp.c */ | ||
| 714 | substdio_put(&smtpto,num,fmt_ulong(num,len+1)); | ||
| 715 | substdio_put(&smtpto,":\n",2); | ||
| 716 | while (len > 0) { | ||
| 717 | n = substdio_feed(&ssin); | ||
| 718 | if (n <= 0) _exit(32); /* wise guy again */ | ||
| 719 | x = substdio_PEEK(&ssin); | ||
| 720 | substdio_put(&smtpto,x,n); | ||
| 721 | substdio_SEEK(&ssin,n); | ||
| 722 | len -= n; | ||
| 723 | } | ||
| 724 | substdio_put(&smtpto,",",1); | ||
| 725 | |||
| 726 | len = sender.len; | ||
| 727 | substdio_put(&smtpto,num,fmt_ulong(num,len)); | ||
| 728 | substdio_put(&smtpto,":",1); | ||
| 729 | substdio_put(&smtpto,sender.s,sender.len); | ||
| 730 | substdio_put(&smtpto,",",1); | ||
| 731 | |||
| 732 | len = 0; | ||
| 733 | for (i = 0;i < reciplist.len;++i) | ||
| 734 | len += fmt_ulong(num,reciplist.sa[i].len) + 1 + reciplist.sa[i].len + 1; | ||
| 735 | substdio_put(&smtpto,num,fmt_ulong(num,len)); | ||
| 736 | substdio_put(&smtpto,":",1); | ||
| 737 | for (i = 0;i < reciplist.len;++i) { | ||
| 738 | substdio_put(&smtpto,num,fmt_ulong(num,reciplist.sa[i].len)); | ||
| 739 | substdio_put(&smtpto,":",1); | ||
| 740 | substdio_put(&smtpto,reciplist.sa[i].s,reciplist.sa[i].len); | ||
| 741 | substdio_put(&smtpto,",",1); | ||
| 742 | } | ||
| 743 | substdio_put(&smtpto,",",1); | ||
| 744 | substdio_flush(&smtpto); | ||
| 745 | |||
| 746 | flagallok = 1; | ||
| 747 | |||
| 748 | for (i = 0;i < reciplist.len;++i) { | ||
| 749 | len = 0; | ||
| 750 | for (;;) { | ||
| 751 | get(&ch); | ||
| 752 | if (ch == ':') break; | ||
| 753 | if (len > 200000000) temp_proto(); | ||
| 754 | if (ch - '0' > 9) temp_proto(); | ||
| 755 | len = 10 * len + (ch - '0'); | ||
| 756 | } | ||
| 757 | if (!len) temp_proto(); | ||
| 758 | get(&ch); --len; | ||
| 759 | if ((ch != 'Z') && (ch != 'D') && (ch != 'K')) temp_proto(); | ||
| 760 | |||
| 761 | if (!stralloc_copyb(&smtptext,&ch,1)) temp_proto(); | ||
| 762 | if (!stralloc_cats(&smtptext,"qmtp: ")) temp_nomem(); | ||
| 763 | |||
| 764 | while (len > 0) { | ||
| 765 | get(&ch); | ||
| 766 | --len; | ||
| 767 | } | ||
| 768 | |||
| 769 | for (len = 0;len < smtptext.len;++len) { | ||
| 770 | ch = smtptext.s[len]; | ||
| 771 | if ((ch < 32) || (ch > 126)) smtptext.s[len] = '?'; | ||
| 772 | } | ||
| 773 | get(&ch); | ||
| 774 | if (ch != ',') temp_proto(); | ||
| 775 | smtptext.s[smtptext.len-1] = '\n'; | ||
| 776 | |||
| 777 | if (smtptext.s[0] == 'K') out("r"); | ||
| 778 | else if (smtptext.s[0] == 'D') { | ||
| 779 | out("h"); | ||
| 780 | flagallok = 0; | ||
| 781 | } | ||
| 782 | else { /* if (smtptext.s[0] == 'Z') */ | ||
| 783 | out("s"); | ||
| 784 | flagallok = 0; | ||
| 785 | } | ||
| 786 | if (substdio_put(subfdoutsmall,smtptext.s+1,smtptext.len-1) == -1) temp_noconn(); | ||
| 787 | zero(); | ||
| 788 | } | ||
| 789 | if (!flagallok) { | ||
| 790 | out("DGiving up on ");outhost();out("\n"); | ||
| 791 | } else { | ||
| 792 | out("KAll received okay by ");outhost();out("\n"); | ||
| 793 | } | ||
| 794 | zerodie(); | ||
| 795 | } | ||
| 796 | |||
| 686 | stralloc canonhost = {0}; | 797 | stralloc canonhost = {0}; |
| 687 | stralloc canonbox = {0}; | 798 | stralloc canonbox = {0}; |
| 688 | 799 | ||
| @@ -780,7 +891,7 @@ char **argv; | |||
| 780 | } | 891 | } |
| 781 | i = str_chr(relayhost,':'); | 892 | i = str_chr(relayhost,':'); |
| 782 | if (relayhost[i]) { | 893 | if (relayhost[i]) { |
| 783 | scan_ulong(relayhost + i + 1,&port); | 894 | scan_ulong(relayhost + i + 1,&smtp_port); |
| 784 | relayhost[i] = 0; | 895 | relayhost[i] = 0; |
| 785 | } | 896 | } |
| 786 | if (!stralloc_copys(&host,relayhost)) temp_nomem(); | 897 | if (!stralloc_copys(&host,relayhost)) temp_nomem(); |
| @@ -837,7 +948,17 @@ char **argv; | |||
| 837 | smtpfd = socket(AF_INET,SOCK_STREAM,0); | 948 | smtpfd = socket(AF_INET,SOCK_STREAM,0); |
| 838 | if (smtpfd == -1) temp_oserr(); | 949 | if (smtpfd == -1) temp_oserr(); |
| 839 | 950 | ||
| 840 | if (timeoutconn(smtpfd,&ip.ix[i].ip,(unsigned int) port,timeoutconnect) == 0) { | 951 | if (qmtp_priority(ip.ix[i].pref)) { |
| 952 | if (timeoutconn(smtpfd,&ip.ix[i].ip,(unsigned int) qmtp_port,timeoutconnect) == 0) { | ||
| 953 | tcpto_err(&ip.ix[i].ip,0); | ||
| 954 | partner = ip.ix[i].ip; | ||
| 955 | qmtp(); /* does not return */ | ||
| 956 | } | ||
| 957 | close(smtpfd); | ||
| 958 | smtpfd = socket(AF_INET,SOCK_STREAM,0); | ||
| 959 | if (smtpfd == -1) temp_oserr(); | ||
| 960 | } | ||
| 961 | if (timeoutconn(smtpfd,&ip.ix[i].ip,(unsigned int) smtp_port,timeoutconnect) == 0) { | ||
| 841 | tcpto_err(&ip.ix[i].ip,0); | 962 | tcpto_err(&ip.ix[i].ip,0); |
| 842 | partner = ip.ix[i].ip; | 963 | partner = ip.ix[i].ip; |
| 843 | #ifdef TLS | 964 | #ifdef TLS |
