You are here

class MoAuthUtilities in Google Authenticator / 2 Factor Authentication - 2FA 7

@file This file is part of miniOrange 2FA module.

The miniOrange 2FA module is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

miniOrange 2FA module is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with miniOrange 2FA module. If not, see <http://www.gnu.org/licenses/>.

Hierarchy

Expanded class hierarchy of MoAuthUtilities

File

classes/Utilities.php, line 21
This file is part of miniOrange 2FA module.

View source
class MoAuthUtilities {
  public static function get_2fa_methods_for_inline_registration($methods_selected) {
    if ($methods_selected === TRUE && variable_get('mo_auth_enable_allowed_2fa_methods', FALSE)) {
      $selected_2fa_methods = json_decode(variable_get('mo_auth_selected_2fa_methods'), TRUE);
      if (is_array($selected_2fa_methods) && !empty($selected_2fa_methods)) {
        return $selected_2fa_methods;
      }
    }
    $options = array(
      AuthenticationType::$EMAIL_VERIFICATION['code'] => AuthenticationType::$EMAIL_VERIFICATION['name'],
      AuthenticationType::$GOOGLE_AUTHENTICATOR['code'] => AuthenticationType::$GOOGLE_AUTHENTICATOR['name'],
      AuthenticationType::$MICROSOFT_AUTHENTICATOR['code'] => AuthenticationType::$MICROSOFT_AUTHENTICATOR['name'],
      AuthenticationType::$AUTHY_AUTHENTICATOR['code'] => AuthenticationType::$AUTHY_AUTHENTICATOR['name'],
      AuthenticationType::$LASTPASS_AUTHENTICATOR['code'] => AuthenticationType::$LASTPASS_AUTHENTICATOR['name'],
      AuthenticationType::$SMS['code'] => AuthenticationType::$SMS['name'],
      AuthenticationType::$OTP_OVER_EMAIL['code'] => AuthenticationType::$OTP_OVER_EMAIL['name'],
      AuthenticationType::$SMS_AND_EMAIL['code'] => AuthenticationType::$SMS_AND_EMAIL['name'],
      AuthenticationType::$OTP_OVER_PHONE['code'] => AuthenticationType::$OTP_OVER_PHONE['name'],
      AuthenticationType::$KBA['code'] => AuthenticationType::$KBA['name'],
      AuthenticationType::$QR_CODE['code'] => AuthenticationType::$QR_CODE['name'],
      AuthenticationType::$PUSH_NOTIFICATIONS['code'] => AuthenticationType::$PUSH_NOTIFICATIONS['name'],
      AuthenticationType::$SOFT_TOKEN['code'] => AuthenticationType::$SOFT_TOKEN['name'],
    );
    return $options;
  }
  public static function addSupportForm(&$form, $form_state) {
    drupal_add_js(drupal_get_path('module', 'mo_auth') . '/includes/js/Phone.js', 'file');
    drupal_add_css(drupal_get_path('module', 'mo_auth') . '/includes/css/phone.css', array(
      'group' => CSS_DEFAULT,
      'every_page' => FALSE,
    ));
    $form['markup_idp_attr_header_top_support'] = array(
      '#markup' => '<div class="mo2f_table_layout_support_2">',
    );
    $form['markup_support_1'] = array(
      '#markup' => '<div style="font-size:20px;margin-top:10px;margin-bottom:8px;"><b>Support:</b></div></span></h3><div>Need any help? Just send us a query so we can help you.<br /></div>',
    );
    $form['miniorange_saml_email_address_support'] = array(
      '#type' => 'textfield',
      '#attributes' => array(
        'style' => 'width:100%',
        'placeholder' => 'Enter your Email',
      ),
      '#default_value' => variable_get('mo_auth_customer_admin_email', ''),
    );
    $form['miniorange_saml_phone_number_support'] = array(
      '#type' => 'textfield',
      '#id' => 'query_phone',
      '#attributes' => array(
        'class' => array(
          'query_phone',
        ),
        'style' => 'width:100%',
      ),
      '#default_value' => variable_get('mo_auth_customer_admin_phone', ''),
    );
    $form['miniorange_saml_support_query_support'] = array(
      '#type' => 'textarea',
      '#cols' => '10',
      '#rows' => '5',
      '#attributes' => array(
        'style' => 'width:100%',
        'placeholder' => 'Write your query here.',
      ),
    );
    $form['miniorange_saml_support_submit_click'] = array(
      '#type' => 'submit',
      '#value' => t('Submit Query'),
      '#submit' => array(
        'miniorange_2fa_send_query',
      ),
      '#prefix' => '<p style="text-align: center">',
      '#suffix' => '</p>',
      '#limit_validation_errors' => array(),
    );
    $form['miniorange_saml_support_note'] = array(
      '#markup' => '<div>If you want custom features in the module, just drop an email to <a href="mailto:drupalsupport@xecurify.com">drupalsupport@xecurify.com</a></div><br><hr><br>',
    );
    self::faq($form, $form_state);
    $form['miniorange_sp_guide_link_end'] = array(
      '#markup' => '</div>',
    );
  }
  public static function send_support_query($email, $phone, $query) {
    if (empty($email) || empty($query)) {
      drupal_set_message(t('The <b><u>Email</u></b> and <b><u>Query</u></b> fields are mandatory.'), 'error');
      return;
    }
    elseif (!valid_email_address($email)) {
      drupal_set_message(t('The email address <b><i>' . $email . '</i></b> is not valid.'), 'error');
      return;
    }
    $support = new Miniorange2FASupport($email, $phone, $query);
    $support_response = $support
      ->sendSupportQuery();
    if ($support_response) {
      drupal_set_message(t('Your support query has been sent successfully. We will get back to you soon.'));
    }
    else {
      drupal_set_message(t('Error sending support query. Please try again.'), 'error');
    }
  }
  public static function faq(&$form, &$form_state) {
    $form['miniorange_2fa_faq'] = array(
      '#markup' => '<div class="mo2f_text_center"><b></b>
                          <a class="mo2f_btn mo2f_btn-primary-faq mo2f_btn_faq_buttons mo_faq_button_left" href="https://faq.miniorange.com/kb/drupal/two-factor-authentication-drupal/" target="_blank">FAQs</a>
                          <b></b><a class="mo2f_btn mo2f_btn-primary-faq mo2f_btn_faq_buttons mo_faq_button_right" href="https://forum.miniorange.com/" target="_blank">Ask questions on forum</a></div>',
    );
  }
  public static function check_roles_to_invoke_2fa($roles) {
    $mo_auth_enable_role_based_2fa = variable_get('mo_auth_enable_role_based_2fa');
    $mo_auth_enable_use_only_2nd_factor = variable_get('mo_auth_two_factor_instead_password');
    if ($mo_auth_enable_role_based_2fa !== TRUE || $mo_auth_enable_use_only_2nd_factor === TRUE) {
      return TRUE;
    }
    $return_value = FALSE;
    $selected_roles = (array) json_decode(variable_get('mo_auth_role_based_2fa_roles'));
    foreach ($selected_roles as $sysName => $displayName) {
      if (in_array($displayName, $roles, TRUE)) {
        $return_value = TRUE;
        break;
      }
    }
    return $return_value;
  }
  public static function check_domain_to_invoke_2fa($moUserEmail) {
    $moUserEmail = strtolower($moUserEmail);
    $mo_auth_enable_domain_based_2fa = variable_get('mo_auth_enable_domain_based_2fa');
    if ($mo_auth_enable_domain_based_2fa != TRUE) {
      return TRUE;
    }
    $return_value = FALSE;
    $selected_domains = explode(';', variable_get('mo_auth_two_factor_domain_based_2fa_domains'));
    $moUserDomain = substr(strrchr($moUserEmail, "@"), 1);
    if (in_array($moUserDomain, $selected_domains)) {
      $return_value = TRUE;
    }
    if ($return_value == TRUE) {
      $exceptionEmails = variable_get('mo_auth_2fa_domain_exception_emails', '');
      $exceptionEmailsArray = explode(";", $exceptionEmails);
      foreach ($exceptionEmailsArray as $key => $value) {
        if (strcasecmp($value, $moUserEmail) == 0) {
          $return_value = FALSE;
          break;
        }
      }
    }
    $whiteOrBlack = variable_get('mo_2fa_domains_are_white_or_black', 'black') == 'white' ? FALSE : TRUE;
    return $return_value == $whiteOrBlack;
  }
  public static function isKbaConfigured($user_configured_array) {
    $kba_configured = 0;
    $total = count($user_configured_array);
    for ($i = 0; $i < $total; $i++) {
      if ($user_configured_array[$i]['value'] == "KBA") {
        $kba_configured = 1;
      }
    }
    return $kba_configured;
  }
  public static function isCurlInstalled() {
    if (in_array('curl', get_loaded_extensions())) {
      return 1;
    }
    else {
      return 0;
    }
  }
  public static function isCustomerRegistered() {
    if (variable_get('mo_auth_customer_admin_email', NULL) == NULL || variable_get('mo_auth_customer_id', NULL) == NULL || variable_get('mo_auth_customer_token_key', NULL) == NULL || variable_get('mo_auth_customer_api_key', NULL) == NULL) {
      return FALSE;
    }
    return TRUE;
  }
  public static function get_timestamp() {
    $url = MoAuthConstants::getBaseUrl() . '/rest/mobile/get-timestamp';
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_ENCODING, "");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_AUTOREFERER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

    // required for https urls
    curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
    curl_setopt($ch, CURLOPT_POST, true);
    $content = curl_exec($ch);
    if (curl_errno($ch)) {
      echo 'Error in sending curl Request';
      exit;
    }
    curl_close($ch);
    return $content;
  }
  public static function getHiddenEmail($email) {
    $split = explode("@", $email);
    if (count($split) == 2) {
      $hidden_email = substr($split[0], 0, 1) . 'xxxxxx' . substr($split[0], -1) . '@' . $split[1];
      return $hidden_email;
    }
    return $email;
  }
  public static function indentSecret($secret) {
    $strlen = strlen($secret);
    $indented = '';
    for ($i = 0; $i <= $strlen; $i = $i + 4) {
      $indented .= substr($secret, $i, 4) . ' ';
    }
    $indented = trim($indented);
    return $indented;
  }
  public static function callService($customer_id, $apiKey, $url, $json) {
    if (!self::isCurlInstalled()) {
      return json_encode(array(
        "status" => 'CURL_ERROR',
        "message" => 'PHP cURL extension is not installed or disabled.',
      ));
    }
    $ch = curl_init($url);
    $current_time_in_millis = round(microtime(TRUE) * 1000);
    $string_to_hash = $customer_id . number_format($current_time_in_millis, 0, '', '') . $apiKey;
    $hash_value = hash("sha512", $string_to_hash);
    $customer_key_header = "Customer-Key: " . $customer_id;
    $timestamp_header = "Timestamp: " . number_format($current_time_in_millis, 0, '', '');
    $authorization_header = "Authorization: " . $hash_value;
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
    curl_setopt($ch, CURLOPT_ENCODING, "");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_AUTOREFERER, TRUE);

    // Required for https urls.
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
      "Content-Type: application/json",
      $customer_key_header,
      $timestamp_header,
      $authorization_header,
    ));
    curl_setopt($ch, CURLOPT_POST, TRUE);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
    curl_setopt($ch, CURLOPT_TIMEOUT, 20);
    $content = curl_exec($ch);

    // $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    if (curl_errno($ch)) {
      return json_encode(array(
        "status" => 'CURL_ERROR',
        "message" => curl_errno($ch),
      ));
    }
    curl_close($ch);
    return json_decode($content);
  }

  /**
   * Return current URL parts.
   */
  public static function mo_auth_get_url_parts() {
    $query_param = current_path();
    $url_parts = explode('/', $query_param);
    return $url_parts;
  }

  /**
   * Collect system specific information using JS files
   * @param $username
   */
  public static function mo2f_collect_device_attributes_handler($username) {
    global $base_url;
    if (empty(session_id())) {
      session_start();
    }
    $session_id_encrypt = session_id();
    $module_path = drupal_get_path('module', 'mo_auth');
    ?>
    <!DOCTYPE html>
    <head>
      <?php

    echo '<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>';
    echo '<script  src="' . $module_path . '/includes/js/rba/js/jquery-1.9.1.js" ></script>';
    echo '<script type="text/javascript" src="' . $base_url . '/' . $module_path . '/includes/js/rba/js/jquery.flash.js" ></script>';
    ?>
    </head>
    <body>
    <div>
      <form id="morba_loginform"  action="<?php

    echo $base_url . '/collectattributes';
    ?>" method="post">
        <h1 style="margin-left: 43%; margin-top: 5%;"><?php

    echo 'Please wait';
    ?>...</h1>
        <img style="margin-left: 44%; margin-top: 1%" src="<?php

    echo $base_url . '/' . $module_path;
    ?>/includes/images/ajax-loader-login.gif" />
        <?php

    ?>
          <p><input type="hidden" id="miniorange_rba_attributes" name="miniorange_rba_attributes" value=""/></p>
          <?php

    echo '<script type="application/javascript" src="' . $base_url . '/' . $module_path . '/includes/js/rba/js/ua-parser.js" ></script>';
    echo '<script type="application/javascript" src="' . $base_url . '/' . $module_path . '/includes/js/rba/js/client.js " ></script>';
    echo '<script type="application/javascript" src="' . $base_url . '/' . $module_path . '/includes/js/rba/js/device_attributes.js" ></script>';
    echo '<script type="application/javascript" src="' . $base_url . '/' . $module_path . '/includes/js/rba/js/swfobject.js" ></script>';
    echo '<script type="application/javascript" src="' . $base_url . '/' . $module_path . '/includes/js/rba/js/fontdetect.js" ></script>';
    echo '<script type="application/javascript" src="' . $base_url . '/' . $module_path . '/includes/js/rba/js/murmurhash3.js" ></script>';
    echo '<script type="application/javascript" src="' . $base_url . '/' . $module_path . '/includes/js/rba/js/miniorange-fp.js" ></script>';
    ?>
        <input type="hidden" name="session_id" value="<?php

    echo $session_id_encrypt;
    ?>"/>
        <input type="hidden" name="username" value="<?php

    echo $username;
    ?>"/>
      </form>
    </div>
    </body>
    </html>
    <?php

    exit;
  }
  public static function showErrorMessage($error, $message, $cause, $closeWindow = FALSE) {
    global $base_url;
    $actionToTakeUponWindow = $closeWindow === TRUE ? 'onClick="self.close();"' : 'href="' . $base_url . '/user/login"';
    echo '<div style="font-family:Calibri;padding:0 3%;">';
    echo '<div style="color: #a94442;background-color: #f2dede;padding: 15px;margin-bottom: 20px;text-align:center;border:1px solid #E6B3B2;font-size:18pt;"> ERROR</div>
                                  <div style="color: #a94442;font-size:14pt; margin-bottom:20px;"><p><strong>Error: </strong>' . $error . '</p>
                                      <p>' . $message . '</p>
                                      <p><strong>Possible Cause: </strong>' . $cause . '</p>
                                  </div>
                                  <div style="margin:3%;display:block;text-align:center;"></div>
                                  <div style="margin:3%;display:block;text-align:center;">
                                      <a style="padding:1%;width:100px;background: #0091CD none repeat scroll 0% 0%;cursor: pointer;font-size:15px;border-width: 1px;border-style: solid;border-radius: 3px;white-space: nowrap;box-sizing: border-box;border-color: #0073AA;box-shadow: 0px 1px 0px rgba(120, 200, 230, 0.6) inset;color: #FFF; text-decoration: none;"type="button"  ' . $actionToTakeUponWindow . ' >Done</a>
                                  </div>';
    exit;
  }

  /**
   * @param $mo_saved_IP_address = IP Addresses entered by user
   * @return boolean | string if error
   * Check whether provided IP is valid or not
   */
  public static function check_for_valid_IPs($mo_saved_IP_address) {

    /** Separate IP address with the semicolon (;) **/
    $whitelisted_IP_array = explode(";", rtrim($mo_saved_IP_address, ";"));
    foreach ($whitelisted_IP_array as $key => $value) {
      if (stristr($value, '-')) {

        /** Check if it is a range of IP address **/
        list($lower, $upper) = explode('-', $value, 2);
        if (!filter_var($lower, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) && !filter_var($upper, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
          return "Invalid IP (<strong> " . $lower . "-" . $upper . "</strong> ) address. Please check lower range and upper range.";
        }
        $lower_range = ip2long($lower);
        $upper_range = ip2long($upper);
        if ($lower_range >= $upper_range) {
          return "Invalid IP range (<strong> " . $lower . "-" . $upper . "</strong> ) address. Please enter range in <strong>( lower_range - upper_range )</strong> format.";
        }
      }
      else {

        /** Check if it is a single IP address **/
        if (!filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
          return " Invalid IP (<strong> " . $value . "</strong> ) address. Please enter valid IP address.";
        }
      }
    }
    return TRUE;
  }

  /**
   * @return bool
   */
  public static function check_white_IPs() {
    $enable_whitelisted_IP = variable_get('mo_auth_two_factor_invoke_2fa_depending_upon_IP', FALSE);
    if ($enable_whitelisted_IP == FALSE) {
      return FALSE;
    }
    $current_IP_address = self::get_client_ip();
    $whitelisted_IP = variable_get('mo_auth_two_factor_whitelist_IP', '');
    if (is_null($whitelisted_IP) || empty($whitelisted_IP)) {
      return FALSE;
    }
    $whitelisted_IP_array = explode(";", $whitelisted_IP);
    $mo_ip_found = FALSE;
    foreach ($whitelisted_IP_array as $key => $value) {
      if (stristr($value, '-')) {

        /** Search in range of IP address **/
        list($lower, $upper) = explode('-', $value, 2);
        $lower_range = ip2long($lower);
        $upper_range = ip2long($upper);
        $current_IP = ip2long($current_IP_address);
        if ($lower_range !== FALSE && $upper_range !== FALSE && $current_IP !== FALSE && ($current_IP >= $lower_range && $current_IP <= $upper_range)) {
          $mo_ip_found = TRUE;
          break;
        }
      }
      else {

        /** Compare with single IP address **/
        if ($current_IP_address == $value) {
          $mo_ip_found = TRUE;
          break;
        }
      }
    }
    return $mo_ip_found;
  }

  /**
   * @return array|false|string
   * Function to get the client IP address
   */
  static function get_client_ip() {
    $ipaddress = '';
    if (getenv('HTTP_CLIENT_IP')) {
      $ipaddress = getenv('HTTP_CLIENT_IP');
    }
    else {
      if (getenv('REMOTE_ADDR')) {
        $ipaddress = getenv('REMOTE_ADDR');
      }
      else {
        if (getenv('HTTP_X_FORWARDED_FOR')) {
          $ipaddress = getenv('HTTP_X_FORWARDED_FOR');
        }
        else {
          if (getenv('HTTP_X_FORWARDED')) {
            $ipaddress = getenv('HTTP_X_FORWARDED');
          }
          else {
            if (getenv('HTTP_FORWARDED_FOR')) {
              $ipaddress = getenv('HTTP_FORWARDED_FOR');
            }
            else {
              if (getenv('HTTP_FORWARDED')) {
                $ipaddress = getenv('HTTP_FORWARDED');
              }
              else {
                $ipaddress = 'UNKNOWN';
              }
            }
          }
        }
      }
    }
    return $ipaddress;
  }
  public static function drupal_is_cli() {
    if (!isset($_SERVER['SERVER_SOFTWARE']) && (php_sapi_name() == 'cli' || is_numeric($_SERVER['argc']) && $_SERVER['argc'] > 0)) {
      return TRUE;
    }
    else {
      return FALSE;
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
MoAuthUtilities::addSupportForm public static function
MoAuthUtilities::callService public static function
MoAuthUtilities::check_domain_to_invoke_2fa public static function
MoAuthUtilities::check_for_valid_IPs public static function
MoAuthUtilities::check_roles_to_invoke_2fa public static function
MoAuthUtilities::check_white_IPs public static function
MoAuthUtilities::drupal_is_cli public static function
MoAuthUtilities::faq public static function
MoAuthUtilities::getHiddenEmail public static function
MoAuthUtilities::get_2fa_methods_for_inline_registration public static function
MoAuthUtilities::get_client_ip static function
MoAuthUtilities::get_timestamp public static function
MoAuthUtilities::indentSecret public static function
MoAuthUtilities::isCurlInstalled public static function
MoAuthUtilities::isCustomerRegistered public static function
MoAuthUtilities::isKbaConfigured public static function
MoAuthUtilities::mo2f_collect_device_attributes_handler public static function Collect system specific information using JS files
MoAuthUtilities::mo_auth_get_url_parts public static function Return current URL parts.
MoAuthUtilities::send_support_query public static function
MoAuthUtilities::showErrorMessage public static function