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