Automated build for v0.01
This commit is contained in:
		
						commit
						791b998489
					
				
					 2771 changed files with 222096 additions and 0 deletions
				
			
		
							
								
								
									
										403
									
								
								plugins/auth_ldap/init.php
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										403
									
								
								plugins/auth_ldap/init.php
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,403 @@ | |||
| <?php | ||||
| 
 | ||||
| /** | ||||
|  * Tiny Tiny RSS plugin for LDAP authentication  | ||||
|  * @author tsmgeek (tsmgeek@gmail.com) | ||||
|  * @author hydrian (ben.tyger@tygerclan.net) | ||||
|  * @copyright GPL2 | ||||
|  *  Requires php-ldap  | ||||
|  * @version 2.00 | ||||
|  */ | ||||
| /** | ||||
|  *  Configuration | ||||
|  *  Put the following options in config.php and customize them for your environment | ||||
|  * | ||||
|  * 	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_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_LOG_ATTEMPTS', FALSE); | ||||
|  *    Enable Debug Logging | ||||
|  *  define('LDAP_AUTH_DEBUG', FALSE); | ||||
|  *     | ||||
|  *     | ||||
|  *     | ||||
|  */ | ||||
| 
 | ||||
| /** | ||||
|  * 	Notes - | ||||
|  * 	LDAP search does not support follow ldap referals. Referals are disabled to  | ||||
|  * 	allow proper login.  This is particular to Active Directory.   | ||||
|  *  | ||||
|  * 	Also group membership can be supported if the user object contains the | ||||
|  * 	the group membership via attributes.  The following LDAP servers can  | ||||
|  * 	support this.    | ||||
|  * 	 * Active Directory | ||||
|  *   * OpenLDAP support with MemberOf Overlay | ||||
|  * | ||||
|  */ | ||||
| class Auth_Ldap extends Plugin implements IAuthModule { | ||||
| 
 | ||||
|     private $link; | ||||
|     private $host; | ||||
|     private $base; | ||||
|     private $logClass; | ||||
|     private $ldapObj = NULL; | ||||
|     private $_debugMode; | ||||
|     private $_serviceBindDN; | ||||
|     private $_serviceBindPass; | ||||
|     private $_baseDN; | ||||
|     private $_useTLS; | ||||
|     private $_host; | ||||
|     private $_port; | ||||
|     private $_scheme; | ||||
|     private $_schemaCacheEnabled; | ||||
|     private $_anonBeforeBind; | ||||
|     private $_allowUntrustedCerts; | ||||
|     private $_ldapLoginAttrib; | ||||
| 
 | ||||
|     function about() { | ||||
|         return array(0.05, | ||||
|             "Authenticates against an LDAP server (configured in config.php)", | ||||
|             "hydrian", | ||||
|             true); | ||||
|     } | ||||
| 
 | ||||
|     function init($host) { | ||||
|         $this->link = $host->get_link(); | ||||
|         $this->host = $host; | ||||
|         $this->base = new Auth_Base($this->link); | ||||
| 
 | ||||
|         $host->add_hook($host::HOOK_AUTH_USER, $this); | ||||
|     } | ||||
| 
 | ||||
|     private function _log($msg, $level = E_USER_NOTICE, $file = '', $line = 0, $context = '') { | ||||
|         $loggerFunction = Logger::get(); | ||||
|         if (is_object($loggerFunction)) { | ||||
|             $loggerFunction->log_error($level, $msg, $file, $line, $context); | ||||
|         } 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 | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param string $subject The subject string | ||||
|      * @param string $ignore Set of characters to leave untouched | ||||
|      * @param int $flags Any combination of LDAP_ESCAPE_* flags to indicate the | ||||
|      *                   set(s) of characters to escape. | ||||
|      * @return string | ||||
|      **/ | ||||
|     function ldap_escape($subject, $ignore = '', $flags = 0) | ||||
|     { | ||||
|         if (!function_exists('ldap_escape')) { | ||||
|             define('LDAP_ESCAPE_FILTER', 0x01); | ||||
|             define('LDAP_ESCAPE_DN',     0x02); | ||||
|              | ||||
|             static $charMaps = array( | ||||
|                 LDAP_ESCAPE_FILTER => array('\\', '*', '(', ')', "\x00"), | ||||
|                 LDAP_ESCAPE_DN     => array('\\', ',', '=', '+', '<', '>', ';', '"', '#'), | ||||
|             ); | ||||
| 
 | ||||
|             // Pre-process the char maps on first call
 | ||||
|             if (!isset($charMaps[0])) { | ||||
|                 $charMaps[0] = array(); | ||||
|                 for ($i = 0; $i < 256; $i++) { | ||||
|                     $charMaps[0][chr($i)] = sprintf('\\%02x', $i);; | ||||
|                 } | ||||
| 
 | ||||
|                 for ($i = 0, $l = count($charMaps[LDAP_ESCAPE_FILTER]); $i < $l; $i++) { | ||||
|                     $chr = $charMaps[LDAP_ESCAPE_FILTER][$i]; | ||||
|                     unset($charMaps[LDAP_ESCAPE_FILTER][$i]); | ||||
|                     $charMaps[LDAP_ESCAPE_FILTER][$chr] = $charMaps[0][$chr]; | ||||
|                 } | ||||
| 
 | ||||
|                 for ($i = 0, $l = count($charMaps[LDAP_ESCAPE_DN]); $i < $l; $i++) { | ||||
|                     $chr = $charMaps[LDAP_ESCAPE_DN][$i]; | ||||
|                     unset($charMaps[LDAP_ESCAPE_DN][$i]); | ||||
|                     $charMaps[LDAP_ESCAPE_DN][$chr] = $charMaps[0][$chr]; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             // Create the base char map to escape
 | ||||
|             $flags = (int)$flags; | ||||
|             $charMap = array(); | ||||
|             if ($flags & LDAP_ESCAPE_FILTER) { | ||||
|                 $charMap += $charMaps[LDAP_ESCAPE_FILTER]; | ||||
|             } | ||||
|             if ($flags & LDAP_ESCAPE_DN) { | ||||
|                 $charMap += $charMaps[LDAP_ESCAPE_DN]; | ||||
|             } | ||||
|             if (!$charMap) { | ||||
|                 $charMap = $charMaps[0]; | ||||
|             } | ||||
| 
 | ||||
|             // Remove any chars to ignore from the list
 | ||||
|             $ignore = (string)$ignore; | ||||
|             for ($i = 0, $l = strlen($ignore); $i < $l; $i++) { | ||||
|                 unset($charMap[$ignore[$i]]); | ||||
|             } | ||||
| 
 | ||||
|             // Do the main replacement
 | ||||
|             $result = strtr($subject, $charMap); | ||||
| 
 | ||||
|             // Encode leading/trailing spaces if LDAP_ESCAPE_DN is passed
 | ||||
|             if ($flags & LDAP_ESCAPE_DN) { | ||||
|                 if ($result[0] === ' ') { | ||||
|                     $result = '\\20' . substr($result, 1); | ||||
|                 } | ||||
|                 if ($result[strlen($result) - 1] === ' ') { | ||||
|                     $result = substr($result, 0, -1) . '\\20'; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             return $result; | ||||
|         }else{ | ||||
|             return ldap_escape($subject, $ignore, $flags); | ||||
|         }     | ||||
|     } | ||||
|          | ||||
|     /** | ||||
|      * 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
 | ||||
|             $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; | ||||
|         } else { | ||||
|             $ip = $_SERVER['REMOTE_ADDR']; | ||||
|         } | ||||
| 
 | ||||
|         return $ip; | ||||
|     } | ||||
| 
 | ||||
|     private function _getBindDNWord() { | ||||
|         return (strlen($this->_serviceBindDN) > 0 ) ? $this->_serviceBindDN : 'anonymous DN'; | ||||
|     } | ||||
| 
 | ||||
|     private function _getTempDir() { | ||||
|         if (!sys_get_temp_dir()) { | ||||
|             $tmpFile = tempnam(); | ||||
|             $tmpDir = dirname($tmpFile); | ||||
|             unlink($tmpFile); | ||||
|             unset($tmpFile); | ||||
|             return $tmpDir; | ||||
|         } else { | ||||
|             return sys_get_temp_dir(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 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) { | ||||
|         if ($login && $password) { | ||||
| 
 | ||||
|             if (!function_exists('ldap_connect')) { | ||||
|                 trigger_error('auth_ldap requires PHP\'s PECL LDAP package installed.'); | ||||
|                 return FALSE; | ||||
|             } | ||||
| 
 | ||||
|             //Loading configuration
 | ||||
|             $this->_debugMode = defined('LDAP_AUTH_DEBUG') ? | ||||
|                     LDAP_AUTH_DEBUG : FALSE; | ||||
| 
 | ||||
|             $this->_anonBeforeBind = defined('LDAP_AUTH_ANONYMOUSBEFOREBIND') ? | ||||
|                     LDAP_AUTH_ANONYMOUSBEFOREBIND : FALSE; | ||||
| 
 | ||||
|             $this->_serviceBindDN = defined('LDAP_AUTH_BINDDN') ? LDAP_AUTH_BINDDN : null; | ||||
|             $this->_serviceBindPass = defined('LDAP_AUTH_BINDPW') ? LDAP_AUTH_BINDPW : null; | ||||
|             $this->_baseDN = defined('LDAP_AUTH_BASEDN') ? LDAP_AUTH_BASEDN : null; | ||||
|             if (!defined('LDAP_AUTH_BASEDN')) { | ||||
|                 $this->_log('LDAP_AUTH_BASEDN is required and not defined.', E_USER_ERROR); | ||||
|                 return FALSE; | ||||
|             } else { | ||||
|                 $this->_baseDN = LDAP_AUTH_BASEDN; | ||||
|             } | ||||
| 
 | ||||
|             $parsedURI = parse_url(LDAP_AUTH_SERVER_URI); | ||||
|             if ($parsedURI === FALSE) { | ||||
|                 $this->_log('Could not parse LDAP_AUTH_SERVER_URI in config.php', E_USER_ERROR); | ||||
|                 return FALSE; | ||||
|             } | ||||
|             $this->_host = $parsedURI['host']; | ||||
|             $this->_scheme = $parsedURI['scheme']; | ||||
| 
 | ||||
|             if (is_int($parsedURI['port'])) { | ||||
|                 $this->_port = $parsedURI['port']; | ||||
|             } else { | ||||
|                 $this->_port = ($this->_scheme === 'ldaps') ? 636 : 389; | ||||
|             } | ||||
| 
 | ||||
|             $this->_useTLS = defined('LDAP_AUTH_USETLS') ? LDAP_AUTH_USETLS : FALSE; | ||||
| 
 | ||||
|             $this->_logAttempts = defined('LDAP_AUTH_LOG_ATTEMPTS') ? | ||||
|                     LDAP_AUTH_LOG_ATTEMPTS : FALSE; | ||||
| 
 | ||||
|             $this->_ldapLoginAttrib = defined('LDAP_AUTH_LOGIN_ATTRIB') ? | ||||
|                     LDAP_AUTH_LOGIN_ATTRIB : null; | ||||
| 
 | ||||
| 
 | ||||
|             /** | ||||
|               Building LDAP connection | ||||
|              * */ | ||||
|             $ldapConnParams = array( | ||||
|                 'host' => $this->_host, | ||||
|                 'basedn' => $this->_baseDN, | ||||
|                 'port' => $this->_port, | ||||
|                 'starttls' => $this->_useTLS | ||||
|             ); | ||||
| 
 | ||||
|             if ($this->_debugMode) | ||||
|                 $this->_log(print_r($ldapConnParams, TRUE), E_USER_NOTICE); | ||||
|             $ldapConn = @ldap_connect($this->_host, $this->_port); | ||||
|             if ($ldapConn === FALSE) { | ||||
|                 $this->_log('Could not connect to LDAP Server: \'' . $this->_host . '\'', E_USER_ERROR); | ||||
|                 return false; | ||||
|             } | ||||
| 
 | ||||
|             /* Enable LDAP protocol version 3. */ | ||||
|             if (!@ldap_set_option($ldapConn, LDAP_OPT_PROTOCOL_VERSION, 3)) { | ||||
|                 $this->_log('Failed to set LDAP Protocol version (LDAP_OPT_PROTOCOL_VERSION) to 3', E_USER_ERROR); | ||||
|                 return false; | ||||
|             } | ||||
| 
 | ||||
|             /* Set referral option */ | ||||
|             if (!@ldap_set_option($ldapConn, LDAP_OPT_REFERRALS, FALSE)) { | ||||
|                 $this->_log('Failed to set LDAP Referrals (LDAP_OPT_REFERRALS) to TRUE', E_USER_ERROR); | ||||
|                 return false; | ||||
|             } | ||||
| 
 | ||||
|             if (stripos($this->_host, "ldaps:") === FALSE and $this->_useTLS) { | ||||
|                 if (!@ldap_start_tls($ldapConn)) { | ||||
|                     $this->_log('Unable to force TLS', E_USER_ERROR); | ||||
|                     return false; | ||||
|                 } | ||||
|             } | ||||
|             $error = @ldap_bind($ldapConn, $this->_serviceBindDN, $this->_serviceBindPass); | ||||
|             if ($error === FALSE) { | ||||
|                 $this->_log( | ||||
|                         'LDAP bind(): Bind failed (' . $error . ')with DN ' . $this->_serviceBindDN, E_USER_ERROR | ||||
|                 ); | ||||
|                 return FALSE; | ||||
|             } else { | ||||
|                 $this->_log( | ||||
|                         'Connected to LDAP Server: ' . LDAP_AUTH_SERVER_URI . ' with ' . $this->_getBindDNWord()); | ||||
|             } | ||||
| 
 | ||||
|             // Bind with service account if orignal connexion was anonymous
 | ||||
|             /* if (($this->_anonBeforeBind) && (strlen($this->_bindDN > 0))) { | ||||
|               $binding=$this->ldapObj->bind($this->_serviceBindDN, $this->_serviceBindPass); | ||||
|               if (get_class($binding) !== 'Net_LDAP2') { | ||||
|               $this->_log( | ||||
|               'Cound not bind service account: '.$binding->getMessage(),E_USER_ERROR); | ||||
|               return FALSE; | ||||
|               } else { | ||||
|               $this->_log('Bind with '.$this->_serviceBindDN.' successful.',E_USER_NOTICE); | ||||
|               } | ||||
|               } */ | ||||
| 
 | ||||
|             //Searching for user
 | ||||
|             $filterObj = str_replace('???', $this->ldap_escape($login), LDAP_AUTH_SEARCHFILTER); | ||||
|             $searchResults = @ldap_search($ldapConn, $this->_baseDN, $filterObj, array('displayName', 'title', 'sAMAccountName', $this->_ldapLoginAttrib), 0, 0, 0); | ||||
|             if ($searchResults === FALSE) { | ||||
|                 $this->_log('LDAP Search Failed on base \'' . $this->_baseDN . '\' for \'' . $filterObj . '\'', E_USER_ERROR); | ||||
|                 return FALSE; | ||||
|             } | ||||
|             $count = @ldap_count_entries($ldapConn, $searchResults); | ||||
|             if ($count === FALSE) { | ||||
|                  | ||||
|             } elseif ($count > 1) { | ||||
|                 $this->_log('Multiple DNs found for username ' . (string) $login, E_USER_WARNING); | ||||
|                 return FALSE; | ||||
|             } elseif ($count === 0) { | ||||
|                 $this->_log((string) $login, 'Unknown User', E_USER_NOTICE); | ||||
|                 return FALSE; | ||||
|             } | ||||
| 
 | ||||
|             //Getting user's DN from search
 | ||||
|             $userEntry = @ldap_first_entry($ldapConn, $searchResults); | ||||
|             if ($userEntry === FALSE) { | ||||
|                 $this->_log('LDAP search(): Unable to retrieve result after searching base \'' . $this->_baseDN . '\' for \'' . $filterObj . '\'', E_USER_WARNING); | ||||
|                 return false; | ||||
|             } | ||||
|             $userAttributes = @ldap_get_attributes($ldapConn, $userEntry); | ||||
|             $userDN = @ldap_get_dn($ldapConn, $userEntry); | ||||
|             if ($userDN == FALSE) { | ||||
|                 $this->_log('LDAP search(): Unable to get DN after searching base \'' . $this->_baseDN . '\' for \'' . $filterObj . '\'', E_USER_WARNING); | ||||
|                 return false; | ||||
|             } | ||||
|             //Binding with user's DN. 
 | ||||
|             if ($this->_debugMode) | ||||
|                 $this->_log('Try to bind with user\'s DN: ' . $userDN); | ||||
|             $loginAttempt = @ldap_bind($ldapConn, $userDN, $password); | ||||
|             if ($loginAttempt === TRUE) { | ||||
|                 $this->_log('User: ' . (string) $login . ' authentication successful'); | ||||
|                 if (strlen($this->_ldapLoginAttrib) > 0) { | ||||
|                     if ($this->_debugMode) | ||||
|                         $this->_log('Looking up TT-RSS username attribute in ' . $this->_ldapLoginAttrib); | ||||
|                     $ttrssUsername = $userAttributes[$this->_ldapLoginAttrib][0]; | ||||
|                     ; | ||||
|                     @ldap_close($ldapConn); | ||||
|                     if (!is_string($ttrssUsername)) { | ||||
|                         $this->_log('Could not find user name attribute ' . $this->_ldapLoginAttrib . ' in LDAP entry', E_USER_WARNING); | ||||
|                         return FALSE; | ||||
|                     } | ||||
|                     return $this->base->auto_create_user($ttrssUsername); | ||||
|                 } else { | ||||
|                     @ldap_close($ldapConn); | ||||
|                     return $this->base->auto_create_user($login); | ||||
|                 } | ||||
|             } else { | ||||
|                 @ldap_close($ldapConn); | ||||
|                 $this->_log('User: ' . (string) $login . ' authentication failed'); | ||||
|                 return FALSE; | ||||
|             } | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Returns plugin API version | ||||
|      * Required for plugin interface | ||||
|      * @return number | ||||
|      */ | ||||
|     function api_version() { | ||||
|         return 2; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| ?>
 | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Fmstrat
						Fmstrat