]>
Commit | Line | Data |
---|---|---|
9fcdd866 | 1 | Catch error from address parsing. |
2ac10c6e | 2 | |
465c3ab7 ER |
3 | --- eventum-20060717/include/class.mail.php~ 2006-07-18 01:21:08.631017731 +0300 |
4 | +++ eventum-20060717/include/class.mail.php 2006-07-18 01:22:01.102190536 +0300 | |
5 | @@ -244,6 +244,9 @@ | |
2ac10c6e ER |
6 | $address = Mime_Helper::encodeValue($address); |
7 | include_once(APP_PEAR_PATH . "Mail/RFC822.php"); | |
8 | $t = Mail_RFC822::parseAddressList($address, null, null, false); | |
9 | + if (PEAR::isError($t)) { | |
10 | + Error_Handler::logError(array($t->getMessage(), $t->getDebugInfo()), __FILE__, __LINE__); | |
2ac10c6e | 11 | + } |
2ac10c6e ER |
12 | if ($multiple) { |
13 | $returns = array(); | |
14 | for ($i = 0; $i < count($t); $i++) { | |
2ac10c6e ER |
15 | ------------------------------------------------------------------------------------------------------- |
16 | Detect and log possibly corrupted MIME emails. | |
17 | ||
18 | --- eventum-1.7.1/include/class.mime_helper.php 2006-04-12 00:48:18.579879862 +0300 | |
19 | +++ /home/glen/class.mime_helper.php 2006-04-12 00:52:33.225568723 +0300 | |
20 | @@ -39,6 +39,7 @@ | |
21 | */ | |
22 | ||
23 | include_once(APP_PEAR_PATH . "Mail/mimeDecode.php"); | |
24 | +include_once(APP_INC_PATH . "class.error_handler.php"); | |
25 | ||
26 | /** | |
27 | * Class to handle the business logic related to the MIME email | |
28 | @@ -88,6 +89,10 @@ | |
29 | { | |
30 | $parts = array(); | |
31 | Mime_Helper::parse_output($output, $parts); | |
32 | + if (empty($parts)) { | |
33 | + Error_Handler::logError(array("Mime_Helper::parse_output failed. Corrupted MIME in email?", $output), __FILE__, __LINE__); | |
34 | + // we continue as if nothing happened until it's clear it's right check to do. | |
35 | + } | |
36 | $str = ''; | |
37 | $is_html = false; | |
38 | if (isset($parts["text"])) { | |
39 | ||
40 | ------------------------------------------------------------------------------------------------------- | |
41 | Rewrite routing part to have consistent API for matching issue_ids from mail headers. | |
42 | Add new method Routing::getMatchingIssueIDs(). | |
2ac10c6e ER |
43 | --- eventum-1.7.1/include/class.routing.php 2006-04-12 00:48:18.189871149 +0300 |
44 | +++ /home/glen/class.routing.php 2006-04-12 00:52:33.295570287 +0300 | |
45 | @@ -104,35 +104,29 @@ | |
46 | if ($setup['email_routing']['status'] != 'enabled') { | |
47 | return array(78, "Error: The email routing interface is disabled.\n"); | |
48 | } | |
49 | - $prefix = $setup['email_routing']['address_prefix']; | |
50 | - // escape plus signs so 'issue+1@example.com' becomes a valid routing address | |
51 | - $prefix = str_replace('+', '\+', $prefix); | |
52 | - $mail_domain = quotemeta($setup['email_routing']['address_host']); | |
53 | - $mail_domain_alias = quotemeta(@$setup['email_routing']['host_alias']); | |
54 | - if (!empty($mail_domain_alias)) { | |
55 | - $mail_domain = "(?:" . $mail_domain . "|" . $mail_domain_alias . ")"; | |
56 | - } | |
57 | - if (empty($prefix)) { | |
58 | + if (empty($setup['email_routing']['address_prefix'])) { | |
59 | return array(78, "Error: Please configure the email address prefix.\n"); | |
60 | } | |
61 | - if (empty($mail_domain)) { | |
62 | + if (empty($setup['email_routing']['address_host'])) { | |
63 | return array(78, "Error: Please configure the email address domain.\n"); | |
64 | } | |
65 | + | |
66 | $structure = Mime_Helper::decode($full_message, true, true); | |
67 | ||
68 | // find which issue ID this email refers to | |
69 | - @preg_match("/$prefix(\d*)@$mail_domain/i", $structure->headers['to'], $matches); | |
70 | - @$issue_id = $matches[1]; | |
71 | + if (isset($structure->headers['to'])) { | |
72 | + $issue_id = Routing::getMatchingIssueIDs($structure->headers['to'], 'email'); | |
73 | + } | |
74 | // validation is always a good idea | |
75 | - if (empty($issue_id)) { | |
76 | + if (empty($issue_id) and isset($structure->headers['cc'])) { | |
77 | // we need to try the Cc header as well | |
78 | - @preg_match("/$prefix(\d*)@$mail_domain/i", $structure->headers['cc'], $matches); | |
79 | - if (!empty($matches[1])) { | |
80 | - $issue_id = $matches[1]; | |
81 | - } else { | |
82 | - return array(65, "Error: The routed email had no associated Eventum issue ID or had an invalid recipient address.\n"); | |
83 | - } | |
84 | + $issue_id = Routing::getMatchingIssueIDs($structure->headers['cc'], 'email'); | |
85 | + } | |
86 | + | |
87 | + if (empty($issue_id)) { | |
88 | + return array(65, "Error: The routed email had no associated Eventum issue ID or had an invalid recipient address.\n"); | |
89 | } | |
90 | + | |
91 | if (empty($email_account_id)) { | |
92 | $issue_prj_id = Issue::getProjectID($issue_id); | |
93 | if (empty($issue_prj_id)) { | |
94 | @@ -305,30 +299,26 @@ | |
95 | if (@$setup['note_routing']['status'] != 'enabled') { | |
96 | return array(78, "Error: The internal note routing interface is disabled.\n"); | |
97 | } | |
98 | - $prefix = $setup['note_routing']['address_prefix']; | |
99 | - // escape plus signs so 'note+1@example.com' becomes a valid routing address | |
100 | - $prefix = str_replace('+', '\+', $prefix); | |
101 | - $mail_domain = quotemeta($setup['note_routing']['address_host']); | |
102 | - if (empty($prefix)) { | |
103 | + if (empty($setup['note_routing']['address_prefix'])) { | |
104 | return array(78, "Error: Please configure the email address prefix.\n"); | |
105 | } | |
106 | - if (empty($mail_domain)) { | |
107 | + if (empty($setup['note_routing']['address_host'])) { | |
108 | return array(78, "Error: Please configure the email address domain.\n"); | |
109 | } | |
110 | $structure = Mime_Helper::decode($full_message, true, true); | |
111 | ||
112 | // find which issue ID this email refers to | |
113 | - @preg_match("/$prefix(\d*)@$mail_domain/i", $structure->headers['to'], $matches); | |
114 | - @$issue_id = $matches[1]; | |
115 | + if (isset($structure->headers['to'])) { | |
116 | + $issue_id = Routing::getMatchingIssueIDs($structure->headers['to'], 'note'); | |
117 | + } | |
118 | // validation is always a good idea | |
119 | - if (empty($issue_id)) { | |
120 | + if (empty($issue_id) and isset($structure->headers['cc'])) { | |
121 | // we need to try the Cc header as well | |
122 | - @preg_match("/$prefix(\d*)@$mail_domain/i", $structure->headers['cc'], $matches); | |
123 | - if (!empty($matches[1])) { | |
124 | - $issue_id = $matches[1]; | |
125 | - } else { | |
126 | - return array(65, "Error: The routed note had no associated Eventum issue ID or had an invalid recipient address.\n"); | |
127 | - } | |
128 | + $issue_id = Routing::getMatchingIssueIDs($structure->headers['cc'], 'note'); | |
129 | + } | |
130 | + | |
131 | + if (empty($issue_id)) { | |
132 | + return array(65, "Error: The routed note had no associated Eventum issue ID or had an invalid recipient address.\n"); | |
133 | } | |
134 | ||
135 | $prj_id = Issue::getProjectID($issue_id); | |
136 | @@ -389,6 +379,7 @@ | |
137 | if ($res != -1) { | |
138 | Support::extractAttachments($issue_id, $full_message, true, $res); | |
139 | } | |
140 | + // FIXME! $res == -2 is not handled | |
141 | History::add($issue_id, Auth::getUserID(), History::getTypeID('note_routed'), "Note routed from " . $structure->headers['from']); | |
142 | ||
143 | return true; | |
144 | @@ -433,30 +424,27 @@ | |
145 | if (@$setup['draft_routing']['status'] != 'enabled') { | |
146 | return array(78, "Error: The email draft interface is disabled.\n"); | |
147 | } | |
148 | - $prefix = $setup['draft_routing']['address_prefix']; | |
149 | - // escape plus signs so 'draft+1@example.com' becomes a valid address | |
150 | - $prefix = str_replace('+', '\+', $prefix); | |
151 | - $mail_domain = quotemeta($setup['draft_routing']['address_host']); | |
152 | - if (empty($prefix)) { | |
153 | + if (empty($setup['draft_routing']['address_prefix'])) { | |
154 | return array(78, "Error: Please configure the email address prefix.\n"); | |
155 | } | |
156 | - if (empty($mail_domain)) { | |
157 | + if (empty($setup['draft_routing']['address_host'])) { | |
158 | return array(78, "Error: Please configure the email address domain.\n"); | |
159 | } | |
160 | + | |
161 | $structure = Mime_Helper::decode($full_message, true, false); | |
162 | ||
163 | // find which issue ID this email refers to | |
164 | - @preg_match("/$prefix(\d*)@$mail_domain/i", $structure->headers['to'], $matches); | |
165 | - @$issue_id = $matches[1]; | |
166 | + if (isset($structure->headers['to'])) { | |
167 | + $issue_id = Routing::getMatchingIssueIDs($structure->headers['to'], 'draft'); | |
168 | + } | |
169 | // validation is always a good idea | |
170 | - if (empty($issue_id)) { | |
171 | + if (empty($issue_id) and isset($structure->headers['cc'])) { | |
172 | // we need to try the Cc header as well | |
173 | - @preg_match("/$prefix(\d*)@$mail_domain/i", $structure->headers['cc'], $matches); | |
174 | - if (!empty($matches[1])) { | |
175 | - $issue_id = $matches[1]; | |
176 | - } else { | |
177 | - return array(65, "Error: The routed draft had no associated Eventum issue ID or had an invalid recipient address.\n"); | |
178 | - } | |
179 | + $issue_id = Routing::getMatchingIssueIDs($structure->headers['cc'], 'draft'); | |
180 | + } | |
181 | + | |
182 | + if (empty($issue_id)) { | |
183 | + return array(65, "Error: The routed email had no associated Eventum issue ID or had an invalid recipient address.\n"); | |
184 | } | |
185 | ||
186 | $prj_id = Issue::getProjectID($issue_id); | |
187 | @@ -477,5 +465,54 @@ | |
188 | History::add($issue_id, Auth::getUserID(), History::getTypeID('draft_routed'), "Draft routed from " . $structure->headers['from']); | |
189 | return true; | |
190 | } | |
191 | + | |
192 | + /** | |
193 | + * Check for $adresses for matches | |
194 | + * | |
195 | + * @param mixed $addresses to check | |
196 | + * @param string Type of address match to find (email, note, draft) | |
197 | + * @return mixed $issue_id in case of match otherwise false | |
198 | + */ | |
199 | + function getMatchingIssueIDs($addresses, $type) | |
200 | + { | |
201 | + $setup = Setup::load(); | |
202 | + $settings = $setup["${type}_routing"]; | |
203 | + if (!is_array($settings)) { | |
204 | + return false; | |
205 | + } | |
206 | + | |
207 | + if (empty($settings['address_prefix'])) { | |
208 | + return false; | |
209 | + } | |
210 | + // escape plus signs so 'issue+1@example.com' becomes a valid routing address | |
211 | + $prefix = quotemeta($settings['address_prefix']); | |
212 | + | |
213 | + if (empty($settings['address_host'])) { | |
214 | + return false; | |
215 | + } | |
216 | + $mail_domain = quotemeta($settings['address_host']); | |
217 | + | |
218 | + // it is not checked for type when host alias is asked. this leaves | |
219 | + // room foradding host_alias for other than email routing. | |
220 | + if (isset($settings['host_alias'])) { | |
221 | + // TODO: can't quotemeta() host alias as it can contain multiple hosts separated with pipe | |
222 | + $mail_domain = '(?:' . $mail_domain . '|' . $settings['host_alias'] . ')'; | |
223 | + } | |
224 | + | |
225 | + // if there are multiple CC or To headers Mail_Mime creates array. | |
226 | + // handle both cases (strings and arrays). | |
227 | + if (!is_array($addresses)) { | |
228 | + $addresses = array($addresses); | |
229 | + } | |
230 | + | |
231 | + // everything safely escaped and checked, try matching address | |
232 | + foreach ($addresses as $address) { | |
233 | + if (preg_match("/$prefix(\d*)@$mail_domain/i", $address, $matches)) { | |
234 | + return $matches[1]; | |
235 | + } | |
236 | + } | |
237 | + | |
238 | + return false; | |
239 | + } | |
240 | } | |
241 | ?> | |
242 | --- eventum-1.7.1/include/class.support.php 2006-04-12 00:48:18.619880756 +0300 | |
243 | +++ /home/glen/class.support.php 2006-04-12 00:52:33.395572521 +0300 | |
244 | @@ -504,22 +504,22 @@ | |
245 | if ($info['ema_use_routing'] == 1) { | |
246 | $setup = Setup::load(); | |
247 | ||
248 | - if (@$setup['email_routing']['status'] == 'enabled') { | |
249 | - $prefix = $setup['email_routing']['address_prefix']; | |
250 | - // escape plus signs so 'issue+1@example.com' becomes a valid routing address | |
251 | - $prefix = str_replace('+', '\+', $prefix); | |
252 | - $mail_domain = $setup['email_routing']['address_host']; | |
253 | - $mail_domain_alias = @$setup['email_routing']['host_alias']; | |
254 | - if (!empty($mail_domain_alias)) { | |
255 | - $mail_domain = "[" . $mail_domain . "|" . $mail_domain_alias . "]"; | |
256 | - } | |
257 | - if (empty($prefix)) { | |
258 | - return false; | |
259 | + // we create addresses array so it can be reused | |
260 | + $addresses = array(); | |
261 | + if (isset($email->to)) { | |
262 | + foreach ($email->to as $address) { | |
263 | + $addresses[] = $address->mailbox . '@' . $address->host; | |
264 | } | |
265 | - if (empty($mail_domain)) { | |
266 | - return false; | |
267 | + } | |
268 | + if (isset($email->cc)) { | |
269 | + foreach ($email->cc as $address) { | |
270 | + $addresses[] = $address->mailbox . '@' . $address->host; | |
271 | } | |
465c3ab7 | 272 | - if ((isset($email->toaddress)) && (preg_match("/$prefix(\d*)@$mail_domain/i", $email->toaddress, $matches))) { |
2ac10c6e ER |
273 | + } |
274 | + | |
275 | + if (@$setup['email_routing']['status'] == 'enabled') { | |
276 | + $res = Routing::getMatchingIssueIDs($addresses, 'email'); | |
277 | + if ($res != false) { | |
278 | $return = Routing::route_emails($message); | |
279 | if ($return == true) { | |
280 | Support::deleteMessage($info, $mbox, $num); | |
281 | @@ -528,18 +528,8 @@ | |
282 | } | |
283 | } | |
284 | if (@$setup['note_routing']['status'] == 'enabled') { | |
285 | - $prefix = $setup['note_routing']['address_prefix']; | |
286 | - // escape plus signs so 'note+1@example.com' becomes a valid routing address | |
287 | - $prefix = str_replace('+', '\+', $prefix); | |
288 | - $mail_domain = $setup['note_routing']['address_host']; | |
289 | - if (empty($prefix)) { | |
290 | - return false; | |
291 | - } | |
292 | - if (empty($mail_domain)) { | |
293 | - return false; | |
294 | - } | |
295 | - | |
296 | - if (preg_match("/$prefix(\d*)@$mail_domain/i", $email->toaddress, $matches)) { | |
297 | + $res = Routing::getMatchingIssueIDs($addresses, 'note'); | |
298 | + if ($res != false) { | |
299 | $return = Routing::route_notes($message); | |
300 | if ($return == true) { | |
301 | Support::deleteMessage($info, $mbox, $num); | |
302 | @@ -548,18 +538,8 @@ | |
303 | } | |
304 | } | |
305 | if (@$setup['draft_routing']['status'] == 'enabled') { | |
306 | - $prefix = $setup['draft_routing']['address_prefix']; | |
307 | - // escape plus signs so 'draft+1@example.com' becomes a valid routing address | |
308 | - $prefix = str_replace('+', '\+', $prefix); | |
309 | - $mail_domain = $setup['draft_routing']['address_host']; | |
310 | - if (empty($prefix)) { | |
311 | - return false; | |
312 | - } | |
313 | - if (empty($mail_domain)) { | |
314 | - return false; | |
315 | - } | |
316 | - | |
317 | - if (preg_match("/$prefix(\d*)@$mail_domain/i", $email->toaddress, $matches)) { | |
318 | + $res = Routing::getMatchingIssueIDs($addresses, 'draft'); | |
319 | + if ($res != false) { | |
320 | $return = Routing::route_drafts($message); | |
321 | if ($return == true) { | |
322 | Support::deleteMessage($info, $mbox, $num); | |
323 | ||
324 | ------------------------------------------------------------------------------------------------------- | |
325 | Fix possible Cc: headers composition of routed Notes where Eventum user email and email from headers differ with case. | |
2ac10c6e ER |
326 | --- eventum-1.7.1/include/class.routing.php 2006-04-12 00:48:18.189871149 +0300 |
327 | +++ /home/glen/class.routing.php 2006-04-12 00:52:33.295570287 +0300 | |
328 | @@ -356,12 +346,11 @@ | |
329 | $cc_users = array(); | |
330 | foreach ($addresses as $email) { | |
331 | if (in_array(strtolower($email), $user_emails)) { | |
332 | - $cc_users[] = $users[$email]; | |
333 | + $cc_users[] = $users[strtolower($email)]; | |
334 | } | |
335 | } | |
336 | ||
337 | $body = Mime_Helper::getMessageBody($structure); | |
338 | - | |
339 | $reference_msg_id = Mail_API::getReferenceMessageID($headers); | |
340 | if (!empty($reference_msg_id)) { | |
341 | $parent_id = Note::getIDByMessageID($reference_msg_id); | |
342 | ------------------------------------------------------------------------------------------------------- | |
343 | API cleanup: drop unneccessary $email_account_id in route_emails to be consistent with download_emails based routing. | |
2ac10c6e ER |
344 | --- eventum-1.7.1/misc/route_emails.php 2006-04-12 00:54:57.398789518 +0300 |
345 | +++ /home/glen/route_emails.php 2006-04-12 01:03:52.300737408 +0300 | |
346 | @@ -33,10 +33,9 @@ | |
347 | include_once(APP_INC_PATH . "db_access.php"); | |
348 | include_once(APP_INC_PATH . "class.routing.php"); | |
349 | ||
350 | -$email_account_id = $HTTP_SERVER_VARS['argv'][1]; | |
351 | $full_message = Misc::getInput(); | |
352 | ||
353 | -$return = Routing::route_emails($full_message, $email_account_id); | |
354 | +$return = Routing::route_emails($full_message); | |
355 | if (is_array($return)) { | |
356 | echo $return[1]; | |
357 | exit($return[0]); | |
358 | --- eventum-1.7.1/include/class.routing.php 2006-04-12 00:54:57.278786838 +0300 | |
359 | +++ /home/glen/class.routing.php 2006-04-12 01:03:45.370582745 +0300 | |
360 | @@ -52,9 +52,8 @@ | |
361 | * Routes an email to the correct issue. | |
362 | * | |
363 | * @param string $full_message The full email message, including headers | |
364 | - * @param integer $email_account_id The ID of the email account this email should be routed too. If empty this method will try to figure it out | |
365 | */ | |
366 | - function route_emails($full_message, $email_account_id = 0) | |
367 | + function route_emails($full_message) | |
368 | { | |
369 | GLOBAL $HTTP_POST_VARS; | |
370 |