From f954922c03e30bfe06b60f35336f9274fa45ee4e Mon Sep 17 00:00:00 2001
From: Thomas Bruederli <thomas@roundcube.net>
Date: Thu, 07 Aug 2014 11:04:05 -0400
Subject: [PATCH] - Implemented 'storage_connected' API hook after successful IMAP login (#1490025) - Added config option 'imap_log_session' to enable Roundcube <-> IMAP session ID logging - Added config option 'log_session_id' to control the lengh of the session identifer in logs

---
 program/lib/Roundcube/rcube.php      |   28 +++++++++++++++++++++++-----
 program/lib/Roundcube/rcube_imap.php |   24 +++++++++++++++++++-----
 2 files changed, 42 insertions(+), 10 deletions(-)

diff --git a/program/lib/Roundcube/rcube.php b/program/lib/Roundcube/rcube.php
index e3e26d8..eedc46c 100644
--- a/program/lib/Roundcube/rcube.php
+++ b/program/lib/Roundcube/rcube.php
@@ -389,8 +389,12 @@
 
         $this->storage->set_options($options);
         $this->set_storage_prop();
-    }
 
+        // subscribe to 'storage_connected' hook for session logging
+        if ($this->config->get('imap_log_session', false)) {
+            $this->plugins->register_hook('storage_connected', array($this, 'storage_log_session'));
+        }
+    }
 
     /**
      * Set storage parameters.
@@ -456,6 +460,16 @@
         }
     }
 
+
+    /**
+     * Callback for IMAP connection events to log session identifiers
+     */
+    public function storage_log_session($args)
+    {
+        if (!empty($args['session']) && session_id()) {
+            $this->write_log('imap_session', $args['session']);
+        }
+    }
 
     /**
      * Create session object and start the session.
@@ -1138,8 +1152,12 @@
             $line = var_export($line, true);
         }
 
-        $date_format = self::$instance ? self::$instance->config->get('log_date_format') : null;
-        $log_driver  = self::$instance ? self::$instance->config->get('log_driver') : null;
+        $date_format = $log_driver = $session_key = null;
+        if (self::$instance) {
+            $date_format = self::$instance->config->get('log_date_format');
+            $log_driver  = self::$instance->config->get('log_driver');
+            $session_key = intval(self::$instance->config->get('log_session_id', 8));
+        }
 
         if (empty($date_format)) {
             $date_format = 'd-M-Y H:i:s O';
@@ -1158,8 +1176,8 @@
         }
 
         // add session ID to the log
-        if ($sess = session_id()) {
-            $line = '<' . substr($sess, 0, 8) . '> ' . $line;
+        if ($session_key > 0 && ($sess = session_id())) {
+            $line = '<' . substr($sess, 0, $session_key) . '> ' . $line;
         }
 
         if ($log_driver == 'syslog') {
diff --git a/program/lib/Roundcube/rcube_imap.php b/program/lib/Roundcube/rcube_imap.php
index 79a8973..ec961c8 100644
--- a/program/lib/Roundcube/rcube_imap.php
+++ b/program/lib/Roundcube/rcube_imap.php
@@ -56,6 +56,7 @@
      */
     protected $icache = array();
 
+    protected $plugins;
     protected $list_page = 1;
     protected $delimiter;
     protected $namespace;
@@ -82,6 +83,7 @@
     public function __construct()
     {
         $this->conn = new rcube_imap_generic();
+        $this->plugins = rcube::get_instance()->plugins;
 
         // Set namespace and delimiter from session,
         // so some methods would work before connection
@@ -147,7 +149,7 @@
 
         $attempt = 0;
         do {
-            $data = rcube::get_instance()->plugins->exec_hook('storage_connect',
+            $data = $this->plugins->exec_hook('storage_connect',
                 array_merge($this->options, array('host' => $host, 'user' => $user,
                     'attempt' => ++$attempt)));
 
@@ -170,8 +172,20 @@
         $this->connect_done = true;
 
         if ($this->conn->connected()) {
+            // check for session identifier
+            $session = null;
+            if (preg_match('/\s+SESSIONID=([^=\s]+)/', $this->conn->result, $m)) {
+                $session = $m[1];
+            }
+
             // get namespace and delimiter
             $this->set_env();
+
+            // trigger post-connect hook
+            $this->plugins->exec_hook('storage_connected', array(
+                'host' => $host, 'user' => $user, 'session' => $session
+            ));
+
             return true;
         }
         // write error log
@@ -1506,7 +1520,7 @@
             $folder = $this->folder;
         }
 
-        $plugin = rcube::get_instance()->plugins->exec_hook('imap_search_before', array(
+        $plugin = $this->plugins->exec_hook('imap_search_before', array(
             'folder'     => $folder,
             'search'     => $search,
             'charset'    => $charset,
@@ -2501,7 +2515,7 @@
             // increase messagecount of the target folder
             $this->set_messagecount($folder, 'ALL', 1);
 
-            rcube::get_instance()->plugins->exec_hook('message_saved', array(
+            $this->plugins->exec_hook('message_saved', array(
                     'folder'  => $folder,
                     'message' => $message,
                     'headers' => $headers,
@@ -2777,7 +2791,7 @@
         }
 
         // Give plugins a chance to provide a list of folders
-        $data = rcube::get_instance()->plugins->exec_hook('storage_folders',
+        $data = $this->plugins->exec_hook('storage_folders',
             array('root' => $root, 'name' => $name, 'filter' => $filter, 'mode' => 'LSUB'));
 
         if (isset($data['folders'])) {
@@ -2909,7 +2923,7 @@
         }
 
         // Give plugins a chance to provide a list of folders
-        $data = rcube::get_instance()->plugins->exec_hook('storage_folders',
+        $data = $this->plugins->exec_hook('storage_folders',
             array('root' => $root, 'name' => $name, 'filter' => $filter, 'mode' => 'LIST'));
 
         if (isset($data['folders'])) {

--
Gitblit v1.9.1