Mercurial > masqmail
annotate src/smtp_in.c @ 209:10da50168dab
replaced the MD5 implementation with the one of Solar Designer
Until now, the sample code of RFC 1321 was used. It had an ugly license.
Now we use the implementation of Solar Designer, which is in the Public Domain.
http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
author | meillo@marmaro.de |
---|---|
date | Sun, 18 Jul 2010 21:58:15 +0200 |
parents | 3708b655a371 |
children | 794071925a22 |
rev | line source |
---|---|
0 | 1 /* MasqMail |
2 Copyright (C) 1999-2001 Oliver Kurth | |
80 | 3 Copyright (C) 2010 markus schnalke <meillo@marmaro.de> |
0 | 4 |
5 This program is free software; you can redistribute it and/or modify | |
6 it under the terms of the GNU General Public License as published by | |
7 the Free Software Foundation; either version 2 of the License, or | |
8 (at your option) any later version. | |
9 | |
10 This program is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 GNU General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU General Public License | |
16 along with this program; if not, write to the Free Software | |
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
18 */ | |
19 | |
20 #include "masqmail.h" | |
21 #include "readsock.h" | |
22 | |
23 /* | |
24 I always forget these rfc numbers: | |
25 RFC 821 (SMTP) | |
26 RFC 1869 (ESMTP) | |
27 RFC 1870 (ESMTP SIZE) | |
28 RFC 2197 (ESMTP PIPELINE) | |
29 RFC 2554 (ESMTP AUTH) | |
30 */ | |
31 | |
32 | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
33 smtp_cmd smtp_cmds[] = { |
15 | 34 {SMTP_HELO, "HELO",}, |
35 {SMTP_EHLO, "EHLO",}, | |
36 {SMTP_MAIL_FROM, "MAIL FROM:",}, | |
37 {SMTP_RCPT_TO, "RCPT TO:",}, | |
38 {SMTP_DATA, "DATA",}, | |
39 {SMTP_QUIT, "QUIT",}, | |
40 {SMTP_RSET, "RSET",}, | |
41 {SMTP_NOOP, "NOOP",}, | |
42 {SMTP_HELP, "HELP"}, | |
0 | 43 }; |
44 | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
45 static smtp_cmd_id |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
46 get_id(const gchar * line) |
0 | 47 { |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
48 gint i; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
49 for (i = 0; i < SMTP_NUM_IDS; i++) { |
80 | 50 if (strncasecmp(smtp_cmds[i].cmd, line, strlen(smtp_cmds[i].cmd)) == 0) { |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
51 return (smtp_cmd_id) i; |
80 | 52 } |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
53 } |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
54 return SMTP_ERROR; |
0 | 55 } |
56 | |
117
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
57 static gboolean |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
58 get_size(gchar *line, unsigned long *msize) { |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
59 gchar *s = NULL; |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
60 |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
61 /* hope we need not to handle cases like SiZe= ...*/ |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
62 s = strstr(line, "SIZE="); |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
63 if (!s) { |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
64 /* try it in lowercase too */ |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
65 if (!(s = strstr(line, "size="))) { |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
66 return FALSE; |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
67 } |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
68 } |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
69 s += 5; |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
70 *msize = atol(s); |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
71 DEBUG(5) debugf("get_size(): line=%s, msize=%ld\n", line, *msize); |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
72 |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
73 return TRUE; |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
74 } |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
75 |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
76 |
0 | 77 /* this is a quick hack: we expect the address to be syntactically correct |
117
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
78 and containing the mailbox only, though we first check for size in |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
79 smtp_in(). |
136
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
80 Return false if address is too long. |
0 | 81 */ |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
82 static gboolean |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
83 get_address(gchar * line, gchar * addr) |
0 | 84 { |
80 | 85 gchar *p = line; |
86 gchar *q = addr; | |
0 | 87 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
88 /* skip MAIL FROM: and RCPT TO: */ |
80 | 89 while (*p && (*p != ':')) { |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
90 p++; |
80 | 91 } |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
92 p++; |
0 | 93 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
94 /* skip spaces: */ |
80 | 95 while (*p && isspace(*p)) { |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
96 p++; |
80 | 97 } |
0 | 98 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
99 /* get address: */ |
136
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
100 while (*p && !isspace(*p)) { |
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
101 if (q >= addr + MAX_ADDRESS-1) { |
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
102 *q = '\0'; |
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
103 return FALSE; |
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
104 } |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
105 *(q++) = *(p++); |
80 | 106 } |
136
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
107 *q = '\0'; |
0 | 108 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
109 return TRUE; |
0 | 110 } |
111 | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
112 static smtp_connection* |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
113 create_base(gchar * remote_host) |
0 | 114 { |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
115 smtp_connection *base = g_malloc(sizeof(smtp_connection)); |
80 | 116 if (!base) { |
117 return NULL; | |
118 } | |
119 | |
120 base->remote_host = g_strdup(remote_host); | |
0 | 121 |
80 | 122 base->prot = PROT_SMTP; |
123 base->next_id = 0; | |
124 base->helo_seen = 0; | |
125 base->from_seen = 0; | |
126 base->rcpt_seen = 0; | |
127 base->msg = NULL; | |
0 | 128 |
80 | 129 return base; |
0 | 130 } |
131 | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
132 static void |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
133 smtp_printf(FILE * out, gchar * fmt, ...) |
0 | 134 { |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
135 va_list args; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
136 va_start(args, fmt); |
0 | 137 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
138 DEBUG(4) { |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
139 gchar buf[256]; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
140 va_list args_copy; |
0 | 141 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
142 va_copy(args_copy, args); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
143 vsnprintf(buf, 255, fmt, args_copy); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
144 va_end(args_copy); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
145 |
208
3708b655a371
added newlines to the end of log and debug messages where missing
meillo@marmaro.de
parents:
204
diff
changeset
|
146 debugf(">>>%s\n", buf); |
0 | 147 } |
148 | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
149 vfprintf(out, fmt, args); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
150 fflush(out); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
151 |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
152 va_end(args); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
153 } |
0 | 154 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
155 void |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
156 smtp_in(FILE * in, FILE * out, gchar * remote_host, gchar * ident) |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
157 { |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
158 gchar *buffer; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
159 smtp_cmd_id cmd_id; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
160 message *msg = NULL; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
161 smtp_connection *psc; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
162 int len; |
117
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
163 unsigned long size, msize; |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
164 |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
165 DEBUG(5) debugf("smtp_in entered, remote_host = %s\n", remote_host); |
0 | 166 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
167 psc = create_base(remote_host); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
168 psc->msg = msg; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
169 |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
170 buffer = (gchar *) g_malloc(BUF_LEN); |
80 | 171 if (!buffer) { |
172 /* this check is actually unneccessary as g_malloc() | |
173 aborts on failure */ | |
174 return; | |
175 } | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
176 |
80 | 177 /* send greeting string, containing ESMTP: */ |
178 smtp_printf(out, "220 %s MasqMail %s ESMTP\r\n", conf.host_name, VERSION); | |
0 | 179 |
80 | 180 while ((len = read_sockline(in, buffer, BUF_LEN, 5 * 60, READSOCKL_CHUG)) >= 0) { |
181 cmd_id = get_id(buffer); | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
182 |
135 | 183 if (conf.defer_all) { |
184 /* I need this to debug delivery failures */ | |
127 | 185 smtp_printf(out, "421 %s service temporarily unavailable.\r\n", conf.host_name); |
135 | 186 destroy_message(msg); |
187 msg = NULL; | |
188 return; | |
127 | 189 } |
190 | |
80 | 191 switch (cmd_id) { |
127 | 192 case SMTP_HELO: |
193 psc->prot = PROT_SMTP; | |
194 psc->helo_seen = TRUE; | |
195 smtp_printf(out, "250 %s pretty old mailer, huh?\r\n", conf.host_name); | |
196 break; | |
197 | |
80 | 198 case SMTP_EHLO: |
199 psc->prot = PROT_ESMTP; | |
200 psc->helo_seen = TRUE; | |
127 | 201 smtp_printf(out, "250-%s Nice to meet you with ESMTP\r\n", conf.host_name); |
202 smtp_printf(out, "250-SIZE %d\r\n", conf.max_msg_size); | |
203 smtp_printf(out, "250-PIPELINING\r\n"); | |
204 smtp_printf(out, "250 HELP\r\n"); | |
80 | 205 break; |
206 | |
207 case SMTP_MAIL_FROM: | |
208 { | |
209 gchar buf[MAX_ADDRESS]; | |
210 address *addr; | |
211 | |
212 if (!psc->helo_seen) { | |
213 smtp_printf(out, "503 need HELO or EHLO\r\n"); | |
214 break; | |
215 } | |
216 if (psc->from_seen) { | |
217 smtp_printf(out, "503 MAIL FROM: already given.\r\n"); | |
218 break; | |
219 } | |
128
f9d5469cb648
moved the SIZE check to a better location
meillo@marmaro.de
parents:
127
diff
changeset
|
220 if (get_size(buffer, &msize)) { |
f9d5469cb648
moved the SIZE check to a better location
meillo@marmaro.de
parents:
127
diff
changeset
|
221 DEBUG(5) debugf("smtp_in(): get_size: msize=%ld, conf.mms=%d\n", |
f9d5469cb648
moved the SIZE check to a better location
meillo@marmaro.de
parents:
127
diff
changeset
|
222 msize, conf.max_msg_size); |
f9d5469cb648
moved the SIZE check to a better location
meillo@marmaro.de
parents:
127
diff
changeset
|
223 if (conf.max_msg_size && (msize > conf.max_msg_size)) { |
f9d5469cb648
moved the SIZE check to a better location
meillo@marmaro.de
parents:
127
diff
changeset
|
224 smtp_printf(out, "552 Message size exceeds fixed limit.\r\n"); |
f9d5469cb648
moved the SIZE check to a better location
meillo@marmaro.de
parents:
127
diff
changeset
|
225 break; |
f9d5469cb648
moved the SIZE check to a better location
meillo@marmaro.de
parents:
127
diff
changeset
|
226 } |
f9d5469cb648
moved the SIZE check to a better location
meillo@marmaro.de
parents:
127
diff
changeset
|
227 } |
136
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
228 if (!get_address(buffer, buf)) { |
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
229 smtp_printf(out, "553 Address too long.\r\n"); |
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
230 break; |
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
231 } |
128
f9d5469cb648
moved the SIZE check to a better location
meillo@marmaro.de
parents:
127
diff
changeset
|
232 |
80 | 233 msg = create_message(); |
234 msg->received_host = remote_host ? g_strdup(remote_host) : NULL; | |
235 msg->received_prot = psc->prot; | |
236 msg->ident = ident ? g_strdup(ident) : NULL; | |
237 /* get transfer id and increment for next one */ | |
238 msg->transfer_id = (psc->next_id)++; | |
239 | |
240 if (remote_host) { | |
241 addr = create_address(buf, TRUE); | |
242 } else { | |
243 addr = create_address_qualified(buf, TRUE, conf.host_name); | |
244 } | |
245 if (!addr) { | |
246 smtp_printf(out, "501 %s: syntax error.\r\n", buf); | |
247 } else if (!addr->domain) { | |
248 smtp_printf(out, "501 return path must be qualified.\r\n", buf); | |
249 } else { | |
250 psc->from_seen = TRUE; | |
251 msg->return_path = addr; | |
252 smtp_printf(out, "250 OK %s is a nice guy.\r\n", addr->address); | |
253 } | |
254 } | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
255 break; |
80 | 256 |
257 case SMTP_RCPT_TO: | |
258 { | |
259 char buf[MAX_ADDRESS]; | |
260 address *addr; | |
261 | |
262 if (!psc->helo_seen) { | |
263 smtp_printf(out, "503 need HELO or EHLO.\r\n"); | |
264 break; | |
265 } | |
266 if (!psc->from_seen) { | |
267 smtp_printf(out, "503 need MAIL FROM: before RCPT TO:\r\n"); | |
268 break; | |
269 } | |
136
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
270 if (!get_address(buffer, buf)) { |
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
271 smtp_printf(out, "553 Address too long.\r\n"); |
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
272 break; |
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
273 } |
80 | 274 |
275 if (remote_host) { | |
276 addr = create_address(buf, TRUE); | |
277 } else { | |
278 addr = create_address_qualified(buf, TRUE, conf.host_name); | |
279 } | |
280 if (!addr) { | |
281 smtp_printf(out, "501 %s: syntax error in address.\r\n", buf); | |
282 break; | |
283 } | |
284 if (addr->local_part[0] == '|') { | |
285 smtp_printf(out, "501 %s: no pipe allowed for SMTP connections\r\n", buf); | |
286 break; | |
287 } | |
288 if (!addr->domain) { | |
289 smtp_printf(out, "501 recipient address must be qualified.\r\n", buf); | |
290 break; | |
291 } | |
292 gboolean do_relay = conf.do_relay; | |
293 if (!do_relay) { | |
294 do_relay = addr_is_local(msg->return_path); | |
295 if (!do_relay) { | |
296 do_relay = addr_is_local(addr); | |
297 } | |
298 } | |
299 if (!do_relay) { | |
300 smtp_printf(out, "550 relaying to %s denied.\r\n", addr_string(addr)); | |
301 break; | |
302 } | |
303 psc->rcpt_seen = TRUE; | |
304 msg->rcpt_list = g_list_append(msg->rcpt_list, addr); | |
305 smtp_printf(out, "250 OK %s is our friend.\r\n", addr->address); | |
306 } | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
307 break; |
80 | 308 |
309 case SMTP_DATA: | |
310 if (!psc->helo_seen) { | |
311 smtp_printf(out, "503 need HELO or EHLO.\r\n"); | |
312 break; | |
313 } | |
314 if (!psc->rcpt_seen) { | |
315 smtp_printf(out, "503 need RCPT TO: before DATA\r\n"); | |
316 break; | |
317 } | |
318 accept_error err; | |
319 | |
320 smtp_printf(out, "354 okay, and do not forget the dot\r\n"); | |
321 | |
322 err = accept_message(in, msg, conf.do_save_envelope_to ? ACC_SAVE_ENVELOPE_TO : 0); | |
323 if (err != AERR_OK) { | |
117
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
324 switch (err) { |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
325 case AERR_TIMEOUT: |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
326 case AERR_EOF: |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
327 return; |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
328 case AERR_SIZE: |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
329 smtp_printf(out, "552 Error: message too large.\r\n"); |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
330 return; |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
331 default: |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
332 /* should never happen: */ |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
333 smtp_printf(out, "451 Unknown error\r\n"); |
80 | 334 return; |
335 } | |
336 } | |
337 | |
338 | |
339 if (!spool_write(msg, TRUE)) { | |
340 smtp_printf(out, "451 Could not write spool file\r\n"); | |
341 return; | |
342 } | |
343 pid_t pid; | |
344 smtp_printf(out, "250 OK id=%s\r\n", msg->uid); | |
345 | |
346 if (remote_host != NULL) { | |
347 logwrite(LOG_NOTICE, "%s <= <%s@%s> host=%s with %s\n", msg->uid, | |
348 msg->return_path->local_part, msg->return_path->domain, | |
349 remote_host, prot_names[psc->prot]); | |
350 } else { | |
351 logwrite(LOG_NOTICE, "%s <= <%s@%s> with %s\n", msg->uid, | |
352 msg->return_path->local_part, msg->return_path->domain, | |
353 prot_names[psc->prot]); | |
354 } | |
355 | |
356 if (conf.do_queue) { | |
357 DEBUG(1) debugf("queuing forced by configuration or option.\n"); | |
358 } else { | |
359 pid = fork(); | |
360 if (pid == 0) { | |
361 _exit(deliver(msg)); | |
362 } else if (pid < 0) { | |
208
3708b655a371
added newlines to the end of log and debug messages where missing
meillo@marmaro.de
parents:
204
diff
changeset
|
363 logwrite(LOG_ALERT, "could not fork for delivery, id = %s\n", msg->uid); |
80 | 364 } |
365 } | |
366 psc->rcpt_seen = psc->from_seen = FALSE; | |
367 destroy_message(msg); | |
368 msg = NULL; | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
369 break; |
80 | 370 |
371 case SMTP_QUIT: | |
372 smtp_printf(out, "221 goodbye\r\n"); | |
81
71ce3a1568e9
moved check for NULL into destroy_message()
meillo@marmaro.de
parents:
80
diff
changeset
|
373 destroy_message(msg); |
71ce3a1568e9
moved check for NULL into destroy_message()
meillo@marmaro.de
parents:
80
diff
changeset
|
374 msg = NULL; |
80 | 375 return; |
376 | |
377 case SMTP_RSET: | |
378 psc->from_seen = psc->rcpt_seen = FALSE; | |
81
71ce3a1568e9
moved check for NULL into destroy_message()
meillo@marmaro.de
parents:
80
diff
changeset
|
379 destroy_message(msg); |
71ce3a1568e9
moved check for NULL into destroy_message()
meillo@marmaro.de
parents:
80
diff
changeset
|
380 msg = NULL; |
80 | 381 smtp_printf(out, "250 OK\r\n"); |
382 break; | |
383 | |
384 case SMTP_NOOP: | |
385 smtp_printf(out, "250 OK\r\n"); | |
386 break; | |
387 | |
388 case SMTP_HELP: | |
389 { | |
390 int i; | |
391 | |
392 smtp_printf(out, "214-supported commands:\r\n"); | |
393 for (i = 0; i < SMTP_NUM_IDS - 1; i++) { | |
394 smtp_printf(out, "214-%s\r\n", smtp_cmds[i].cmd); | |
395 } | |
396 smtp_printf(out, "214 %s\r\n", smtp_cmds[i].cmd); | |
397 } | |
398 break; | |
399 | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
400 default: |
80 | 401 smtp_printf(out, "501 command not recognized\r\n"); |
402 DEBUG(1) debugf("command not recognized, was '%s'\n", buffer); | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
403 break; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
404 } |
0 | 405 } |
80 | 406 switch (len) { |
407 case -3: | |
408 logwrite(LOG_NOTICE, "connection timed out\n"); | |
409 break; | |
410 case -2: | |
411 logwrite(LOG_NOTICE, "line overflow\n"); | |
412 break; | |
413 case -1: | |
414 logwrite(LOG_NOTICE, "received EOF\n"); | |
415 break; | |
416 default: | |
417 break; | |
418 } | |
0 | 419 } |