1<?php
2/**
3 * Copyright 2004-2017 Horde LLC (http://www.horde.org/)
4 *
5 * See the enclosed file COPYING for license information (LGPL). If you did
6 * not receive this file, see http://www.horde.org/licenses/lgpl21.
7 *
8 * @author   Jon Parise <jon@horde.org>
9 * @category Horde
10 * @license  http://www.horde.org/licenses/lgpl21 LGPL-2.1
11 * @package  Auth
12 */
13
14/**
15 * The Horde_Auth_Peclsasl:: class provides a SASL-based implementation of the
16 * Horde authentication system.
17 *
18 * SASL is the Simple Authentication and Security Layer (as defined by RFC
19 * 2222). It provides a system for adding plugable authenticating support to
20 * connection-based protocols.
21 *
22 * This driver relies on the PECL sasl package:
23 *   http://pecl.php.net/package/sasl
24 *
25 * @author    Jon Parise <jon@horde.org>
26 * @category  Horde
27 * @copyright 2004-2017 Horde LLC
28 * @license   http://www.horde.org/licenses/lgpl21 LGPL-2.1
29 * @package   Auth
30 */
31class Horde_Auth_Peclsasl extends Horde_Auth_Base
32{
33    /**
34     * Constructor.
35     *
36     * @param array $params  Optional parameters:
37     * <pre>
38     * 'app' - (string) The name of the authenticating application.
39     *         DEFAULT: horde
40     * 'service' - (string) The name of the SASL service to use when
41     *             authenticating.
42     *             DEFAULT: php
43     * </pre>
44     *
45     * @throws Horde_Auth_Exception
46     */
47    public function __construct(array $params = array())
48    {
49        if (!Horde_Util::extensionExists('sasl')) {
50            throw new Horde_Auth_Exception('Horde_Auth_Peclsasl:: requires the sasl PECL extension to be loaded.');
51        }
52
53        $params = array_merge(array(
54            'app' => 'horde',
55            'service' => 'php'
56        ), $params);
57
58        parent::__construct($params);
59
60        sasl_server_init($this->_params['app']);
61    }
62
63    /**
64     * Find out if a set of login credentials are valid.
65     *
66     * @param string $userId      The userId to check.
67     * @param array $credentials  An array of login credentials.
68     *
69     * @throws Horde_Auth_Exception
70     */
71    protected function _authenticate($userId, $credentials)
72    {
73        if (empty($credentials['password'])) {
74            throw new Horde_Auth_Exception('', Horde_Auth::REASON_BADLOGIN);
75        }
76
77        $conn = sasl_server_new($this->_params['service']);
78        if (!is_resource($conn)) {
79            throw new Horde_Auth_Exception('Failed to create new SASL connection.');
80        }
81
82        if (!sasl_checkpass($conn, $userId, $credentials['password'])) {
83            throw new Horde_Auth_Exception(sasl_errdetail($conn));
84        }
85    }
86
87}
88