s/qmail 4.2.29a
Next generation secure email transport
Loading...
Searching...
No Matches
recipients.c
Go to the documentation of this file.
1#include <unistd.h>
2#include "cdbread.h"
3#include "byte.h"
4#include "open.h"
5#include "control.h"
6#include "constmap.h"
7#include "stralloc.h"
8#include "recipients.h"
9#include "wait.h"
10#include "str.h"
11#include "fd.h"
12#include "sig.h"
13#include "case.h"
14#include "buffer.h"
15#include "auto_break.h"
16#include "qmail.h"
17
18#define FDAUTH 3
19
20static stralloc key = {0};
21static stralloc domain = {0};
22static stralloc wildhost = {0};
23static stralloc address = {0};
24static stralloc rcptline = {0};
25static stralloc vkey = {0};
26static stralloc verp = {0};
27static stralloc user = {0};
28static stralloc ukey = {0};
29static int flagrcpts = 0;
30static int fdrcps;
31static struct cdb cdb;
32
49{
50 flagrcpts = control_readfile(&rcptline,"control/recipients",0);
51 if (flagrcpts != 1) return flagrcpts;
52 return 0;
53}
54
55char rcptbuf[512];
56buffer br = BUFFER_INIT(safewrite,FDAUTH,rcptbuf,sizeof(rcptbuf));
57
58int callapam(char *pam,char *addr)
59{
60 int i;
61 int j=0;
62 int wstat;
63 int pi[2];
64 int child;
65 char ch;
66 static stralloc mailaddress = {0};
67
68 char *childargs[7] = {0, 0, 0, 0, 0, 0, 0};
69 stralloc pamarg = {0};
70 stralloc pamname = {0};
71 stralloc pamarg1 = {0};
72 stralloc pamarg2 = {0};
73 stralloc pamarg3 = {0};
74 stralloc pamarg4 = {0};
75 stralloc pamarg5 = {0};
76
77 for (i = 0; (ch = pam[i]); i++) {
78 if (j < 6) {
79 if (ch != ' ')
80 if (!stralloc_append(&pamarg,&ch)) return -2;
81 if (ch == ' ' || ch == '\n' || i == str_len(pam) - 1) {
82 if (!stralloc_0(&pamarg)) return -2;
83 switch (j) {
84 case 0:
85 if (!stralloc_copy(&pamname,&pamarg)) return -2;
86 childargs[0] = pamname.s;
87 case 1:
88 if (!stralloc_copy(&pamarg1,&pamarg)) return -2;
89 childargs[1] = pamarg1.s;
90 case 2:
91 if (!stralloc_copy(&pamarg2,&pamarg)) return -2;
92 childargs[2] = pamarg2.s;
93 case 3:
94 if (!stralloc_copy(&pamarg3,&pamarg)) return -2;
95 childargs[3] = pamarg3.s;
96 case 4:
97 if (!stralloc_copy(&pamarg4,&pamarg)) return -2;
98 childargs[4] = pamarg4.s;
99 case 5:
100 if (!stralloc_copy(&pamarg5,&pamarg)) return -2;
101 childargs[5] = pamarg5.s;
102 }
103 j++;
104 if (!stralloc_copys(&pamarg,"")) return -2;
105 }
106 }
107 }
108 childargs[j] = 0;
109
110 close(FDAUTH);
111 if (pipe(pi) == -1) return -3;
112 if (pi[0] != FDAUTH) return -3;
113
114 switch (child = fork()) {
115 case -1:
116 return -3;
117 case 0:
118 close(pi[1]);
119 if (fd_copy(FDAUTH,pi[0]) == -1) return -3;
120 sig_pipedefault();
121 execvp(childargs[0],childargs);
122 return 111;
123 }
124 close(pi[0]);
125
126/* checkpassword compliant form: address\0\0\0 */
127
128 if (!stralloc_copys(&mailaddress,addr)) return -2;
129 if (!stralloc_0(&mailaddress)) return -2;
130 if (!stralloc_0(&mailaddress)) return -2;
131 if (!stralloc_0(&mailaddress)) return -2;
132
133 buffer_init(&br,write,pi[1],rcptbuf,sizeof(rcptbuf));
134 if (buffer_put(&br,mailaddress.s,mailaddress.len) == -1) return -3;
135 if (buffer_flush(&br) == -1) return -3;
136 close(pi[1]);
137
138 if (wait_pid(&wstat,child) == -1) return -3;
139 if (wait_crashed(wstat)) return -3;
140 return wait_exitcode(wstat);
141}
142
143int recipients_parse(char *rhost,int rlen,char *addr,char *rkey,int klen,char *vaddr,char *vkey,int vlen,char *ukey,int ulen)
144{
145 int i;
146 int r;
147 int j = 0;
148 int k = 0;
149 int u = 0;
150 static stralloc line = {0};
151 int seenhost = 0;
152
153 if (!stralloc_copys(&line,"")) return -2;
154 if (!stralloc_copys(&wildhost,"!")) return -2;
155 if (!stralloc_cats(&wildhost,rhost)) return -2;
156 if (!stralloc_0(&wildhost)) return -2;
157
158 for (i = 0; i < rcptline.len; ++i) {
159 if (!stralloc_append(&line,&rcptline.s[i])) return -2;
160
161 if (rcptline.s[i] == '\0') {
162 if (!stralloc_0(&line)) return -2;
163
164 j = byte_chr(line.s,line.len,':'); /* cdb */
165 k = byte_chr(line.s,line.len,'|'); /* pam */
166 u = byte_chr(line.s,line.len,'='); /* assign users */
167
168 if (!str_diffn(line.s,wildhost.s,wildhost.len - 1)) return 4; /* wilddomain */
169 if ((j && j < line.len) || (k && k < line.len) || (u && u < line.len))
170 if (!str_diffn(line.s,"@",1)) /* exact */
171 if (!str_diffn(line.s + 1,rhost,rlen - 1)) seenhost = 1;
172
173 if (!seenhost) { /* domain */
174 if (j && rlen >= j)
175 if (!str_diffn(line.s,rhost + rlen - j - 1,j - 1)) seenhost = 2;
176 if (k && rlen >= k)
177 if (!str_diffn(line.s,rhost + rlen - k - 1,k - 1)) seenhost = 3;
178 if (u && rlen >= u)
179 if (!str_diffn(line.s,rhost + rlen - u - 1,u - 1)) seenhost = 4;
180 }
181 if (!seenhost) /* pass-thru */
182 if (!str_diffn(line.s,"!*",2)) return 5;
183
184 if (k && k < line.len) /* pam */
185 if (seenhost || !str_diffn(line.s,"*",1)) {
186 r = callapam(line.s + k + 1,addr);
187 if (vlen > 0 && r != 0)
188 r = callapam(line.s + k + 1,vaddr);
189 if (r == 0) return 2;
190 if (r == 111) return r;
191 }
192
193 if (u && u < line.len) /* qmail-users */
194 if (seenhost || !str_diffn(line.s,"*",1)) {
195 fdrcps = open_read("users/assign.cdb");
196 if (fdrcps != -1) {
197 cdb_init(&cdb,fdrcps);
198 r = cdb_find(&cdb,ukey,ulen - 1);
199 cdb_free(&cdb);
200 close(fdrcps);
201 if (r) return 3;
202 }
203 }
204
205 if (j && j < line.len) /* cdb */
206 if (seenhost || !str_diffn(line.s,"*",1)) {
207 fdrcps = open_read(line.s + j + 1);
208 if (fdrcps != -1) {
209 cdb_init(&cdb,fdrcps);
210 r = cdb_find(&cdb,rkey,klen - 2);
211 if (vlen > 0 && r == 0)
212 r = cdb_find(&cdb,vkey,vlen - 2);
213 cdb_free(&cdb);
214 close(fdrcps);
215 if (r) return 1;
216 }
217 }
218
219 if (!seenhost) {
220 fdrcps = open_read(line.s); /* legacy cdb */
221 if (fdrcps != -1) {
222 cdb_init(&cdb,fdrcps);
223 r = cdb_find(&cdb,rkey,klen - 2);
224 if (vlen > 0 && r == 0)
225 r = cdb_find(&cdb,vkey,vlen - 2);
226 cdb_free(&cdb);
227 close(fdrcps);
228 if (r) return 1;
229 }
230 }
231
232 if (!stralloc_copys(&line,"")) return -2;
233 }
234 }
235 return 0;
236}
237
238int recipients(char *buf,int len)
239{
240 int at;
241 int i;
242 int r;
243
244 if (flagrcpts != 1) return 10;
245
246 at = byte_rchr(buf,len,'@');
247 if (at && at < len) {
248 if (!stralloc_copyb(&domain,buf + at + 1,len - at - 1)) return -2;
249 if (!stralloc_copyb(&address,buf,len)) return -2;
250 } else {
251 if (!stralloc_copyb(&address,buf,len)) return -2;
252 if (!stralloc_append(&address,"@")) return -2;
253 if (!stralloc_copys(&domain,"localhost")) return -2;
254 if (!stralloc_cat(&address,&domain)) return -2;
255 }
256 if (!stralloc_copyb(&user,buf,at - 1)) return -2;
257
258 if (!stralloc_0(&user)) return -2;
259 if (!stralloc_0(&address)) return -2;
260 if (!stralloc_0(&domain)) return -2;
261
262 if (!stralloc_copys(&key,":")) return -2;
263 if (!stralloc_cat(&key,&address)) return -2;
264 if (!stralloc_0(&key)) return -2; /* \0\0 terminated */
265 case_lowerb(key.s,key.len);
266 case_lowerb(domain.s,domain.len);
267
268 if (!stralloc_copys(&ukey,"!")) return -2;
269 if (!stralloc_cat(&ukey,&user)) return -2;
270 if (!stralloc_0(&ukey)) return -2; /* \0 terminated */
271 case_lowerb(ukey.s,ukey.len);
272
273
274 for (i = 0; i < at; i++) { /* VERP addresses */
275 if (buf[i] == *auto_break || buf[i] == '=' || buf[i] == '+') { /* SRS delimiter */
276 if (!stralloc_copyb(&verp,buf,i + 1)) return -2;
277 if (!stralloc_append(&verp,"@")) return -2;
278 if (!stralloc_cat(&verp,&domain)) return -2;
279 if (!stralloc_copys(&vkey,":")) return -2;
280 if (!stralloc_cat(&vkey,&verp)) return -2;
281 if (!stralloc_0(&vkey)) return -2; /* \0\0 terminated */
282 case_lowerb(vkey.s,vkey.len);
283 break;
284 }
285 }
286
287 r = recipients_parse(domain.s,domain.len,address.s,key.s,key.len,verp.s,vkey.s,vkey.len,ukey.s,ukey.len);
288 if (r) return r;
289 return 0;
290}
char auto_break[]
int control_readfile(stralloc *sa, char *fn, int flagme)
Definition: control.c:86
int stralloc_copys(stralloc *, char const *)
stralloc key
Definition: fastforward.c:116
struct cdb cdb
Definition: fastforward.c:119
char buf[100+FMT_ULONG]
Definition: hier.c:10
stralloc line
Definition: maildir2mbox.c:27
stralloc address
Definition: newaliases.c:89
stralloc user
char ** childargs
Definition: qmail-popup.c:129
int j
Definition: qmail-send.c:920
stralloc addr
Definition: qmail-smtpd.c:521
char rcptbuf[512]
Definition: recipients.c:55
buffer br
Definition: recipients.c:56
int recipients_parse(char *rhost, int rlen, char *addr, char *rkey, int klen, char *vaddr, char *vkey, int vlen, char *ukey, int ulen)
Definition: recipients.c:143
int callapam(char *pam, char *addr)
Definition: recipients.c:58
#define FDAUTH
Definition: recipients.c:18
int recipients_init()
Definition: recipients.c:48
int recipients(char *buf, int len)
Definition: recipients.c:238
ssize_t safewrite()
uint32_t k[64]
Definition: sha256.c:26
void write()