SMS Login Architecture

Author: Ajay Kumar [ ajuonline at gmail dot com]
Created: 2008/06/07 05:56
Link Back: GSoC 2008 Messaging Module

Current login architecture takes into consideration only Sahana Core users, i.e. users who are registered as users in the Sahana system and their record exists in the DB.
Public usage for potential news alert broadcasts, or public information IVR via SMS can be implemented following the similar approach. The module is being written keeping this in mind.

Files to be added:

  1. /mod/msg/lib_sms_main.inc [Base structure committed to CVS]
    1. Purpose of File: Main include file for the SMS System calls other files and performs functions
  2. /mod/msg/lib_sms_handler.inc [Base structure committed to CVS]
    1. Purpose of File: Handles all communication as a result of SMS input. Parse SMS, Check keywords, Trigger corresponding functions as per SMS input
  3. /mod/msg/lib_sms_session.inc
    1. Purpose of File: Provide SMS Based Session management based on caller ID/mobile number
  4. /inc/lib_security/lib_sms_auth.inc [Base structure committed to CVS]
    1. Check Screenshot of working code
    2. Purpose of File: Provide SMS Based Authorisation as per Sahana Framework draws from lib_auth.inc
  5. /inc/lib_security/lib_sms_acl.inc
    1. Purpose of File: Provide SMS Based Authentication and assigns role to User as per Sahana Framework draws from lib_acl.inc
  6. /mod/msg/lib_sms_errors.inc [Base structure committed to CVS]
    1. Purpose of File: Errors sent to users as output via SMS on receiving SMS input.
  7. /mod/msg/lib_sms_menu.inc
    1. Purpose of File: SMS Menu sent to users

Changes in SQL Schema:

  1. Add 1 field in table “person_uuid”. Field name: mobile_number char(32) NULL UNIQUE. Purpose: Store mobile number of the user in the format “919898989898” without using any special characters.
  2. Add 1 field in table “users”. Field name: “sms_auth_status” varchar(60) NULL DEFAULT active. Purpose: To check if a particular user is authorised to communicate to Sahana Server over SMS.

** This needs to be done in one of the messaging tables. Still to figure out where and how exactly.

Pseudocode:

  1. Take SMS Input from SMS Plugin's handler. We process SMS after its posted to Sahana & inserted to DB.
  2. We get the following values in the array $received_message[]:
    1. ['sender'] = Caller ID
    2. ['received'] = Received Timestamp
    3. ['message'] = Message text
  3. Check “sender” session state/authenticated state
    1. if “sender” has a VALID and AUTHENTICATED session
      1. If “senders” “menu_state” EXISTS in “session” i.e. last menu accessed by SMS to resume processing of SMS input
      2. If “senders” “menu_state” NOT EXISTS in “session”, we process incoming SMS from Scratch
  4. If “sender” session is INVALID and UNAUTHENTICATED, the check authentication via ”/inc/security/lib_sms_auth.inc”
    1. if value of “sender” exists in field “mobile_number” of “person_uuid” table.
      1. retrieve “p_uuid” of user
      2. check “sms_auth_status” of user with “p_uuid” in table “users”
      3. If “sms_auth_status” == active.
        1. return login result as 1
        2. proceed to message parsing & keyword check.
      4. else if [sms_auth_status!=active]
        1. send_sms_error(“Sorry you are not authorised to access the Sahana SMS Server. Kindly login or contact Sahana Administrator”)
        2. Code Terminates
    2. else if value of “sender” does NOT exists in field “mobile_number” of “person_uuid” table.
      1. This part checks for keyword “login username password” in the “message” and autheticates user via ”/inc/security/lib_sms_auth.inc”
      2. Parse the message by $parsed_message = _shn_msg_parse_short_message($message);
      3. Check if $parsed_message[0] == “login” then send $parsed_message to login check function in /lib/security/lib_sms_auth.inc
      4. Else if $parsed_message[0] != “login” send send_sms_error(“Sorry you are not authorised to access the Sahana SMS Server. Kindly login or contact Sahana Administrator”)

Parser Function:

function _shn_msg_parse_short_message($message){
     $parsed_message=array();
     $parsed_message = explode(" ", $message);
     return $parsed_message;
 }

Small Prototype in PHP Demonstrating the Login via SMS to Sahana DB

         <?
         $message=$_GET["msg"];
 
         function _shn_msg_parse_short_message($message){
             $parsed_message=array();
             $parsed_message = explode(" ", $message);
             return $parsed_message;
         }
 
         $output = _shn_msg_parse_short_message($message);
         $count = count($output);
         echo "Count = $count <br \>";
         print_r($output);
         echo "<br \>Login Part:<br \>";
         if($output[0]=='login')
         {
         $user = $output[1];
         echo "User name: ".$user;
         echo "<br \>Password = ";
         for($i=2; $i<$count; $i++){
           $password .= $output[$i];
           if($i!=$count-1) $password .= " "; // to avoid additional space
         }
 
         }
         echo "\"".$password."\"";
         $pass = $password;
 
         //Sahana Login replace DB functions from sysconf.inc and /inc/handler_db.inc
         mysql_connect("localhost", "root", "") or die(mysql_error());
         mysql_select_db("sahana") or die(mysql_error());
 
         //Sahana Password building from lib_auth.inc
         	$q = "  SELECT p_uuid,salt  FROM users
                             WHERE user_name = '$user'";
         	$res=mysql_query($q) or die(mysql_error());
         	if(mysql_num_rows($res)==0){
         		echo "User name does not exists";
                         break;
         	}else{
         		while($result = mysql_fetch_array($res)){
         		$salt=$result['salt'];
         		}
         		echo "<br \>Salt = ".$salt."<br \>"; 
         	}
 
         	$pwd=substr($pass, 0, 4).$salt.substr($pass, 4);
 
         	// Create a digest of the password collected from the challenge 
         	$password_digest = md5(trim($pwd)); 
         	echo "Digest : ".$password_digest; 
         	// Formulate the SQL to find the user 
         	$q = "  SELECT p_uuid  FROM users \\
                             WHERE user_name = '$user'
                             AND password = '$password_digest' and salt='{$salt}'";
         	$res=mysql_query($q) or die(mysql_error());
         	if(mysql_num_rows($res)==0){ 
         		echo "<br \>Login Failed"; 
         	}else{ 
         		echo "<br \>Login Success";
         	}
?>

* — Ajay Kumar 2008/06/07 05:39


Navigation
  • Navigate