*
* @package miniOrange OAuth
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
*/
/**
* This library is miniOrange Authentication Service.
* Contains Request Calls to Customer service.
**/
class molms_2f_Utility {
public static function get_hidden_phone( $phone ) {
$hidden_phone = 'xxxxxxx' . substr( $phone, strlen( $phone ) - 3 );
return $hidden_phone;
}
public static function mo2f_check_empty_or_null( $value ) {
if ( ! isset( $value ) || $value == '' ) {
return true;
}
return false;
}
public static function is_curl_installed() {
if ( in_array( 'curl', get_loaded_extensions() ) ) {
return 1;
} else {
return 0;
}
}
public static function get_all_plugins_installed() {
$all_plugins = get_plugins();
$plugins = array();
$form = "";
$plugins["None"] = "None";
foreach ( $all_plugins as $plugin_name => $plugin_details ) {
$plugins[ $plugin_name ] = $plugin_details["Name"];
}
unset( $plugins['2fa-learndash-lms/miniorange_lms_2_factor_settings.php'] );
$form .= '
Please select the plugin
';
return $form;
}
public static function mo2f_check_number_length( $token ) {
if ( is_numeric( $token ) ) {
if ( strlen( $token ) >= 4 && strlen( $token ) <= 8 ) {
return true;
} else {
return false;
}
} else {
return false;
}
}
public static function mo2f_get_hidden_email( $email ) {
if ( ! isset( $email ) || trim( $email ) === '' ) {
return "";
}
$emailsize = strlen( $email );
$partialemail = substr( $email, 0, 1 );
$temp = strrpos( $email, "@" );
$endemail = substr( $email, $temp - 1, $emailsize );
for ( $i = 1; $i < $temp; $i ++ ) {
$partialemail = $partialemail . 'x';
}
$hiddenemail = $partialemail . $endemail;
return $hiddenemail;
}
public static function check_if_email_is_already_registered( $email ) {
global $molms_db_queries;
$users = get_users( array() );
foreach ( $users as $user ) {
$user_email = $molms_db_queries->get_user_detail( 'mo2f_user_email', $user->ID );
if ( $user_email == $email ) {
return true;
}
}
return false;
}
public static function check_if_request_is_from_mobile_device( $useragent ) {
if ( preg_match( '/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i', $useragent ) || preg_match( '/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i', substr( $useragent, 0, 4 ) ) ) {
return true;
} else {
return false;
}
}
public static function set_user_values( $user_session_id, $variable, $value ) {
global $molms_db_queries;
$key = get_site_option( 'mo2f_encryption_key' );
$data_option = null;
if ( empty( $data_option ) ) {
//setting session
$_SESSION[ $variable ] = $value;
// setting cookie values
if ( is_array( $value ) ) {
if ( $variable == 'mo_2_factor_kba_questions' ) {
molms_2f_Utility::mo2f_set_cookie_values( 'kba_question1', $value[0]['question'] );
molms_2f_Utility::mo2f_set_cookie_values( 'kba_question2', $value[1]['question'] );
} elseif ( $variable == 'mo2f_rba_status' ) {
molms_2f_Utility::mo2f_set_cookie_values( 'mo2f_rba_status_status', $value["status"] );
molms_2f_Utility::mo2f_set_cookie_values( 'mo2f_rba_status_sessionUuid', $value["sessionUuid"] );
molms_2f_Utility::mo2f_set_cookie_values( 'mo2f_rba_status_decision_flag', $value["decision_flag"] );
}
} else {
molms_2f_Utility::mo2f_set_cookie_values( $variable, $value );
}
// setting values in database
$user_session_id = molms_2f_Utility::decrypt_data( $user_session_id, $key );
if ( is_array( $value ) ) {
$string_value = json_encode( $value );
$molms_db_queries->save_user_login_details( $user_session_id, array( $variable => $string_value ) );
} else {
$molms_db_queries->save_user_login_details( $user_session_id, array( $variable => $value ) );
}
} elseif ( ! empty( $data_option ) && $data_option == "sessions" ) {
$_SESSION[ $variable ] = $value;
} elseif ( ! empty( $data_option ) && $data_option == "cookies" ) {
if ( is_array( $value ) ) {
if ( $variable == 'mo_2_factor_kba_questions' ) {
molms_2f_Utility::mo2f_set_cookie_values( 'kba_question1', $value[0] );
molms_2f_Utility::mo2f_set_cookie_values( 'kba_question2', $value[1] );
} elseif ( $variable == 'mo2f_rba_status' ) {
molms_2f_Utility::mo2f_set_cookie_values( 'mo2f_rba_status_status', $value["status"] );
molms_2f_Utility::mo2f_set_cookie_values( 'mo2f_rba_status_sessionUuid', $value["sessionUuid"] );
molms_2f_Utility::mo2f_set_cookie_values( 'mo2f_rba_status_decision_flag', $value["decision_flag"] );
}
} else {
molms_2f_Utility::mo2f_set_cookie_values( $variable, $value );
}
} elseif ( ! empty( $data_option ) && $data_option == "tables" ) {
$user_session_id = molms_2f_Utility::decrypt_data( $user_session_id, $key );
if ( is_array( $value ) ) {
$string_value = json_encode( $value );
$molms_db_queries->save_user_login_details( $user_session_id, array( $variable => $string_value ) );
} else {
$molms_db_queries->save_user_login_details( $user_session_id, array( $variable => $value ) );
}
}
}
/**
* The function sets the cookie value after encryption and encoding.
*
* @param string $cookiename - the cookie name
* @param string $cookievalue - the cookie value to be set
*
* @return string
*/
public static function mo2f_set_cookie_values( $cookiename, $cookievalue ) {
$key = get_site_option( 'mo2f_encryption_key' );
$current_time = new DateTime( 'now' );
$current_time = $current_time->format( 'Y-m-d H:i:sP' );
$cookievalue = $cookievalue . '&' . $current_time;
$cookievalue_encrypted = molms_2f_Utility::encrypt_data( $cookievalue, $key );
setcookie( $cookiename, base64_encode( $cookievalue_encrypted ), null, null, null, null, true );
$_COOKIE[ $cookiename ] = base64_encode( $cookievalue_encrypted );
}
/*
Returns Random string with length provided in parameter.
*/
/**
* @param string $data - the key=value pairs separated with &
*
* @return string
*/
public static function encrypt_data( $data, $key ) {
$plaintext = $data;
$ivlen = openssl_cipher_iv_length( $cipher = "AES-128-CBC" );
$iv = openssl_random_pseudo_bytes( $ivlen );
$ciphertext_raw = openssl_encrypt( $plaintext, $cipher, $key, $options = OPENSSL_RAW_DATA, $iv );
$hmac = hash_hmac( 'sha256', $ciphertext_raw, $key, $as_binary = true );
$ciphertext = base64_encode( $iv . $hmac . $ciphertext_raw );
return $ciphertext;
}
/**
* @param string $data - crypt response from Sagepay
*
* @return string
*/
public static function decrypt_data( $data, $key ) {
$c = base64_decode( $data );
$ivlen = openssl_cipher_iv_length( $cipher = "AES-128-CBC" );
$iv = substr( $c, 0, $ivlen );
$hmac = substr( $c, $ivlen, $sha2len = 32 );
$ciphertext_raw = substr( $c, $ivlen + $sha2len );
$original_plaintext = openssl_decrypt( $ciphertext_raw, $cipher, $key, $options = OPENSSL_RAW_DATA, $iv );
$calcmac = hash_hmac( 'sha256', $ciphertext_raw, $key, $as_binary = true );
$decrypted_text = '';
if ( is_string( $hmac ) and is_string( $calcmac ) ) {
if ( hash_equals( $hmac, $calcmac ) ) {//PHP 5.6+ timing attack safe comparison
$decrypted_text = $original_plaintext;
}
}
return $decrypted_text;
}
public static function get_client_ipaddress() {
$ip = null;
if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) {
$ip = isset( $_SERVER['HTTP_CLIENT_IP'] ) ? sanitize_text_field( $_SERVER['HTTP_CLIENT_IP'] ) : '';
} elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
$ip = isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ? sanitize_text_field( $_SERVER['HTTP_X_FORWARDED_FOR'] ) : '';
} else {
$ip = isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( $_SERVER['REMOTE_ADDR'] ) : '';
}
return $ip;
}
public static function random_str( $length, $keyspace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' ) {
$randomString = '';
$charactersLength = strlen( $keyspace );
$keyspace = $keyspace . microtime( true );
$keyspace = str_shuffle( $keyspace );
for ( $i = 0; $i < $length; $i ++ ) {
$randomString .= $keyspace[ rand( 0, $charactersLength - 1 ) ];
}
return $randomString;
}
/**
* The function returns the session variables, and if not, retrieves the cookie values set in case the right permissions are not aassigned for the sessions folder in the server.
*
* @param string $variable - the session or cookie variable name
* @param string $session_id - the session id of the user
*
* @return string
*/
public static function mo2f_retrieve_user_temp_values( $variable, $session_id = null ) {
global $molms_db_queries;
$data_option = null;
if ( empty( $data_option ) ) {
if ( isset( $_SESSION[ $variable ] ) && ! empty( $_SESSION[ $variable ] ) ) {
if ( $variable == 'mo_2_factor_kba_questions' ) {
$kba_array[0]['question'] = sanitize_text_field( $_SESSION[ $variable ][0]['question'] );
$kba_array[1]['question'] = sanitize_text_field( $_SESSION[ $variable ][1]['question'] );
return $kba_array;
}
return sanitize_text_field( $_SESSION[ $variable ] );
} else {
$key = get_site_option( 'mo2f_encryption_key' );
$cookie_value = false;
if ( $variable == 'mo2f_rba_status' ) {
if ( isset( $_COOKIE['mo2f_rba_status_status'] ) && ! empty( $_COOKIE['mo2f_rba_status_status'] ) ) {
$mo2f_rba_status_status = molms_2f_Utility::mo2f_get_cookie_values( 'mo2f_rba_status_status' );
$mo2f_rba_status_sessionUuid = molms_2f_Utility::mo2f_get_cookie_values( 'mo2f_rba_status_sessionUuid' );
$mo2f_rba_status_decision_flag = molms_2f_Utility::mo2f_get_cookie_values( 'mo2f_rba_status_decision_flag' );
$cookie_value = array(
"status" => $mo2f_rba_status_status,
"sessionUuid" => $mo2f_rba_status_sessionUuid,
"decision_flag" => $mo2f_rba_status_decision_flag
);
}
} elseif ( $variable == 'mo_2_factor_kba_questions' ) {
if ( isset( $_COOKIE['kba_question1'] ) && ! empty( $_COOKIE['kba_question1'] ) ) {
$kba_question1['question'] = molms_2f_Utility::mo2f_get_cookie_values( 'kba_question1' );
$kba_question2['question'] = molms_2f_Utility::mo2f_get_cookie_values( 'kba_question2' );
$cookie_value = array( $kba_question1, $kba_question2 );
}
} else {
$cookie_value = molms_2f_Utility::mo2f_get_cookie_values( $variable );
}
if ( $cookie_value ) {
return $cookie_value;
} else {
$session_id = molms_2f_Utility::decrypt_data( $session_id, $key );
$db_value = $molms_db_queries->get_user_login_details( $variable, $session_id );
if ( in_array( $variable, array( "mo2f_rba_status", "mo_2_factor_kba_questions" ) ) ) {
$db_value = json_decode( $db_value );
}
return $db_value;
}
}
} elseif ( ! empty( $data_option ) && $data_option == "sessions" ) {
if ( isset( $_SESSION[ $variable ] ) && ! empty( $_SESSION[ $variable ] ) ) {
return ( $_SESSION[ $variable ] );
}
} elseif ( ! empty( $data_option ) && $data_option == "cookies" ) {
$key = get_site_option( 'mo2f_encryption_key' );
$cookie_value = false;
if ( $variable == 'mo2f_rba_status' ) {
if ( isset( $_COOKIE['mo2f_rba_status_status'] ) && ! empty( $_COOKIE['mo2f_rba_status_status'] ) ) {
$mo2f_rba_status_status = molms_2f_Utility::mo2f_get_cookie_values( 'mo2f_rba_status_status' );
$mo2f_rba_status_sessionUuid = molms_2f_Utility::mo2f_get_cookie_values( 'mo2f_rba_status_sessionUuid' );
$mo2f_rba_status_decision_flag = molms_2f_Utility::mo2f_get_cookie_values( 'mo2f_rba_status_decision_flag' );
$cookie_value = array(
"status" => $mo2f_rba_status_status,
"sessionUuid" => $mo2f_rba_status_sessionUuid,
"decision_flag" => $mo2f_rba_status_decision_flag
);
}
} elseif ( $variable == 'mo_2_factor_kba_questions' ) {
if ( isset( $_COOKIE['kba_question1'] ) && ! empty( $_COOKIE['kba_question1'] ) ) {
$kba_question1 = molms_2f_Utility::mo2f_get_cookie_values( 'kba_question1' );
$kba_question2 = molms_2f_Utility::mo2f_get_cookie_values( 'kba_question2' );
$cookie_value = array( $kba_question1, $kba_question2 );
}
} else {
$cookie_value = molms_2f_Utility::mo2f_get_cookie_values( $variable );
}
if ( $cookie_value ) {
return $cookie_value;
}
} elseif ( ! empty( $data_option ) && $data_option == "tables" ) {
$key = get_site_option( 'mo2f_encryption_key' );
$session_id = molms_2f_Utility::decrypt_data( $session_id, $key );
$db_value = $molms_db_queries->get_user_login_details( $variable, $session_id );
if ( in_array( $variable, array( "mo2f_rba_status", "mo_2_factor_kba_questions" ) ) ) {
$db_value = json_decode( $db_value );
}
return $db_value;
}
}
/**
* The function gets the cookie value after decoding and decryption.
*
* @param string $cookiename - the cookie name
*
* @return string
*/
public static function mo2f_get_cookie_values( $cookiename ) {
$key = get_site_option( 'mo2f_encryption_key' );
if ( isset( $_COOKIE[ $cookiename ] ) ) {
$decrypted_data = molms_2f_Utility::decrypt_data( base64_decode( sanitize_text_field( $_COOKIE[ $cookiename ] ) ), $key );
if ( $decrypted_data ) {
$decrypted_data_array = explode( '&', $decrypted_data );
$cookie_value = $decrypted_data_array[0];
$cookie_creation_time = new DateTime( $decrypted_data_array[1] );
$current_time = new DateTime( 'now' );
$interval = $cookie_creation_time->diff( $current_time );
$minutes = $interval->format( '%i' );
$is_cookie_valid = $minutes <= 5 ? true : false;
return $is_cookie_valid ? $cookie_value : false;
} else {
return false;
}
} else {
return false;
}
}
/**
* The function unsets the session variables passed.
*
* @param array $variables - the array of session variables to be unset
*
* @return NA
*/
public static function unset_session_variables( $variables ) {
if ( gettype( $variables ) == "array" ) {
foreach ( $variables as $variable ) {
if ( isset( $_SESSION[ $variable ] ) ) {
unset( $_SESSION[ $variable ] );
}
}
} else {
if ( isset( $_SESSION[ $variables ] ) ) {
unset( $_SESSION[ $variables ] );
}
}
}
/**
* The function unsets the cookie variables passed.
*
* @param array $variables - the array of cookie variables to be unset
*
* @return NA
*/
public static function unset_cookie_variables( $variables ) {
if ( gettype( $variables ) == "array" ) {
foreach ( $variables as $variable ) {
if ( isset( $_COOKIE[ $variable ] ) ) {
setcookie( $variable, '', time() - 3600, null, null, null, true );
}
}
} else {
if ( isset( $_COOKIE[ $variables ] ) ) {
setcookie( $variables, '', time() - 3600, null, null, null, true );
}
}
}
/**
* The function unsets the temp table variables passed.
*
* @param array $variables - the array of temporary table variables to be unset
* @param string $session_id - the session_id for which it should be destroyed
*
* @return NA
*/
public static function unset_temp_user_details_in_table( $variables, $session_id, $command = '' ) {
global $molms_db_queries;
$key = get_site_option( 'mo2f_encryption_key' );
$session_id = molms_2f_Utility::decrypt_data( $session_id, $key );
if ( $command == "destroy" ) {
$molms_db_queries->delete_user_login_sessions( $session_id );
} else {
$molms_db_queries->save_user_login_details( $session_id, array( $variables => '' ) );
}
}
/**
* The function decodes the twofactor methods
*
* @param array $variables - the selected 2-factor method and the decode type.
*
* @return NA
*/
public static function molms_decode_2_factor( $selected_2_factor_method, $decode_type ) {
if ( $selected_2_factor_method == 'NONE' ) {
return $selected_2_factor_method;
} elseif ( $selected_2_factor_method == "OTP Over Email" ) {
$selected_2_factor_method = "OTPOverEmail";
}
$wpdb_2fa_methods = array(
"miniOrangeQRCodeAuthentication" => "miniOrange QR Code Authentication",
"miniOrangeSoftToken" => "miniOrange Soft Token",
"miniOrangePushNotification" => "miniOrange Push Notification",
"GoogleAuthenticator" => "Google Authenticator",
"AuthyAuthenticator" => "Authy Authenticator",
"SecurityQuestions" => "Security Questions",
"EmailVerification" => "Email Verification",
"OTPOverSMS" => "OTP Over SMS",
"OTPOverEmail" => "OTP Over Email"
);
$server_2fa_methods = array(
"miniOrange QR Code Authentication" => "MOBILE AUTHENTICATION",
"miniOrange Soft Token" => "SOFT TOKEN",
"miniOrange Push Notification" => "PUSH NOTIFICATIONS",
"Google Authenticator" => "GOOGLE AUTHENTICATOR",
"Authy Authenticator" => "GOOGLE AUTHENTICATOR",
"Security Questions" => "KBA",
"Email Verification" => "OUT OF BAND EMAIL",
"OTP Over SMS" => "SMS",
"EMAIL" => "OTP Over Email",
"OTPOverEmail" => "OTP Over Email"
);
$server_to_wpdb_2fa_methods = array(
"MOBILE AUTHENTICATION" => "miniOrange QR Code Authentication",
"SOFT TOKEN" => "miniOrange Soft Token",
"PUSH NOTIFICATIONS" => "miniOrange Push Notification",
"GOOGLE AUTHENTICATOR" => "Google Authenticator",
"KBA" => "Security Questions",
"OUT OF BAND EMAIL" => "Email Verification",
"SMS" => "OTP Over SMS",
"EMAIL" => "OTP Over Email",
"OTPOverEmail" => "OTP Over Email",
"OTP OVER EMAIL" => "OTP Over Email",
"OTP Over SMS" => "OTP Over SMS",
"Security Questions" => "Security Questions",
"Google Authenticator" => "Google Authenticator"
);
$methodname = '';
if ( $decode_type == "wpdb" ) {
$methodname = isset( $wpdb_2fa_methods[ $selected_2_factor_method ] ) ? $wpdb_2fa_methods[ $selected_2_factor_method ] : $selected_2_factor_method;
} elseif ( $decode_type == "server" ) {
$methodname = isset( $server_2fa_methods[ $selected_2_factor_method ] ) ? $server_2fa_methods[ $selected_2_factor_method ] : $selected_2_factor_method;
} else {
$methodname = isset( $server_to_wpdb_2fa_methods[ $selected_2_factor_method ] ) ? $server_to_wpdb_2fa_methods[ $selected_2_factor_method ] : $selected_2_factor_method;
}
return $methodname;
}
public static function get_plugin_name_by_identifier( $plugin_identitifier ) {
$all_plugins = get_plugins();
$plugin_details = $all_plugins[ $plugin_identitifier ];
return $plugin_details["Name"] ? $plugin_details["Name"] : "No Plugin selected";
}
public static function isBlank( $value ) {
if ( ! isset( $value ) || empty( $value ) ) {
return true;
}
return false;
}
public static function get_index_value( $var, $index ) {
switch ( $var ) {
case 'GLOBALS':
return isset( $GLOBALS[ $index ] ) ? $GLOBALS[ $index ] : false;
break;
default:
return false;
break;
}
}
}