]> CyberLeo.Net >> Repos - Github/YOURLS.git/blob - includes/functions-auth.php
Stricter coding, fix warning when API request with nonexistent login
[Github/YOURLS.git] / includes / functions-auth.php
1 <?php\r
2 // Check for valid user. Returns true or an error message\r
3 function yourls_is_valid_user() {\r
4         static $valid = false;\r
5         \r
6         if( $valid )\r
7                 return true;\r
8 \r
9         // Logout request\r
10         if( isset( $_GET['mode'] ) && $_GET['mode'] == 'logout') {\r
11                 yourls_store_cookie( null );\r
12                 return 'Logged out successfully';\r
13         }\r
14         \r
15         // Check cookies or login request. Login form has precedence.\r
16         global $yourls_user_passwords;\r
17         \r
18         // In the future maybe I'll implement nonces like in WP. Will be something like\r
19         // ?nonce=fn(login,pwd,action)\r
20         \r
21         // Determine auth method and check credentials\r
22         if\r
23                 // API only: Secure (no login or pwd) and time limited token\r
24                 // ?timestamp=12345678&signature=md5(totoblah12345678)\r
25                 ( yourls_is_API() &&\r
26                   isset($_REQUEST['timestamp']) && !empty($_REQUEST['timestamp']) &&\r
27                   isset($_REQUEST['signature']) && !empty($_REQUEST['signature'])\r
28                 )\r
29                 {\r
30                         $valid = yourls_check_signature_timestamp();\r
31                 }\r
32                 \r
33         elseif\r
34                 // API only: Secure (no login or pwd)\r
35                 // ?signature=md5(totoblah)\r
36                 ( yourls_is_API() &&\r
37                   !isset($_REQUEST['timestamp']) &&\r
38                   isset($_REQUEST['signature']) && !empty($_REQUEST['signature'])\r
39                 )\r
40                 {\r
41                         $valid = yourls_check_signature();\r
42                 }\r
43         \r
44         elseif\r
45                 // API or normal: login with username & pwd\r
46                 ( isset($_REQUEST['username']) && isset($_REQUEST['password'])\r
47                   && !empty( $_REQUEST['username'] ) && !empty( $_REQUEST['password']  ) )\r
48                 {\r
49                         $valid = yourls_check_username_password();\r
50                 }\r
51         \r
52         elseif\r
53                 // Normal only: cookies\r
54                 ( !yourls_is_API() && \r
55                   isset($_COOKIE['yourls_username']) && isset($_COOKIE['yourls_password']) )\r
56                 {\r
57                         $valid = yourls_check_auth_cookie();\r
58                 }\r
59 \r
60         // Login for the win!\r
61         if ( $valid ) {\r
62                 // (Re)store encrypted cookie and tell it's ok\r
63                 if ( !yourls_is_API() ) // No need to store a cookie when used in API mode.\r
64                         yourls_store_cookie( YOURLS_USER );\r
65                 return true;\r
66         }\r
67         \r
68         // Login failed\r
69         if ( isset($_REQUEST['username']) || isset($_REQUEST['password']) ) {\r
70                 return 'Invalid username or password';\r
71         } else {\r
72                 return 'Please log in';\r
73         }\r
74 }\r
75 \r
76 // Check auth against list of login=>pwd. Sets user if applicable, returns bool\r
77 function yourls_check_username_password() {\r
78         global $yourls_user_passwords;\r
79         if( isset( $yourls_user_passwords[ $_REQUEST['username'] ] ) && $yourls_user_passwords[ $_REQUEST['username'] ] == $_REQUEST['password'] ) {\r
80                 yourls_set_user( $_REQUEST['username'] );\r
81                 return true;\r
82         }\r
83         return false;\r
84 }\r
85 \r
86 // Check auth against encrypted COOKIE data. Sets user if applicable, returns bool\r
87 function yourls_check_auth_cookie() {\r
88         global $yourls_user_passwords;\r
89         foreach( $yourls_user_passwords as $valid_user => $valid_password ) {\r
90                 if( \r
91                         yourls_salt($valid_user) == $_COOKIE['yourls_username']\r
92                         && yourls_salt($valid_password) == $_COOKIE['yourls_password'] \r
93                 ) {\r
94                         yourls_set_user( $valid_user );\r
95                         return true;\r
96                 }\r
97         }\r
98         return false;\r
99 }\r
100 \r
101 // Check auth against signature and timestamp. Sets user if applicable, returns bool\r
102 function yourls_check_signature_timestamp() {\r
103         // Timestamp in PHP : time()\r
104         // Timestamp in JS: parseInt(new Date().getTime() / 1000)\r
105         global $yourls_user_passwords;\r
106         foreach( $yourls_user_passwords as $valid_user => $valid_password ) {\r
107                 if (\r
108                         (\r
109                                 md5( $_REQUEST['timestamp'].yourls_auth_signature( $valid_user ) ) == $_REQUEST['signature']\r
110                                 or\r
111                                 md5( yourls_auth_signature( $valid_user ).$_REQUEST['timestamp'] ) == $_REQUEST['signature']\r
112                         )\r
113                         &&\r
114                         yourls_check_timestamp( $_REQUEST['timestamp'] )\r
115                         ) {\r
116                         yourls_set_user( $valid_user );\r
117                         return true;\r
118                 }\r
119         }\r
120         return false;\r
121 }\r
122 \r
123 // Check auth against signature. Sets user if applicable, returns bool\r
124 function yourls_check_signature() {\r
125         global $yourls_user_passwords;\r
126         foreach( $yourls_user_passwords as $valid_user => $valid_password ) {\r
127                 if ( yourls_auth_signature( $valid_user ) == $_REQUEST['signature'] ) {\r
128                         yourls_set_user( $valid_user );\r
129                         return true;\r
130                 }\r
131         }\r
132         return false;\r
133 }\r
134 \r
135 // Generate secret signature hash\r
136 function yourls_auth_signature( $username = false ) {\r
137         if( !$username && defined('YOURLS_USER') ) {\r
138                 $username = YOURLS_USER;\r
139         }\r
140         return ( $username ? substr( yourls_salt( $username ), 0, 10 ) : 'Cannot generate auth signature: no username' );\r
141 }\r
142 \r
143 // Check a timestamp is from the past and not too old\r
144 function yourls_check_timestamp( $time ) {\r
145         $now = time();\r
146         return ( $now >= $time && ceil( $now - $time ) < YOURLS_NONCE_LIFE );\r
147 }\r
148 \r
149 // Store new cookie. No $user will delete the cookie.\r
150 function yourls_store_cookie( $user = null ) {\r
151         if( !$user ) {\r
152                 $pass = null;\r
153                 $time = time() - 3600;\r
154         } else {\r
155                 global $yourls_user_passwords;\r
156                 if( isset($yourls_user_passwords[$user]) ) {\r
157                         $pass = $yourls_user_passwords[$user];\r
158                 } else {\r
159                         die('Stealing cookies?'); // This should never happen\r
160                 }\r
161                 $time = time() + YOURLS_COOKIE_LIFE;\r
162         }\r
163         if ( !headers_sent() ) {\r
164                 setcookie('yourls_username', yourls_salt( $user ), $time, '/' );\r
165                 setcookie('yourls_password', yourls_salt( $pass ), $time, '/' );\r
166         }\r
167 }\r
168 \r
169 // Set user name\r
170 function yourls_set_user( $user ) {\r
171         if( !defined('YOURLS_USER') )\r
172                 define('YOURLS_USER', $user);\r
173 }\r