]> CyberLeo.Net >> Repos - Github/YOURLS.git/blob - includes/functions-auth.php
PHPdoc-ish-ification of older functions. Fixes issue 1244.
[Github/YOURLS.git] / includes / functions-auth.php
1 <?php\r
2 /**
3  * Check for valid user. Returns true or an error message
4  *
5  */
6 function yourls_is_valid_user() {\r
7         static $valid = false;\r
8         \r
9         if( $valid )\r
10                 return true;\r
11                 \r
12         $unfiltered_valid = false;\r
13 \r
14         // Logout request\r
15         if( isset( $_GET['action'] ) && $_GET['action'] == 'logout' ) {\r
16                 yourls_do_action( 'logout' );\r
17                 yourls_store_cookie( null );\r
18                 return yourls__( 'Logged out successfully' );\r
19         }\r
20         \r
21         // Check cookies or login request. Login form has precedence.\r
22         global $yourls_user_passwords;\r
23         \r
24         yourls_do_action( 'pre_login' );\r
25 \r
26         // Determine auth method and check credentials\r
27         if\r
28                 // API only: Secure (no login or pwd) and time limited token\r
29                 // ?timestamp=12345678&signature=md5(totoblah12345678)\r
30                 ( yourls_is_API() &&\r
31                   isset( $_REQUEST['timestamp'] ) && !empty($_REQUEST['timestamp'] ) &&\r
32                   isset( $_REQUEST['signature'] ) && !empty($_REQUEST['signature'] )\r
33                 )\r
34                 {\r
35                         yourls_do_action( 'pre_login_signature_timestamp' );\r
36                         $unfiltered_valid = yourls_check_signature_timestamp();\r
37                 }\r
38                 \r
39         elseif\r
40                 // API only: Secure (no login or pwd)\r
41                 // ?signature=md5(totoblah)\r
42                 ( yourls_is_API() &&\r
43                   !isset( $_REQUEST['timestamp'] ) &&\r
44                   isset( $_REQUEST['signature'] ) && !empty( $_REQUEST['signature'] )\r
45                 )\r
46                 {\r
47                         yourls_do_action( 'pre_login_signature' );\r
48                         $unfiltered_valid = yourls_check_signature();\r
49                 }\r
50         \r
51         elseif\r
52                 // API or normal: login with username & pwd\r
53                 ( isset( $_REQUEST['username'] ) && isset( $_REQUEST['password'] )\r
54                   && !empty( $_REQUEST['username'] ) && !empty( $_REQUEST['password']  ) )\r
55                 {\r
56                         yourls_do_action( 'pre_login_username_password' );\r
57                         $unfiltered_valid = yourls_check_username_password();\r
58                 }\r
59         \r
60         elseif\r
61                 // Normal only: cookies\r
62                 ( !yourls_is_API() && \r
63                   isset( $_COOKIE['yourls_username'] ) && isset( $_COOKIE['yourls_password'] ) )\r
64                 {\r
65                         yourls_do_action( 'pre_login_cookie' );\r
66                         $unfiltered_valid = yourls_check_auth_cookie();\r
67                 }\r
68 \r
69         $valid = yourls_apply_filter( 'is_valid_user', $unfiltered_valid );\r
70 \r
71         // Login for the win!\r
72         if ( $valid ) {\r
73                 yourls_do_action( 'login' );\r
74                 // (Re)store encrypted cookie if needed and tell it's ok\r
75                 if ( !yourls_is_API() && $unfiltered_valid ) \r
76                         yourls_store_cookie( YOURLS_USER );\r
77                 return true;\r
78         }\r
79         \r
80         // Login failed\r
81         yourls_do_action( 'login_failed' );\r
82 \r
83         if ( isset( $_REQUEST['username'] ) || isset( $_REQUEST['password'] ) ) {\r
84                 return yourls__( 'Invalid username or password' );\r
85         } else {\r
86                 return yourls__( 'Please log in' );\r
87         }\r
88 }\r
89 \r
90 /**
91  * Check auth against list of login=>pwd. Sets user if applicable, returns bool
92  *
93  */
94 function yourls_check_username_password() {\r
95         global $yourls_user_passwords;\r
96         if( isset( $yourls_user_passwords[ $_REQUEST['username'] ] ) && yourls_check_password_hash( $yourls_user_passwords[ $_REQUEST['username'] ], $_REQUEST['password'] ) ) {\r
97                 yourls_set_user( $_REQUEST['username'] );\r
98                 return true;\r
99         }\r
100         return false;\r
101 }\r
102 \r
103 /**
104  * Check a REQUEST password sent in plain text against stored password which can be a salted hash
105  *
106  */
107 function yourls_check_password_hash( $stored, $plaintext ) {\r
108         if ( substr( $stored, 0, 4 ) == 'md5:' and strlen( $stored ) == 42 ) {\r
109                 // Stored password is a salted hash: "md5:<$r = rand(10000,99999)>:<md5($r.'thepassword')>"\r
110                 // And 42. Of course. http://www.google.com/search?q=the+answer+to+life+the+universe+and+everything\r
111                 list( $temp, $salt, $md5 ) = explode( ':', $stored );\r
112                 return( $stored == 'md5:'.$salt.':'.md5( $salt.$plaintext ) );\r
113         } else {\r
114                 // Password was sent in clear\r
115                 $message  = '';\r
116                 $message .= yourls__( '<strong>Notice</strong>: your password is stored as clear text in your <tt>config.php</tt>' );\r
117                 $message .= yourls__( 'Did you know you can easily improve the security of your YOURLS install by <strong>encrypting</strong> your password?' );\r
118                 $message .= yourls__( 'See <a href="http://yourls.org/userpassword">UsernamePassword</a> for details' );\r
119                 yourls_add_notice( $message, 'notice' );\r
120                 return( $stored == $plaintext );\r
121         }\r
122 }\r
123 \r
124 \r
125 /**
126  * Check auth against encrypted COOKIE data. Sets user if applicable, returns bool
127  *
128  */
129 function yourls_check_auth_cookie() {\r
130         global $yourls_user_passwords;\r
131         foreach( $yourls_user_passwords as $valid_user => $valid_password ) {\r
132                 if( \r
133                         yourls_salt( $valid_user ) == $_COOKIE['yourls_username']\r
134                         && yourls_salt( $valid_password ) == $_COOKIE['yourls_password'] \r
135                 ) {\r
136                         yourls_set_user( $valid_user );\r
137                         return true;\r
138                 }\r
139         }\r
140         return false;\r
141 }\r
142 \r
143 /**
144  * Check auth against signature and timestamp. Sets user if applicable, returns bool
145  *
146  */
147 function yourls_check_signature_timestamp() {\r
148         // Timestamp in PHP : time()\r
149         // Timestamp in JS: parseInt(new Date().getTime() / 1000)\r
150         global $yourls_user_passwords;\r
151         foreach( $yourls_user_passwords as $valid_user => $valid_password ) {\r
152                 if (\r
153                         (\r
154                                 md5( $_REQUEST['timestamp'].yourls_auth_signature( $valid_user ) ) == $_REQUEST['signature']\r
155                                 or\r
156                                 md5( yourls_auth_signature( $valid_user ).$_REQUEST['timestamp'] ) == $_REQUEST['signature']\r
157                         )\r
158                         &&\r
159                         yourls_check_timestamp( $_REQUEST['timestamp'] )\r
160                         ) {\r
161                         yourls_set_user( $valid_user );\r
162                         return true;\r
163                 }\r
164         }\r
165         return false;\r
166 }\r
167 \r
168 /**
169  * Check auth against signature. Sets user if applicable, returns bool
170  *
171  */
172 function yourls_check_signature() {\r
173         global $yourls_user_passwords;\r
174         foreach( $yourls_user_passwords as $valid_user => $valid_password ) {\r
175                 if ( yourls_auth_signature( $valid_user ) == $_REQUEST['signature'] ) {\r
176                         yourls_set_user( $valid_user );\r
177                         return true;\r
178                 }\r
179         }\r
180         return false;\r
181 }\r
182 \r
183 /**
184  * Generate secret signature hash
185  *
186  */
187 function yourls_auth_signature( $username = false ) {\r
188         if( !$username && defined('YOURLS_USER') ) {\r
189                 $username = YOURLS_USER;\r
190         }\r
191         return ( $username ? substr( yourls_salt( $username ), 0, 10 ) : 'Cannot generate auth signature: no username' );\r
192 }\r
193 \r
194 /**
195  * Check if timestamp is not too old
196  *
197  */
198 function yourls_check_timestamp( $time ) {\r
199         $now = time();\r
200         // Allow timestamp to be a little in the future or the past -- see Issue 766\r
201         return yourls_apply_filter( 'check_timestamp', abs( $now - $time ) < YOURLS_NONCE_LIFE, $time );\r
202 }\r
203 \r
204 /**
205  * Store new cookie. No $user will delete the cookie.
206  *
207  */
208 function yourls_store_cookie( $user = null ) {\r
209         if( !$user ) {\r
210                 $pass = null;\r
211                 $time = time() - 3600;\r
212         } else {\r
213                 global $yourls_user_passwords;\r
214                 if( isset($yourls_user_passwords[$user]) ) {\r
215                         $pass = $yourls_user_passwords[$user];\r
216                 } else {\r
217                         die( 'Stealing cookies?' ); // This should never happen\r
218                 }\r
219                 $time = time() + YOURLS_COOKIE_LIFE;\r
220         }\r
221         \r
222         $domain   = yourls_apply_filter( 'setcookie_domain',   parse_url( YOURLS_SITE, 1 ) );\r
223         $secure   = yourls_apply_filter( 'setcookie_secure',   yourls_is_ssl() );\r
224         $httponly = yourls_apply_filter( 'setcookie_httponly', true );\r
225                 \r
226         if ( !headers_sent() ) {\r
227                 // Set httponly if the php version is >= 5.2.0\r
228                 if( version_compare( phpversion(), '5.2.0', 'ge' ) ) {\r
229                         setcookie('yourls_username', yourls_salt( $user ), $time, '/', $domain, $secure, $httponly );\r
230                         setcookie('yourls_password', yourls_salt( $pass ), $time, '/', $domain, $secure, $httponly );\r
231                 } else {\r
232                         setcookie('yourls_username', yourls_salt( $user ), $time, '/', $domain, $secure );\r
233                         setcookie('yourls_password', yourls_salt( $pass ), $time, '/', $domain, $secure );\r
234                 }\r
235         }\r
236 }\r
237 \r
238 /**
239  * Set user name
240  *
241  */
242 function yourls_set_user( $user ) {\r
243         if( !defined( 'YOURLS_USER' ) )\r
244                 define( 'YOURLS_USER', $user );\r
245 }\r