=== modified file 'www/sites/all/modules/mailhandler/mailhandler.admin.inc'
--- www/sites/all/modules/mailhandler/mailhandler.admin.inc 2009-11-24 19:05:46 +0000
+++ www/sites/all/modules/mailhandler/mailhandler.admin.inc 2009-11-24 19:07:54 +0000
@@ -17,6 +17,7 @@
     'mime' => 'TEXT/HTML,TEXT/PLAIN',
     'security' => 0,
     'replies' => 1,
+    'authenticate' => 1,
     'fromheader' => '',
     'commands' => '',
     'sigseparator' => '',
@@ -121,6 +122,8 @@
 
   $form['replies'] = array('#type' => 'radios', '#title' => t('Send error replies'), '#options' => array(t('Disabled'), t('Enabled')), '#default_value' => $edit['replies'], '#description' => t('Send helpful replies to all unsuccessful e-mail submissions. Consider disabling when a listserv posts to this mailbox.'));
 
+  $form['authenticate'] = array('#type' => 'checkbox', '#title' => t('Authenticate using From header'), '#default_value' => $edit['authenticate'], '#description' => t('This is a default behaviour for authenticating (matching) users using a From header (see below). This setting is considered as a failback method. If none of the external authentication modules match a user, mailhandler will use a From header if you check this box.'));
+
   $form['fromheader'] = array('#type' => 'textfield', '#title' => t('From header'), '#default_value' => $edit['fromheader'], '#description' => t('Use this e-mail header to determine the author of the resulting node. Admins usually leave this field blank (thus using the <strong>From</strong> header), but <strong>Sender</strong> is also useful when working with listservs.'));
 
   $form['commands'] = array('#type' => 'textarea', '#title' => t('Default commands'), '#default_value' => $edit['commands'], '#description' => t('A set of commands which are added to each message. One command per line. See <a href="@link">Commands</a>.', array('@link' => url('admin/help/mailhandler/#commands'))));
@@ -221,11 +224,11 @@
 function mailhandler_add_edit_mailbox_submit($form, &$form_state) {
 // TODO: try to rewrite these monsters wth drupal_write_record();
   if ($form_state['values']['mid']) {
-    db_query("UPDATE {mailhandler} SET mail = '%s', mailto = '%s', domain = '%s', port = %d, folder = '%s', name = '%s', pass = '%s', extraimap = '%s', mime = '%s', imap = '%s', security = %d, replies = %d, fromheader = '%s', commands = '%s', sigseparator = '%s', enabled = %d, delete_after_read = %d, format = %d WHERE mid = %d", $form_state['values']['mail'], $form_state['values']['mailto'], $form_state['values']['domain'], $form_state['values']['port'], $form_state['values']['folder'], $form_state['values']['name'], $form_state['values']['pass'], $form_state['values']['extraimap'], $form_state['values']['mime'], $form_state['values']['imap'], $form_state['values']['security'], $form_state['values']['replies'], $form_state['values']['fromheader'], $form_state['values']['commands'], $form_state['values']['sigseparator'], $form_state['values']['enabled'], $form_state['values']['delete_after_read'], $form_state['values']['format'], $form_state['values']['mid']);
+    db_query("UPDATE {mailhandler} SET mail = '%s', mailto = '%s', domain = '%s', port = %d, folder = '%s', name = '%s', pass = '%s', extraimap = '%s', mime = '%s', imap = '%s', security = %d, replies = %d, fromheader = '%s', commands = '%s', sigseparator = '%s', enabled = %d, delete_after_read = %d, format = %d, authenticate = %d WHERE mid = %d", $form_state['values']['mail'], $form_state['values']['mailto'], $form_state['values']['domain'], $form_state['values']['port'], $form_state['values']['folder'], $form_state['values']['name'], $form_state['values']['pass'], $form_state['values']['extraimap'], $form_state['values']['mime'], $form_state['values']['imap'], $form_state['values']['security'], $form_state['values']['replies'], $form_state['values']['fromheader'], $form_state['values']['commands'], $form_state['values']['sigseparator'], $form_state['values']['enabled'], $form_state['values']['delete_after_read'], $form_state['values']['format'], $form_state['values']['authenticate'], $form_state['values']['mid']);
     drupal_set_message(t('Mailbox %mailbox updated.', array('%mailbox' => $form_state['values']['mail'])));
   }
   else {
-    db_query("INSERT INTO {mailhandler} (mail, mailto, domain, port, folder, name, pass, extraimap, mime, imap, security, replies, fromheader, commands, sigseparator, enabled, delete_after_read, format) VALUES ('%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', %d, %d, %d)", $form_state['values']['mail'], $form_state['values']['mailto'], $form_state['values']['domain'], $form_state['values']['port'], $form_state['values']['folder'], $form_state['values']['name'], $form_state['values']['pass'], $form_state['values']['extraimap'], $form_state['values']['mime'], $form_state['values']['imap'], $form_state['values']['security'], $form_state['values']['replies'], $form_state['values']['fromheader'], $form_state['values']['commands'], $form_state['values']['sigseparator'], $form_state['values']['enabled'], $form_state['values']['delete_after_read'], $form_state['values']['format']);
+    db_query("INSERT INTO {mailhandler} (mail, mailto, domain, port, folder, name, pass, extraimap, mime, imap, security, replies, fromheader, commands, sigseparator, enabled, delete_after_read, format, authenticate) VALUES ('%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', %d, %d, %d, %d)", $form_state['values']['mail'], $form_state['values']['mailto'], $form_state['values']['domain'], $form_state['values']['port'], $form_state['values']['folder'], $form_state['values']['name'], $form_state['values']['pass'], $form_state['values']['extraimap'], $form_state['values']['mime'], $form_state['values']['imap'], $form_state['values']['security'], $form_state['values']['replies'], $form_state['values']['fromheader'], $form_state['values']['commands'], $form_state['values']['sigseparator'], $form_state['values']['enabled'], $form_state['values']['delete_after_read'], $form_state['values']['format'], $formstate['values']['authenticate']);
     drupal_set_message(t('Mailbox %mailbox added.', array('%mailbox' => $form_state['values']['mail'])));
   }
 

=== modified file 'www/sites/all/modules/mailhandler/mailhandler.install'
--- www/sites/all/modules/mailhandler/mailhandler.install 2009-11-24 17:45:46 +0000
+++ www/sites/all/modules/mailhandler/mailhandler.install 2009-11-24 19:39:40 +0000
@@ -124,6 +124,11 @@
         'not null' => TRUE,
         'default' => 0,
       ),
+      'authenticate' => array(
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
     ),
     'primary key' => array('mid'),
     'indexes' => array(
@@ -143,6 +148,13 @@
   //return _system_update_utf8(array('mailhandler'));
 }
 
+function mailhandler_update_6002() {
+  $ret = array();
+  db_add_field($ret, 'mailhandler', 'authenticate', array('type' => 'int', 'not null' => TRUE));
+  $ret[] = update_sql('UPDATE {mailhandler} SET authenticate = 1');
+  return $ret;
+}
+
 
 /**
  * Check that the IMAP extension exists for PHP.
@@ -163,4 +175,4 @@
 
 /**
 
-**/
\ No newline at end of file
+**/

=== modified file 'www/sites/all/modules/mailhandler/mailhandler.retrieve.inc'
--- www/sites/all/modules/mailhandler/mailhandler.retrieve.inc  2009-11-24 19:05:46 +0000
+++ www/sites/all/modules/mailhandler/mailhandler.retrieve.inc  2009-11-24 19:35:52 +0000
@@ -383,27 +383,42 @@
  */
 function mailhandler_authenticate($node, $header, $origbody, $mailbox) {
 
-  // $fromaddress really refers to the mail header which is authoritative for authentication
-  list($fromaddress, $fromname) = mailhandler_get_fromaddress($header, $mailbox);
-  if ($from_user = mailhandler_user_load($fromaddress, $node->pass, $mailbox)) {
-    $node->uid = $from_user->uid; // success!
-    $node->name = $from_user->name;
-  }
-  else if (function_exists('mailalias_user')) { // since $fromaddress failed, try e-mail aliases
-    $result = db_query("SELECT mail FROM {users} WHERE data LIKE '%%%s%%'", $fromaddress);
-    while ($alias = db_result($result)) {
-      if ($from_user = mailhandler_user_load($alias, $node->pass, $mailbox)) {
-        $node->uid = $from_user->uid; // success!
-        $node->name = $from_user->name;
+  // Might be rewritten below.
+  $fromname = 'Anonymous';
+
+  foreach(module_implements('mailhandler_authenticate') as $module) {
+    $function = $module . '_mailhandler_authenticate';
+    $auth_result = $$function($header, $origbody, $mailbox);
+    if (isset($auth_result) && !empty($auth_result)) {
+      // One of the modules succesfully matched a Drupal user and returned his mail address.
+      if ($auth_user = mailhandler_user_load($auth_result, $node->pass, $mailbox)) {
+        // One matched, do not proceed with other modules.
         break;
       }
     }
   }
-  if (!$from_user) {
-    // failed authentication. we will still try to submit anonymously.
+
+  // None of the modules matched a Drupal user, try a fallback method.
+  // Only try authenticating if the mailbox->authenticate is set.
+  // Why above? Because it's a security bug if we allow multiple authentication
+  // modules and then always fallback to default From.
+  if (!isset($auth_user) && $mailbox->authenticate) {
+      // $fromaddress really refers to the mail header which is authoritative for authentication
+      list($fromaddress, $fromname) = mailhandler_get_fromaddress($header, $mailbox);
+      $auth_user = mailhandler_user_load($fromaddress, $node->pass, $mailbox);
+  }
+
+  if ($auth_user->uid) {
+        $node->uid = $auth_user->uid;
+        $node->name = $auth_user->name;
+        break;
+      }
+  } else  {
+    // Failed authentication. We will still try to submit anonymously.
     $node->uid = 0;
     $node->name = $fromname; // use the name supplied in email headers
   }
+
   return $node;
 }
 


