Better way of handling encryption key in imap client lib
authorMichael M Slusarz <slusarz@curecanti.org>
Tue, 7 Sep 2010 06:30:36 +0000 (00:30 -0600)
committerMichael M Slusarz <slusarz@curecanti.org>
Tue, 7 Sep 2010 07:12:49 +0000 (01:12 -0600)
This method doesn't require us to explicitly set encryption key when
unserializing the object.

framework/Imap_Client/lib/Horde/Imap/Client.php
framework/Imap_Client/lib/Horde/Imap/Client/Base.php
imp/lib/Imap.php

index 2e53a49..2e1706a 100644 (file)
@@ -136,7 +136,6 @@ class Horde_Imap_Client
      *   lifetime - [OPTIONAL] (integer) The lifetime of the cache data (in
      *              seconds).
      *   slicesize - [OPTIONAL] (integer) The slicesize to use.
-     *
      * capability_ignore - (array) A list of IMAP capabilites to ignore, even
      *                     if they are supported on the server.
      *                     DEFAULT: No supported capabilities are ignored
@@ -148,7 +147,9 @@ class Horde_Imap_Client
      *         identified. The value can be any PHP supported wrapper that can
      *         be opened via fopen().
      *         DEFAULT: No debug output
-     * encryptKey - (string) The key used to encrypt the password.
+     * encryptKey - (array) A callback to a function that returns the key
+     *              used to encrypt the password. This function MUST be
+     *              static.
      *              DEFAULT: No encryption
      * hostspec - (string) The hostname or IP address of the server.
      *            DEFAULT: 'localhost'
index bf61c7f..c1d0972 100644 (file)
@@ -117,15 +117,9 @@ abstract class Horde_Imap_Client_Base implements Serializable
             throw new InvalidArgumentException('Horde_Imap_Client requires a username and password.');
         }
 
-        // Encrypt password.
-        if ($params['encryptKey']) {
-            $secret = new Horde_Secret();
-            $params['password'] = $secret->write($params['encryptKey'], $params['password']);
-            $params['_passencrypt'] = true;
-        }
-
         // Default values.
         $params = array_merge(array(
+            'encryptKey' => null,
             'hostspec' => 'localhost',
             'port' => ((isset($params['secure']) && ($params['secure'] == 'ssl')) ? 993 : 143),
             'secure' => false,
@@ -149,10 +143,32 @@ abstract class Horde_Imap_Client_Base implements Serializable
 
         $this->_params = $params;
 
+        // Encrypt password.
+        if (!is_null($this->_params['encryptKey'])) {
+            $secret = new Horde_Secret();
+            $this->_params['password'] = $secret->write($this->_getEncryptKey(), $this->_params['password']);
+            $this->_params['_passencrypt'] = true;
+        }
+
         $this->_init();
     }
 
     /**
+     * Get encryption key.
+     *
+     * @return string  The encryption key.
+     * @throws Horde_Imap_Client_Exception
+     */
+    protected function _getEncryptKey()
+    {
+        if (is_callable($this->_params['encryptKey'])) {
+            return call_user_func($this->_params['encryptKey']);
+        }
+
+        throw new Horde_Imap_Client_Exception('encryptKey parameter is not a valid callback.');
+    }
+
+    /**
      * Do initialization tasks.
      */
     protected function _init()
@@ -194,9 +210,6 @@ abstract class Horde_Imap_Client_Base implements Serializable
             $store[$val] = $this->$val;
         }
 
-        /* Don't store password encryption key. */
-        unset($store['_params']['encryptKey']);
-
         return serialize($store);
     }
 
@@ -266,17 +279,6 @@ abstract class Horde_Imap_Client_Base implements Serializable
     }
 
     /**
-     * Sets the password encryption key. Required after calling unserialize()
-     * on this object if the password is encrypted.
-     *
-     * @param string $key  The encryption key.
-     */
-    public function setEncryptionKey($key)
-    {
-        $this->_params['encryptKey'] = $key;
-    }
-
-    /**
      * Returns a value from the internal params array.
      *
      * @param string $key  The param key.
@@ -287,12 +289,12 @@ abstract class Horde_Imap_Client_Base implements Serializable
     {
         /* Passwords may be stored encrypted. */
         if (($key == 'password') && !empty($this->_params['_passencrypt'])) {
-            if (!isset($this->_params['encryptKey'])) {
+            try {
+                $secret = new Horde_Secret();
+                return $secret->read($this->_getEncryptKey(), $this->_params['password']);
+            } catch (Horde_Imap_Client_Exception $e) {
                 return null;
             }
-
-            $secret = new Horde_Secret();
-            return $secret->read($this->_params['encryptKey'], $this->_params['password']);
         }
 
         return isset($this->_params[$key])
index 5b3724e..580a2e3 100644 (file)
@@ -100,7 +100,6 @@ class IMP_Imap
 
         try {
             $this->ob = @unserialize($_SESSION['imp']['imap_ob'][$this->_serverkey]);
-            $this->ob->setEncryptionKey($GLOBALS['injector']->getInstance('Horde_Secret')->getKey('imp'));
         } catch (Exception $e) {
             /* Throw fatal error here - should never reach here and if we
              * do, we are out of luck. */
@@ -139,7 +138,7 @@ class IMP_Imap
             'capability_ignore' => empty($server['capability_ignore']) ? array() : $server['capability_ignore'],
             'comparator' => empty($server['comparator']) ? false : $server['comparator'],
             'debug' => isset($server['debug']) ? $server['debug'] : null,
-            'encryptKey' => $GLOBALS['injector']->getInstance('Horde_Secret')->getKey('imp'),
+            'encryptKey' => array(__CLASS__, 'getEncryptKey'),
             'hostspec' => isset($server['hostspec']) ? $server['hostspec'] : null,
             'id' => empty($server['id']) ? false : $server['id'],
             'lang' => empty($server['lang']) ? false : $server['lang'],
@@ -464,5 +463,11 @@ class IMP_Imap
         return $servers[$server];
     }
 
+    /* Callback functions used in Horde_Imap_Client_Base. */
+
+    public function getEncryptKey()
+    {
+        return $GLOBALS['injector']->getInstance('Horde_Secret')->getKey('imp');
+    }
 
 }