s/qmail 4.3.20
Next generation secure email transport
Loading...
Searching...
No Matches
srsforward.c
Go to the documentation of this file.
1#include <unistd.h>
2#include <sys/types.h>
3#include "control.h"
4#include "sig.h"
5#include "constmap.h"
6#include "readwrite.h"
7#include "exit.h"
8#include "env.h"
9#include "qmail.h"
10#include "auto_qmail.h"
11#include "getoptb.h"
12#include "buffer.h"
13#include "str.h"
14#include "fmt.h"
15#include "stralloc.h"
16#include "logmsg.h"
17#include "srs2.h"
18#include "qmail.h"
19
20#define WHO "srsforward"
21
22void die_nomem() { logmsg(WHO,111,FATAL,"out of memory"); }
23void die_control() { logmsg(WHO,110,FATAL,"Unable to read control files"); }
24
25struct qmail qqt;
26
27char *srsdomaininfo = 0;
28stralloc srsdomains = {0};
30stralloc srshost = {0};
31stralloc srserror = {0};
32
35
44static int srserror_str(int code) {
45 if (!stralloc_copys(&srserror,"SRS: ")) die_nomem();
46 if (!stralloc_cats(&srserror,srs_strerror(code))) die_nomem();
47 if (!stralloc_0(&srserror)) die_nomem();
48 return -3;
49}
50
51ssize_t mywrite(int fd,char *buf,int len)
52{
53 qmail_put(&qqt,buf,len);
54 return len;
55}
56
59buffer bi = BUFFER_INIT(buffer_unixread,0,inbuf,sizeof(inbuf));
60buffer bo = BUFFER_INIT(mywrite,-1,outbuf,sizeof(outbuf));
61
62char num[FMT_ULONG];
63
64int main(int argc,char * const *argv)
65{
66 int i, j, r;
67 int opt;
68 char *qqx;
69 srs_t *srs;
70 stralloc cookie = {0};
71 char separator = '=';
72 char srssender[BUFSIZE_AUTH];
73 char *host = 0;
74 char *sender = 0;
75 char *dtline = 0;
76 char *sendhost = 0;
77 int alwaysrewrite = 0;
78
79 sig_pipeignore();
80
81 sender = env_get("NEWSENDER");
82 if (!sender)
83 logmsg(WHO,100,FATAL,"NEWSENDER not set");
84 host = env_get("HOST");
85 if (!host)
86 logmsg(WHO,100,FATAL,"HOST not set");
87 dtline = env_get("DTLINE");
88 if (!dtline)
89 logmsg(WHO,100,FATAL,"DTLINE not set");
90
91 if (chdir(auto_qmail) == -1)
92 logmsg(WHO,111,FATAL,B("unable to chdir to: ",auto_qmail));
93
94 if (!stralloc_cats(&srshost,"!")) die_nomem();
95 if (!stralloc_cats(&srshost,host)) die_nomem();
96
97 switch (control_readfile(&srsdomains,"control/srsdomains",0)) {
98 case -1: die_control();
99 case 0: if (!constmap_init(&mapsrsdomains,"",0,1)) die_nomem(); break;
100 case 1: if (!constmap_init(&mapsrsdomains,srsdomains.s,srsdomains.len,1)) die_nomem(); break;
101 }
102 if (constmap(&mapsrsdomains,srshost.s,srshost.len)) flagforward = 0; // domain blacklisted, bounce
103 if ((srsdomaininfo = constmap(&mapsrsdomains,host,str_len(host))) == 0) {
104 if ((srsdomaininfo = constmap(&mapsrsdomains,"*",1)) == 0) return 0; // '*' means always SRS
105 else alwaysrewrite = 1;
106 }
107
108 if (*srsdomaininfo) {
109 i = str_chr(srsdomaininfo,'|'); // multiple cookies; separated by ' '
110 if (srsdomaininfo[i] == '|') {
111 srsdomaininfo[i] = 0;
112 j = str_chr(srsdomaininfo + i + 1,'|');
113 if (srsdomaininfo[i + j + 1] == '|') {
114 srsdomaininfo[i + j + 1] = 0;
115 sendhost = srsdomaininfo + i + j + 2; // separator: - + =
116 }
117 separator = srsdomaininfo[i + 1];
118 }
119 if (!stralloc_copys(&cookie,srsdomaininfo)) die_nomem();
120 if (!stralloc_0(&cookie)) die_nomem();
121 if (!stralloc_copys(&srshost,"")) die_nomem();
122 if (*sendhost) {
123 j = str_len(sendhost);
124 if (sendhost[j - 1] == '.') {
125 if (!stralloc_copys(&srshost,sendhost)) die_nomem();
126 if (!stralloc_cats(&srshost,host)) die_nomem();
127 } else
128 if (!stralloc_copys(&srshost,sendhost)) die_nomem();
129 } else
131 if (!stralloc_0(&srshost)) die_nomem();
132 } else
133 die_control();
134
135 /* Check options */
136
137 while ((opt = getoptb(argc,(char **)argv,"pP")) != opteof)
138 switch (opt) {
139 case 'p': flagpassthrough = 0; break;
140 case 'P': flagpassthrough = 100; break;
141 }
142 argv += optind - 1;
143
144 if (!flagforward) {
145 logmsg(WHO,flagpassthrough,INFO,B("not srsforwarding: ",sender));
147 }
148
149 /* Let's go SRS rewrite */
150
151 srs = srs_new();
152
153 if (separator == '-' || separator == '+' || separator == '=') { // '=' is default
154 r = srs_set_separator(srs,separator);
155 if (r != SRS_SUCCESS) return srserror_str(r);
156 }
157 if (alwaysrewrite) {
158 r = srs_set_alwaysrewrite(srs,alwaysrewrite);
159 if (r != SRS_SUCCESS) return srserror_str(r);
160 }
161
162 for (j = 0, i = 0; j < cookie.len; j++) {
163 if (cookie.s[j] == ' ' || cookie.s[j] == '\0' ) {
164 cookie.s[j] = '\0';
165 r = srs_add_secret(srs,cookie.s + i);
166 if (r != SRS_SUCCESS) return srserror_str(r);
167 i = j + 1;
168 if (cookie.s[i] == ' ') { j++; continue; }
169 }
170 }
171
172 if ((r = srs_forward(srs,srssender,sizeof(srssender),sender,srshost.s)) != SRS_SUCCESS)
173 logmsg(WHO,100,FATAL,B("Unable to srsforward: ",sender," ",srs_strerror(r)));
174
175 if (qmail_open(&qqt) == -1)
176 logmsg(WHO,111,FATAL,"unable to fork: ");
178 if (buffer_copy(&bo,&bi) != 0)
179 logmsg(WHO,111,FATAL,"unable to read message: ");
180 buffer_flush(&bo);
181
182 num[fmt_ulong(num,qmail_qp(&qqt))] = 0;
183
184 qmail_from(&qqt,srssender);
185 while (*++argv) qmail_to(&qqt,*argv);
186 qqx = qmail_close(&qqt);
187 if (*qqx) logmsg(WHO,*qqx == 'D' ? 100 : 111,FATAL,qqx + 1);
188 logmsg(WHO,0,LOG,B(srssender,": qp ",num));
189}
char auto_qmail[]
int main()
Definition: chkshsgr.c:6
int constmap_init(struct constmap *cm, char *s, int len, int flagcolon)
Definition: constmap.c:35
int control_readfile(stralloc *sa, char *fn, int flagme)
Definition: control.c:87
int stralloc_copys(stralloc *, char const *)
void _exit(int)
stralloc sender
Definition: fastforward.c:71
char * dtline
Definition: fastforward.c:70
char buf[100+FMT_ULONG]
Definition: hier.c:11
char host[256]
Definition: hostname.c:5
int fd
unsigned long code
Definition: qmail-remote.c:603
int j
Definition: qmail-send.c:926
void qmail_to(struct qmail *, char *)
Definition: qmail.c:83
#define BUFSIZE_LINE
Definition: qmail.h:8
void qmail_from(struct qmail *, char *)
Definition: qmail.c:73
void qmail_put(struct qmail *, char *, int)
Definition: qmail.c:63
char * qmail_close(struct qmail *)
Definition: qmail.c:90
unsigned long qmail_qp(struct qmail *)
Definition: qmail.c:53
void qmail_puts(struct qmail *, char *)
Definition: qmail.c:68
#define BUFSIZE_AUTH
Definition: qmail.h:9
int qmail_open(struct qmail *)
Definition: qmail.c:21
int srs_set_separator(srs_t *srs, char value)
Definition: srs2.c:161
int srs_add_secret(srs_t *, const char *)
Definition: srs2.c:137
srs_t * srs_new()
Definition: srs2.c:107
int srs_forward(srs_t *, char *, int, const char *, const char *)
Definition: srs2.c:528
#define SRS_SUCCESS
Definition: srs2.h:40
const char * srs_strerror(int)
Definition: srs2.c:74
void die_control()
Definition: srsforward.c:23
ssize_t mywrite(int fd, char *buf, int len)
Definition: srsforward.c:51
void die_nomem()
Definition: srsforward.c:22
struct qmail qqt
Definition: srsforward.c:25
stralloc srshost
Definition: srsforward.c:30
stralloc srserror
Definition: srsforward.c:31
int flagforward
Definition: srsforward.c:33
char outbuf[BUFSIZE_LINE]
Definition: srsforward.c:58
char num[FMT_ULONG]
Definition: srsforward.c:62
buffer bi
Definition: srsforward.c:59
int flagpassthrough
Definition: srsforward.c:34
char * srsdomaininfo
Definition: srsforward.c:27
buffer bo
Definition: srsforward.c:60
#define WHO
Definition: srsforward.c:20
char inbuf[BUFSIZE_LINE]
Definition: srsforward.c:57
stralloc srsdomains
Definition: srsforward.c:28
struct constmap mapsrsdomains
Definition: srsforward.c:29
Definition: srs2.h:79
Definition: qmail.h:14