]> git.mxchange.org Git - friendica.git/blob - include/auth.php
Merge remote-tracking branch 'upstream/develop' into 1705-some-more-dba
[friendica.git] / include / auth.php
1 <?php
2
3 use Friendica\App;
4 use Friendica\Core\Config;
5
6 require_once('include/security.php');
7 require_once('include/datetime.php');
8
9 // When the "Friendica" cookie is set, take the value to authenticate and renew the cookie.
10 if (isset($_COOKIE["Friendica"])) {
11         $data = json_decode($_COOKIE["Friendica"]);
12         if (isset($data->uid)) {
13                 $r = q("SELECT `user`.*, `user`.`pubkey` as `upubkey`, `user`.`prvkey` as `uprvkey`
14                 FROM `user` WHERE `uid` = %d AND NOT `blocked` AND NOT `account_expired` AND NOT `account_removed` AND `verified` LIMIT 1",
15                         intval($data->uid)
16                 );
17
18                 if ($r) {
19                         if ($data->hash != cookie_hash($r[0])) {
20                                 logger("Hash for user ".$data->uid." doesn't fit.");
21                                 nuke_session();
22                                 goaway(z_root());
23                         }
24
25                         // Renew the cookie
26                         // Expires after 7 days by default,
27                         // can be set via system.auth_cookie_lifetime
28                         $authcookiedays = Config::get('system', 'auth_cookie_lifetime', 7);
29                         new_cookie($authcookiedays*24*60*60, $r[0]);
30
31                         // Do the authentification if not done by now
32                         if (!isset($_SESSION) OR !isset($_SESSION['authenticated'])) {
33                                 authenticate_success($r[0]);
34
35                                 if (get_config('system','paranoia'))
36                                         $_SESSION['addr'] = $data->ip;
37                         }
38                 }
39         }
40 }
41
42
43 // login/logout
44
45 if (isset($_SESSION) && x($_SESSION,'authenticated') && (!x($_POST,'auth-params') || ($_POST['auth-params'] !== 'login'))) {
46
47         if ((x($_POST,'auth-params') && ($_POST['auth-params'] === 'logout')) || ($a->module === 'logout')) {
48
49                 // process logout request
50                 call_hooks("logging_out");
51                 nuke_session();
52                 info(t('Logged out.').EOL);
53                 goaway(z_root());
54         }
55
56         if (x($_SESSION,'visitor_id') && !x($_SESSION,'uid')) {
57                 $r = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1",
58                         intval($_SESSION['visitor_id'])
59                 );
60                 if (dbm::is_result($r)) {
61                         $a->contact = $r[0];
62                 }
63         }
64
65         if (x($_SESSION,'uid')) {
66
67                 // already logged in user returning
68
69                 $check = get_config('system','paranoia');
70                 // extra paranoia - if the IP changed, log them out
71                 if ($check && ($_SESSION['addr'] != $_SERVER['REMOTE_ADDR'])) {
72                         logger('Session address changed. Paranoid setting in effect, blocking session. '.
73                                 $_SESSION['addr'].' != '.$_SERVER['REMOTE_ADDR']);
74                         nuke_session();
75                         goaway(z_root());
76                 }
77
78                 $r = q("SELECT `user`.*, `user`.`pubkey` as `upubkey`, `user`.`prvkey` as `uprvkey`
79                 FROM `user` WHERE `uid` = %d AND NOT `blocked` AND NOT `account_expired` AND NOT `account_removed` AND `verified` LIMIT 1",
80                         intval($_SESSION['uid'])
81                 );
82
83                 if (!dbm::is_result($r)) {
84                         nuke_session();
85                         goaway(z_root());
86                 }
87
88                 // Make sure to refresh the last login time for the user if the user
89                 // stays logged in for a long time, e.g. with "Remember Me"
90                 $login_refresh = false;
91                 if (!x($_SESSION['last_login_date'])) {
92                         $_SESSION['last_login_date'] = datetime_convert('UTC','UTC');
93                 }
94                 if (strcmp(datetime_convert('UTC','UTC','now - 12 hours'), $_SESSION['last_login_date']) > 0) {
95
96                         $_SESSION['last_login_date'] = datetime_convert('UTC','UTC');
97                         $login_refresh = true;
98                 }
99                 authenticate_success($r[0], false, false, $login_refresh);
100         }
101 } else {
102
103         session_unset();
104
105         if (x($_POST,'password') && strlen($_POST['password']))
106                 $encrypted = hash('whirlpool',trim($_POST['password']));
107         else {
108                 if ((x($_POST,'openid_url')) && strlen($_POST['openid_url']) ||
109                    (x($_POST,'username')) && strlen($_POST['username'])) {
110
111                         $noid = get_config('system','no_openid');
112
113                         $openid_url = trim((strlen($_POST['openid_url'])?$_POST['openid_url']:$_POST['username']));
114
115                         // validate_url alters the calling parameter
116
117                         $temp_string = $openid_url;
118
119                         // if it's an email address or doesn't resolve to a URL, fail.
120
121                         if ($noid || strpos($temp_string,'@') || !validate_url($temp_string)) {
122                                 $a = get_app();
123                                 notice(t('Login failed.').EOL);
124                                 goaway(z_root());
125                                 // NOTREACHED
126                         }
127
128                         // Otherwise it's probably an openid.
129
130                         try {
131                                 require_once('library/openid.php');
132                                 $openid = new LightOpenID;
133                                 $openid->identity = $openid_url;
134                                 $_SESSION['openid'] = $openid_url;
135                                 $_SESSION['remember'] = $_POST['remember'];
136                                 $openid->returnUrl = App::get_baseurl(true).'/openid';
137                                 goaway($openid->authUrl());
138                         } catch (Exception $e) {
139                                 notice(t('We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID.').'<br /><br >'.t('The error message was:').' '.$e->getMessage());
140                         }
141                         // NOTREACHED
142                 }
143         }
144
145         if (x($_POST,'auth-params') && $_POST['auth-params'] === 'login') {
146
147                 $record = null;
148
149                 $addon_auth = array(
150                         'username' => trim($_POST['username']),
151                         'password' => trim($_POST['password']),
152                         'authenticated' => 0,
153                         'user_record' => null
154                 );
155
156                 /**
157                  *
158                  * A plugin indicates successful login by setting 'authenticated' to non-zero value and returning a user record
159                  * Plugins should never set 'authenticated' except to indicate success - as hooks may be chained
160                  * and later plugins should not interfere with an earlier one that succeeded.
161                  *
162                  */
163
164                 call_hooks('authenticate', $addon_auth);
165
166                 if ($addon_auth['authenticated'] && count($addon_auth['user_record']))
167                         $record = $addon_auth['user_record'];
168                 else {
169
170                         // process normal login request
171
172                         $r = q("SELECT `user`.*, `user`.`pubkey` as `upubkey`, `user`.`prvkey` as `uprvkey`
173                                 FROM `user` WHERE (`email` = '%s' OR `nickname` = '%s')
174                                 AND `password` = '%s' AND NOT `blocked` AND NOT `account_expired` AND NOT `account_removed` AND `verified` LIMIT 1",
175                                 dbesc(trim($_POST['username'])),
176                                 dbesc(trim($_POST['username'])),
177                                 dbesc($encrypted)
178                         );
179                         if (dbm::is_result($r))
180                                 $record = $r[0];
181                 }
182
183                 if (!$record || !count($record)) {
184                         logger('authenticate: failed login attempt: '.notags(trim($_POST['username'])).' from IP '.$_SERVER['REMOTE_ADDR']);
185                         notice(t('Login failed.').EOL);
186                         goaway(z_root());
187                 }
188
189                 if (! $_POST['remember']) {
190                         new_cookie(0); // 0 means delete on browser exit
191                 }
192
193                 // if we haven't failed up this point, log them in.
194                 $_SESSION['remember'] = $_POST['remember'];
195                 $_SESSION['last_login_date'] = datetime_convert('UTC','UTC');
196                 authenticate_success($record, true, true);
197         }
198 }
199
200 /**
201  * @brief Kills the "Friendica" cookie and all session data
202  */
203 function nuke_session() {
204
205         new_cookie(-3600); // make sure cookie is deleted on browser close, as a security measure
206         session_unset();
207         session_destroy();
208 }