This repository has been archived by the owner on Apr 11, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
75 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ | |
* @author hydrian ([email protected]) | ||
* @copyright GPL2 | ||
* Requires php-ldap and PEAR Net::LDAP2 | ||
* @version 0.04 | ||
* @version 0.05 | ||
*/ | ||
|
||
/** | ||
|
@@ -14,13 +14,14 @@ | |
* define('LDAP_AUTH_SERVER_URI', 'ldaps://LDAPServerHostname:port/'); | ||
* define('LDAP_AUTH_USETLS', FALSE); // Enable TLS Support for ldaps:// | ||
* define('LDAP_AUTH_ALLOW_UNTRUSTED_CERT', TRUE); // Allows untrusted certificate | ||
* define('LDAP_AUTH_BINDDN', 'cn=serviceaccount,dc=example,dc=com'); | ||
* define('LDAP_AUTH_BINDPW', 'ServiceAccountsPassword'); | ||
* define('LDAP_AUTH_BASEDN', 'dc=example,dc=com'); | ||
* define('LDAP_AUTH_ANONYMOUSBEFOREBIND', FALSE); | ||
* // ??? will be replaced with the entered username(escaped) at login | ||
* define('LDAP_AUTH_SEARCHFILTER', '(&(objectClass=person)(uid=???))'); | ||
* // Optional configuration | ||
* define('LDAP_AUTH_BINDDN', 'cn=serviceaccount,dc=example,dc=com'); | ||
* define('LDAP_AUTH_BINDPW', 'ServiceAccountsPassword'); | ||
* define('LDAP_AUTH_LOGIN_ATTRIB', 'uid'); | ||
* | ||
* define('LDAP_AUTH_SCHEMA_CACHE_ENABLE', TRUE); | ||
* Enables Schema Caching (Recommended) | ||
|
@@ -71,35 +72,64 @@ function init($host) { | |
} | ||
|
||
private function _log($msg, $level = E_USER_WARNING) { | ||
trigger_error($msg, $level); | ||
$loggerFunction = Logger::get(); | ||
if (is_object($loggerFunction)) { | ||
$loggerFunction->log_error($level, $msg); | ||
} else { | ||
trigger_error($msg, $level); | ||
} | ||
|
||
} | ||
|
||
/** | ||
* Logs login attempts | ||
* @param string $username Given username that attempts to log in to TTRSS | ||
* @param string $result "Logging message for type of result. (Success / Fail)" | ||
* @return boolean | ||
* @deprecated | ||
* | ||
* Now that _log support syslog and log levels and graceful fallback user. | ||
*/ | ||
private function _logAttempt($username, $result) { | ||
|
||
|
||
return trigger_error('TT-RSS Login Attempt: user '.(string)$username. | ||
' attempted to login ('.(string)$result.') from '.(string)$ip, | ||
E_USER_NOTICE | ||
); | ||
} | ||
|
||
/** | ||
* Finds client's IP address | ||
* @return string | ||
*/ | ||
private function _getClientIP () { | ||
if (!empty($_SERVER['HTTP_CLIENT_IP'])) { | ||
//check ip from share internet | ||
|
||
$ip=$_SERVER['HTTP_CLIENT_IP']; | ||
} | ||
elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { | ||
//to check ip is pass from proxy | ||
//to check ip is pass from proxy | ||
$ip=$_SERVER['HTTP_X_FORWARDED_FOR']; | ||
} | ||
else { | ||
$ip=$_SERVER['REMOTE_ADDR']; | ||
} | ||
|
||
return trigger_error('TT-RSS Login Attempt: user '.(string)$username. | ||
' attempted to login ('.(string)$result.') from '.(string)$ip, | ||
E_USER_NOTICE | ||
); | ||
return $ip; | ||
} | ||
|
||
/** | ||
* Main Authentication method | ||
* Required for plugin interface | ||
* @param unknown $login User's username | ||
* @param unknown $password User's password | ||
* @return boolean | ||
*/ | ||
function authenticate($login, $password) { | ||
$this->logClass = Logger::get(); | ||
if ($login && $password) { | ||
|
||
|
||
|
||
if (!function_exists('ldap_connect')) { | ||
trigger_error('auth_ldap requires PHP\'s PECL LDAP package installed.'); | ||
return FALSE; | ||
|
@@ -115,6 +145,9 @@ function authenticate($login, $password) { | |
$anonymousBeforeBind=defined('LDAP_AUTH_ANONYMOUSBEFOREBIND') ? | ||
LDAP_AUTH_ANONYMOUSBEFOREBIND : FALSE; | ||
|
||
$bindDN = defined('LDAP_AUTH_BINDDN') ? LDAP_AUTH_BINDDN : null; | ||
$bindPW = defined('LDAP_AUTH_BINDPW') ? LDAP_AUTH_BINDPW : null; | ||
|
||
$parsedURI=parse_url(LDAP_AUTH_SERVER_URI); | ||
if ($parsedURI === FALSE) { | ||
$this->_log('Could not parse LDAP_AUTH_SERVER_URI in config.php'); | ||
|
@@ -127,8 +160,8 @@ function authenticate($login, $password) { | |
); | ||
|
||
if (!$anonymousBeforeBind) { | ||
$ldapConnParams['binddn']= LDAP_AUTH_BINDDN; | ||
$ldapConnParams['bindpw']= LDAP_AUTH_BINDPW; | ||
$ldapConnParams['binddn']= $bindDN; | ||
$ldapConnParams['bindpw']= $bindPW; | ||
} | ||
$ldapConnParams['starttls']= defined('LDAP_AUTH_USETLS') ? | ||
LDAP_AUTH_USETLS : FALSE; | ||
|
@@ -152,15 +185,21 @@ function authenticate($login, $password) { | |
} | ||
$this->ldapObj = new Net_LDAP2; | ||
$ldapConn=$this->ldapObj->connect($ldapConnParams); | ||
if (Net_LDAP2::isError($ldapConn)) { | ||
$this->_log('Could not connect to LDAP Server: '.$ldapConn->getMessage()); | ||
if ($this->ldapObj->isError($ldapConn)) { | ||
$this->_log( | ||
'Could not connect to LDAP Server: '.$ldapConn->getMessage(), | ||
E_USER_ERROR | ||
); | ||
return FALSE; | ||
} | ||
// Bind with service account if orignal connexion was anonymous | ||
if ($anonymousBeforeBind) { | ||
$binding=$this->ldapObj->bind(LDAP_AUTH_BINDDN, LDAP_AUTH_BINDPW); | ||
$binding=$this->ldapObj->bind($bindDN, $bindPW); | ||
if ($this->ldapObj->isError($binding)) { | ||
$this->_log('Cound not bind service account: '.$binding->getMessage()); | ||
$this->_log( | ||
'Cound not bind service account: '.$binding->getMessage(), | ||
E_USER_ERROR | ||
); | ||
return FALSE; | ||
} | ||
} | ||
|
@@ -196,30 +235,35 @@ function authenticate($login, $password) { | |
} | ||
|
||
//Searching for user | ||
$completedSearchFiler=str_replace('???',$login,LDAP_AUTH_SEARCHFILTER); | ||
$filterObj=Net_LDAP2_Filter::parse($completedSearchFiler); | ||
$completedSearchFilter=str_replace('???',$login,LDAP_AUTH_SEARCHFILTER); | ||
$filterObj=Net_LDAP2_Filter::parse($completedSearchFilter); | ||
if (PEAR::isError($filterObj)) { | ||
$this->_log( 'Could not parse LDAP Search filter', E_USER_ERROR); | ||
return FALSE; | ||
} | ||
$searchResults=$this->ldapObj->search(LDAP_AUTH_BASEDN, $filterObj); | ||
if ($this->ldapObj->isError($searchResults)) { | ||
$this->_log('LDAP Search Failed: '.$searchResults->getMessage()); | ||
return FALSE; | ||
} elseif ($searchResults->count() === 0) { | ||
if ($logAttempts) $this->_logAttempt((string)$login, 'Unknown User'); | ||
$this->_log((string)$login, 'Unknown User', E_USER_NOTICE); | ||
return FALSE; | ||
} elseif ($searchResults->count() > 1 ) { | ||
$this->_log('Multiple DNs found for username '.$login); | ||
$this->_log('Multiple DNs found for username '.$login, E_USER_WARNING); | ||
return FALSE; | ||
} | ||
//Getting user's DN from search | ||
$userEntry=$searchResults->shiftEntry(); | ||
$userDN=$userEntry->dn(); | ||
//Binding with user's DN. | ||
$loginAttempt=$this->ldapObj->bind($userDN, $password); | ||
$this->_log('Try binding with user\'s DN: '.$userDN); | ||
$loginAttempt=$ldapConn->bind($userDN, $password); | ||
$ldapConn->disconnect(); | ||
if ($loginAttempt === TRUE) { | ||
if ($logAttempts) $this->_logAttempt((string)$login, 'successful'); | ||
$this->_log('User: '.(string)$login.' authentication successful', E_USER_NOTICE); | ||
return $this->base->auto_create_user($login); | ||
} elseif ($loginAttempt->getCode() == 49) { | ||
if ($logAttempts) $this->_logAttempt((string)$login, 'bad password'); | ||
$this->_log('User: '.(string)$login.' authentication failed', E_USER_NOTICE); | ||
return FALSE; | ||
} else { | ||
$this->_log('Unknown Error: Code: '.$loginAttempt->getCode(). | ||
|
@@ -230,6 +274,11 @@ function authenticate($login, $password) { | |
return false; | ||
} | ||
|
||
/** | ||
* Returns plugin API version | ||
* Required for plugin interface | ||
* @return number | ||
*/ | ||
function api_version() { | ||
return 2; | ||
} | ||
|