summaryrefslogtreecommitdiffstats
path: root/qmail-remote.c
diff options
context:
space:
mode:
Diffstat (limited to 'qmail-remote.c')
-rw-r--r--qmail-remote.c133
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 */ 37unsigned long smtp_port = 25; /* silly rabbit, /etc/services is for users */
36unsigned long port = PORT_SMTP; 38unsigned long qmtp_port = 209;
37 39
38GEN_ALLOC_typedef(saa,stralloc,sa,len,a) 40GEN_ALLOC_typedef(saa,stralloc,sa,len,a)
39GEN_ALLOC_readyplus(saa,stralloc,sa,len,a,i,n,x,10,saa_readyplus) 41GEN_ALLOC_readyplus(saa,stralloc,sa,len,a,i,n,x,10,saa_readyplus)
@@ -87,6 +89,8 @@ void temp_chdir() { out("Z\
87Unable to switch to home directory. (#4.3.0)\n"); zerodie(); } 89Unable to switch to home directory. (#4.3.0)\n"); zerodie(); }
88void temp_control() { out("Z\ 90void temp_control() { out("Z\
89Unable to read control files. (#4.3.0)\n"); zerodie(); } 91Unable to read control files. (#4.3.0)\n"); zerodie(); }
92void temp_proto() { out("Z\
93recipient did not talk proper QMTP (#4.3.0)\n"); zerodie(); }
90void perm_partialline() { out("D\ 94void perm_partialline() { out("D\
91SMTP cannot transfer messages with partial final lines. (#5.6.2)\n"); zerodie(); } 95SMTP cannot transfer messages with partial final lines. (#5.6.2)\n"); zerodie(); }
92void perm_usage() { out("D\ 96void 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
169char inbuf[1024]; 173char inbuf[1500];
170substdio ssin = SUBSTDIO_FDBUF(read,0,inbuf,sizeof inbuf); 174substdio ssin = SUBSTDIO_FDBUF(read,0,inbuf,sizeof inbuf);
171char smtptobuf[1024]; 175char smtptobuf[1500];
172substdio smtpto = SUBSTDIO_FDBUF(safewrite,-1,smtptobuf,sizeof smtptobuf); 176substdio smtpto = SUBSTDIO_FDBUF(safewrite,-1,smtptobuf,sizeof smtptobuf);
173char smtpfrombuf[128]; 177char smtpfrombuf[128];
174substdio smtpfrom = SUBSTDIO_FDBUF(saferead,-1,smtpfrombuf,sizeof smtpfrombuf); 178substdio 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
690int 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
698void 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
686stralloc canonhost = {0}; 797stralloc canonhost = {0};
687stralloc canonbox = {0}; 798stralloc 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