]> git.defcon.no Git - hermes/commitdiff
Starting to get parts of an auth-framework operational...
authorJon Langseth <jon.langseth@lilug.no>
Wed, 18 Jan 2012 23:17:00 +0000 (00:17 +0100)
committerJon Langseth <jon.langseth@lilug.no>
Wed, 18 Jan 2012 23:17:00 +0000 (00:17 +0100)
api/auth.php
api/lib/auth_base.php
api/lib/auth_plugins/permitall.php

index 38b1560a7fbf409c9f45c5b00cf2df99c7e06bc2..1cad4029d9eb3d34e65110d2dc0e6523ef179ffc 100644 (file)
@@ -21,10 +21,86 @@ if ( !$config['sql_link'] )
 //*************************************************************************************        
        switch ( $_SERVER['PATH_INFO'] )
        {
+               case "/login":
+                       // Allow login using username and password, or API key.
+                       // On successful login, a named session should be started,
+                       // some data related to the session should be stored,
+                       // and the name of the session provided to the user
+                       // in the result.
+                       $type = false;
+                       $authid = false;
+
+                       if ( array_key_exists('username', $_GET) 
+                               && array_key_exists('password', $_GET) )
+                       {
+                               if ( 1 == authuser_verify( sql_clean($_GET['username']), sql_clean($_GET['password'])))
+                               {
+                                       $type = "user";
+                                       $authid = $_GET['username'];
+                               }
+                               else
+                               {
+                                       print json_encode( array( 'response' => 'failed', 'cause' => 'unauthorized', 'description' => 'Login failed') );
+                                       exit;
+                               }
+                       }
+                       else if ( array_key_exists('api_key', $_GET) )
+                       {
+                               if ( apikey_verify( sql_clean( $_GET['api_key'] ) ) == 1 )
+                               {
+                                       $type = "key";
+                                       $authid = $_GET['api_key'];
+                               }
+                               else
+                               {
+                                       print json_encode( array( 'response' => 'failed', 'cause' => 'unauthorized', 'description' => 'Login failed') );
+                                       exit;
+                               }
+                       }
+                       else
+                       {
+                               print json_encode ( array( 'response' => 'invalid') );
+                               break;  
+                       }
+                       $session_name = set_credentials( $authid, $type );
+                       $auth_key = update_authkey( $session_name, $authid );
+                       print json_encode( array( 'response' => 'ok', 'session' => $session_name, 'auth_key' => $auth_key ));
+                       break;
+               case "/ping":
+                       // API clients are required to periodically ping the server
+                       // The time between pings (interval) is 5 minutes?
+                       // A ping call should refresh cookie lifetimes and
+                       // generate and store a new auth_key
+                       // The ping required a valid session...
+                       // A successful ping returns a 'response' => 'pong'
+                       // along with the new auth_key.
+                       token_auth();
+                       $session_name = $_GET['session'];
+                       $authid = $_SESSION['authid'];
+                       $auth_key = update_authkey( $session_name, $authid );
+                       print json_encode( array( 'response' => 'pong', 'auth_key' => $auth_key ));
+                       break;
+               case "/logout":
+                       // De-authenticate/deauthorize the ongoing session.
+                       // I.e. destroy session data, remove session cookies.
+                       $session_name = "";
+                       if ( array_key_exists('session', $_GET ) )
+                               $session_name = $_GET['session'];
+                       session_name($session_name);
+                       session_start();
+                       clear_credentials($session_name);
+
+                       if ( $_SESSION )
+                               print json_encode ( array( 'response' => 'wtffailed?') );
+                       else
+                               print json_encode ( array( 'response' => 'ok') );
+                       break;
                case "/list_users":
                        // List valid API user-acounts.
                        // Fail with notauthorized if current authentication
                        // does not have write access.
+                       // Should not return users from backend, 
+                       // but should only return users with authorization.
                case "/authorize_user":
                        // Add or update a valid back-end user in authorization
                        // if the current authentication has write access.
index ae8a5ebf9989bdea71d30417757d3a03a1252f6c..dfecae7995e3626e33fcdb4249bfc887136c437a 100644 (file)
@@ -15,15 +15,13 @@ else
 {  print json_encode( array( 'response' => 'error', 'cause' => 'config-error' ) ); exit; }
 /*******************************/
 
-function check_authkey ( $key )
+function apikey_verify( $key )
 {
-       global $config;
-       if ( $key == "6327c08b70f9" ) return true;
+       if ( $key == "6327c08b70f9" ) return 1;
        return false;
-
 }
 
-function new_key(  )
+function new_key( $hex = false )
 {
        // Basically this is at the moment a slightly modified
        // version of generate_password() from user_functiions.php
@@ -33,8 +31,13 @@ function new_key(  )
        $string = "";
         while ( strlen( $string ) < $length )
         {
-               $string .= crypt( substr(sha1(rand()), 0, $length) );
-               $string = preg_replace( '/\W/', '', $string);
+               if ( $hex )
+                       $string .= substr(md5(rand().rand()), 0, $length);
+               else
+               {
+                       $string .= crypt( substr(sha1(rand()), 0, $length) );
+                       $string = preg_replace( '/\W/', '', $string);
+               }
         }
        return substr( $string, 0, $length );
 }
@@ -49,14 +52,114 @@ function token_auth( )
 {
        global $_GET;
 
-       if ( array_key_exists('auth_key', $_GET ) )
-       { if ( ! check_authkey($_GET['auth_key'] ) ) simple_authfail(); }
+       // TODO: Part of ping/pong requirement.
+       // Run a function to clear all authkeys older than 5 minutes.
+       // expire_authkeys();
+
+       if ( array_key_exists('session', $_GET ) 
+            && array_key_exists('auth_key', $_GET ) )
+       { 
+               if ( ! check_session($_GET['session'] ) ) simple_authfail();
+               if ( ! check_authkey($_GET['auth_key'] ) ) simple_authfail(); 
+       }
        else simple_authfail();
 }
 
+function get_cookie_path ()
+{
+       $name = $_SERVER["SCRIPT_NAME"];
+       $file = basename($name);
+       $path = preg_replace("/".$file."/", "", $name);
+       return $path;
+
+}
+
+function check_authkey ( $key )
+{
+       // TODO: Make real, actual checks...
+       if ( $key ) return true;
+       return false;
+}
+
+function update_authkey ( $session, $authid )
+{
+       $key = substr(new_key(), 0, 8);
+       return $key;
+}
+
+function check_session ( $name )
+{
+       session_name( $name );
+       session_start();
+       if ( ! $_SESSION['authid'] )
+       {
+               return clear_credentials($name);
+       }
+       if ( ! $_COOKIE['client_key'] )
+       {
+               return clear_credentials($name);
+       }
+
+       $authid = $_SESSION['authid'];
+       $type   = $_SESSION['type'];
+       $client_key = $_COOKIE['client_key'];
+
+       $level = get_authorization( $type, $authid );
+       if ( $level == false )
+       {
+               return clear_credentials($name);
+       }
+
+       $session_key = md5( $name . $authid );
+       if ( $client_key != $session_key )
+       {
+               return clear_credentials($name);
+       }
+
+       // TODO: Database checks?
+
+       // TODO: Refresh cookie
+
+       // If we got this far, things are looking good.
+       return true;
+}
+
+function set_credentials( $authid, $type )
+{
+       $name = new_key(true);
+       session_name( $name );
+       session_start();
+       $_SESSION['authid'] = $authid;
+       $_SESSION['type']   = $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)
+{
+       setcookie('client_key', '', 0, get_cookie_path() );
+       setcookie($name, '', 0, "/");
+
+       $_SESSION = array();
+       session_destroy();
+       return false;
+}
+function get_authorization()
+{
+       return 1;
+}
 function can_write ( )
 {
-       // Stub, to be called on any API nodes taht write data in the DB.
+       // 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;
 }
 
index 24a1ad41511b87d0de179be55843e1b140cc1e60..8bcd2baf84c7b3b1f2bbd9083ecd322125bb1599 100644 (file)
@@ -33,6 +33,10 @@ function authmethod_readonly ()
 // Fetch user geckos (basic display info)
 function authuser_getinfo ( $username )
 {
+       // Obviously we are returning dummy data here.
+       // on a real auth method, valid returns values
+       // would be a $user array on success, or false
+       // on error.
        $user['name']     = "Default User";
        $user['email']    = "example@example.com";
        return $user;