Z-Push Virtual User Support

Z

I’m a fan of push mail. Not having to pull your mail manually or at a given interval is a huge advantage. That’s why I use Z-Push on my private mail server.

Lately I’ve been playing for the second time with the Autodiscovery protocol. Found a neaty little PHP script that does all the magic for me and it seems to work on both iOS 6 and Android 4.2.2. Great! But there was one little problem. Autodiscovery always put the whole email adress as the username. I don’t allow that in my mail configuration. So what now? I couldn’t find a way to persuade Autodiscovery to put the right username as username and I found that this would be too complicated as you can have aliases for mail, so the login part would be wrong anyway.

Fortunately I already use the virtuser_file plugin in RoundCube Mail. Porting it to Z-Push was a piece of cake. Here’s the patch if you’re interested:

--- backend/imap.php.orig	2013-03-27 14:28:03.231378003 +0100
+++ backend/imap.php	2013-03-27 15:01:04.395096310 +0100
@@ -65,6 +65,48 @@
      * default backend methods
      */
 
+    public function email2user($p)
+    {
+            $r = $this->findinvirtual('/^' . preg_quote($p, '/') . '\s/');
+
+            for ($i=0; $i<count($r); $i++)="" {="" +="" $arr="preg_split('/\s+/'," trim($r[$i]));="" if="" (count($arr)=""> 0) {
+                        $res = trim($arr[count($arr)-1]);
+                        break;
+                }
+            }
+
+            return $res;
+    }
+
+    public function findinvirtual($pattern)
+    {
+	    $file = "/etc/mail/virtual";
+            $result = array();
+            $virtual = null;
+
+            if ($file)
+                $virtual = file($file);
+
+            if (empty($virtual))
+                    return $result;
+
+            // check each line for matches
+            foreach ($virtual as $line) {
+                $line = trim($line);
+                if (empty($line) || $line[0]=='#')
+                    continue;
+
+                if (preg_match($pattern, $line))
+                    $result[] = $line;
+            }
+
+            return $result;
+    }
+
+
     /**
      * Authenticates the user
      *
@@ -84,6 +126,10 @@
         if (!function_exists("imap_open"))
             throw new FatalException("BackendIMAP(): php-imap module is not installed", 0, null, LOGLEVEL_FATAL);
 
+	# if username is a full email, try to find out the real user
+	if (preg_match("/@/", $username))
+		$username = $this->email2user($username);
+
         /* BEGIN fmbiete's contribution r1527, ZP-319 */
         $this->excludedFolders = array();
         if (defined('IMAP_EXCLUDED_FOLDERS')) {
@@ -1804,4 +1850,4 @@
     /* END fmbiete's contribution r1528, ZP-320 */
 };
 
-?>
\ Brak znaku nowej linii na końcu pliku
+?>
</count($r);>

This works with Z-Push 2.0.7. My virtual map file looks like this:

email@domain.tld real_username1
email2@anotherdomain.tld real_username1
test@domain.tld real_username2
etc...

If you like it, you can copy&paste the patch or download it from here

Cheers!

About the author

Bartosz

iOS and OS X software engineer. Currently working in Berlin, Germany.

By Bartosz