Mercurial > masqmail-0.2
annotate src/smtp_in.c @ 162:52c82d755215
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 22:01:04 +0200 |
parents | 6b78aaced5e1 |
children |
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 #ifdef ENABLE_SMTP_SERVER | |
33 | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
34 smtp_cmd smtp_cmds[] = { |
15 | 35 {SMTP_HELO, "HELO",}, |
36 {SMTP_EHLO, "EHLO",}, | |
37 {SMTP_MAIL_FROM, "MAIL FROM:",}, | |
38 {SMTP_RCPT_TO, "RCPT TO:",}, | |
39 {SMTP_DATA, "DATA",}, | |
40 {SMTP_QUIT, "QUIT",}, | |
41 {SMTP_RSET, "RSET",}, | |
42 {SMTP_NOOP, "NOOP",}, | |
43 {SMTP_HELP, "HELP"}, | |
0 | 44 }; |
45 | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
46 static smtp_cmd_id |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
47 get_id(const gchar * line) |
0 | 48 { |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
49 gint i; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
50 for (i = 0; i < SMTP_NUM_IDS; i++) { |
80 | 51 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
|
52 return (smtp_cmd_id) i; |
80 | 53 } |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
54 } |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
55 return SMTP_ERROR; |
0 | 56 } |
57 | |
117
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
58 static gboolean |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
59 get_size(gchar *line, unsigned long *msize) { |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
60 gchar *s = NULL; |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
61 |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
62 /* 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
|
63 s = strstr(line, "SIZE="); |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
64 if (!s) { |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
65 /* try it in lowercase too */ |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
66 if (!(s = strstr(line, "size="))) { |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
67 return FALSE; |
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 } |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
70 s += 5; |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
71 *msize = atol(s); |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
72 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
|
73 |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
74 return TRUE; |
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 |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
77 |
0 | 78 /* 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
|
79 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
|
80 smtp_in(). |
136
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
81 Return false if address is too long. |
0 | 82 */ |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
83 static gboolean |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
84 get_address(gchar * line, gchar * addr) |
0 | 85 { |
80 | 86 gchar *p = line; |
87 gchar *q = addr; | |
0 | 88 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
89 /* skip MAIL FROM: and RCPT TO: */ |
80 | 90 while (*p && (*p != ':')) { |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
91 p++; |
80 | 92 } |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
93 p++; |
0 | 94 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
95 /* skip spaces: */ |
80 | 96 while (*p && isspace(*p)) { |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
97 p++; |
80 | 98 } |
0 | 99 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
100 /* get address: */ |
136
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
101 while (*p && !isspace(*p)) { |
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
102 if (q >= addr + MAX_ADDRESS-1) { |
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
103 *q = '\0'; |
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
104 return FALSE; |
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
105 } |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
106 *(q++) = *(p++); |
80 | 107 } |
136
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
108 *q = '\0'; |
0 | 109 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
110 return TRUE; |
0 | 111 } |
112 | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
113 static smtp_connection* |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
114 create_base(gchar * remote_host) |
0 | 115 { |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
116 smtp_connection *base = g_malloc(sizeof(smtp_connection)); |
80 | 117 if (!base) { |
118 return NULL; | |
119 } | |
120 | |
121 base->remote_host = g_strdup(remote_host); | |
0 | 122 |
80 | 123 base->prot = PROT_SMTP; |
124 base->next_id = 0; | |
125 base->helo_seen = 0; | |
126 base->from_seen = 0; | |
127 base->rcpt_seen = 0; | |
128 base->msg = NULL; | |
0 | 129 |
80 | 130 return base; |
0 | 131 } |
132 | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
133 static void |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
134 smtp_printf(FILE * out, gchar * fmt, ...) |
0 | 135 { |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
136 va_list args; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
137 va_start(args, fmt); |
0 | 138 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
139 DEBUG(4) { |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
140 gchar buf[256]; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
141 va_list args_copy; |
0 | 142 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
143 va_copy(args_copy, args); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
144 vsnprintf(buf, 255, fmt, args_copy); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
145 va_end(args_copy); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
146 |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
147 debugf(">>>%s", buf); |
0 | 148 } |
149 | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
150 vfprintf(out, fmt, args); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
151 fflush(out); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
152 |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
153 va_end(args); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
154 } |
0 | 155 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
156 void |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
157 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
|
158 { |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
159 gchar *buffer; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
160 smtp_cmd_id cmd_id; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
161 message *msg = NULL; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
162 smtp_connection *psc; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
163 int len; |
117
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
164 unsigned long size, msize; |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
165 |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
166 DEBUG(5) debugf("smtp_in entered, remote_host = %s\n", remote_host); |
0 | 167 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
168 psc = create_base(remote_host); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
169 psc->msg = msg; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
170 |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
171 buffer = (gchar *) g_malloc(BUF_LEN); |
80 | 172 if (!buffer) { |
173 /* this check is actually unneccessary as g_malloc() | |
174 aborts on failure */ | |
175 return; | |
176 } | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
177 |
80 | 178 /* send greeting string, containing ESMTP: */ |
179 smtp_printf(out, "220 %s MasqMail %s ESMTP\r\n", conf.host_name, VERSION); | |
0 | 180 |
80 | 181 while ((len = read_sockline(in, buffer, BUF_LEN, 5 * 60, READSOCKL_CHUG)) >= 0) { |
182 cmd_id = get_id(buffer); | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
183 |
135 | 184 if (conf.defer_all) { |
185 /* I need this to debug delivery failures */ | |
127 | 186 smtp_printf(out, "421 %s service temporarily unavailable.\r\n", conf.host_name); |
135 | 187 destroy_message(msg); |
188 msg = NULL; | |
189 return; | |
127 | 190 } |
191 | |
80 | 192 switch (cmd_id) { |
127 | 193 case SMTP_HELO: |
194 psc->prot = PROT_SMTP; | |
195 psc->helo_seen = TRUE; | |
196 smtp_printf(out, "250 %s pretty old mailer, huh?\r\n", conf.host_name); | |
197 break; | |
198 | |
80 | 199 case SMTP_EHLO: |
200 psc->prot = PROT_ESMTP; | |
201 psc->helo_seen = TRUE; | |
127 | 202 smtp_printf(out, "250-%s Nice to meet you with ESMTP\r\n", conf.host_name); |
203 smtp_printf(out, "250-SIZE %d\r\n", conf.max_msg_size); | |
204 smtp_printf(out, "250-PIPELINING\r\n"); | |
205 smtp_printf(out, "250 HELP\r\n"); | |
80 | 206 break; |
207 | |
208 case SMTP_MAIL_FROM: | |
209 { | |
210 gchar buf[MAX_ADDRESS]; | |
211 address *addr; | |
212 | |
213 if (!psc->helo_seen) { | |
214 smtp_printf(out, "503 need HELO or EHLO\r\n"); | |
215 break; | |
216 } | |
217 if (psc->from_seen) { | |
218 smtp_printf(out, "503 MAIL FROM: already given.\r\n"); | |
219 break; | |
220 } | |
128
f9d5469cb648
moved the SIZE check to a better location
meillo@marmaro.de
parents:
127
diff
changeset
|
221 if (get_size(buffer, &msize)) { |
f9d5469cb648
moved the SIZE check to a better location
meillo@marmaro.de
parents:
127
diff
changeset
|
222 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
|
223 msize, conf.max_msg_size); |
f9d5469cb648
moved the SIZE check to a better location
meillo@marmaro.de
parents:
127
diff
changeset
|
224 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
|
225 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
|
226 break; |
f9d5469cb648
moved the SIZE check to a better location
meillo@marmaro.de
parents:
127
diff
changeset
|
227 } |
f9d5469cb648
moved the SIZE check to a better location
meillo@marmaro.de
parents:
127
diff
changeset
|
228 } |
136
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
229 if (!get_address(buffer, buf)) { |
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
230 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
|
231 break; |
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
232 } |
128
f9d5469cb648
moved the SIZE check to a better location
meillo@marmaro.de
parents:
127
diff
changeset
|
233 |
80 | 234 msg = create_message(); |
235 msg->received_host = remote_host ? g_strdup(remote_host) : NULL; | |
236 msg->received_prot = psc->prot; | |
237 msg->ident = ident ? g_strdup(ident) : NULL; | |
238 /* get transfer id and increment for next one */ | |
239 msg->transfer_id = (psc->next_id)++; | |
240 | |
241 if (remote_host) { | |
242 addr = create_address(buf, TRUE); | |
243 } else { | |
244 addr = create_address_qualified(buf, TRUE, conf.host_name); | |
245 } | |
246 if (!addr) { | |
247 smtp_printf(out, "501 %s: syntax error.\r\n", buf); | |
248 } else if (!addr->domain) { | |
249 smtp_printf(out, "501 return path must be qualified.\r\n", buf); | |
250 } else { | |
251 psc->from_seen = TRUE; | |
252 msg->return_path = addr; | |
253 smtp_printf(out, "250 OK %s is a nice guy.\r\n", addr->address); | |
254 } | |
255 } | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
256 break; |
80 | 257 |
258 case SMTP_RCPT_TO: | |
259 { | |
260 char buf[MAX_ADDRESS]; | |
261 address *addr; | |
262 | |
263 if (!psc->helo_seen) { | |
264 smtp_printf(out, "503 need HELO or EHLO.\r\n"); | |
265 break; | |
266 } | |
267 if (!psc->from_seen) { | |
268 smtp_printf(out, "503 need MAIL FROM: before RCPT TO:\r\n"); | |
269 break; | |
270 } | |
136
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
271 if (!get_address(buffer, buf)) { |
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
272 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
|
273 break; |
6b78aaced5e1
check max length of addresses in SMTP dialog
meillo@marmaro.de
parents:
135
diff
changeset
|
274 } |
80 | 275 |
276 if (remote_host) { | |
277 addr = create_address(buf, TRUE); | |
278 } else { | |
279 addr = create_address_qualified(buf, TRUE, conf.host_name); | |
280 } | |
281 if (!addr) { | |
282 smtp_printf(out, "501 %s: syntax error in address.\r\n", buf); | |
283 break; | |
284 } | |
285 if (addr->local_part[0] == '|') { | |
286 smtp_printf(out, "501 %s: no pipe allowed for SMTP connections\r\n", buf); | |
287 break; | |
288 } | |
289 if (!addr->domain) { | |
290 smtp_printf(out, "501 recipient address must be qualified.\r\n", buf); | |
291 break; | |
292 } | |
293 gboolean do_relay = conf.do_relay; | |
294 if (!do_relay) { | |
295 do_relay = addr_is_local(msg->return_path); | |
296 if (!do_relay) { | |
297 do_relay = addr_is_local(addr); | |
298 } | |
299 } | |
300 if (!do_relay) { | |
301 smtp_printf(out, "550 relaying to %s denied.\r\n", addr_string(addr)); | |
302 break; | |
303 } | |
304 psc->rcpt_seen = TRUE; | |
305 msg->rcpt_list = g_list_append(msg->rcpt_list, addr); | |
306 smtp_printf(out, "250 OK %s is our friend.\r\n", addr->address); | |
307 } | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
308 break; |
80 | 309 |
310 case SMTP_DATA: | |
311 if (!psc->helo_seen) { | |
312 smtp_printf(out, "503 need HELO or EHLO.\r\n"); | |
313 break; | |
314 } | |
315 if (!psc->rcpt_seen) { | |
316 smtp_printf(out, "503 need RCPT TO: before DATA\r\n"); | |
317 break; | |
318 } | |
319 accept_error err; | |
320 | |
321 smtp_printf(out, "354 okay, and do not forget the dot\r\n"); | |
322 | |
323 err = accept_message(in, msg, conf.do_save_envelope_to ? ACC_SAVE_ENVELOPE_TO : 0); | |
324 if (err != AERR_OK) { | |
117
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
325 switch (err) { |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
326 case AERR_TIMEOUT: |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
327 case AERR_EOF: |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
328 return; |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
329 case AERR_SIZE: |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
330 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
|
331 return; |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
332 default: |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
333 /* should never happen: */ |
5ec5e6637049
added server-side SMTP SIZE support (patch by Paolo)
meillo@marmaro.de
parents:
81
diff
changeset
|
334 smtp_printf(out, "451 Unknown error\r\n"); |
80 | 335 return; |
336 } | |
337 } | |
338 | |
339 | |
340 if (!spool_write(msg, TRUE)) { | |
341 smtp_printf(out, "451 Could not write spool file\r\n"); | |
342 return; | |
343 } | |
344 pid_t pid; | |
345 smtp_printf(out, "250 OK id=%s\r\n", msg->uid); | |
346 | |
347 if (remote_host != NULL) { | |
348 logwrite(LOG_NOTICE, "%s <= <%s@%s> host=%s with %s\n", msg->uid, | |
349 msg->return_path->local_part, msg->return_path->domain, | |
350 remote_host, prot_names[psc->prot]); | |
351 } else { | |
352 logwrite(LOG_NOTICE, "%s <= <%s@%s> with %s\n", msg->uid, | |
353 msg->return_path->local_part, msg->return_path->domain, | |
354 prot_names[psc->prot]); | |
355 } | |
356 | |
357 if (conf.do_queue) { | |
358 DEBUG(1) debugf("queuing forced by configuration or option.\n"); | |
359 } else { | |
360 pid = fork(); | |
361 if (pid == 0) { | |
362 _exit(deliver(msg)); | |
363 } else if (pid < 0) { | |
364 logwrite(LOG_ALERT, "could not fork for delivery, id = %s", msg->uid); | |
365 } | |
366 } | |
367 psc->rcpt_seen = psc->from_seen = FALSE; | |
368 destroy_message(msg); | |
369 msg = NULL; | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
370 break; |
80 | 371 |
372 case SMTP_QUIT: | |
373 smtp_printf(out, "221 goodbye\r\n"); | |
81
71ce3a1568e9
moved check for NULL into destroy_message()
meillo@marmaro.de
parents:
80
diff
changeset
|
374 destroy_message(msg); |
71ce3a1568e9
moved check for NULL into destroy_message()
meillo@marmaro.de
parents:
80
diff
changeset
|
375 msg = NULL; |
80 | 376 return; |
377 | |
378 case SMTP_RSET: | |
379 psc->from_seen = psc->rcpt_seen = FALSE; | |
81
71ce3a1568e9
moved check for NULL into destroy_message()
meillo@marmaro.de
parents:
80
diff
changeset
|
380 destroy_message(msg); |
71ce3a1568e9
moved check for NULL into destroy_message()
meillo@marmaro.de
parents:
80
diff
changeset
|
381 msg = NULL; |
80 | 382 smtp_printf(out, "250 OK\r\n"); |
383 break; | |
384 | |
385 case SMTP_NOOP: | |
386 smtp_printf(out, "250 OK\r\n"); | |
387 break; | |
388 | |
389 case SMTP_HELP: | |
390 { | |
391 int i; | |
392 | |
393 smtp_printf(out, "214-supported commands:\r\n"); | |
394 for (i = 0; i < SMTP_NUM_IDS - 1; i++) { | |
395 smtp_printf(out, "214-%s\r\n", smtp_cmds[i].cmd); | |
396 } | |
397 smtp_printf(out, "214 %s\r\n", smtp_cmds[i].cmd); | |
398 } | |
399 break; | |
400 | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
401 default: |
80 | 402 smtp_printf(out, "501 command not recognized\r\n"); |
403 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
|
404 break; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
405 } |
0 | 406 } |
80 | 407 switch (len) { |
408 case -3: | |
409 logwrite(LOG_NOTICE, "connection timed out\n"); | |
410 break; | |
411 case -2: | |
412 logwrite(LOG_NOTICE, "line overflow\n"); | |
413 break; | |
414 case -1: | |
415 logwrite(LOG_NOTICE, "received EOF\n"); | |
416 break; | |
417 default: | |
418 break; | |
419 } | |
0 | 420 } |
421 #endif |