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