]>
git.defcon.no Git - hermes/blob - api/lib/auth_base.php
3 # Copyright (c) 2012, Gjøvik University College
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions are met:
8 # * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer.
10 # * Redistributions in binary form must reproduce the above copyright
11 # notice, this list of conditions and the following disclaimer in the
12 # documentation and/or other materials provided with the distribution.
13 # * Neither the name of the Gjøvik University College nor the
14 # names of its contributors may be used to endorse or promote products
15 # derived from this software without specific prior written permission.
17 # THIS SOFTWARE IS PROVIDED BY Gjøvik University College ''AS IS'' AND ANY
18 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 # DISCLAIMED. IN NO EVENT SHALL Gjøvik University College BE LIABLE FOR ANY
21 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 require_once('config.php');
30 $config = get_config();
32 function authlevel_value( $level )
46 function authlevel_name( $level )
51 return 'limited_read';
61 /*******************************
62 * Load authentication plugin ..
63 *******************************/
64 if ( preg_match('/^\w+$/', $config['auth_backend']))
66 if ( !@include_once
( 'lib/auth_plugins/' . $config['auth_backend'] . ".php" ) )
67 { print json_encode( array( 'response' => 'error', 'cause' => 'auth-load' ) ); exit; }
70 { print json_encode( array( 'response' => 'error', 'cause' => 'config-error' ) ); exit; }
71 /*******************************/
73 function new_key( $hex = false )
75 // Basically this is at the moment a slightly modified
76 // version of generate_password() from user_functiions.php
77 // The behaviour/output of this function is expected to change
78 // so using generate_password() directly does not make sense...
81 while ( strlen( $string ) < $length )
84 $string .= substr(md5(rand().rand()), 0, $length+
1);
87 $string .= crypt( substr(sha1(rand()), 0, $length+
1) );
88 $string = preg_replace( '/\W/', '', $string);
91 return substr( $string, 1, $length );
94 function simple_authfail()
96 print json_encode( array( 'response' => 'failed', 'cause' => 'unauthorized', 'description' => 'Not authorized') );
100 function token_auth( )
104 // TODO: Part of ping/pong requirement.
105 // Run a function to clear all authkeys older than 5 minutes.
108 if ( array_key_exists('session', $_POST )
109 && array_key_exists('auth_key', $_POST ) )
111 if ( ! check_session($_POST['session'] ) ) simple_authfail();
112 if ( ! check_authkey($_POST['auth_key'] ) ) simple_authfail();
114 else simple_authfail();
117 function get_cookie_path ()
119 $name = $_SERVER["SCRIPT_NAME"];
120 $file = basename($name);
121 $path = preg_replace("/".$file."/", "", $name);
126 function check_authkey ( $key )
128 // TODO: Make real, actual checks...
129 if ( $key ) return true;
133 function expire_authkeys()
137 // Force deletion of sessions that have expired keys.
138 $query = sprintf("SELECT session, sessid FROM %s WHERE `last` < DATE_SUB( NOW(), INTERVAL %d MINUTE)",
139 $config['sessionkeys_table'],
140 $config['sessionkey_lifetime']);
141 $result = sql_dbquery( $config['hermes_db'], $query );
142 while ( $row = @mysql_fetch_row
( $result ) )
144 remove_session( $row[0], $row[1] );
147 $query = sprintf("DELETE FROM %s WHERE `last` < DATE_SUB( NOW(), INTERVAL %d MINUTE)",
148 $config['sessionkeys_table'],
149 $config['sessionkey_lifetime']);
151 sql_dbexec( $config['hermes_db'], $query );
154 function update_authkey ( $session, $authid )
158 $key = substr(new_key(), 0, 8);
162 // TODO: Refresh cookie
164 $remote = $_SERVER['REMOTE_ADDR'];
165 $query = sprintf("INSERT INTO %s ( `sessid`, `session`, `authid`, `client`, `key`, `last` )
166 VALUES ( '%s', '%s', '%s', '%s', '%s', NOW() )
167 ON DUPLICATE KEY UPDATE `key` = '%s', `last` = NOW()",
168 $config['sessionkeys_table'],
175 if ( ! sql_dbexec( $config['hermes_db'], $query ) )
179 $_SESSION['kkey'] = $key;
180 $_SESSION['when'] = time();
184 function check_session ( $name )
186 session_name( $name );
188 if ( ! $_SESSION['authid'] )
190 return clear_credentials($name);
192 if ( ! $_COOKIE['client_key'] )
194 return clear_credentials($name);
197 $authid = $_SESSION['authid'];
198 $type = $_SESSION['type'];
199 $client_key = $_COOKIE['client_key'];
201 $level = get_authorization( $type, $authid );
202 if ( $level == false )
204 return clear_credentials($name);
207 $session_key = md5( $name . $authid );
208 if ( $client_key != $session_key )
210 return clear_credentials($name);
213 // If we got this far, things are looking good.
217 function set_credentials( $authid, $type )
219 $name = new_key(true);
220 session_name( $name );
222 $_SESSION['authid'] = $authid;
223 $_SESSION['type'] = $type;
225 $client_key = md5( $name . $authid );
226 setcookie('client_key', $client_key, time()+
180*60, get_cookie_path() );
231 function clear_credentials($name)
235 setcookie('client_key', '', 0, get_cookie_path() );
237 remove_session($name);
240 $query = sprintf("DELETE FROM %s WHERE `session` = '%s'",
241 $config['sessionkeys_table'],
243 sql_dbexec( $config['hermes_db'], $query );
248 function remove_session ($name, $id = null )
253 setcookie($name, '', 0, "/");
256 $current_session = session_name( );
257 $current_sessid = session_id( );
262 setcookie( $name, '', 0, "/");
266 if ( $current_session && $current_session != $name )
268 session_id($current_sessid);
272 function add_apikey ( $host, $level )
275 if ( !is_numeric($level) ) return false;
279 // Try to add the new key to authorizations first. If this
280 // fails, there will be the least amount of data to clean up ...
281 if ( ! update_authorization( "key", $key, $level ) ) return false;
283 $query = sprintf("INSERT INTO %s ( host, apikey ) VALUES ( '%s', '%s' )",
284 $config['apikeys_table'],
288 if ( ! sql_dbexec( $config['hermes_db'], $query ) ) return false;
292 function remove_apikey( $key )
295 if ( ! verify_apikey( $key, true ) ) return false;
296 if ( ! remove_authorization( $key ) ) return false;
298 $query = sprintf("DELETE FROM %s WHERE apikey = '%s'",
299 $config['apikeys_table'],
301 if ( ! sql_dbexec( $config['hermes_db'], $query ) ) return false;
306 function verify_apikey( $key, $skip_hostcheck = false )
310 $query = sprintf("SELECT host FROM %s WHERE apikey = '%s'",
311 $config['apikeys_table'],
313 $row = sql_dbquery_single( $config['hermes_db'], $query );
314 if (!$row) return false;
315 $host = $row['host'];
317 if ( $host && ( $skip_hostcheck ) )
320 if ( $host == $_SERVER['REMOTE_ADDR'] ) return true;
325 function list_apikeys ()
328 $query = sprintf("SELECT k.apikey AS apikey, k.host AS host,
329 a.access_level AS access_level
330 FROM %s k INNER JOIN %s a ON k.apikey = a.authid
331 WHERE a.type = 'key'",
332 $config['apikeys_table'],
333 $config['authorizations_table']);
335 $result = sql_dbquery( $config['hermes_db'], $query);
336 if ( ! $result ) return $list;
337 while ( $row = @mysql_fetch_assoc
( $result ) )
339 array_push( $list, array(
340 'api_key' => $row['apikey'],
341 'host' => $row['host'],
342 'level' => authlevel_name( $row['access_level'] )
349 function list_authusers ()
352 $query = sprintf("SELECT authid, access_level
354 WHERE type = 'user'",
355 $config['authorizations_table']);
357 $result = sql_dbquery( $config['hermes_db'], $query);
358 if ( ! $result ) return $list;
359 while ( $row = @mysql_fetch_assoc
( $result ) )
361 $username = $row['authid'];
362 $user_data = authuser_getinfo( $username );
364 // TODO: Remove invalid users here?
365 if ( ! $user_data ) continue;
367 array_push( $list, array(
369 'name' => $user_data['name'],
370 'email' => $user_data['email'],
371 'level' => authlevel_name( $row['access_level'] )
380 function update_authorization( $type, $authid, $level )
383 if ( !is_numeric($level) ) return false;
384 if ( ($type != "key") && ($type != "user") ) return false;
386 $query = sprintf("INSERT INTO %s ( authid, type, access_level ) VALUES ( '%s', '%s', %d )
387 ON DUPLICATE KEY UPDATE access_level=%d",
388 $config['authorizations_table'],
392 if ( ! sql_dbexec( $config['hermes_db'], $query ) ) return false;
396 function remove_authorization( $authid )
399 $query = sprintf("DELETE FROM %s WHERE authid = '%s'",
400 $config['authorizations_table'],
401 sql_clean($authid) );
402 //print $query . "\n\n";
403 if ( ! sql_dbexec( $config['hermes_db'], $query ) ) return false;
408 function get_authorization( $type, $authid )
412 // If API-key is used, but key fails verification, write is impossible.
413 if ( ( $type == "key" ) && ( ! verify_apikey( $authid, true ) ) )
416 // If User-login is used, but backend is unable to provide info, fail.
417 if ( ( $type == "user" ) && ( ! authuser_getinfo( $authid ) ) )
420 // The only types of access control supported are "user" or "key".
421 if ( ($type != "user" ) && ($type != "key") )
424 $query = sprintf("SELECT access_level FROM %s WHERE authid = '%s'",
425 $config['authorizations_table'],
426 sql_clean($authid) );
427 $row = sql_dbquery_single( $config['hermes_db'], $query );
428 if (!$row) return false;
429 $level = $row['access_level'];
433 function can_write ( )
435 // Stub, to be called on any API nodes that write data in the DB.
436 $authid = $_SESSION['authid'];
437 $type = $_SESSION['type'];
439 $level = get_authorization( $type, $authid );
440 if ( $level >= authlevel_value('read_write') ) return $level;