[ingo] Requesting comment on a patch to enable "proxy" authentication in Ingo

Etienne Goyer etienne.goyer at linuxquebec.com
Wed Aug 6 13:23:24 PDT 2003


Sorry to bounce that mail from the past.  I would really like some
feedback about the possibility of having this change integrated in Ingo.
Just knowing if interest is there would be enough at the moment, as a 
project of mine depend on the feature added by this patch.

Thanks for your feedback !


On Mon, Jul 21, 2003 at 03:14:59PM -0400, Etienne Goyer wrote:
> Hi list,
> 
> I have a patch here that implement so-called "proxy" authentication with
> Ingo.  For those unfamiliar with the concept, protocol that use SASL for
> authentication and authorization have the possibility (not necessarily
> implemented) to allow one user to proxy for another.  This could be used,
> for example, by an administrative user to perform routine maintenance on
> behalf of a user, etc.
> 
> Protocol that can use various SASL method, such as IMAP and
> Managesieve, can pass both an authentication id (shortened to authcid)
> and an authorization id (shortened to authzid) to the SASL mechanism.
> If the authcid and the authzid differ, the mechanism is supposed to
> verify the authcid and the password to authenticate.  If authcid is
> permitted to act on behalf of authzid, authorization is granted. I am 
> not an expert on SASL myself so I may have gotten some of the lingo
> wrong, but this is basically how it work. 
> 
> To implement this feature, change had to be made to the Net_Sieve
> module.  I submit a patch to the maintainer of this module this morning;
> hopefully, it will be accepted.
> 
> One of the change made to Ingo to make this work is quite intrusive.
> Since not every backend type support "proxy" authentication, I had to
> move the credentials fetching from lib/Ingo.php to the specific backend
> drivers (lib/Driver/*).  This make more sense to me, but create some
> code duplication for adding realm to the username.  Overall, I think it
> is worth it since future backend driver may have different requirement
> in this regard.
> 
> My patch include change to both the timsieved and vfs driver, but I
> tested only the timsieved driver.  I cannot foresee any problem vfs, but
> this will have to be tested eventually.
> 
> Here is included my patchs for both Ingo and Net_Sieve.  Since
> integration of the required part in Net_Sieve is not yet complete, it's
> too soon to integrate my changes in Ingo but I would like feedback about
> suitability of them.  These change are critical to me and I would be 
> willing to do more work if they are not acceptable for some reason in
> their current state. I am eagerly awaiting comment from those wielding 
> the mighty commit bit  :) 
> 
> Regards,
> 
> -- 
> Etienne Goyer                    Linux Québec Technologies Inc.
> http://www.LinuxQuebec.com       etienne.goyer at linuxquebec.com

> diff -ur ingo.orig/config/backends.php.dist ingo/config/backends.php.dist
> --- ingo.orig/config/backends.php.dist	Mon Jul 21 10:40:58 2003
> +++ ingo/config/backends.php.dist	Mon Jul 21 10:46:12 2003
> @@ -44,6 +44,10 @@
>          'hostspec' => 'mail.example.com',
>          // Login type of the server
>          'logintype' => 'PLAIN',
> +        // Authentication id (username by default)
> +        //'authcid' => 'cyrus',
> +        // Password for authcid (if different than user's)
> +        //'password' = '',
>          // Port number of the timsieved server
>          'port' => 2000,
>          // Name of the sieve script
> diff -ur ingo.orig/lib/Driver/timsieved.php ingo/lib/Driver/timsieved.php
> --- ingo.orig/lib/Driver/timsieved.php	Mon Jul 21 10:01:32 2003
> +++ ingo/lib/Driver/timsieved.php	Mon Jul 21 10:57:38 2003
> @@ -38,19 +38,42 @@
>       * Sets a script running on the backend.
>       *
>       * @param string $script    The sieve script.
> -     * @param string $username  The backend username.
> -     * @param string $password  The backend password.
>       *
>       * @return mixed  True on success.
>       *                Returns PEAR_Error on error.
>       */
> -    function setScriptActive($script, $username, $password)
> +    function setScriptActive($script)
>      {
> -        $sieve = &new Net_Sieve($username,
> +	$authzid = Auth::getAuth();
> +        $backend = Ingo::getBackend();
> +        if (is_a($backend, 'PEAR_Error')) {
> +            $notification->push($backend->getMessage(), 'horde.error');
> +            return false;
> +        } else {
> +            if (($backend['hordeauth'] == 'user') &&
> +                (($pos = strpos($authzid, '@')) !== false)) {
> +                $authzid = substr($authzid, 0, $pos);
> +            }
> +        }
> +
> +	if (isset($this->_params['authcid'])) {
> +            if (isset($this->_params['password'])) {
> +                $authcid = $this->_params['authcid'];
> +                $password = $this->_params['password'];
> +            } else {
> +                return PEAR::raiseError(_(sprintf("No password for authentication id had been specified.")));
> +            }
> +	} else {
> +            $authcid = $authzid;
> +	    $password = Auth::getCredential('password');
> +	}
> +
> +        $sieve = &new Net_Sieve($authzid,
>                                  $password,
>                                  $this->_params['hostspec'],
>                                  $this->_params['port'],
> -                                $this->_params['logintype']);
> +                                $this->_params['logintype'],
> +				$authcid);
>  
>          if (is_a($sieve, 'PEAR_Error')) {
>              return $sieve;
> diff -ur ingo.orig/lib/Driver/vfs.php ingo/lib/Driver/vfs.php
> --- ingo.orig/lib/Driver/vfs.php	Mon Jul 21 10:30:35 2003
> +++ ingo/lib/Driver/vfs.php	Mon Jul 21 10:55:26 2003
> @@ -41,13 +41,24 @@
>       *
>       * @return mixed  True on success, or PEAR_Error on failure.
>       */
> -    function setScriptActive($script, $username, $password)
> +    function setScriptActive($script)
>      {
>          if ($this->_params['vfstype'] != 'ftp') {
>              return PEAR::raiseError(_(sprintf("VFS type '%s' not yet implemented.", $this->_params['vfstype'])));
>          }
> -        $this->_params['username'] = $username;
> -        $this->_params['password'] = $password;
> +
> +        $this->_params['username'] = Auth::getAuth;
> +        $this->_params['password'] = Auth::getCredentials('password');
> +        $backend = Ingo::getBackend();
> +        if (is_a($backend, 'PEAR_Error')) {
> +            $notification->push($backend->getMessage(), 'horde.error');
> +            return false;
> +        } else {        
> +            if (($backend['hordeauth'] == 'user') &&
> +                (($pos = strpos($this->_params['username'], '@')) !== false)) {
> +                $this->_params['username'] = substr($this->_params['username'], 0, $pos);
> +            }
> +        }
>  
>          require_once HORDE_BASE . '/lib/VFS.php';
>          $vfs = &VFS::singleton($this->_params['vfstype'], $this->_params);
> diff -ur ingo.orig/lib/Ingo.php ingo/lib/Ingo.php
> --- ingo.orig/lib/Ingo.php	Mon Jul 21 10:39:20 2003
> +++ ingo/lib/Ingo.php	Mon Jul 21 10:40:03 2003
> @@ -75,18 +75,12 @@
>              return false;
>          }
>  
> -        $uid = Auth::getAuth();
> -        if (($backend['hordeauth'] == 'user') &&
> -            (($pos = strpos($uid, '@')) !== false)) {
> -            $uid = substr($uid, 0, $pos);
> -        }
> -
>          require_once INGO_BASE . '/lib/Driver.php';
>          if (empty($backend['driver'])) {
>              $notification->push(sprintf(_("No '%s' element found in backend configuration."), 'driver'), 'horde.error');
>          } else {
>              $driver = &Ingo_Driver::singleton($backend['driver'], $backend['params']);
> -            $res = $driver->setScriptActive($script, $uid, Auth::getCredential('password'));
> +            $res = $driver->setScriptActive($script);
>              if (is_a($res, 'PEAR_Error')) {
>                  $notification->push(sprintf(_("There was an error activating this script. The driver said: %s"), $res->getMessage()), 'horde.error');
>              } elseif ($res === true) {

> --- Sieve.php.orig	Mon Jul 21 09:26:01 2003
> +++ Sieve.php	Mon Jul 21 11:20:46 2003
> @@ -104,20 +104,24 @@
>      * using the getError() method.
>      *
>      * @access public
> -    * @param  string $user      Login username
> -    * @param  string $pass      Login password
> +    * @param  string $authzid   Authorization id
> +    * @param  string $pass      Password
>      * @param  string $host      Hostname of server
>      * @param  string $port      Port of server
>      * @param  string $logintype Type of login to perform
> +    * @param  string $authcid   Authentication id (if any, default to authzid)
>      */
> -    function Net_Sieve($user, $pass, $host = 'localhost', $port = 2000, $logintype = 'PLAIN')
> +    function Net_Sieve($authzid, $pass, $host = 'localhost', $port = 2000, $logintype = 'PLAIN', $authcid)
>      {
>          $this->_state = NET_SIEVE_STATE_DISCONNECTED;
>  
> -        $this->_data['user'] = $user;
> -        $this->_data['pass'] = $pass;
> -        $this->_data['host'] = $host;
> -        $this->_data['port'] = $port;
> +        if (!isset($authcid)) { $authcid = $authzid; }
> +
> +        $this->_data['authzid'] = $authzid;
> +        $this->_data['pass']    = $pass;
> +        $this->_data['host']    = $host;
> +        $this->_data['port']    = $port;
> +        $this->_data['authcid'] = $authcid;
>          $this->_sock = &new Net_Socket();
>  
>          if (PEAR::isError($res = $this->_connect($host, $port))) {
> @@ -125,7 +129,7 @@
>              return;
>          }
>  
> -        if (PEAR::isError($res = $this->_login($user, $pass, $logintype))) {
> +        if (PEAR::isError($res = $this->_login($authzid, $pass, $logintype, $authcid))) {
>              $this->_error = $res;
>          }
>      }
> @@ -266,17 +270,18 @@
>      * Logs into server.
>      *
>      * @access private
> -    * @param  string $user      Login username
> -    * @param  string $pass      Login password
> +    * @param  string $authzid   Authorization id
> +    * @param  string $pass      Password
>      * @param  string $logintype Type of login method to use
> +    * @param  string $authcid   Authentication id (if any)
>      * @return mixed             True on success, PEAR_Error otherwise
>      */
> -    function _login($user, $pass, $logintype = 'PLAIN')
> +    function _login($authzid, $pass, $logintype = 'PLAIN', $authcid)
>      {
>          if (NET_SIEVE_STATE_AUTHORISATION == $this->_state) {
>  
>              if ($logintype == 'PLAIN' AND in_array('PLAIN', $this->_capability['sasl'])) {
> -                $this->_sendCmd(sprintf('AUTHENTICATE "PLAIN" "%s"', base64_encode(chr(0) . $user . chr(0) . $pass)));
> +                $this->_sendCmd(sprintf('AUTHENTICATE "PLAIN" "%s"', base64_encode($authzid . chr(0) . $authcid . chr(0) . $pass)));
>  
>              } elseif ($logintype == 'PLAIN' AND in_array('LOGIN', $this->_capability['sasl'])) {
>                  $this->_sendCmd('AUTHENTICATE "LOGIN"');
> @@ -532,4 +537,4 @@
>          }
>      }
>  }
> -?>
> \ No newline at end of file
> +?>

> -- 
> Ingo mailing list
> Frequently Asked Questions: http://horde.org/faq/
> To unsubscribe, mail: ingo-unsubscribe at lists.horde.org


-- 
Etienne Goyer                    Linux Québec Technologies Inc.
http://www.LinuxQuebec.com       etienne.goyer at linuxquebec.com


More information about the ingo mailing list