aboutsummaryrefslogtreecommitdiffhomepage
path: root/application/security/LoginManager.php
diff options
context:
space:
mode:
Diffstat (limited to 'application/security/LoginManager.php')
-rw-r--r--application/security/LoginManager.php95
1 files changed, 77 insertions, 18 deletions
diff --git a/application/security/LoginManager.php b/application/security/LoginManager.php
index 0b0ce0b1..d74c3118 100644
--- a/application/security/LoginManager.php
+++ b/application/security/LoginManager.php
@@ -1,6 +1,7 @@
1<?php 1<?php
2namespace Shaarli\Security; 2namespace Shaarli\Security;
3 3
4use Exception;
4use Shaarli\Config\ConfigManager; 5use Shaarli\Config\ConfigManager;
5 6
6/** 7/**
@@ -8,9 +9,6 @@ use Shaarli\Config\ConfigManager;
8 */ 9 */
9class LoginManager 10class LoginManager
10{ 11{
11 /** @var string Name of the cookie set after logging in **/
12 public static $STAY_SIGNED_IN_COOKIE = 'shaarli_staySignedIn';
13
14 /** @var array A reference to the $_GLOBALS array */ 12 /** @var array A reference to the $_GLOBALS array */
15 protected $globals = []; 13 protected $globals = [];
16 14
@@ -31,17 +29,21 @@ class LoginManager
31 29
32 /** @var string User sign-in token depending on remote IP and credentials */ 30 /** @var string User sign-in token depending on remote IP and credentials */
33 protected $staySignedInToken = ''; 31 protected $staySignedInToken = '';
32 /** @var CookieManager */
33 protected $cookieManager;
34 34
35 /** 35 /**
36 * Constructor 36 * Constructor
37 * 37 *
38 * @param ConfigManager $configManager Configuration Manager instance 38 * @param ConfigManager $configManager Configuration Manager instance
39 * @param SessionManager $sessionManager SessionManager instance 39 * @param SessionManager $sessionManager SessionManager instance
40 * @param CookieManager $cookieManager CookieManager instance
40 */ 41 */
41 public function __construct($configManager, $sessionManager) 42 public function __construct($configManager, $sessionManager, $cookieManager)
42 { 43 {
43 $this->configManager = $configManager; 44 $this->configManager = $configManager;
44 $this->sessionManager = $sessionManager; 45 $this->sessionManager = $sessionManager;
46 $this->cookieManager = $cookieManager;
45 $this->banManager = new BanManager( 47 $this->banManager = new BanManager(
46 $this->configManager->get('security.trusted_proxies', []), 48 $this->configManager->get('security.trusted_proxies', []),
47 $this->configManager->get('security.ban_after'), 49 $this->configManager->get('security.ban_after'),
@@ -85,10 +87,9 @@ class LoginManager
85 /** 87 /**
86 * Check user session state and validity (expiration) 88 * Check user session state and validity (expiration)
87 * 89 *
88 * @param array $cookie The $_COOKIE array
89 * @param string $clientIpId Client IP address identifier 90 * @param string $clientIpId Client IP address identifier
90 */ 91 */
91 public function checkLoginState($cookie, $clientIpId) 92 public function checkLoginState($clientIpId)
92 { 93 {
93 if (! $this->configManager->exists('credentials.login')) { 94 if (! $this->configManager->exists('credentials.login')) {
94 // Shaarli is not configured yet 95 // Shaarli is not configured yet
@@ -96,9 +97,7 @@ class LoginManager
96 return; 97 return;
97 } 98 }
98 99
99 if (isset($cookie[self::$STAY_SIGNED_IN_COOKIE]) 100 if ($this->staySignedInToken === $this->cookieManager->getCookieParameter(CookieManager::STAY_SIGNED_IN)) {
100 && $cookie[self::$STAY_SIGNED_IN_COOKIE] === $this->staySignedInToken
101 ) {
102 // The user client has a valid stay-signed-in cookie 101 // The user client has a valid stay-signed-in cookie
103 // Session information is updated with the current client information 102 // Session information is updated with the current client information
104 $this->sessionManager->storeLoginInfo($clientIpId); 103 $this->sessionManager->storeLoginInfo($clientIpId);
@@ -139,26 +138,86 @@ class LoginManager
139 */ 138 */
140 public function checkCredentials($remoteIp, $clientIpId, $login, $password) 139 public function checkCredentials($remoteIp, $clientIpId, $login, $password)
141 { 140 {
142 $hash = sha1($password . $login . $this->configManager->get('credentials.salt')); 141 // Check login matches config
142 if ($login !== $this->configManager->get('credentials.login')) {
143 return false;
144 }
143 145
144 if ($login != $this->configManager->get('credentials.login') 146 // Check credentials
145 || $hash != $this->configManager->get('credentials.hash') 147 try {
146 ) { 148 $useLdapLogin = !empty($this->configManager->get('ldap.host'));
149 if ((false === $useLdapLogin && $this->checkCredentialsFromLocalConfig($login, $password))
150 || (true === $useLdapLogin && $this->checkCredentialsFromLdap($login, $password))
151 ) {
152 $this->sessionManager->storeLoginInfo($clientIpId);
153 logm(
154 $this->configManager->get('resource.log'),
155 $remoteIp,
156 'Login successful'
157 );
158 return true;
159 }
160 }
161 catch(Exception $exception) {
147 logm( 162 logm(
148 $this->configManager->get('resource.log'), 163 $this->configManager->get('resource.log'),
149 $remoteIp, 164 $remoteIp,
150 'Login failed for user ' . $login 165 'Exception while checking credentials: ' . $exception
151 ); 166 );
152 return false;
153 } 167 }
154 168
155 $this->sessionManager->storeLoginInfo($clientIpId);
156 logm( 169 logm(
157 $this->configManager->get('resource.log'), 170 $this->configManager->get('resource.log'),
158 $remoteIp, 171 $remoteIp,
159 'Login successful' 172 'Login failed for user ' . $login
173 );
174 return false;
175 }
176
177
178 /**
179 * Check user credentials from local config
180 *
181 * @param string $login Username
182 * @param string $password Password
183 *
184 * @return bool true if the provided credentials are valid, false otherwise
185 */
186 public function checkCredentialsFromLocalConfig($login, $password) {
187 $hash = sha1($password . $login . $this->configManager->get('credentials.salt'));
188
189 return $login == $this->configManager->get('credentials.login')
190 && $hash == $this->configManager->get('credentials.hash');
191 }
192
193 /**
194 * Check user credentials are valid through LDAP bind
195 *
196 * @param string $remoteIp Remote client IP address
197 * @param string $clientIpId Client IP address identifier
198 * @param string $login Username
199 * @param string $password Password
200 *
201 * @return bool true if the provided credentials are valid, false otherwise
202 */
203 public function checkCredentialsFromLdap($login, $password, $connect = null, $bind = null)
204 {
205 $connect = $connect ?? function($host) {
206 $resource = ldap_connect($host);
207
208 ldap_set_option($resource, LDAP_OPT_PROTOCOL_VERSION, 3);
209
210 return $resource;
211 };
212 $bind = $bind ?? function($handle, $dn, $password) {
213 return ldap_bind($handle, $dn, $password);
214 };
215
216 return $bind(
217 $connect($this->configManager->get('ldap.host')),
218 sprintf($this->configManager->get('ldap.dn'), $login),
219 $password
160 ); 220 );
161 return true;
162 } 221 }
163 222
164 /** 223 /**