X-Git-Url: https://git.defcon.no/?a=blobdiff_plain;f=api%2Flib%2Fauth_base.php;h=0bf65f75eea7900dbc4dc0c5209f9e50545e4c85;hb=87cde98c94c33708506b8e94db43726393df5dfa;hp=dfecae7995e3626e33fcdb4249bfc887136c437a;hpb=726f4037a48240b4104070bad824ea2e31e959e1;p=hermes diff --git a/api/lib/auth_base.php b/api/lib/auth_base.php index dfecae7..0bf65f7 100644 --- a/api/lib/auth_base.php +++ b/api/lib/auth_base.php @@ -1,8 +1,63 @@ 'error', 'cause' => 'config-error' ) ); exit; } /*******************************/ -function apikey_verify( $key ) -{ - if ( $key == "6327c08b70f9" ) return 1; - return false; -} - function new_key( $hex = false ) { // Basically this is at the moment a slightly modified @@ -32,14 +81,14 @@ function new_key( $hex = false ) while ( strlen( $string ) < $length ) { if ( $hex ) - $string .= substr(md5(rand().rand()), 0, $length); + $string .= substr(md5(rand().rand()), 0, $length+1); else { - $string .= crypt( substr(sha1(rand()), 0, $length) ); + $string .= crypt( substr(sha1(rand()), 0, $length+1) ); $string = preg_replace( '/\W/', '', $string); } } - return substr( $string, 0, $length ); + return substr( $string, 1, $length ); } function simple_authfail() @@ -50,17 +99,17 @@ function simple_authfail() function token_auth( ) { - global $_GET; + global $_POST; // TODO: Part of ping/pong requirement. // Run a function to clear all authkeys older than 5 minutes. - // expire_authkeys(); + expire_authkeys(); - if ( array_key_exists('session', $_GET ) - && array_key_exists('auth_key', $_GET ) ) + if ( array_key_exists('session', $_POST ) + && array_key_exists('auth_key', $_POST ) ) { - if ( ! check_session($_GET['session'] ) ) simple_authfail(); - if ( ! check_authkey($_GET['auth_key'] ) ) simple_authfail(); + if ( ! check_session($_POST['session'] ) ) simple_authfail(); + if ( ! check_authkey($_POST['auth_key'] ) ) simple_authfail(); } else simple_authfail(); } @@ -81,9 +130,54 @@ function check_authkey ( $key ) return false; } +function expire_authkeys() +{ + global $config; + + // Force deletion of sessions that have expired keys. + $query = sprintf("SELECT session, sessid FROM %s WHERE `last` < DATE_SUB( NOW(), INTERVAL %d MINUTE)", + $config['sessionkeys_table'], + $config['sessionkey_lifetime']); + $result = sql_dbquery( $config['hermes_db'], $query ); + while ( $row = @mysql_fetch_row( $result ) ) + { + remove_session( $row[0], $row[1] ); + } + + $query = sprintf("DELETE FROM %s WHERE `last` < DATE_SUB( NOW(), INTERVAL %d MINUTE)", + $config['sessionkeys_table'], + $config['sessionkey_lifetime']); + + sql_dbexec( $config['hermes_db'], $query ); +} + function update_authkey ( $session, $authid ) { + global $config; + $key = substr(new_key(), 0, 8); + + expire_authkeys(); + + // TODO: Refresh cookie + + $remote = $_SERVER['REMOTE_ADDR']; + $query = sprintf("INSERT INTO %s ( `sessid`, `session`, `authid`, `client`, `key`, `last` ) + VALUES ( '%s', '%s', '%s', '%s', '%s', NOW() ) + ON DUPLICATE KEY UPDATE `key` = '%s', `last` = NOW()", + $config['sessionkeys_table'], + session_id(), + session_name(), + sql_clean($authid), + sql_clean($remote), + sql_clean($key), + sql_clean($key)); + if ( ! sql_dbexec( $config['hermes_db'], $query ) ) + { + mysql_error(); + } + $_SESSION['kkey'] = $key; + $_SESSION['when'] = time(); return $key; } @@ -116,10 +210,6 @@ function check_session ( $name ) return clear_credentials($name); } - // TODO: Database checks? - - // TODO: Refresh cookie - // If we got this far, things are looking good. return true; } @@ -135,32 +225,220 @@ function set_credentials( $authid, $type ) $client_key = md5( $name . $authid ); setcookie('client_key', $client_key, time()+180*60, get_cookie_path() ); - // TODO: Stuff data to database for further checks? - // TODO: Do magic with the KEY - return $name; } function clear_credentials($name) { + global $config; + setcookie('client_key', '', 0, get_cookie_path() ); - setcookie($name, '', 0, "/"); + remove_session($name); $_SESSION = array(); + + $query = sprintf("DELETE FROM %s WHERE `session` = '%s'", + $config['sessionkeys_table'], + sql_clean($name)); + sql_dbexec( $config['hermes_db'], $query ); + + return false; +} + +function remove_session ($name, $id = null ) +{ + if ( $id == null ) + { + session_destroy(); + setcookie($name, '', 0, "/"); + return; + } + $current_session = session_name( ); + $current_sessid = session_id( ); + session_commit(); + + session_id( $id ); + session_start(); + setcookie( $name, '', 0, "/"); + $_SESSION=array(); session_destroy(); + + if ( $current_session && $current_session != $name ) + { + session_id($current_sessid); + session_start(); + } +} +function add_apikey ( $host, $level ) +{ + global $config; + if ( !is_numeric($level) ) return false; + + $key = new_key(); + + // Try to add the new key to authorizations first. If this + // fails, there will be the least amount of data to clean up ... + if ( ! update_authorization( "key", $key, $level ) ) return false; + + $query = sprintf("INSERT INTO %s ( host, apikey ) VALUES ( '%s', '%s' )", + $config['apikeys_table'], + sql_clean($host), + sql_clean($key)); + + if ( ! sql_dbexec( $config['hermes_db'], $query ) ) return false; + return $key; +} + +function remove_apikey( $key ) +{ + global $config; + if ( ! verify_apikey( $key, true ) ) return false; + if ( ! remove_authorization( $key ) ) return false; + + $query = sprintf("DELETE FROM %s WHERE apikey = '%s'", + $config['apikeys_table'], + sql_clean($key) ); + if ( ! sql_dbexec( $config['hermes_db'], $query ) ) return false; + + return true; +} + +function verify_apikey( $key, $skip_hostcheck = false ) +{ + global $config; + + $query = sprintf("SELECT host FROM %s WHERE apikey = '%s'", + $config['apikeys_table'], + sql_clean($key) ); + $row = sql_dbquery_single( $config['hermes_db'], $query ); + if (!$row) return false; + $host = $row['host']; + + if ( $host && ( $skip_hostcheck ) ) + return true; + + if ( $host == $_SERVER['REMOTE_ADDR'] ) return true; return false; + +} + +function list_apikeys () +{ + global $config; + $query = sprintf("SELECT k.apikey AS apikey, k.host AS host, + a.access_level AS access_level + FROM %s k INNER JOIN %s a ON k.apikey = a.authid + WHERE a.type = 'key'", + $config['apikeys_table'], + $config['authorizations_table']); + $list = array(); + $result = sql_dbquery( $config['hermes_db'], $query); + if ( ! $result ) return $list; + while ( $row = @mysql_fetch_assoc( $result ) ) + { + array_push( $list, array( + 'api_key' => $row['apikey'], + 'host' => $row['host'], + 'level' => authlevel_name( $row['access_level'] ) + )); + } + return $list; + +} + +function list_authusers () +{ + global $config; + $query = sprintf("SELECT authid, access_level + FROM %s + WHERE type = 'user'", + $config['authorizations_table']); + $list = array(); + $result = sql_dbquery( $config['hermes_db'], $query); + if ( ! $result ) return $list; + while ( $row = @mysql_fetch_assoc( $result ) ) + { + $username = $row['authid']; + $user_data = authuser_getinfo( $username ); + + // TODO: Remove invalid users here? + if ( ! $user_data ) continue; + + array_push( $list, array( + 'user' => $username, + 'name' => $user_data['name'], + 'email' => $user_data['email'], + 'level' => authlevel_name( $row['access_level'] ) + )); + } + return $list; + } -function get_authorization() + + + +function update_authorization( $type, $authid, $level ) { - return 1; + global $config; + if ( !is_numeric($level) ) return false; + if ( ($type != "key") && ($type != "user") ) return false; + + $query = sprintf("INSERT INTO %s ( authid, type, access_level ) VALUES ( '%s', '%s', %d ) + ON DUPLICATE KEY UPDATE access_level=%d", + $config['authorizations_table'], + sql_clean($authid), + $type, + $level, $level); + if ( ! sql_dbexec( $config['hermes_db'], $query ) ) return false; + return true; } + +function remove_authorization( $authid ) +{ + global $config; + $query = sprintf("DELETE FROM %s WHERE authid = '%s'", + $config['authorizations_table'], + sql_clean($authid) ); + //print $query . "\n\n"; + if ( ! sql_dbexec( $config['hermes_db'], $query ) ) return false; + return true; +} + + +function get_authorization( $type, $authid ) +{ + global $config; + + // If API-key is used, but key fails verification, write is impossible. + if ( ( $type == "key" ) && ( ! verify_apikey( $authid, true ) ) ) + return false; + + // If User-login is used, but backend is unable to provide info, fail. + if ( ( $type == "user" ) && ( ! authuser_getinfo( $authid ) ) ) + return false; + + // The only types of access control supported are "user" or "key". + if ( ($type != "user" ) && ($type != "key") ) + return false; + + $query = sprintf("SELECT access_level FROM %s WHERE authid = '%s'", + $config['authorizations_table'], + sql_clean($authid) ); + $row = sql_dbquery_single( $config['hermes_db'], $query ); + if (!$row) return false; + $level = $row['access_level']; + return $level; +} + function can_write ( ) { // Stub, to be called on any API nodes that write data in the DB. $authid = $_SESSION['authid']; $type = $_SESSION['type']; + $level = get_authorization( $type, $authid ); - return true; + if ( $level >= authlevel_value('read_write') ) return $level; + else return false; } ?>