#!/bin/sh
# Example script for performing advanced user authorization for VirtualHere
# Sponsored by ben@wildblue.de
#
# Return 1 if the user is allowed to access this device
# Return 0 if the user is not allowed to access this device
#
# Parameters are passed in as:
# $1 = VENDOR_ID
# $2 = PRODUCT_ID
# $3 = CLIENT_ID
# $4 = CLIENT_IP
# $5 = PRODUCT_SERIAL
#
# Example: ./auth.sh "0529" "0001" "ben (ben)" "192.168.1.100" ""
# ----------------------------------------------------------------------
logger "Authorizing -> '$1' '$2' '$3' '$4' '$5'";


# Enable Logging of all Requests
   ENABLE_LOGGING=true;
   LOGFILE=/var/log/VirtualHere_Auth.log;

# Configured Devices
#  DEVICE_CONFIG_X=( UniqueID "Device_NickName"      "VendorID" "ProductID");
   DEVICE_CONFIG_0=( 0        "NotConfiguredDevices" ALL                   );
   DEVICE_CONFIG_1=( 1        "USB-Dongle"           "0529"      "0001"    );
   DEVICE_CONFIG_2=( 2        "KVM-Switch"           "0B39"      "1001"    );
   DEVICE_CONFIG_3=( 3        "Mouse"                "0A01"      "1000"    );

# Configured Users
#  USER_CONFIG_X=( UniqueID   "username"   USB-IDs );
   USER_CONFIG_0=( 0          "everyone"   0       );
   USER_CONFIG_1=( 1          "admin"      0 1     );
   USER_CONFIG_2=( 2          "ben"        ALL     );
   USER_CONFIG_3=( 3          "joe"          1 2   );
   USER_CONFIG_4=( 4          "flo"                );
   USER_CONFIG_5=( 5          "patrik"     0   2   );

# Configured IP-Addresses
#  IP_CONFIG_X=( UniqueID     "IP-address"               UserIDs );
   IP_CONFIG_0=( 0            "NotConfiguredAddresses"   0 1 2   );
   IP_CONFIG_1=( 1            "192.168.1.100"            0 1 2 3 );
   IP_CONFIG_2=( 2            "192.168.1.140"            ALL     );
   IP_CONFIG_3=( 3            "192.168.1.101"              1 2   );
   IP_CONFIG_4=( 4            "192.168.1.102"                    );
   IP_CONFIG_5=( 5            "192.168.1.130"            0   2   );


# ----------------------------------------------------------------------
# Map Parameters to readable VariableNames
   VENDOR_ID=$1;
   PRODUCT_ID=$2;
   CLIENT_ID=$3;
   CLIENT_IP=$4;
   PRODUCT_SERIAL=$5;


# Pre-Authorization-Check (requested User and current Device must be configured)
   CURRENT_DEVICE=();
   for ARRAY_NAME in ${!DEVICE_CONFIG_@}; do
      # Get Data from DeviceConfig-Array
      DEVICE_CONFIG=($(eval "echo \${$ARRAY_NAME[@]}"));

      # Check DeviceConfig-Arguments
      COUNT_ARGS=${#DEVICE_CONFIG[@]};
      if [[ $COUNT_ARGS -eq 4 ]]; then
         # This Device has a complete DataSet
         # Is this the CurrentRequested Device
         DEVICE_UID=${DEVICE_CONFIG[0]};
         DEVICE_NICKNAME=${DEVICE_CONFIG[1]};
         DEVICE_VENDOR_ID=${DEVICE_CONFIG[2]};
         DEVICE_PRODUCT_ID=${DEVICE_CONFIG[3]};

         if [ "$VENDOR_ID" == "$DEVICE_VENDOR_ID" ] &&
            [ "$PRODUCT_ID" == "$DEVICE_PRODUCT_ID" ]; then
            CURRENT_DEVICE=(${DEVICE_CONFIG[@]});
         fi
      fi
   done;
   if [[ "${#CURRENT_DEVICE[*]}" -eq 0 ]]; then CURRENT_DEVICE=(${DEVICE_CONFIG_0[@]}); fi

   CURRENT_USER=();
   for ARRAY_NAME in ${!USER_CONFIG_@}; do
      # Get Data from UserConfig-Array
      USER_CONFIG=($(eval "echo \${$ARRAY_NAME[@]}"));

      # Check UserConfig-Arguments
      COUNT_ARGS=${#USER_CONFIG[@]};
      if [[ $COUNT_ARGS -gt 2 ]]; then
         # This User has Device-Authentification specified
         # Is this the CurrentRequested User
         USER_NAME=${USER_CONFIG[1]};
         if [[ "$CLIENT_ID" == *"($USER_NAME)"* ]]; then
            CURRENT_USER=(${USER_CONFIG[@]});
         fi
      fi
   done;
   if [[ "${#CURRENT_USER[*]}" -eq 0 ]]; then CURRENT_USER=(${USER_CONFIG_0[@]});     fi

   CURRENT_IPADDRESS=();
   for ARRAY_NAME in ${!IP_CONFIG_@}; do
      # Get Data from IPConfig-Array
      IP_CONFIG=($(eval "echo \${$ARRAY_NAME[@]}"));

      # Check IPConfig-Arguments
      COUNT_ARGS=${#IP_CONFIG[@]};
      if [[ $COUNT_ARGS -gt 2 ]]; then
         # This IP-Address has a complete DataSet
         # Is this the CurrentRequested IP-Address
         IP_ADDRESS=${IP_CONFIG[1]};

         if [[ "$CLIENT_IP" == "$IP_ADDRESS" ]]; then
            CURRENT_IPADDRESS=(${IP_CONFIG[@]});
         fi
      fi
   done;
   if [[ "${#CURRENT_IPADDRESS[*]}" -eq 0 ]]; then CURRENT_IPADDRESS=(${IP_CONFIG_0[@]});  fi


# Configured Device-User-IpAddress Authorization
   if [ "${#CURRENT_USER[*]}" -gt 0  ] &&
      [ "${#CURRENT_DEVICE[*]}" -gt 0 ] &&
      [ "${#CURRENT_IPADDRESS[*]}" -gt 0 ]; then
      USER_AUTHORIZED=false;
      ID_USER=0;
      for AUTH_PARAM in ${CURRENT_USER[@]}; do
         if [[ ID_USER -gt 1 ]]; then
            if [ "$AUTH_PARAM" == "ALL" ] ||
               [ "$AUTH_PARAM" == ${CURRENT_DEVICE[0]} ]; then
               USER_AUTHORIZED=true;
            fi
         fi
         let "ID_USER += 1";
      done;

      IPADDRESS_AUTHORIZED=false;
      ID_IPADDRESS=0;
      for AUTH_PARAM in ${CURRENT_IPADDRESS[@]}; do
         if [[ ID_IPADDRESS -gt 1 ]]; then
            if [ "$AUTH_PARAM" == "ALL" ] ||
               [ "$AUTH_PARAM" == ${CURRENT_USER[0]} ]; then
               IPADDRESS_AUTHORIZED=true;
            fi
         fi
         let "ID_IPADDRESS += 1";
      done;
   fi

   AUTHORIZED=false;
   AUTH_RESULT="NOT Authorized!";
   if [ "$USER_AUTHORIZED" == true ] &&
      [ "$IPADDRESS_AUTHORIZED" == true ]; then
      AUTHORIZED=true;
      AUTH_RESULT="Authorized!";
   fi

# Define Logging
   if [[ "$ENABLE_LOGGING" == true ]]; then
      # Create new Logfile-Entry with current Date, User and Parameters
      echo "`date`, User: [$USER]"                                >> $LOGFILE;
      echo "    Used Parameters     : ['$1' '$2' '$3' '$4' '$5']" >> $LOGFILE;
      echo "    Selected Device     : ${CURRENT_DEVICE[@]}"       >> $LOGFILE;
      echo "    Selected User       : ${CURRENT_USER[@]}"         >> $LOGFILE;
      echo "    Selected IP-Address : ${CURRENT_IPADDRESS[@]}"    >> $LOGFILE;
      echo "    Auth-Result         : $AUTH_RESULT"               >> $LOGFILE;
   fi


# Final Authorization of the current Request
   logger $AUTH_RESULT;

   if [[ "$AUTHORIZED" == true ]]; then exit 1;
   else exit 0; fi
