]> git.defcon.no Git - hermes/blobdiff - api/auth.php
Added license text
[hermes] / api / auth.php
index 38b1560a7fbf409c9f45c5b00cf2df99c7e06bc2..451581321a03b1f6e233d73713f73ad8a34388b5 100644 (file)
@@ -1,4 +1,30 @@
 <?php
+/*
+#  Copyright (c) 2012, Gjøvik University College
+#  All rights reserved.
+
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#      * Redistributions of source code must retain the above copyright
+#        notice, this list of conditions and the following disclaimer.
+#      * Redistributions in binary form must reproduce the above copyright
+#        notice, this list of conditions and the following disclaimer in the
+#        documentation and/or other materials provided with the distribution.
+#      * Neither the name of the Gjøvik University College nor the
+#        names of its contributors may be used to endorse or promote products
+#        derived from this software without specific prior written permission.
+#       
+#  THIS SOFTWARE IS PROVIDED BY Gjøvik University College ''AS IS'' AND ANY
+#  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+#  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+#  DISCLAIMED. IN NO EVENT SHALL Gjøvik University College BE LIABLE FOR ANY
+#  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+#  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+#  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+#  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+#  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
 require_once('config.php');
 require_once('lib/auth_base.php');
 require_once('lib/common_functions.php');
@@ -19,12 +45,155 @@ if ( !$config['sql_link'] )
 }
 
 //*************************************************************************************        
+if ( ( $_SERVER['PATH_INFO'] == "/login" ) || ( $_SERVER['PATH_INFO'] == "/logout" ) )
+{
        switch ( $_SERVER['PATH_INFO'] )
        {
-               case "/list_users":
-                       // List valid API user-acounts.
-                       // Fail with notauthorized if current authentication
-                       // does not have write access.
+               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', $_POST) 
+                               && array_key_exists('password', $_POST) )
+                       {
+                               if ( 1 == authuser_verify( sql_clean($_POST['username']), sql_clean($_POST['password'])))
+                               {
+                                       $type = "user";
+                                       $authid = $_POST['username'];
+                               }
+                               else
+                               {
+                                       print json_encode( array( 'response' => 'failed', 'cause' => 'unauthorized', 'description' => 'Login failed') );
+                                       exit;
+                               }
+                       }
+                       else if ( array_key_exists('api_key', $_POST) )
+                       {
+                               if ( verify_apikey( sql_clean( $_POST['api_key'] ) ) == 1 )
+                               {
+                                       $type = "key";
+                                       $authid = $_POST['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 "/logout":
+                       // De-authenticate/deauthorize the ongoing session.
+                       // I.e. destroy session data, remove session cookies.
+                       $session_name = "";
+                       if ( array_key_exists('session', $_POST ) )
+                               $session_name = $_POST['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;
+               default:
+                       print json_encode ( array( 'response' => 'invalid') );
+       }
+}
+else
+{
+       token_auth();
+
+       switch ( $_SERVER['PATH_INFO'] )
+       {
+               case "/ping":
+                       // API clients are required to periodically ping the server
+                       // The time between pings (interval) is 5 minutes?
+                       // A ping call refreshes cookie lifetimes, then
+                       // generates and stores a new auth_key
+                       // The ping required a valid session...
+                       // A successful ping returns a 'response' => 'pong'
+                       // along with the new auth_key.
+                       $session_name = $_POST['session'];
+                       $authid = $_SESSION['authid'];
+                       $auth_key = update_authkey( $session_name, $authid );
+                       print json_encode( array( 'response' => 'pong', 'auth_key' => $auth_key ));
+                       break;
+               case "/new_apikey":
+                       // If the current authorization has write access, create
+                       // a new API key with requested access (ro/rw).
+                       if ( ! can_write() )
+                               simple_authfail();
+
+                       if ( array_key_exists('host_ip', $_POST )
+                               && array_key_exists('access', $_POST ))
+                       {
+                               $host = $_POST['host_ip'];
+                               $access = $_POST['access'];
+
+                               if (! preg_match("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/", $host) || ! authlevel_value( $access ) )
+                               {
+                                       print json_encode ( array( 'response' => 'invalid', 'cause' => 'parameters' ) );
+                                       break;  
+                               }
+                               $level = authlevel_value( $access );
+                               $key = add_apikey( $host, $level );
+                               if ( ! $key )
+                               {
+                                       print json_encode( array( 'response' => 'failed', 'cause' => 'error', 'detail' => 'Database error.'));
+                                       break;
+                               }
+                               print json_encode( array( 'response' => 'ok', 'key' => $key, 'host' => $host, 'access' => authlevel_name( get_authorization( "key", $key ) ) ) );
+                               break;
+                       }
+                       else print json_encode ( array( 'response' => 'invalid') );
+                       break;  
+               case "/remove_apikey":
+                       // If the current authorization has write access,
+                       // remove the given API key.
+                       if ( ! can_write() )
+                               simple_authfail();
+
+                       if ( array_key_exists('api_key', $_POST ) )
+                       {
+                               $key = sql_clean( $_POST['api_key'] );
+                               // Perform a key-verification, skipping host/remote-address check.
+                               if ( ! verify_apikey( $key, true ) )
+                               {
+                                       print json_encode( array ( 'response' => 'failed', 'cause' => 'nonexistant'));
+                                       break;
+                               }
+                               if ( ! remove_apikey( $key ) )
+                               {
+                                       print json_encode( array( 'response' => 'failed', 'cause' => 'error', 'detail' => 'Database error.'));
+                                       break;
+                               }
+                               print json_encode( array( 'response' => 'ok', 'key' => $key ) );
+                               break;
+                       }
+                       else print json_encode ( array( 'response' => 'invalid') );
+                       break;  
+               case "/list_apikeys":
+                       // List valid API keys.
+                       // Fail is current authorization does not have write access.
+                       if ( ! can_write() )
+                               simple_authfail();
+                       $list = list_apikeys();
+                       print json_encode( array( 'response' => 'ok', 'list' => $list ) );
+                       break;
                case "/authorize_user":
                        // Add or update a valid back-end user in authorization
                        // if the current authentication has write access.
@@ -32,30 +201,104 @@ if ( !$config['sql_link'] )
                        // needed parameters should be username and access level
                        // If the authorization does not exist, add it.
                        // If the user is already authorized, replace access level.
+                       if ( ! can_write() )
+                               simple_authfail();
+
+                       if ( array_key_exists('username', $_POST )
+                               && array_key_exists('access', $_POST ))
+                       {
+                               $user = $_POST['username'];
+                               $access = $_POST['access'];
+                               $level = authlevel_value( $access );
+
+                               if ( ! $level )
+                               {
+                                       print json_encode ( array( 'response' => 'invalid', 'cause' => 'parameters' ) );
+                                       break;  
+                               }
+                               if ( ! authuser_getinfo( $user ) )
+                               {
+                                       print json_encode( array ( 'response' => 'failed', 'cause' => 'nonexistant'));
+                                       break;
+                               }
+
+                               if ( ! update_authorization( "user", $user, $level ) )
+                               {
+                                       print json_encode( array( 'response' => 'failed', 'cause' => 'error', 'detail' => 'Database error.'));
+                                       break;
+                               }
+
+                               print json_encode( array( 'response' => 'ok', 'user' => $user, 'access' => authlevel_name( get_authorization( "user", $user ) ) ) );
+                               break;
+                       }
+                       else print json_encode ( array( 'response' => 'invalid') );
+                       break;  
+
+               case "/remove_user":
+                       // If the current authentication has write access:
+                       // Remove authorization for the given users.
+                       // Delete user from backend if backend is read-write.
+                       if ( ! can_write() )
+                               simple_authfail();
+
+                       if ( array_key_exists('username', $_POST ))
+                       {
+                               $user = $_POST['username'];
+
+                               $t_level = get_authorization( "user", $user ); 
+
+                               if ( $t_level && ! remove_authorization( $user ) )
+                               {
+                                       print json_encode( array( 'response' => 'failed', 'cause' => 'error', 'detail' => 'Database error.'));
+                                       break;
+                               }
+                               if ( ! authmethod_readonly() )
+                               {
+                                       if ( !authuser_getinfo( $user ) )
+                                       {
+                                               print json_encode( array ( 'response' => 'failed', 'cause' => 'nonexistant'));
+                                               break;
+                                       }
+                                       if ( !authuser_delete( $user ) )
+                                       {
+                                               print json_encode( array( 'response' => 'failed', 'cause' => 'error', 'detail' => 'Database error.'));
+                                               break;
+                                       }
+                               }
+
+                               print json_encode( array( 'response' => 'ok', 'user' => $user ) );
+                               break;
+                       }
+                       else print json_encode ( array( 'response' => 'invalid') );
+                       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.
+                       if ( ! can_write() )
+                               simple_authfail();
+                       $list = list_authusers();
+                       print json_encode( array( 'response' => 'ok', 'list' => $list ) );
+                       break;
+
                case "/add_user":
                        // Add user to backend if backend is read-write and
                        // the current authentication has write access.
+                       // The created user should be added to authorizations
+                       // with an access level of "limited_read (1)"
                case "/update_user":
                        // Update the given user in the backend, if the backend
                        // is read-write, and the current authentication has
                        // write access.
-               case "/remove_user":
-                       // Delete user from backend if backend is read-write
-                       // and the current authentication has write access.
-               case "/list_apikeys":
-                       // List valid API keys.
-                       // Fail is current authorization does not have write access.
-               case "/new_apikey":
-                       // If the current authorization has write access, create
-                       // a new API key with requested access (ro/rw).
-               case "/remove_apikey":
-                       // If the current authorization has write access,
-                       // remove the given API key.
                        print json_encode ( array( 'response' => 'notimplemented') );
                        break;
                default:
                        print json_encode ( array( 'response' => 'invalid') );
        }
+}
 //*************************************************************************************        
 mysql_close( $config['sql_link'] );
 ?>