Server IP : 66.29.132.122 / Your IP : 3.137.184.33 Web Server : LiteSpeed System : Linux business142.web-hosting.com 4.18.0-553.lve.el8.x86_64 #1 SMP Mon May 27 15:27:34 UTC 2024 x86_64 User : admazpex ( 531) PHP Version : 7.2.34 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /var/softaculous/sitepad/editor/site-data/plugins/loginizer-security/ |
Upload File : |
<?php function loginizer_security_init(){ global $loginizer; // TODO: Disable loginizer/loginizer.php // ATM, it will not load if the premium plugin is loaded // Load license if(!defined('SITEPAD')){ // Check if there is a license file and update it in the database if(file_exists(__DIR__.'/license.key')){ $license = trim(file_get_contents(__DIR__.'/license.key')); if(!empty($license)){ $resp = wp_remote_get(LOGINIZER_API.'license.php?license='.$license, array('timeout' => 30)); if(is_array($resp)){ $json = json_decode($resp['body'], true); //print_r($json); } // Save the License if(!empty($json['license'])){ update_option('loginizer_license', $json); } } unlink(__DIR__.'/license.key'); } $loginizer['license'] = get_option('loginizer_license'); // Check for updates include_once('updater/plugin-update-checker.php'); $loginizer_updater = Loginizer_PucFactory::buildUpdateChecker(LOGINIZER_API.'updates.php?version='.LOGINIZER_VERSION, LOGINIZER_FILE); // Add the license key to query arguments $loginizer_updater->addQueryArgFilter('loginizer_updater_filter_args'); // Show the text to install the license key add_filter('puc_manual_final_check_link-loginizer-security', 'loginizer_updater_check_link', 10, 1); add_filter('plugin_row_meta', 'loginizer_plugin_row_links', 10, 2); // Update license details as well if(!empty($loginizer['license']) && (time() - @$loginizer['license']['last_update']) >= 86400){ $resp = wp_remote_get(LOGINIZER_API.'license.php?license='.$loginizer['license']['license']); // Did we get a response ? if(is_array($resp)){ $tosave = json_decode($resp['body'], true); // Is it the license ? if(!empty($tosave['license'])){ $tosave['last_update'] = time(); update_option('loginizer_license', $tosave); } } } } // Checking For SSO if(!empty($_GET['ssotoken'])){ add_filter('authenticate', 'loginizer_sso_authenticate', 10003, 3); add_action('wp_login_errors', 'loginizer_error_handler', 10001, 2); add_action('wp_login', 'loginizer_login_success', 10, 2); } // CSRF Session URL if(!empty($loginizer['enable_csrf_protection']) && loginizer_is_csrf_prot_mod_set()){ add_action('init', 'loginizer_csrf_sess_init'); add_filter('login_redirect', 'loginizer_login_csrf_redirect', 200, 3); add_action('admin_bar_menu', 'loginizer_csrf_admin_bar_shortcut', 70); add_filter('admin_url', 'loginizer_csrf_admin_redirects', 100005, 3); add_filter('wp_redirect', 'loginizer_csrf_wp_redirects'); add_action('set_auth_cookie', 'loginizer_admin_url_cookie'); // Creates session key and handles cookies add_action('wp_logout', 'loginizer_destroy_csrf_session', 10, 1); } // Ajax handler for updating htaccess for rename admin and CSRF add_action('wp_ajax_loginizer_update_csrf_mod', 'loginizer_update_csrf_mod'); // Handles Concurrent Sessions if(!empty($loginizer['limit_session']) && !empty($loginizer['limit_session']['enable'])){ add_filter('wp_authenticate_user', 'loginizer_limit_sessions'); add_filter('check_password', 'loginizer_limit_destroy_sessions_handler', 10, 4); } // MasterStudy Login filter add_filter('stm_lms_login', 'loginizer_handle_stm_lms_login'); add_filter('loginizer_system_information', 'loginizer_premium_system_info', 10); add_filter('loginizer_pre_page_dashboard', 'loginizer_premium_page_dashboard', 10); // A way to remove the settings if(file_exists(LOGINIZER_DIR.'/reset_admin.txt')){ update_option('loginizer_wp_admin', array()); } // Are we to ban user emails ? if(!empty($loginizer['domains_blacklist']) && count($loginizer['domains_blacklist']) > 0){ add_filter('registration_errors', 'loginizer_domains_blacklist', 10, 3); add_filter('woocommerce_registration_errors', 'loginizer_domains_blacklist', 10, 3); } // Is email password less login enabled ? if(!empty($loginizer['email_pass_less']) && !defined('XMLRPC_REQUEST')){ // Add a handler for the GUI Login add_filter('authenticate', 'loginizer_epl_wp_authenticate', 10002, 3); // Dont show password error add_filter('wp_login_errors', 'loginizer_epl_error_handler', 10000, 2); // Hide the password field add_action('login_enqueue_scripts', 'loginizer_epl_hide_pass'); add_action('wp_enqueue_scripts', 'loginizer_epl_hide_woocommerce_pass'); } // Are we to rename the login ? if(!empty($loginizer['login_slug'])){ //$loginizer['login_slug'] = 'login'; // Add the filters / actions add_filter('site_url', 'loginizer_rl_site_url', 10, 2); add_filter('network_site_url', 'loginizer_rl_site_url', 10, 2); add_filter('wp_redirect', 'loginizer_rl_wp_redirect', 10, 2); add_filter('register', 'loginizer_rl_register'); add_action('wp_loaded', 'loginizer_rl_wp_loaded'); } // Rename the WP-ADMIN folder if(!defined('SITEPAD') && !empty($loginizer['admin_slug'])){ add_filter('admin_url', 'loginizer_admin_url', 10001, 3); add_action('set_auth_cookie', 'loginizer_admin_url_cookie'); // For multisite if(lz_is_multisite()){ add_filter('network_admin_url', 'loginizer_network_admin_url', 10001, 2); } if(!empty($loginizer['restrict_wp_admin']) && preg_match('/\/wp-admin/is', $_SERVER['REQUEST_URI'])){ die(empty($loginizer['wp_admin_msg']) ? $loginizer['wp_admin_d_msg'] : $loginizer['wp_admin_msg']); } } // WP-Admin Test AJAX handler add_action('wp_ajax_loginizer_wp_admin', 'loginizer_wp_admin_ajax'); // Are we to rename the xmlrpc ? if(!defined('SITEPAD') && !empty($loginizer['xmlrpc_slug']) && empty($loginizer['xmlrpc_disable'])){ // Add the filters / actions add_action('wp_loaded', 'loginizer_xml_rename_wp_loaded'); } // Are we to DISABLE the xmlrpc ? if(!empty($loginizer['xmlrpc_disable'])){ // Add the filters / actions add_filter('xmlrpc_enabled', 'loginizer_xmlrpc_null'); add_filter('bloginfo_url', 'loginizer_xmlrpc_remove_pingback_url', 10000, 2); add_action('wp_loaded', 'loginizer_xmlrpc_disable'); } // Are we to disable pingbacks ? if(!empty($loginizer['pingbacks_disable'])){ // Add the filters / actions add_filter('xmlrpc_methods', 'loginizer_pingbacks_disable'); } //----------------------------------- // Add the captcha filters / actions //----------------------------------- if(!empty($loginizer['social_settings']) && !loginizer_is_blacklisted()){ // Shortcode has options shape|divider|type add_shortcode('loginizer_social', 'loginizer_social_shortcode'); if(!empty($_COOKIE['lz_social_error'])){ add_action('woocommerce_before_customer_login_form', 'loginizer_social_wc_error'); } if(!empty($loginizer['social_settings']['general']['save_avatar'])){ add_filter('get_avatar', 'loginizer_social_update_avatar', 1, 5); } if(!empty($loginizer['social_settings']['login']['registration_form'])){ add_action('register_form', 'loginizer_social_btn_login', 100); } if(in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))){ if(!empty($loginizer['social_settings']['woocommerce']['login_form'])){ add_action('woocommerce_login_form', 'loginizer_social_btn_woocommerce', 100); } if(!empty($loginizer['social_settings']['woocommerce']['registration_form'])){ add_action('woocommerce_register_form', 'loginizer_social_btn_woocommerce'); } } if(!empty($loginizer['social_settings']['comment']['enable_buttons'])){ add_action('comment_form_must_log_in_after', 'loginizer_social_btn_comment'); } } if(!empty($loginizer['captcha_key']) || !empty($loginizer['captcha_no_google']) || !empty($loginizer['captcha_status'])){ add_action('login_init', 'loginizer_cap_session_key'); // Is reCaptcha on for login ? if(!empty($loginizer['captcha_login']) && !defined('XMLRPC_REQUEST')){ add_filter('authenticate', 'loginizer_cap_login_verify', 10000); add_action('login_form', 'loginizer_cap_form_login', 100); add_action('woocommerce_login_form', 'loginizer_cap_form_login', 100); // Need to make more room for login form if(empty($loginizer['captcha_remove_css'])){ add_action('login_enqueue_scripts', 'loginizer_cap_login_form'); } } // Is reCaptcha on for Lost Password utility ? if(!empty($loginizer['captcha_lostpass'])){ add_action('allow_password_reset', 'loginizer_cap_lostpass_verify', 10, 2); add_action('lostpassword_form', 'loginizer_cap_form_login', 100); add_filter('woocommerce_lostpassword_form', 'loginizer_cap_form_login'); } // Is reCaptcha on for Reset Password utility ? if(!empty($loginizer['captcha_resetpass'])){ add_filter('validate_password_reset', 'loginizer_cap_resetpass_verify', 10, 2); add_action('resetpass_form', 'loginizer_cap_reset_form', 99); add_filter('woocommerce_resetpassword_form', 'loginizer_cap_form_login'); } // Is reCaptcha on for registration ? if(!empty($loginizer['captcha_register'])){ add_filter('registration_errors', 'loginizer_cap_register_verify', 10, 3); add_action('register_form', 'loginizer_cap_form_login', 100); // For BuddyPress add_filter('bp_signup_validate', 'loginizer_cap_register_verify_buddypress', 10, 3); add_action('bp_after_signup_profile_fields', 'loginizer_cap_form_login', 100); add_filter('woocommerce_before_checkout_process', 'loginizer_wc_before_checkout_process', 10); add_filter('woocommerce_register_form', 'loginizer_cap_form_login'); add_filter('woocommerce_registration_errors', 'loginizer_cap_register_verify', 10, 3); if(!empty($loginizer['captcha_wc_checkout'])){ add_action('woocommerce_checkout_order_review', 'loginizer_cap_form_ecommerce'); } } // Are we to show Captcha for guests only ? if((is_user_logged_in() && empty($loginizer['captcha_user_hide'])) || !is_user_logged_in()){ // Is reCaptcha on for comment utility ? if(!empty($loginizer['captcha_comment'])){ add_filter('preprocess_comment', 'loginizer_cap_comment_verify'); add_action('comment_form', 'loginizer_cap_comment_form'); } // Is reCaptcha on for WooCommerce Logout utility ? if(!empty($loginizer['captcha_wc_checkout'])){ add_action('woocommerce_after_checkout_validation', 'loginizer_wc_checkout_verify'); add_action('woocommerce_checkout_order_review', 'loginizer_cap_form_ecommerce'); } } } //----------------- // Two Factor Auth //----------------- if(!defined('SITEPAD') && loginizer_is_2fa_enabled() && !defined('XMLRPC_REQUEST')){ // After username and password check has been verified, are we to redirect ? add_filter('authenticate', 'loginizer_user_redirect', 10003, 3); $user_id = get_current_user_id(); $lz_2fa_state = get_transient('loginizer_2fa_'. $user_id); // To redirect after login if(!empty($_COOKIE['loginizer_2fa_' . $user_id]) && !empty($lz_2fa_state) && $lz_2fa_state != '2fa'){ loginizer_2fa_ajax_redirect(); } $login_slug = 'wp-login.php'; if($loginizer['login_slug']){ $login_slug = $loginizer['login_slug']; } if(loginizer_cur_page() !== $login_slug && !empty($lz_2fa_state) && $lz_2fa_state == '2fa'){ wp_logout(); wp_safe_redirect(admin_url()); exit; } // Shows the Question / 2fa field add_action('login_form_loginizer_security', 'loginizer_user_security'); // Ajax handler add_action('wp_ajax_loginizer_ajax', 'loginizer_user_page_ajax'); $cur_user = wp_get_current_user(); //Add the Loginizer Security Settings Page for WooCommerce if(class_exists('WooCommerce') && loginizer_is_2fa_applicable($cur_user)){ add_action( 'init', 'loginizer_add_premium_security_endpoint' ); add_filter( 'query_vars', 'loginizer_premium_security_query_vars', 0 ); add_filter( 'woocommerce_account_menu_items', 'loginizer_add_premium_security_link_my_account' ); add_action( 'woocommerce_account_loginizer-security_endpoint', 'loginizer_user_page' ); } // Is the user logged in ? if(is_user_logged_in()){ // Load user settings loginizer_load_user_settings($tfa_uid, $tfa_user, $tfa_settings, $tfa_current_pref); // If 2FA applicable as per role if(loginizer_is_2fa_applicable($tfa_user)){ // Add to Settings menu on sites add_action('admin_menu', 'loginizer_user_menu'); // Show the user the notification to set a 2FA $loginizer['loginizer_2fa_notice'] = get_user_meta($tfa_uid, 'loginizer_2fa_notice'); // Are we to show the loginizer notification to set a 2FA if(empty($loginizer['loginizer_2fa_notice']) && (empty($_COOKIE['loginizer_2fa_notice_'.$tfa_uid]) || $_COOKIE['loginizer_2fa_notice_'.$tfa_uid] != md5(wp_get_session_token())) && (empty($tfa_current_pref) || $tfa_current_pref == 'none') && lz_optget('page') != 'loginizer_user' ){ add_action('admin_notices', 'loginizer_2fa_notice'); } // Are we to disable the notice forever ? if(isset($_GET['loginizer_2fa_notice']) && (int)$_GET['loginizer_2fa_notice'] == 0){ update_user_meta($tfa_uid, 'loginizer_2fa_notice', time()); die('DONE'); } // Are we to disable the notice temporarily ? if(isset($_GET['loginizer_2fa_notice']) && (int)$_GET['loginizer_2fa_notice'] == 1){ @setcookie('loginizer_2fa_notice_'.$tfa_uid, md5(wp_get_session_token()), time() + (3 * DAY_IN_SECONDS), COOKIEPATH, COOKIE_DOMAIN, is_ssl()); } } add_filter('manage_users_columns', 'loginizer_2fa_columns_users'); add_filter('manage_users_custom_column', 'loginizer_2fa_column_data', 10, 3); } } // Checksum is enabled right i.e. its not disabled ? if(!defined('SITEPAD') && empty($loginizer['disable_checksum'])){ // Create an action always add_action('loginizer_do_checksum', 'loginizer_checksums'); // Difference in seconds since last time $diff = (time() - $loginizer['checksums_last_run']); // Has it crossed the time ? if(($diff / 86400) >= $loginizer['checksum_frequency']){ //loginizer_checksums(); wp_schedule_single_event(time(), 'loginizer_do_checksum'); } } } function loginizer_social_wc_error(){ // Showing woocommerce error if(!function_exists('wc_add_wp_error_notices')){ return; } $errors = loginizer_social_login_error_handler(); if(empty($errors) || !is_wp_error($errors)){ return; } wc_add_wp_error_notices($errors); loginizer_woocommerce_error_handler(); woocommerce_output_all_notices(); } function loginizer_premium_system_info(){ global $loginizer; echo ' <tr> <th align="left" valign="top">'.__('Loginizer License', 'loginizer').'</th> <td align="left"> '.(empty($loginizer['license']) ? '<span style="color:red">Unlicensed</span> ' : '').' <input type="text" name="lz_license" value="'.(empty($loginizer['license']) ? '' : $loginizer['license']['license']).'" size="30" placeholder="e.g. WXCSE-SFJJX-XXXXX-AAAAA-BBBBB" style="width:300px;" /> <input name="save_lz" class="button button-primary" value="Update License" type="submit" />'; if(!empty($loginizer['license'])){ $expires = $loginizer['license']['expires']; $expires = substr($expires, 0, 4).'/'.substr($expires, 4, 2).'/'.substr($expires, 6); echo '<div style="margin-top:10px;">License Active : '.(empty($loginizer['license']['active']) ? '<span style="color:red">No</span>' : '<span style="color:green">Yes</span>').' License Expires : '.($loginizer['license']['expires'] <= date('Ymd') ? '<span style="color:red">'.$expires.'</span>' : $expires).' </div>'; } echo '</td> </tr>'; } function loginizer_premium_page_dashboard(){ global $loginizer, $lz_error; // Is there a license key ? if(isset($_POST['save_lz'])){ $license = lz_optpost('lz_license'); // Check if its a valid license if(empty($license)){ $lz_error['lic_invalid'] = __('The license key was not submitted', 'loginizer'); return loginizer_page_dashboard_T(); } $resp = wp_remote_get(LOGINIZER_API.'license.php?license='.$license, array('timeout' => 30)); if(is_array($resp)){ $json = json_decode($resp['body'], true); //print_r($json); }else{ $lz_error['resp_invalid'] = __('The response was malformed<br>'.var_export($resp, true), 'loginizer'); return loginizer_page_dashboard_T(); } // Save the License if(empty($json['license'])){ $lz_error['lic_invalid'] = __('The license key is invalid', 'loginizer'); return loginizer_page_dashboard_T(); }else{ update_option('loginizer_license', $json); // Mark as saved $GLOBALS['lz_saved'] = true; $loginizer['license'] = get_option('loginizer_license'); } } } // Add our license key if ANY function loginizer_updater_filter_args($queryArgs) { global $loginizer; if ( !empty($loginizer['license']['license']) ) { $queryArgs['license'] = $loginizer['license']['license']; } return $queryArgs; } // Handle the Check for update link and ask to install license key function loginizer_updater_check_link($final_link){ global $loginizer; if(empty($loginizer['license']['license'])){ return '<a href="'.admin_url('admin.php?page=loginizer').'">Install License Key to Update</a>'; } return $final_link; } // Change the Admin URL function loginizer_admin_url($url, $path, $blog_id){ global $loginizer; //echo $url."\n";echo $path."\n"; $new = str_replace('wp-admin', $loginizer['admin_slug'], $url); //echo $new.'<br>'; return $new; } function loginizer_network_admin_url($url, $path){ global $loginizer; //echo $url.'<br>';echo $path.'<br>'; $new = str_replace('wp-admin', $loginizer['admin_slug'], $url); //echo $new.'<br>'; return $new; } // Required to be able to Login function loginizer_admin_url_cookie($auth_cookie, $expire = 0, $expiration = '', $user_id = '', $scheme = ''){ global $loginizer; if($scheme == 'secure_auth' || is_ssl()){ $auth_cookie_name = SECURE_AUTH_COOKIE; $secure = true; }else { $auth_cookie_name = AUTH_COOKIE; $secure = false; } $admin_slug = $loginizer['admin_slug']; // Auth cookie has the user's username in it as the first word before pipe | so we get the user name through that if(!empty($loginizer['enable_csrf_protection']) && !empty($auth_cookie)){ $u_login = explode('|', $auth_cookie); $u_login = $u_login[0]; $user = get_user_by('login', $u_login); $session = get_user_meta($user->ID, 'loginizer_csrf_session', true); if(empty($session)){ loginizer_csrf_create_session($user->ID); } $session = get_user_meta($user->ID, 'loginizer_csrf_session', true); $admin_slug = 'wp-admin-' . $session; if(!empty($loginizer['admin_slug'])){ $admin_slug = $loginizer['admin_slug'] . '-' . $session; } } @setcookie($auth_cookie_name, $auth_cookie, $expire, SITECOOKIEPATH . $admin_slug, COOKIE_DOMAIN, $secure, true); } // Verifies if the token is valid and creates the user session function loginizer_epl_verify(){ global $loginizer; if(empty($_GET['uid']) || empty($_GET['lepltoken'])){ return false; } $uid = (int) sanitize_key($_GET['uid']); $token = sanitize_key($_GET['lepltoken']); $action = 'loginizer_epl_'.$uid; $hash = get_user_meta($uid, $action, true); $expires = get_user_meta($uid, $action.'_expires', true); include_once(ABSPATH.'/'.$loginizer['wp-includes'].'/class-phpass.php'); $wp_hasher = new PasswordHash(8, TRUE); $time = time(); if(!$wp_hasher->CheckPassword($expires.$token, $hash) || $expires < $time){ $token_error_msg = __('The token is invalid or has expired. Please request a new email', 'loginizer'); // Throw an error return new WP_Error('token_invalid', $token_error_msg, 'loginizer_epl'); }else{ if(!empty($loginizer['limit_session']) && !empty($loginizer['limit_session']['enable'])){ $limit_session = loginizer_limit_destroy_sessions($uid); if(empty($limit_session)){ return new WP_Error('loginizer_session_limit', __('User ID not found so can not proceed', 'loginizer'), 'loginizer_epl'); } } // Login the User wp_set_auth_cookie($uid); // Delete the meta delete_user_meta($uid, $action); delete_user_meta($uid, $action.'_expires'); $user = get_user_by('id', $uid); $redirect = !empty($_REQUEST['redirect_to']) ? esc_url_raw($_REQUEST['redirect_to']) : ''; if(!empty($loginizer['passwordless_redirect']) && !empty($user) && !empty($user->roles)){ $roles = $user->roles; if(!is_array($user->roles)) { $roles = [$user->roles]; } // To check if we need a custom redirect for the role this user has foreach($roles as $r){ if(!empty($loginizer['passwordless_redirect_for']) && in_array($r, $loginizer['passwordless_redirect_for'])){ $redirect = $loginizer['passwordless_redirect']; break; } } } $redirect_to = !empty($redirect) ? $redirect : admin_url(); $redirect_to = loginizer_csrf_change_url($redirect_to, $uid); loginizer_update_attempt_stats(1); // Redirect and exit wp_safe_redirect($redirect_to); exit; } return false; } // Hides the password field for the password less email login function loginizer_epl_hide_pass() { ?> <style type="text/css"> label[for="user_pass"], .user-pass-wrap { display:none; } </style> <?php } // Hides the password field for the password less email login (WooCommerce) function loginizer_epl_hide_woocommerce_pass() { ?> <style type="text/css"> label[for="password"], .password-input, .lost_password{ display:none !important; } </style> <?php } // Handles the error of the password not being there function loginizer_epl_error_handler($errors, $redirect_to){ //echo 'loginizer_epl_error_handler :';print_r($errors->errors);echo '<br>'; // Remove the empty password error if(is_wp_error($errors)){ $errors->remove('empty_password'); } return $errors; } // Handles the verification of the username or email function loginizer_epl_wp_authenticate($user, $username, $password){ global $loginizer; //echo 'loginizer_epl_wp_authenticate : '; print_r($user).'<br>'; if(is_wp_error($user)){ // Ignore certain codes $ignore_codes = array('empty_username', 'empty_password'); if(is_wp_error($user) && !in_array($user->get_error_code(), $ignore_codes)) { return $user; } } // Is it a login attempt $verified = loginizer_epl_verify(); if(is_wp_error($verified)){ return $verified; } if(empty($username) && empty($_POST)){ return $user; } $email = NULL; // Is it an email address ? if(is_email($username) && email_exists($username)){ $email = $username; } // Maybe its a username if(!is_email($username) && username_exists($username)){ $user = get_user_by('login', $username); if($user){ $email = $user->data->user_email; } } // Did you get any valid email ? if(empty($email)){ $account_error_msg = __('The username or email you provided does not exist !', 'loginizer'); return new WP_Error('invalid_account', $account_error_msg, 'loginizer_epl'); } if(!empty($loginizer['limit_session']) && !empty($loginizer['limit_session']['enable'])){ $user = get_user_by('email', $email); $session_limit = loginizer_limit_sessions($user); if(is_wp_error($session_limit)){ return $session_limit; } } // Send the email $site_name = get_bloginfo('name'); $login_url = loginizer_epl_login_url($email); $vars = array('email' => $email, 'site_name' => $site_name, 'site_url' => get_site_url(), 'login_url' => $login_url); $subject = lz_lang_vars_name($loginizer['passwordless_sub'], $vars); $message = lz_lang_vars_name($loginizer['passwordless_msg'], $vars); //echo $subject.'<br><br>';echo $message; $headers = array(); // Do we need to send the email as HTML ? if(!empty($loginizer['passwordless_html'])){ $headers[] = 'Content-Type: text/html; charset=UTF-8'; if(!empty($loginizer['passwordless_msg_is_custom'])){ $message = html_entity_decode($message); }else{ $message = preg_replace("/\<br\s*\/\>/i", "<br/>", $message); $message = preg_replace('/(?<!<br\/>)\n/i', "<br/>\n", $message); } } $sent = wp_mail($email, $subject, $message, $headers); //echo $login_url; if(empty($sent)){ $email_not_sent = __('There was a problem sending your email. Please try again or contact an admin.', 'loginizer'); return new WP_Error('email_not_sent', $email_not_sent, 'loginizer_epl'); }else{ $loginizer['no_loginizer_logs'] = 1; $email_sent_msg = __('An email has been sent with the Login URL', 'loginizer'); return new WP_Error('email_sent', $email_sent_msg, 'message'); } } // Generate the URL for the function loginizer_epl_login_url($email){ // Get the User ID $user = get_user_by('email', $email); $token = loginizer_epl_token($user->ID); // The current URL $redirect_url = ''; if(!empty($_REQUEST['redirect_to'])){ $redirect_url = $_REQUEST['redirect_to']; } elseif (!empty($_REQUEST['redirect'])){ $redirect_url = $_REQUEST['redirect']; } elseif(!empty(wp_validate_redirect($_SERVER['HTTP_REFERER']))){ $redirect_url = wp_validate_redirect($_SERVER['HTTP_REFERER']); } $redirect_param = (!empty($redirect_url) ? '&redirect_to='.urlencode($redirect_url) : ''); $url = wp_login_url().'?uid='.$user->ID.'&lepltoken='.$token.$redirect_param; return $url; } // Creates a one time token function loginizer_epl_token($uid = 0){ global $loginizer; // Variables $time = time(); $expires = ($time + 600); $action = 'loginizer_epl_'.$uid; include_once( ABSPATH . '/'.$loginizer['wp-includes'].'/class-phpass.php'); $wp_hasher = new PasswordHash(8, TRUE); // Create the token with a random salt and the time $token = wp_hash(wp_generate_password(20, false).$action.$time); // Create a hash of the token $stored_hash = $wp_hasher->HashPassword($expires.$token); // Store the hash and when it expires update_user_meta($uid, $action, $stored_hash); update_user_meta($uid, $action.'_expires', $expires); return $token; } // Send a 404 function loginizer_set_404(){ global $wp_query; status_header(404); $wp_query->set_404(); if( (($template = get_404_template()) || ($template = get_index_template())) && ($template = apply_filters('template_include', $template)) ){ include($template); } die(); } // Find the page being accessed function loginizer_cur_page(){ $blog_url = trailingslashit(get_bloginfo('url')); $server_host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ''; $server_uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : ''; // Build the Current URL $url = (is_ssl() ? 'https://' : 'http://') . $server_host . $server_uri; if(is_ssl() && preg_match('/^http\:/is', $blog_url)){ $blog_url = substr_replace($blog_url, 's', 4, 0); } // The relative URL to the Blog URL $req = str_replace($blog_url, '', $url); $req = str_replace('index.php/', '', $req); // We dont need the args $parts = explode('?', $req, 2); $relative = basename($parts[0]); // Remove trailing slash $relative = rtrim($relative, '/'); $tmp = explode('/', $relative, 2); $page = end($tmp); //echo 'Page : '.$page.'<br>'; return $page; } // Converts the URL as per the one stored function loginizer_rl_convert_url($link){ global $loginizer; $dbt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 7); // If the login page is to be kept secret if(!empty($loginizer['rename_login_secret']) && loginizer_cur_page() !== $loginizer['login_slug'] && !is_user_logged_in() && (empty($dbt[6]) || $dbt[6]['function'] != 'get_the_password_form')){ return $link; } $result = $link; if(!empty($loginizer['login_slug']) && strpos($link, $loginizer['login_basename']) !== false){ $result = str_replace($loginizer['login_basename'], $loginizer['login_slug'], $link); } if(!empty($loginizer['xmlrpc_slug']) && strpos($link, 'xmlrpc.php') !== false){ $result = str_replace($loginizer['login_basename'], $loginizer['login_slug'], $link); } return $result; } function loginizer_rl_site_url($link){ $result = loginizer_rl_convert_url($link); return $result; } function loginizer_rl_wp_redirect($link){ $result = loginizer_rl_convert_url($link); return $result; } function loginizer_rl_register($link){ $result = loginizer_rl_convert_url($link); return $result; } // Shows the Login correctly function loginizer_rl_wp_loaded(){ global $loginizer, $interim_login; $page = loginizer_cur_page(); // Is it wp-login.php ? if ($page === $loginizer['login_basename']) { loginizer_set_404(); } // Is it our SLUG ? If not then return if($page !== rtrim($loginizer['login_slug'], '/')){ return false; } // We dont want a WP plugin caching this page @define('NO_CACHE', true); @define('WTC_IN_MINIFY', true); @define('WP_CACHE', false); $user_login = ''; $error = ''; // Prevent errors from defining constants again error_reporting(E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR); include ABSPATH.'/'.$loginizer['login_basename']; exit(); } // Renames the XML-RPC functionality function loginizer_xml_rename_wp_loaded(){ global $loginizer; $page = loginizer_cur_page(); // Is it xmlrpc.php ? if ($page === 'xmlrpc.php') { loginizer_set_404(); } // Is it our SLUG ? If not then return if($page !== $loginizer['xmlrpc_slug']){ return false; } // We dont want a WP plugin caching this page @define('NO_CACHE', true); @define('WTC_IN_MINIFY', true); @define('WP_CACHE', false); // Prevent errors from defining constants again error_reporting(E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR); include ABSPATH.'/xmlrpc.php'; exit(); } // Disables the XML-RPC functionality function loginizer_xmlrpc_null(){ return null; } // Disables the XML-RPC functionality function loginizer_xmlrpc_disable(){ global $loginizer; $page = loginizer_cur_page(); // Is it xmlrpc.php ? if ($page === 'xmlrpc.php'){ echo 'XML-RPC is disabled'; exit(); } } // Disables the XML-RPC functionality function loginizer_xmlrpc_remove_pingback_url($output, $show) { if($show == 'pingback_url'){ $output = ''; } return $output; } // Disable Pingbacks function loginizer_pingbacks_disable($methods) { if(isset($methods['pingback.ping'])){ unset($methods['pingback.ping']); } if(isset($methods['pingback.extensions.getPingbacks'])){ unset($methods['pingback.extensions.getPingbacks']); } return $methods; } //======================== // Captcha Codes //======================== // Adjusts the login form function loginizer_cap_login_form(){ ?> <style type="text/css"> #login { width: 350px !important; padding: 4% 0 0 !important; } </style> <?php } // Verify the login captcha is valid ? function loginizer_cap_login_verify($user){ if(defined('REST_REQUEST') && !empty(REST_REQUEST)){ return $user; } if(!loginizer_cap_verify()){ $captcha_fail_msg = __('The CAPTCHA verification failed. Please try again.', 'loginizer'); return new WP_Error('loginizer_cap_login_error', $captcha_fail_msg, 'loginizer_cap'); } return $user; } // Verify the lostpass captcha is valid ? function loginizer_cap_lostpass_verify($res, $uid){ if(!loginizer_cap_verify()){ $captcha_fail_msg = __('The CAPTCHA verification failed. Please try again.', 'loginizer'); return new WP_Error('loginizer_cap_lostpass_error', $captcha_fail_msg, 'loginizer_cap'); } return $res; } // Verify the resetpass captcha is valid ? function loginizer_cap_resetpass_verify($errors, $user){ if(!loginizer_cap_verify()){ $captcha_fail_msg = __('The CAPTCHA verification failed. Please try again.', 'loginizer'); $errors->add('loginizer_resetpass_cap_error', $captcha_fail_msg, 'loginizer_cap'); } } // Verify the register captcha is valid ? function loginizer_cap_register_verify($errors, $username = '', $email = ''){ if(!loginizer_cap_verify()){ $captcha_fail_msg = __('The CAPTCHA verification failed. Please try again.', 'loginizer'); $errors->add('loginizer_cap_register_error', $captcha_fail_msg, 'loginizer_cap'); } return $errors; } // Verify the register captcha is valid ? function loginizer_cap_register_verify_buddypress($errors, $username = '', $email = ''){ global $bp; // $bp is for BuddyPress Registration it does not pass $errors if(!loginizer_cap_verify()){ $captcha_fail_msg = __('The CAPTCHA verification failed. Please try again.', 'loginizer'); // $bp is for BuddyPress $bp->signup->errors['signup_username'] = $captcha_fail_msg; } return $errors; } // Verify the register captcha is valid ? function loginizer_cap_comment_verify($comment){ if(!loginizer_cap_verify()){ wp_die('The CAPTCHA verification failed. Please try again.', 200); } return $comment; } // Verify WooCommerce Checkout Orders function loginizer_wc_checkout_verify(){ global $loginizer; // Is the registration function verifying it ? if(!is_user_logged_in() && get_option('woocommerce_enable_signup_and_login_from_checkout', 'yes') == 'yes' && !empty($loginizer['captcha_register'])){ // So, no need of any more verification // Lets verify }elseif(!loginizer_cap_verify()){ $captcha_fail_msg = __('The CAPTCHA verification failed. Please try again.', 'loginizer'); wc_add_notice($captcha_fail_msg, 'error'); } } // Reset password form passes $user, hence we need to manually write echo function loginizer_cap_reset_form($user = false){ loginizer_cap_form_login(false); } // For comment form pass false to echo the form function loginizer_cap_comment_form($post_id = 0){ echo '<br />';loginizer_cap_form_social(false); } // Converts numbers to words function loginizer_cap_num_to_words( $number ) { $words = array( 1 => __( 'one', 'loginizer' ), 2 => __( 'two', 'loginizer' ), 3 => __( 'three', 'loginizer' ), 4 => __( 'four', 'loginizer' ), 5 => __( 'five', 'loginizer' ), 6 => __( 'six', 'loginizer' ), 7 => __( 'seven', 'loginizer' ), 8 => __( 'eight', 'loginizer' ), 9 => __( 'nine', 'loginizer' ), 10 => __( 'ten', 'loginizer' ), 11 => __( 'eleven', 'loginizer' ), 12 => __( 'twelve', 'loginizer' ), 13 => __( 'thirteen', 'loginizer' ), 14 => __( 'fourteen', 'loginizer' ), 15 => __( 'fifteen', 'loginizer' ), 16 => __( 'sixteen', 'loginizer' ), 17 => __( 'seventeen', 'loginizer' ), 18 => __( 'eighteen', 'loginizer' ), 19 => __( 'nineteen', 'loginizer' ), 20 => __( 'twenty', 'loginizer' ), 30 => __( 'thirty', 'loginizer' ), 40 => __( 'forty', 'loginizer' ), 50 => __( 'fifty', 'loginizer' ), 60 => __( 'sixty', 'loginizer' ), 70 => __( 'seventy', 'loginizer' ), 80 => __( 'eighty', 'loginizer' ), 90 => __( 'ninety', 'loginizer' ) ); if ( isset( $words[$number] ) ) return $words[$number]; else { $reverse = false; switch ( get_bloginfo( 'language' ) ) { case 'de-DE': $spacer = 'und'; $reverse = true; break; case 'nl-NL': $spacer = 'en'; $reverse = true; break; case 'ru-RU': case 'pl-PL': case 'en-EN': default: $spacer = ' '; } $first = (int) (substr( $number, 0, 1 ) * 10); $second = (int) substr( $number, -1 ); return ($reverse === false ? $words[$first] . $spacer . $words[$second] : $words[$second] . $spacer . $words[$first]); } } // Encode the operation function loginizer_cap_encode_op($string){ return $string; } // Get the session key. If not there create one function loginizer_cap_session_key(){ if(isset($_COOKIE['lz_math_sess']) && preg_match('/[a-z0-9]/is', $_COOKIE['lz_math_sess']) && strlen($_COOKIE['lz_math_sess']) == 40){ return $_COOKIE['lz_math_sess']; } // Generate the key $new_session_key = lz_RandomString(40); // Set the cookie if(@setcookie('lz_math_sess', $new_session_key, time() + (30 * DAY_IN_SECONDS), COOKIEPATH, COOKIE_DOMAIN, is_ssl())){ // Set this to use first time $_COOKIE['lz_math_sess'] = $new_session_key; } return $new_session_key; } // Generate the Captcha field if its a Math Captcha function loginizer_cap_phrase($form = 'default'){ global $loginizer; $ops = array('add' => '+', 'subtract' => '−', 'multiply' => '×', 'divide' => '÷', ); $input = '<input type="text" size="2" length="2" id="loginizer_cap_math" style="display: inline-block; width: 60px!important; vertical-align: middle; margin-bottom: 0; border:1px solid #8c8f94;" name="loginizer_cap_math" value="" aria-required="true"/>'; if(empty($loginizer['captcha_add'])){ unset($ops['add']); } if(empty($loginizer['captcha_subtract'])){ unset($ops['subtract']); } if(empty($loginizer['captcha_multiply'])){ unset($ops['multiply']); } if(empty($loginizer['captcha_divide'])){ unset($ops['divide']); } // Randomly select an operation $rnd_op = array_rand($ops, 1); $number[3] = $ops[$rnd_op]; // Select where to place empty input $rnd_input = mt_rand(0, 2); // Generate the numbers switch ($rnd_op){ case 'add': if($rnd_input === 0){ $number[0] = mt_rand(1, 10); $number[1] = mt_rand(1, 89); }elseif($rnd_input === 1) { $number[0] = mt_rand(1, 89); $number[1] = mt_rand(1, 10); }elseif($rnd_input === 2){ $number[0] = mt_rand(1, 9); $number[1] = mt_rand(1, 10 - $number[0]); } $number[2] = $number[0] + $number[1]; break; case 'subtract': if($rnd_input === 0){ $number[0] = mt_rand(2, 10); $number[1] = mt_rand(1, $number[0] - 1); }elseif($rnd_input === 1){ $number[0] = mt_rand(11, 99); $number[1] = mt_rand(1, 10); }elseif($rnd_input === 2){ $number[0] = mt_rand(11, 99); $number[1] = mt_rand($number[0] - 10, $number[0] - 1); } $number[2] = $number[0] - $number[1]; break; case 'multiply': if($rnd_input === 0){ $number[0] = mt_rand(1, 10); $number[1] = mt_rand(1, 9); }elseif($rnd_input === 1){ $number[0] = mt_rand(1, 9); $number[1] = mt_rand(1, 10); }elseif($rnd_input === 2){ $number[0] = mt_rand(1, 10); $number[1] = ($number[0] > 5 ? 1 : ($number[0] === 4 && $number[0] === 5 ? mt_rand(1, 2 ) : ($number[0] === 3 ? mt_rand(1, 3 ) : ($number[0] === 2 ? mt_rand(1, 5 ) : mt_rand(1, 10 ))))); } $number[2] = $number[0] * $number[1]; break; case 'divide': $divide = array( 1 => 99, 2 => 49, 3 => 33, 4 => 24, 5 => 19, 6 => 16, 7 => 14, 8 => 12, 9 => 11, 10 => 9 ); if($rnd_input === 0){ $divide = array( 2 => array( 1, 2 ), 3 => array( 1, 3 ), 4 => array( 1, 2, 4 ), 5 => array( 1, 5 ), 6 => array( 1, 2, 3, 6 ), 7 => array( 1, 7 ), 8 => array( 1, 2, 4, 8 ), 9 => array( 1, 3, 9 ), 10 => array( 1, 2, 5, 10 ) ); $number[0] = mt_rand(2, 10); $number[1] = $divide[$number[0]][mt_rand(0, count( $divide[$number[0]] ) - 1 )]; }elseif($rnd_input === 1){ $number[1] = mt_rand(1, 10); $number[0] = $number[1] * mt_rand(1, $divide[$number[1]]); }elseif($rnd_input === 2){ $number[2] = mt_rand(1, 10 ); $number[0] = $number[2] * mt_rand(1, $divide[$number[2]]); $number[1] = (int) ($number[0] / $number[2]); } if(! isset( $number[2] ) ) $number[2] = (int) ($number[0] / $number[1]); break; } // Are we to display in words ? if(!empty($loginizer['captcha_words'])){ if($rnd_input === 0){ $number[1] = loginizer_cap_num_to_words( $number[1] ); $number[2] = loginizer_cap_num_to_words( $number[2] ); }elseif($rnd_input === 1){ $number[0] = loginizer_cap_num_to_words( $number[0] ); $number[2] = loginizer_cap_num_to_words( $number[2] ); }elseif($rnd_input === 2){ $number[0] = loginizer_cap_num_to_words( $number[0] ); $number[1] = loginizer_cap_num_to_words( $number[1] ); } } // Finally make the input field if(in_array( $form, array( 'default' ) ) ){ // As per the position of the empty input if($rnd_input === 0 ){ $return = $input . ' ' . $number[3] . ' ' . loginizer_cap_encode_op( $number[1] ) . ' = ' . loginizer_cap_encode_op( $number[2] ); }elseif($rnd_input === 1 ){ $return = loginizer_cap_encode_op( $number[0] ) . ' ' . $number[3] . ' ' . $input . ' = ' . loginizer_cap_encode_op( $number[2] ); }elseif($rnd_input === 2 ){ $return = loginizer_cap_encode_op( $number[0] ) . ' ' . $number[3] . ' ' . loginizer_cap_encode_op( $number[1] ) . ' = ' . $input; } } // Get the session ID $session_id = loginizer_cap_session_key(); // Save the time set_transient('lz_math_cap_'.$session_id, sha1(AUTH_KEY . $number[$rnd_input] . $session_id, false), $loginizer['captcha_time']); // Save the value in the users cookie //loginizer_cap_cookie_set(sha1(AUTH_KEY . $number[$rnd_input] . $session_id, false)); // In some themes the input field does not look fine if it is not in a div it used to take full page height for the input text tag $return = '<div>'.$return.'</div>'; return $return; } // Captcha form for ecommerce function loginizer_cap_form_ecommerce($return = false, $id = ''){ return loginizer_cap_form($return, $id, 'ecommerce'); } // Captcha form for login function loginizer_cap_form_login($return = false, $id = ''){ return loginizer_cap_form($return, $id, 'login'); } // Captcha form for comments/social function loginizer_cap_form_social($return = false, $id = ''){ return loginizer_cap_form($return, $id, 'social'); } // Shows the captcha function loginizer_cap_form($return = false, $id = '', $page_type = 'login'){ global $loginizer; // Math Captcha if(!empty($loginizer['captcha_no_google'])){ // We generate it only once if(empty($GLOBALS['lz_captcha_no_google'])){ $GLOBALS['lz_captcha_no_google'] = $loginizer['captcha_text'].'<br>'.loginizer_cap_phrase().'<br><br>'; } // Store this value $field = $GLOBALS['lz_captcha_no_google']; // hcaptcha }else if(!empty($loginizer['captcha_status']) && $loginizer['captcha_status'] === 3){ if (!wp_script_is('loginizer_hcaptcha_script', 'registered')) { wp_register_script('loginizer_hcaptcha_script', 'https://js.hcaptcha.com/1/api.js', ['jquery'], 1, ['strategy' => 'defer']); } wp_enqueue_script('loginizer_hcaptcha_script'); $field = '<div class="h-captcha" data-sitekey="' . esc_attr($loginizer['hcaptcha_sitekey']) . '" data-hl="' . esc_attr($loginizer['hcaptcha_lang']) . '" data-theme="' . esc_attr($loginizer['hcaptcha_theme']) . '" data-size="' .esc_attr($loginizer['hcaptcha_size']) .'" ></div>'; // Cloudflare Turnstile } elseif(!empty($loginizer['captcha_status']) && $loginizer['captcha_status'] === 4){ $do_multiple = false; if(!wp_script_is('loginizer_turnstil_script', 'registered')){ wp_register_script('loginizer_turnstil_script', 'https://challenges.cloudflare.com/turnstile/v0/api.js', ['jquery'], 0, ['strategy' => 'defer']); } wp_enqueue_script('loginizer_turnstil_script'); $field = '<div class="cf-turnstile" id="lz-turnstile-div" data-sitekey="'.esc_attr($loginizer['turn_captcha_key']).'" data-theme="'.esc_attr($loginizer['turn_captcha_theme']).'" data-language="'.esc_attr($loginizer['turn_captcha_lang']).'" data-size="'.esc_attr($loginizer['turn_captcha_size']).'"></div>'; // Google reCaptcha } else { $field = ''; $query_string = array(); $captcha_type = (!empty($loginizer['captcha_type']) ? $loginizer['captcha_type'] : ''); $site_key = $loginizer['captcha_key']; $theme = $loginizer['captcha_theme']; $size = $loginizer['captcha_size']; $no_js = $loginizer['captcha_no_js']; $captcha_ver = 2; $captcha_js_ver = '2.0'; $invisible = 0; if($captcha_type == 'v3'){ $invisible = 1; $captcha_ver = 3; $captcha_js_ver = '3.0'; $do_multiple = 1; $lz_cap_div_class = 'lz-recaptcha-invisible-v3'; if(!empty($site_key)){ $query_string['render'] = $site_key; } } // For v2 invisible if($captcha_type == 'v2_invisible'){ $invisible = 1; $do_multiple = 1; $size = 'invisible'; $lz_cap_div_class = 'lz-recaptcha-invisible-v2'; $query_string['render'] = 'explicit'; } // Is this a first call ? if(!wp_script_is('loginizer_cap_script', 'registered')){ $language = $loginizer['captcha_lang']; if(!empty($language)){ $query_string['hl'] = $language; } // We need these variables in JS if(!empty($invisible)){ $field .= '<script> var lz_cap_ver = "'.$captcha_ver.'"; var lz_cap_sitekey = "'.$site_key.'"; var lz_cap_div_class = "'.$lz_cap_div_class.'"; var lz_cap_page_type = "'.$page_type.'"; var lz_cap_invisible = "1"; </script>'; } wp_register_script('loginizer_cap_script', "https://".$loginizer['captcha_domain']."/recaptcha/api.js?".http_build_query($query_string), array('jquery'), $captcha_js_ver, true); // We need to load multiple times }else{ $do_multiple = 1; } if(!empty($do_multiple)){ if(!wp_script_is('loginizer_multi_cap_script', 'registered')){ wp_register_script('loginizer_multi_cap_script', LOGINIZER_URL.'/assets/js/multi-recaptcha.js', array('jquery'), $captcha_js_ver, true); } wp_enqueue_script('loginizer_multi_cap_script'); } wp_enqueue_script('loginizer_cap_script'); // For v3 everything is done in javascript if(empty($invisible)){ $field .= "<div ".(!empty($id) ? 'id="'.$id.'"' : '')." class='g-recaptcha lz-recaptcha' data-sitekey='$site_key' data-theme='$theme' data-size='$size'></div>"; if($no_js == 1){ $field .= " <noscript> <div style='width: 302px; height: 352px;'> <div style='width: 302px; height: 352px; position: relative;'> <div style='width: 302px; height: 352px; position: absolute;'> <iframe src='https://".$loginizer['captcha_domain']."/recaptcha/api/fallback?k=$site_key' frameborder='0' scrolling='no' style='width: 302px; height:352px; border-style: none;'> </iframe> </div> <div style='width: 250px; height: 80px; position: absolute; border-style: none; bottom: 21px; left: 25px; margin: 0px; padding: 0px; right: 25px;'> <textarea name='g-recaptcha-response' class='g-recaptcha-response' style='width: 250px; height: 80px; border: 1px solid #c1c1c1; margin: 0px; padding: 0px; resize: none;' value=''> </textarea> </div> </div> </div> </noscript>"; } $field .= '<br>'; }else{ $field .= '<div class="'.$lz_cap_div_class.'"></div>'; if($captcha_ver == 3){ $field .= '<input type="hidden" name="g-recaptcha-response" class="lz-v3-input" value="">'; } } } // Are we to return the code ? if($return){ return $field; // Lets echo it }else{ echo $field; } } // Verifies the Google Captcha and is called by individual for verifiers function loginizer_cap_verify(){ global $loginizer; // WooCommerce is calling this function as well. Hence Captcha fails if(isset($GLOBALS['called_loginizer_cap_verify'])){ return $GLOBALS['called_loginizer_cap_verify']; } // Is the post set ? if(count($_POST) < 1){ return true; } // Some plugin allows to login via Google account does not post the captcha details but does add ONLY rememberme to POST causing the captcha validation to trigger if(count($_POST) == 1 && isset($_POST['rememberme'])){ return true; } $GLOBALS['called_loginizer_cap_verify'] = true; // Math Captcha if(!empty($loginizer['captcha_no_google'])){ $response = (int) (!empty($_POST['loginizer_cap_math']) ? $_POST['loginizer_cap_math'] : ''); // Is the response valid ? if(!is_numeric($response) || empty($response)){ $GLOBALS['called_loginizer_cap_verify'] = false; return false; } // Get the session ID $session_id = loginizer_cap_session_key(); // Is the response valid ? if(empty($session_id)){ $GLOBALS['called_loginizer_cap_verify'] = false; return false; } // Get the Value stored $captcha_value = get_transient('lz_math_cap_'.$session_id); // Do we have a stored value ? if(empty($captcha_value) || strlen($captcha_value) != 40){ $GLOBALS['called_loginizer_cap_verify'] = false; return false; } // Is the value matching if($captcha_value != sha1(AUTH_KEY . $response . $session_id, false)){ $GLOBALS['called_loginizer_cap_verify'] = false; return false; } return true; // hcaptcha }else if(!empty($loginizer['hcaptcha_sitekey']) && !empty($loginizer['captcha_status']) && $loginizer['captcha_status'] == 3){ if(empty($loginizer['hcaptcha_sitekey'])){ return true; } $hresponse = (!empty($_POST['h-captcha-response']) ? $_POST['h-captcha-response'] : ''); $ip = lz_getip(); // Is the IP or response not there ? if(empty($hresponse) || empty($ip)){ $GLOBALS['called_loginizer_cap_verify'] = false; return false; } $url = 'https://hcaptcha.com/siteverify'; // Verify the post $req = wp_remote_post($url, [ 'timeout' => 10, 'body' => [ 'secret' => $loginizer['hcaptcha_secretkey'], 'response' => $hresponse, 'remoteip' => $ip, ] ] ); // Was there an error posting ? if(is_wp_error($req)){ $GLOBALS['called_loginizer_cap_verify'] = false; return false; } // Process the post response $resp = wp_remote_retrieve_body($req); // Is the body valid if(empty($resp)){ $GLOBALS['called_loginizer_cap_verify'] = false; return false; } $json = json_decode($resp, true); if(!empty($json['success'])){ return true; } // Google Captcha } elseif(!empty($loginizer['turn_captcha_secret']) && !empty($loginizer['captcha_status']) && $loginizer['captcha_status'] == 4){ $response = (!empty($_POST['cf-turnstile-response']) ? $_POST['cf-turnstile-response'] : ''); $ip = lz_getip(); // Is the IP or response not there ? if(empty($response) || empty($ip)){ $GLOBALS['called_loginizer_cap_verify'] = false; return false; } $url = 'https://challenges.cloudflare.com/turnstile/v0/siteverify'; $req = wp_remote_post($url, [ 'timeout' => 10, 'body' => [ 'response' => $response, 'secret' => $loginizer['turn_captcha_secret'], 'remoteip' => $ip ] ]); if(is_wp_error($req)){ $GLOBALS['called_loginizer_cap_verify'] = false; return false; } // Process the post response $resp = wp_remote_retrieve_body($req); // Is the body valid if(empty($resp)){ $GLOBALS['called_loginizer_cap_verify'] = false; return false; } $json = json_decode($resp, true); if(!empty($json['success'])){ return true; } }else{ // If secret key is not there, return if(empty($loginizer['captcha_secret'])){ return true; } $response = (!empty($_POST['g-recaptcha-response']) ? $_POST['g-recaptcha-response'] : ''); $ip = lz_getip(); // Is the IP or response not there ? if(empty($response) || empty($ip)){ $GLOBALS['called_loginizer_cap_verify'] = false; return false; } $url = 'https://'.$loginizer['captcha_domain'].'/recaptcha/api/siteverify'; // Verify the post $req = wp_remote_post($url, [ 'timeout' => 10, 'body' => [ 'secret' => $loginizer['captcha_secret'], 'response' => $response, 'remoteip' => $ip ] ] ); // Was there an error posting ? if(is_wp_error($req)){ $GLOBALS['called_loginizer_cap_verify'] = false; return false; } // Process the post response $resp = wp_remote_retrieve_body($req); // Is the body valid if(empty($resp)){ $GLOBALS['called_loginizer_cap_verify'] = false; return false; } $json = json_decode($resp, true); if(!empty($json['success'])){ return true; } } // Couldnt verify $GLOBALS['called_loginizer_cap_verify'] = false; return false; } function loginizer_wc_before_checkout_process(){ global $loginizer; // This is checkout page. If admin has disabled captcha on checkout // and the user is registering during checkout we have not displayed the captcha form so we should not verify the same if(empty($loginizer['captcha_wc_checkout'])){ remove_filter('woocommerce_registration_errors', 'loginizer_cap_register_verify'); } } //========================================= // Registration Domain Blacklist //========================================= function loginizer_domains_blacklist($errors, $username, $email){ global $wpdb, $loginizer, $lz_error; $domains = $loginizer['domains_blacklist']; $domains = is_array($domains) ? $domains : array(); // Are you blacklisted ? foreach($domains as $domain_to_match){ $domain_to_match = str_replace('*', '(.*?)', $domain_to_match); if(preg_match('/'.$domain_to_match.'$/is', $email)){ $match_found = 1; } } // Did we get a match ? if(!empty($match_found)){ $errors->add('loginizer_domains_blacklist_error', 'The domain of your email is banned from registering on this website', 'loginizer_domains_blacklist'); } return $errors; } //========================================= // 2 Factor Auth / Question based security //========================================= // Handle the users secondary login i.e. 2fa / question, etc. function loginizer_user_redirect($user, $username, $password){ global $loginizer; // Is the post set ? if(count($_POST) < 1){ return $user; } //print_r($user);die(); // Is it a valid user ? if(!is_a($user, 'WP_User')){ return $user; } // The user has given correct details // Now does the user have any of our features enabled ? $settings = get_user_meta($user->ID, 'loginizer_user_settings', true); //print_r($settings);die(); // Is it applicable as per role if(!loginizer_is_2fa_applicable($user)){ return $user; } if(loginizer_is_whitelisted_2fa()){ return $user; } // Set the default return to the user only $ret = $user; // Is it a secondary question ? if(!empty($settings['pref']) && $settings['pref'] == 'question'){ // Is there a question and answer if(!empty($settings['question']) && !empty($settings['answer'])){ $save = 1; } } // Is it a 2fa via App ? if(!empty($settings['pref']) && $settings['pref'] == '2fa_app'){ if(!empty($settings['app_enable'])){ $save = 1; } } // Is it a 2fa via email ? if((!empty($settings['pref']) && $settings['pref'] == '2fa_email') || ((empty($settings['pref']) || @$settings['pref'] == 'none') && !empty($loginizer['2fa_email_force'])) ){ // Generate a 6 digit code $otp = wp_rand(100000, 999999); $r['code'] = base64_encode($otp); // Email them $site_name = get_bloginfo('name'); $first_name = get_user_meta($user->ID, 'first_name', true); $last_name = get_user_meta($user->ID, 'last_name', true); if(empty($first_name)){ $first_name = $user->data->display_name; } $vars = array('email' => $user->data->user_email, 'otp' => $otp, 'site_name' => $site_name, 'site_url' => get_site_url(), 'display_name' => $user->data->display_name, 'user_login' => $user->data->user_login, 'first_name' => $first_name, 'last_name' => $last_name); $subject = lz_lang_vars_name($loginizer['2fa_email_sub'], $vars); $message = lz_lang_vars_name($loginizer['2fa_email_msg'], $vars); //echo $user->data->user_email.'<br>'.$message;die(); $sent = wp_mail($user->data->user_email, $subject, $message); if(empty($sent)){ // For plugins that login using AJAX if(!empty(get_transient('loginizer_2fa_'. $user->ID))){ return array('message' => esc_html__('There was a problem sending your email with the OTP. Please try again or contact an admin.', 'loginizer')); } return new WP_Error('email_not_sent', 'There was a problem sending your email with the OTP. Please try again or contact an admin.', 'loginizer_2fa_email'); }else{ $save = 1; } } // Are we to create and save a token ? if(!empty($save)){ // Are we to be remembered ? $r['rememberme'] = lz_optreq('rememberme'); // Create a token $token = loginizer_user_token($user->ID, $r); // For custom redirect on Login when 2FA is enabled $custom_redirects = get_option('loginizer_2fa_custom_redirect'); if(!empty($custom_redirects) && !empty($user->roles)){ foreach($user->roles as $role){ if(!empty($custom_redirects[$role]) && wp_validate_redirect($custom_redirects[$role])){ $_REQUEST['redirect_to'] = wp_validate_redirect($custom_redirects[$role]); break; } } } $redirect_to = ''; if(!empty($_REQUEST['redirect_to'])){ $redirect_to = '&redirect_to='.urlencode($_REQUEST['redirect_to']); } elseif(!empty($_REQUEST['redirect'])){ $redirect_to = '&redirect_to='.urlencode($_REQUEST['redirect']); } elseif(!empty(wp_validate_redirect($_SERVER['HTTP_REFERER']))){ $redirect_to = '&redirect_to='.urlencode(wp_validate_redirect($_SERVER['HTTP_REFERER'])); } // Form the URL $url = wp_login_url().'?action=loginizer_security&uid='.$user->ID.'&lutoken='.$token.$redirect_to.(isset( $_REQUEST['interim-login'] ) ? '&interim-login=1' : '').(!empty($_SERVER['IS_WPE']) ? '&wpe-login=true' : ''); // For plugins that login using AJAX if(!empty(get_transient('loginizer_2fa_'. $user->ID))){ return $url; } loginizer_update_attempt_stats(1); // Lets redirect wp_safe_redirect($url); die(); } return $ret; } // Creates a one time token function loginizer_user_token($uid = 0, $r = array()){ global $loginizer; // Variables $time = time(); $expires = ($time + 600); $action = 'loginizer_user_token'; include_once( ABSPATH.'/'.$loginizer['wp-includes'].'/class-phpass.php'); $wp_hasher = new PasswordHash(8, TRUE); // Create the token with a random salt and the time $token = wp_hash(wp_generate_password(20, false).$action.$time); // Create a hash of the token $r['stored_hash'] = $wp_hasher->HashPassword($expires.$token); $r['expires'] = $expires; // Store the hash and when it expires update_user_meta($uid, $action, $r); return $token; } // Process the secondary form i.e. question / 2fa, etc. function loginizer_user_security(){ global $loginizer, $lz, $lz_error, $interim_login; if(empty($_GET['uid']) || empty($_GET['lutoken'])){ return false; } $uid = (int) sanitize_key($_GET['uid']); $token = sanitize_key($_GET['lutoken']); $action = 'loginizer_user_token'; $meta = get_user_meta($uid, $action, true); $hash = !empty($meta['stored_hash']) ? $meta['stored_hash'] : ''; $expires = !empty($meta['expires']) ? $meta['expires'] : ''; include_once(ABSPATH.'/'.$loginizer['wp-includes'].'/class-phpass.php'); $wp_hasher = new PasswordHash(8, TRUE); $time = time(); if(!$wp_hasher->CheckPassword($expires.$token, $hash) || $expires < $time){ // Throw an error $lz['error'] = sprintf(__('The token is invalid or has expired. Please provide your user details by clicking <a href="%s">here</a>', 'loginizer'), wp_login_url()); loginizer_user_security_form(); } // Get the username $userdata = get_userdata($uid); $username = $userdata->data->user_login; // Load the settings $lz['settings'] = get_user_meta($uid, 'loginizer_user_settings', true); // If the user was just created and the settings is empty if(empty($lz['settings'])){ $lz['settings'] = array(); } if((empty($lz['settings']['pref']) || $lz['settings']['pref'] == 'none') && !empty($loginizer['2fa_email_force'])){ $lz['settings']['pref'] = '2fa_email'; } /* Make sure post was from this page */ if(count($_POST) > 0 && !check_admin_referer('loginizer-enduser')){ $lz['error'] = __('The form security was compromised !', 'loginizer'); loginizer_user_security_form(); } // Has the user reached max attempts ? if(!loginizer_can_login()){ $lz['error'] = $lz_error; loginizer_user_security_form(); } $interim_login = isset( $_REQUEST['interim-login'] ); // Process the post if(!empty($_POST['lus_submit'])){ if(@$lz['settings']['pref'] == 'question'){ // Is there an answer ? $answer = lz_optpost('lus_value'); // Is the answer correct ? if($answer != @base64_decode($lz['settings']['answer'])){ loginizer_login_failed($username.' | 2FA-Answer', 1); $lz['error'][] = __('The answer is wrong !', 'loginizer'); $lz['error'][] = loginizer_retries_left(); loginizer_user_security_form(); // Login the user }else{ $do_login = 1; } } if(@$lz['settings']['pref'] == '2fa_email'){ // Is there an OTP ? $otp = lz_optpost('lus_value'); // Is the answer correct ? if($otp != @base64_decode($meta['code'])){ loginizer_login_failed($username.' | 2FA-Email', 1); $lz['error'][] = __('The OTP is wrong !', 'loginizer'); $lz['error'][] = loginizer_retries_left(); loginizer_user_security_form(); // Login the user }else{ $do_login = 1; } } // App based login if(@$lz['settings']['pref'] == '2fa_app'){ // Is there an OTP ? $otp = lz_optpost('lus_value'); $app2fa = loginizer_2fa_app($uid); // Is the answer correct ? if($otp != $app2fa['2fa_otp']){ // Maybe its an Emergency OTP if(empty($lz['settings']['2fa_emergency']) || !@in_array($otp, $lz['settings']['2fa_emergency'])){ loginizer_login_failed($username.' | 2FA-APP', 1); $lz['error'][] = __('The OTP is wrong !', 'loginizer'); $lz['error'][] = loginizer_retries_left(); loginizer_user_security_form(); }else{ // Remove the Emergency used and save the rest unset($lz['settings']['2fa_emergency'][$otp]); // Save it update_user_meta($uid, 'loginizer_user_settings', $lz['settings']); $do_login = 1; } // Login the user }else{ $do_login = 1; } } // Are we to login ? if(!empty($do_login)){ $remember_me = !empty($meta['rememberme']) ? true : false; // Login the User wp_set_auth_cookie($uid, $remember_me); // Delete the meta delete_user_meta($uid, $action); delete_transient('loginizer_2fa_' . $uid); // it is generated when the user logins through some ajax form $redirect_to = !empty($_REQUEST['redirect_to']) ? $_REQUEST['redirect_to'] : admin_url(); // Redirect and exit // Interim Login is used when session times out due to inactivity and login form is opened in a popup iframe if ( $interim_login ) { $message = '<p class="message">' . __( 'You have logged in successfully.', 'loginizer' ) . '</p>'; $interim_login = 'success'; login_header( '', $message ); ?> </div> <?php /** This action is documented in wp-login.php */ do_action( 'login_footer' ); ?> </body></html> <?php }else{ $redirect_to = loginizer_csrf_change_url($redirect_to, $uid); wp_safe_redirect($redirect_to); } exit; } } loginizer_user_security_form(); } // Shows the secondary form i.e. question / 2fa, etc. function loginizer_user_security_form(){ global $loginizer, $lz; // Some plugins uses these actions do_action( 'login_init' ); do_action( "login_form_login" ); // Deletes cookie by setting past time, this cookie is created when you login from a login that works using AJAX @setCookie('loginizer_2fa_' . get_current_user_id(), '', time() - DAY_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN, true); login_header(); if(!empty($lz['error'])){ if(!is_array($lz['error'])){ $lz['error'] = array($lz['error']); } echo '<div id="login_error" class="notice notice-error">'; foreach($lz['error'] as $ek => $error_txt){ echo wp_kses($error_txt, NULL).'<br />'; } echo '</div>'; } if(!empty($lz['settings'])){ echo '<form action="" method="post" autocomplete="new-password">'; wp_nonce_field('loginizer-enduser'); // Are we to ask a question if(@$lz['settings']['pref'] == 'question'){ echo '<p> '.$loginizer['2fa_msg']['otp_question'].' : <br /><br /> <span title="" style="color:#444; font-size:16px"> '.$lz['settings']['question'].'<br /> </span> </p> <br /> <p> <label title=""> '.$loginizer['2fa_msg']['otp_answer'].' <div class="wp-pwd"> <input type="text" name="lus_value" id="lus_value" class="input password-input" value="" size="20" autocomplete="off" /> </div> </label> </p>'; } // Its a 2fa email if(@$lz['settings']['pref'] == '2fa_email'){ echo '<p>'.$loginizer['2fa_msg']['otp_email'].'</p> <br> <p> <label title=""> '.$loginizer['2fa_msg']['otp_field'].' <div class="wp-pwd"> <input type="text" name="lus_value" id="lus_value" class="input password-input" value="" size="20" autocomplete="off" /> </div> </label> </p>'; } // Its a 2fa app ? if(@$lz['settings']['pref'] == '2fa_app'){ echo '<p>'.$loginizer['2fa_msg']['otp_app'].'</p> <br> <p> <label title=""> '.$loginizer['2fa_msg']['otp_field'].' <div class="wp-pwd"> <input type="text" name="lus_value" id="lus_value" class="input password-input" value="" size="20" autocomplete="off" /> </div> </label> </p>'; } echo '<p class="submit"> <input type="submit" id="lus_submit" name="lus_submit" class="button button-primary button-large" value="'.__('Log In', 'loginizer').'" /> </p> </form>'; } // Focus on the field login_footer('lus_value'); exit(); } // Show the 2fa Notice function loginizer_2fa_notice(){ echo ' <style> .lz_button { background-color: #4CAF50; /* Green */ border: none; color: white; padding: 8px 16px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 4px 2px; -webkit-transition-duration: 0.4s; /* Safari */ transition-duration: 0.4s; cursor: pointer; } .lz_button:focus{ border: none; color: white; } .lz_button1 { color: white; background-color: #4CAF50; border:3px solid #4CAF50; } .lz_button1:hover { box-shadow: 0 6px 8px 0 rgba(0,0,0,0.24), 0 9px 25px 0 rgba(0,0,0,0.19); color: white; border:3px solid #4CAF50; } .lz_button2 { color: white; background-color: #0085ba; } .lz_button2:hover { box-shadow: 0 6px 8px 0 rgba(0,0,0,0.24), 0 9px 25px 0 rgba(0,0,0,0.19); color: white; } .lz_button3 { color: white; background-color: #365899; } .lz_button3:hover { box-shadow: 0 6px 8px 0 rgba(0,0,0,0.24), 0 9px 25px 0 rgba(0,0,0,0.19); color: white; } .lz_button4 { color: white; background-color: rgb(66, 184, 221); } .lz_button4:hover { box-shadow: 0 6px 8px 0 rgba(0,0,0,0.24), 0 9px 25px 0 rgba(0,0,0,0.19); color: white; } .loginizer_2fa_notice-close{ float:right; text-decoration:none; margin: 5px 10px 0px 0px; } .loginizer_2fa_notice-close:hover{ color: red; } </style> <script> jQuery(document).ready( function() { (function($) { $("#loginizer_2fa_notice .loginizer_2fa_notice-close").click(function(){ var data; // Hide it $("#loginizer_2fa_notice").hide(); // Save this preference $.post("'.admin_url('?loginizer_2fa_notice=0').'", data, function(response) { //alert(response); }); }); $("#loginizer_2fa_notice .lz_button2").click(function(){ var data; // Hide it $("#loginizer_2fa_notice").hide(); // Save this preference $.post("'.admin_url('?loginizer_2fa_notice=1').'", data, function(response) { //alert(response); }); }); })(jQuery); }); </script> <div class="notice notice-success" id="loginizer_2fa_notice" style="min-height:120px"> <a class="loginizer_2fa_notice-close" href="javascript:" aria-label="Dismiss this Notice"> <span class="dashicons dashicons-dismiss"></span> Dismiss Forever </a> <img src="'.LOGINIZER_URL.'/assets/images/loginizer-200.png" style="float:left; margin:10px 20px 10px 10px" width="100" /> <p style="font-size:16px">'.__('The site admin has enabled Two Factor Authentication features to secure your account. <br>For your safety, you must setup your login security preferences.', 'loginizer').'</p> <p> <a class="lz_button lz_button1" href="'.admin_url('?page=loginizer_user').'">'.__('Setup My Security Settings', 'loginizer').'</a> <a id="" class="lz_button lz_button2" href="javascript:void(0)">'.__('Remind me later', 'loginizer').'</a> </p> </div>'; } // Shows the user menu to all users function loginizer_user_menu(){ add_menu_page(__('My Loginizer Security Settings', 'loginizer'), __('My Security', 'loginizer'), 'read', 'loginizer_user', 'loginizer_user_page', '', 72); } // Generates the 2FA as seen in the APP function loginizer_2fa_app_key($settings, $length = 6, $counter = 0){ $key = $settings['2fa_key']; $type = (empty($settings['2fa_type']) ? 'totp' : $settings['2fa_type']); if($type == 'hotp'){ $stored_in_db = 1; $counter = !empty($counter) ? $counter : $stored_in_db; $res = HOTP::generateByCounter($key, $counter); }else{ $time = !empty($counter) ? $counter : time(); $res = HOTP::generateByTime($key, 30, $time); } return $res->toHotp($length); } // Returns the 2fa_app data. Is also used during ajax function loginizer_2fa_app($uid = 0){ // Include necessary stuff include_once(LOGINIZER_DIR.'/lib/hotp.php'); include_once(LOGINIZER_DIR.'/lib/Base32.php'); $uid = empty($uid) ? get_current_user_id() : $uid; $user = get_user_by('id', $uid); // For 2fa_app we must be prepared $tmpkey = get_user_meta($uid, 'loginizer_user_2fa_tmpkey', true); $settings['2fa_key'] = empty($tmpkey) ? '' : base64_decode($tmpkey);// Just decode it // We might need to create a 10 char secret KEY for 2fa App based if(empty($settings['2fa_key']) || isset($_REQUEST['reset_2fa_key'])){ // Generate $settings['2fa_key'] = strtoupper(lz_RandomString(10)); // Save the new one update_user_meta($uid, 'loginizer_user_2fa_tmpkey', base64_encode($settings['2fa_key'])); } // Base32 Key $settings['2fa_key_32'] = Base32::encode($settings['2fa_key']); // The QR Code text $url = preg_replace('/^https?:\/\//', '', site_url()); $site_name = get_bloginfo('name'); $settings['2fa_qr'] = 'otpauth://'.(empty($settings['2fa_type']) ? 'totp' : $settings['2fa_type']).'/'.rawurlencode($url).':'.@$user->user_login.'?secret='.Base32::encode($settings['2fa_key']).'&issuer='.rawurlencode($site_name).'&counter='; // Time now $settings['2fa_server_time'] = get_date_from_gmt(gmdate('Y-m-d H:i:s'), 'Y-m-d H:i:s'); // Current OTP $settings['2fa_otp'] = loginizer_2fa_app_key($settings); return $settings; } // Handles the users choice page POST function loginizer_user_page_post(&$error = array()){ global $loginizer, $loginizer_allowed; /* Make sure post was from this page */ if(count($_POST) > 0){ check_admin_referer('loginizer-user'); } $uid = get_current_user_id(); if(!empty($_POST['submit'])){ // What has the user selected ? $Nsettings['pref'] = lz_optpost('loginizer_user_choice'); if(empty($loginizer_allowed[$Nsettings['pref']])){ $error['lz_not_allowed'] = __('You have submitted an invalid preference', 'loginizer'); return 0; } // Process security question if($Nsettings['pref'] == 'question'){ $Nsettings['question'] = lz_optpost('lz_question'); $Nsettings['answer'] = lz_optpost('lz_answer'); // Was there a question ? if(empty($Nsettings['question'])){ $error['lz_no_question'] = __('No question was submitted', 'loginizer'); } // Question too long ? if(strlen($Nsettings['question']) > 255){ $error['lz_question_long'] = __('The question is too long', 'loginizer'); } // Was there an answer ? if(empty($Nsettings['answer'])){ $error['lz_no_answer'] = __('No answer was submitted', 'loginizer'); } // Question too long ? if(strlen($Nsettings['answer']) > 255){ $error['lz_answer_long'] = __('The answer is too long', 'loginizer'); } if(!empty($error)){ return 0; } // Hash the answer $Nsettings['answer'] = base64_encode($Nsettings['answer']); } // Process 2fa via Email if($Nsettings['pref'] == '2fa_email'){ // Actually nothing to store ! } // Process 2fa via App if($Nsettings['pref'] == '2fa_app'){ // Enable APP $Nsettings['app_enable'] = (int) lz_optpost('lz_app_enable'); // Any one time passwords ? $emergency = lz_optpost('lz_2fa_emergency'); // Is there any Emergency OTP if(!empty($emergency)){ $emergency = explode(',', $emergency); // Loop through and correct foreach($emergency as $ek => $ev){ $orig = $ev; $ev = (int) $ev; $_emergency[$ev] = $ev; if(strlen($ev) != 6){ $incorrect[] = $orig; } } if(!empty($incorrect)){ $error['lz_emergency'] = __('The emergency code(s) are incorrect', 'loginizer').' : '.implode(', ', $incorrect); } $Nsettings['2fa_emergency'] = $_emergency; } if(!empty($error)){ return 0; } } // Lets save the settings update_user_meta($uid, 'loginizer_user_settings', $Nsettings); return 1; } } // Loginizer 2FA User settings loader function loginizer_load_user_settings(&$uid, &$user, &$settings, &$current_pref){ $uid = get_current_user_id(); $user = wp_get_current_user();//print_r($user); $settings = get_user_meta($uid, 'loginizer_user_settings', true); $settings = empty($settings) ? array() : $settings; $current_pref = @$settings['pref']; $current_pref = empty($current_pref) ? '' : $current_pref; } function loginizer_is_whitelisted_2fa(){ global $wpdb, $loginizer, $lz_error; $whitelist = $loginizer['2fa_whitelist']; foreach($whitelist as $k => $v){ // Is the IP in the blacklist ? if(inet_ptoi($v['start']) <= inet_ptoi($loginizer['current_ip']) && inet_ptoi($loginizer['current_ip']) <= inet_ptoi($v['end'])){ $result = 1; break; } // Is it in a wider range ? if(inet_ptoi($v['start']) >= 0 && inet_ptoi($v['end']) < 0){ // Since the end of the RANGE (i.e. current IP range) is beyond the +ve value of inet_ptoi, // if the current IP is <= than the start of the range, it is within the range // OR // if the current IP is <= than the end of the range, it is within the range if(inet_ptoi($v['start']) <= inet_ptoi($loginizer['current_ip']) || inet_ptoi($loginizer['current_ip']) <= inet_ptoi($v['end'])){ $result = 1; break; } } } // You are whitelisted if(!empty($result)){ return true; } return false; } // If 2FA is ON and there are roles, then is 2FA applicable to the user function loginizer_is_2fa_applicable($user = array()){ global $loginizer; // If roles is empty then its applicable to all if(empty($loginizer['2fa_roles'])){ return true; } // Are there any roles we need to check if(!empty($loginizer['2fa_roles'])){ foreach($loginizer['2fa_roles'] as $role => $v){ if(in_array($role, $user->roles)){ return true; } } } return false; } // The settings page shown to users function loginizer_user_page(){ global $loginizer, $loginizer_allowed; $loginizer_allowed = array(); $loginizer_allowed['none'] = 1; if(!empty($loginizer['2fa_app'])){ $loginizer_allowed['2fa_app'] = 1; } if(!empty($loginizer['2fa_email'])){ $loginizer_allowed['2fa_email'] = 1; } if(!empty($loginizer['2fa_sms'])){ $loginizer_allowed['2fa_sms'] = 1; } if(!empty($loginizer['question'])){ $loginizer_allowed['question'] = 1; } //------------------ // Process the form //------------------ $error = array(); $saved = loginizer_user_page_post($error); //------------------ // Load Settings //------------------ loginizer_load_user_settings($uid, $user, $settings, $current_pref); $app2fa = loginizer_2fa_app(); //------------------ // Show the Page //------------------ echo '<h2>'.__('Loginizer Security Settings', 'loginizer').'</h2>'; if(!empty($saved)){ echo '<div class="updated notice is-dismissible"><p><strong>'.__('Settings saved.', 'loginizer').'</strong></p></div>'; } if(!empty($error)){ lz_report_error($error); } if(is_admin()){ echo '<p class="">'.__('These are your personal security and login settings and will not affect other users.', 'loginizer').'</p>'; }else{ if(class_exists('WooCommerce')){ echo '<style> body.woocommerce-account ul li.woocommerce-MyAccount-navigation-link--loginizer-security a:before{ content: "\f3ed" } </style>'; } } if (current_user_can('manage_options')) { echo '<p><a href="https://wordpress.org/plugins/loginizer/faq/">'._e('You should also bookmark the FAQs, which explain how to de-activate the plugin even if you cannot log in.', 'loginizer').'</a></p>'; } wp_enqueue_script('jquery-qrcode', LOGINIZER_URL.'/assets/js/jquery.qrcode.min.js', array('jquery'), '0.12.0'); // Give the user the drop down to choose the settings echo 'Choose Preference : <form method="post" action=""> '.wp_nonce_field('loginizer-user').' <select name="loginizer_user_choice" id="loginizer_user_choice" onchange="loginizer_pref_handle();"> <option value="none" '.($current_pref == 'none' ? 'selected="selected"' : '').'>None (Not Recommended !)</option> '.(empty($loginizer['2fa_app']) ? '' : '<option value="2fa_app" '.($current_pref == '2fa_app' ? 'selected="selected"' : '').'>2fa : Google Authenticator, Authy, etc</option>').' '.(empty($loginizer['2fa_email']) ? '' : '<option value="2fa_email" '.($current_pref == '2fa_email' || ((empty($current_pref) || $current_pref == 'none') && !empty($loginizer['2fa_email_force'])) ? 'selected="selected"' : '').'>2fa : Email Auth Code</option>').' '.(empty($loginizer['2fa_sms']) ? '' : '<option value="2fa_sms" '.($current_pref == '2fa_sms' ? 'selected="selected"' : '').'>2fa : SMS Auth Code</option>').' '.(empty($loginizer['question']) ? '' : '<option value="question" '.($current_pref == 'question' ? 'selected="selected"' : '').'>Solve Security Question</option>').' </select> <script> var loginizer_nonce = "'.wp_create_nonce('loginizer_ajax').'"; // Handle on change function loginizer_pref_handle(){ (function($) { // Get the value var current = $("#loginizer_user_choice").val(); $(".loginizer_upd").each(function(){ if($(this).attr("id") == "loginizer_"+current){ $(this).show(); }else{ $(this).hide(); } }); // Are we to show the QR Code ? if(current == "2fa_app"){ loginizer_2fa_app_load(); } })(jQuery); }; // Show the QR Code and stuff function loginizer_2fa_app_load(reset){ reset = reset || 0; // Remove existing QRCode jQuery("#loginizer_2fa_app_qr").html(""); // Refresh OTP if(reset == 2){ var data = new Object(); data["action"] = "loginizer_ajax"; data["nonce"] = loginizer_nonce; // AJAX and on success function jQuery.post(ajaxurl, data, function(response){ jQuery("#loginizer_2fa_app_time").html(response["2fa_server_time"]); jQuery("#loginizer_2fa_app_key").val(response["2fa_key"]); jQuery("#loginizer_2fa_app_key_32").val(response["2fa_key_32"]); jQuery("#loginizer_2fa_app_otp").html(response["2fa_otp"]); jQuery("#loginizer_2fa_app_qr").attr("data-qrcode", response["2fa_qr"]); }); } // Reset code if(reset == 1){ var confirmed = confirm("'.__('Warning: If you reset the secret key you will have to update your apps with the new one. Are you sure you want to continue ?', 'loginizer').'"); if(confirmed){ // Data to Post var data = new Object(); data["action"] = "loginizer_ajax"; data["nonce"] = loginizer_nonce; data["reset_2fa_key"] = 1; // AJAX and on success function jQuery.post(ajaxurl, data, function(response){ jQuery("#loginizer_2fa_app_time").html(response["2fa_server_time"]); jQuery("#loginizer_2fa_app_key").val(response["2fa_key"]); jQuery("#loginizer_2fa_app_key_32").val(response["2fa_key_32"]); jQuery("#loginizer_2fa_app_otp").html(response["2fa_otp"]); jQuery("#loginizer_2fa_app_qr").attr("data-qrcode", response["2fa_qr"]); }); }else{ return; } } var qrtext = jQuery("#loginizer_2fa_app_qr").attr("data-qrcode"); jQuery("#loginizer_2fa_app_qr").qrcode({"text" : qrtext}); return; }; // Onload stuff jQuery(document).ready(function(){ loginizer_pref_handle(); }); </script> <style> .loginizer_upd{ display: none; } </style> <br /> <div id="loginizer_2fa_app" class="loginizer_upd"> <h2>'.__('App based Two Factor Auth Code Settings', 'loginizer').'</h2> <p> '.__('<b>NOTE :</b> Generating two-factor codes depends upon your web-server and your device agreeing upon the time.', 'loginizer').' <br> '.__('The current UTC time according to this server when this page loaded', 'loginizer').': <b id="loginizer_2fa_app_time">'.$app2fa['2fa_server_time'].'</b> </p> <table border="0" cellpadding="8" cellspacing="1" width="500"> <tr> <td width="50%"><b>Enable :</b></td> <td><input type="checkbox" value="1" name="lz_app_enable" '.lz_POSTchecked('lz_app_enable', (empty($settings['app_enable']) ? false : true)).' /></td> </tr> <tr> <tr> <td> <b>Secret Key :</b><br> <a href="javascript:loginizer_2fa_app_load(1)">Reset Secret Key</a> </td> <td><input type="text" name="lz_2fa_key" id="loginizer_2fa_app_key" value="'.$app2fa['2fa_key'].'" disabled="disabled" /></td> </tr> <tr> <td><b>Secret Key (Base32) :</b><br> Used by Google Authenticator, Authy, etc.</td> <td><input type="text" name="lz_2fa_key_32" id="loginizer_2fa_app_key_32" value="'.$app2fa['2fa_key_32'].'" disabled="disabled" /></td> </tr> <tr> <td> <b>'.__('One Time Emergency Codes', 'loginizer').' :</b><br> '.__('(Optional) You can specify 6 digit emergency codes seperated by a comma. Each can be used only once. You can specify upto 10.', 'loginizer').' </td> <td><input type="text" name="lz_2fa_emergency" value="'.lz_POSTval('lz_2fa_emergency', (empty($settings['2fa_emergency']) ? '' : implode(', ', $settings['2fa_emergency']) ) ).'" placeholder="e.g. 124667, 976493, 644335" /></td> </tr> </table> <br><br> <table border="0" cellpadding="8" cellspacing="1" width="500" style="background: #FFF" align="center"> <tr> <td colspan="2"><b>'.__('If you enable app based Two Factor Auth, then verify that your application is showing the same One Time Password (OTP) as shown on this page before you log out.', 'loginizer').'</b> </tr> <tr> <td> <b>'.__('Current OTP', 'loginizer').' :</b><br> <a href="javascript:loginizer_2fa_app_load(2)">'.__('Refresh', 'loginizer').'</a> </td> <td><h1 id="loginizer_2fa_app_otp">'.loginizer_2fa_app_key($app2fa).'</h1></td> </tr> <tr> <td width="30%" valign="top"><b>QR Code :</b></td> <td><div id="loginizer_2fa_app_qr" data-qrcode="'.esc_attr($app2fa['2fa_qr']).'"></div></td> </tr> </table> </div> <div id="loginizer_question" class="loginizer_upd"> <h2>'.__('Security Question Settings', 'loginizer').'</h2> <p>'.__('A secondary question set by you will be asked on a successful login', 'loginizer').'</p> <table border="0" cellpadding="8" cellspacing="1"> <tr> <td><b>Question :</b></td> <td><input type="text" name="lz_question" value="'.(empty($settings['question']) ? '' : $settings['question']).'" size="40" placeholder="e.g. The name of my pet is ?" /></td> </tr> <tr> <td><b>Answer :</b><br />Is case sensitive</td> <td><input type="text" name="lz_answer" value="'.(empty($settings['answer']) ? '' : base64_decode($settings['answer'])).'" placeholder="e.g. tommy" /></td> </tr> </table> </div> <div id="loginizer_2fa_email" class="loginizer_upd"> <h2>'.__('Email Two Factor Auth Code Settings', 'loginizer').'</h2> <p> '.__('A One Time Password (OTP) will be asked on a successful login. The OTP will be emailed to your email address', 'loginizer').' : <br> <h2>'.$user->data->user_email.'</h2> </p> </div> <div id="loginizer_2fa_sms" class="loginizer_upd"> <h2>'.__('SMS Two Factor Auth Code Settings', 'loginizer').'</h2> <p> '.__('A One Time Password (OTP) will be asked on a successful login. The OTP will be sent via SMS to your mobile.', 'loginizer').' <br> </p> <table border="0" cellpadding="8" cellspacing="1"> <tr> <td><b>'.__('Mobile Number', 'loginizer').' :</b></td> <td><input type="text" name="lz_mobile" value="'.(empty($settings['mobile']) ? '' : base64_decode($settings['mobile'])).'" placeholder="e.g. +18557852145" /></td> </tr> </table> </div>'; //WooCommerce Loginizer Security Settings - Switch between the normal submit button and the submit button that's only available in the admin panel if ( ! is_admin() && ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) ) { echo '<br><input type="submit" name="submit" value="Submit" />'; }else{ submit_button(); } echo '</form>'; } // AJAX callback function used to generate new secret function loginizer_user_page_ajax(){ global $user_id; // Some AJAX security check_ajax_referer('loginizer_ajax', 'nonce'); header('Content-Type: application/json'); // Data $result = loginizer_2fa_app(); // Echo JSON and die echo json_encode($result); die(); } // AJAX callback function used to TEST the new SLUG function loginizer_wp_admin_ajax(){ global $user_id; // Some AJAX security check_ajax_referer('loginizer_admin_ajax', 'nonce'); if(!current_user_can('manage_options')){ wp_die(__('Sorry, but you do not have permissions to change settings.', 'loginizer')); } header('Content-Type: application/json'); // Data $result['result'] = '1'; // Echo JSON and die echo json_encode($result); die(); } // Do the checksum of the core function loginizer_checksums(){ global $loginizer, $loginizer_allowed, $wp_local_package; // Update the time update_option('loginizer_checksums_last_run', time()); // Get the locale and version $version = $GLOBALS['wp_version']; $locale = 'en_US'; if(!empty($wp_local_package)){ $locale = $wp_local_package; } //echo $version.' - '.$locale; // Load the checksums $resp = wp_remote_get('https://api.wordpress.org/core/checksums/1.0/?version='.$version.'&locale='.$locale, array('timeout' => 10)); //lz_print($resp); if(!is_array($resp)){ return false; } $checksums = json_decode($resp['body'], true);//lz_print($checksums); $checksums = $checksums['checksums']; //lz_print($checksums); // WP-content could be renamed ! $wp_content = basename(dirname(dirname(dirname(__FILE__)))); $diffed = array(); // Loop through and check foreach($checksums as $ck => $md5){ // Do not check for plugins and themes as some user might not have updated files if(substr($ck, 0, 18) == 'wp-content/plugins'){ continue; } if(substr($ck, 0, 17) == 'wp-content/themes'){ continue; } if(substr($ck, 0, 20) == 'wp-content/languages'){ continue; } if(in_array($ck, array('readme.html', 'license.txt', 'wp-config-sample.php'))){ continue; } if(substr($ck, 0, 10) == 'wp-content'){ $ck = substr_replace($ck, $wp_content, 0, 10); //echo $ck."\n"; } $path = lz_cleanpath(ABSPATH.'/'.$ck); // Skip checksum for the file that does not exists, it is possible that the theme/plugin is deleted by the user if(!file_exists($path) && preg_match('#/(themes|plugins)#is', $path)){ continue; } $cur_md5 = @md5_file($path); if($cur_md5 != $md5){ $diffed[$ck]['cur_md5'] = $cur_md5; $diffed[$ck]['md5'] = $md5; } } //lz_print($diffed); // Store the diffed ones update_option('loginizer_checksums_diff', $diffed); // Load any ignored files $ignores = get_option('loginizer_checksums_ignore'); // Create a final diff list to email the admin if(is_array($ignores)){ foreach($ignores as $ck => $path){ unset($diffed[$path]); } } // Send an email to the admin, IF we are to email if(!empty($diffed) && is_array($diffed) && count($diffed) > 0 && empty($loginizer['no_checksum_email'])){ // Send the email $site_name = get_bloginfo('name'); $email = lz_is_multisite() ? get_site_option('admin_email') : get_option('admin_email'); $subject = __("File Checksum Mismatch - $site_name", 'loginizer'); $message = "Hi, Loginizer has just completed checking the MD5 checksums of your WordPress site : $site_name - ".get_site_url()." The following files have been found that do not match the MD5 checksums as per your version : "; foreach($diffed as $path => $val){ $message .= "Path: ".$path." Expected MD5: ".$val['md5']." Found MD5: ".$val['cur_md5']." "; } $message .= " It is recommended you check this ASAP and download the files again to replace them. If you are aware of modifications made to the above files, please update the Ignored files list in Loginizer. Regards, $site_name"; //echo $message; $sent = wp_mail($email, $subject, $message); } } // Is the Username blacklisted function loginizer_user_blacklisted($username){ global $wpdb, $loginizer, $lz_error; $username_blacklist = $loginizer['username_blacklist']; $username_blacklist = is_array($username_blacklist) ? $username_blacklist : array(); // Are you blacklisted ? foreach($username_blacklist as $user_to_match){ $user_to_match = str_replace('*', '(.*?)', $user_to_match); if(preg_match('/^'.$user_to_match.'$/is', $username)){ $match_found = 1; } } // Did we get a match ? if(empty($match_found)){ return false; } // Lets make sure there is no username in the database by that name $user_search = get_user_by('login', $username); // If not found then search by email if(!empty($user_search)){ return false; } $blacklist = get_option('loginizer_blacklist'); $newid = ( empty($blacklist) ? 0 : max(array_keys($blacklist)) ) + 1; // Add to the blacklist $blacklist[$newid]['start'] = lz_getip(); $blacklist[$newid]['end'] = lz_getip(); $blacklist[$newid]['time'] = time(); // Update the database update_option('loginizer_blacklist', $blacklist); // Reload $loginizer['blacklist'] = get_option('loginizer_blacklist'); // Show the error $lz_error['user_blacklisted'] = __('This username has been blacklisted, and so have you been blacklisted !', 'loginizer'); return true; } function loginizer_plugin_row_links($pluginMeta, $pluginFile){ global $loginizer; $isRelevant = $pluginFile == 'loginizer-security/loginizer-security.php'; if (!empty($isRelevant) && current_user_can('update_plugins')){ // Show the Renew License link if the license is expired if(!empty($loginizer['license']['expires']) && ($loginizer['license']['expires'] <= date('Ymd'))){ $linkUrl = 'https://www.softaculous.com/clients?ca=loginizer_buy&plan='.$loginizer['license']['plan'].'&license='.$loginizer['license']['license']; $linkText = __('Renew License', 'loginizer'); $pluginMeta[] = sprintf('<a href="%s" target="_blank" style="color:red;">%s</a>', esc_attr($linkUrl), $linkText); } } return $pluginMeta; } // Check if any one 2FA option is enabled by admin function loginizer_is_2fa_enabled(){ global $loginizer; return (!empty($loginizer['2fa_app']) || !empty($loginizer['2fa_email']) || !empty($loginizer['2fa_sms']) || !empty($loginizer['question'])); } // Add TFA Settings Column to the Users Table function loginizer_2fa_columns_users($column){ if(loginizer_is_2fa_enabled()){ $column['tfa'] = __('Loginizer 2FA', 'loginizer'); } return $column; } // Update the users' selected 2FA preference function loginizer_2fa_column_data($val, $column_name, $user_id){ if(loginizer_is_2fa_enabled()){ switch($column_name){ case 'tfa' : $settings = get_user_meta($user_id, 'loginizer_user_settings', true); if(empty($settings) || empty($settings['pref']) || ($settings['pref'] == 'none')){ return __('<i>None</i>', 'loginizer'); } switch($settings['pref']){ case 'question': return __('Security Questions', 'loginizer'); break; case '2fa_app': return __('Google Authenticator / Authy', 'loginizer'); break; case '2fa_email': return __('Email Auth Code', 'loginizer'); break; case '2fa_sms': return __('SMS Auth Code', 'loginizer'); break; } default: } } return $val; } function loginizer_2fa_ajax_redirect(){ $url = get_transient('loginizer_2fa_' . get_current_user_id()); set_transient('loginizer_2fa_' . get_current_user_id(), '2fa', 600); wp_safe_redirect($url); die('Didn\'t redirect'); } // WooCommerce Loginizer My Security Page Functions - Start // These functions are required in order for the My Security page to be created in WooCommerce User section function loginizer_add_premium_security_endpoint(){ add_rewrite_endpoint( 'loginizer-security', EP_ROOT | EP_PAGES ); } // Add new query var function loginizer_premium_security_query_vars( $vars ) { $vars[] = 'loginizer-security'; return $vars; } // Insert the link into the My Account menu function loginizer_add_premium_security_link_my_account( $items ) { $items['loginizer-security'] = 'Security'; return $items; } // Rewrite rules function loginizer_woocommerce_rewrite_rule(){ add_rewrite_rule( 'loginizer-security(/(.*))?/?$', 'index.php?&loginizer-security=$matches[2]', 'top' ); add_rewrite_rule( '(.?.+?)/loginizer-security(/(.*))?/?$', 'index.php?pagename=$matches[1]&loginizer-security=$matches[3]', 'top' ); flush_rewrite_rules(); } //WooCommerce Loginizer Security Page Functions - End /********************************************* * CSRF Protection Session Functions - Starts **********************************************/ function loginizer_csrf_sess_init(){ global $loginizer; if(!is_user_logged_in()){ return; } $login_slug = 'wp-login.php'; if($loginizer['login_slug']){ $login_slug = $loginizer['login_slug']; } if(loginizer_cur_page() == $login_slug && strpos($_SERVER['REQUEST_URI'], 'action') === FALSE){ wp_logout(); return; } if(!is_admin()){ return; } preg_match('/(?:lzs.{20})/U', esc_url_raw($_SERVER['REQUEST_URI']), $matches); if(empty($matches)){ wp_redirect(wp_login_url()); die('Didn\'t had security protection'); } loginizer_csrf_verify_session($matches[0]); } // Destroys session for CSRF protection function loginizer_destroy_csrf_session($user_id){ delete_user_meta($user_id, 'loginizer_csrf_session'); $sess_key = get_user_meta($user_id, 'loginizer_csrf_session', true); @setCookie('lz_csrf_sess', $sess_key, time() - 3600, COOKIEPATH, COOKIE_DOMAIN, true); // deleting the cookie by setting past time } // Creates session for CSRF protection function loginizer_csrf_create_session($user_id){ if(!empty($_COOKIE['lz_csrf_sess']) && sanitize_key($_COOKIE['lz_csrf_sess']) == get_option('loginizer_session_'. $user_id) && !empty($_REQUEST['interim-login'])){ return; } $sess_key = loginizer_sess_key(); update_user_meta($user_id, 'loginizer_csrf_session', $sess_key); @setCookie('lz_csrf_sess', $sess_key, time() + DAY_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN, true); } // Verifies that the session is active function loginizer_csrf_verify_session($key) { $key = trim($key, '/'); $user_id = get_current_user_id(); $session_key = get_user_meta($user_id, 'loginizer_csrf_session', true); if(trim($session_key) != trim($key)){ wp_logout(); wp_redirect(wp_login_url()); die('Died'); } } // Checks if .htaccess file have the mod rewrite for CSRF protection function loginizer_is_csrf_prot_mod_set(){ $is_mod_set = get_transient('loginizer_csrf_mod_rewrite'); if(!empty($is_mod_set)){ return true; } $htaccess = file_get_contents(ABSPATH . '/.htaccess'); preg_match('/^# BEGIN Loginizer/m', $htaccess, $matches); if(empty($matches)){ return false; } // set transient to expire after 1 hour set_transient('loginizer_csrf_mod_rewrite', true, 3600); return true; } /* If the user is logged in and its session ends then if the user is redirected to login page then it has a redirect_to url, which has the old csrf session key in the redirect URL, this function removes that session key from the redirect_to parameter in the url */ function loginizer_csrf_wp_redirects($location){ global $loginizer; $admin_slug = 'wp-admin'; /* WordPress redirects to https://host/wp-login?redirect_to=VALUES if you are not logged in and enter the URL https://host/wp-admin so then if I tried to login, I was not able to get user id in anyway hence removing the redirect_to was the possible solution bcoz this dosent cause the same issue */ if(strpos($location, '?redirect_to') !== FALSE && strpos($location, 'lzs') === FALSE){ $location = preg_replace('/\?redirect_to=.*/', '', $location); return $location; } if(!empty($loginizer['admin_slug'])){ $admin_slug = $loginizer['admin_slug']; } // Return if it does not have CSRF key or is not admin url if(strpos($location, 'lzs') === FALSE || strpos($location, $admin_slug) === FALSE){ return $location; } // If the query with redirect_to has csrf key then remove that string $url = parse_url($location); if(empty($url['query'])){ return $location; } if(strpos($url['query'], 'redirect_to') === FALSE){ $location = preg_replace('/\?redirect_to=.*/', '', $location); return $location; } $query = rawurldecode($url['query']); $query = preg_replace('/'.$admin_slug.'-lzs.{20}/U', $admin_slug . '/', $query); $location = preg_replace('/\?.+/', '?' . rawurlencode($query), $location); return $location; } // Generates CSRF session string function loginizer_sess_key(){ return 'lzs' . wp_generate_password(20, false); } // Updates redirects with session string function loginizer_csrf_admin_redirects($url, $path, $scheme){ global $loginizer; $admin_slug = 'wp-admin'; if(!is_user_logged_in()){ return $url; } $user_id = get_current_user_id(); $session_key = get_user_meta($user_id, 'loginizer_csrf_session', true); if(strpos($url, 'lzs') !== FALSE){ return $url; } if(!empty($loginizer['admin_slug'])){ $admin_slug = $loginizer['admin_slug']; } $url = preg_replace('/(?:-?lzs.{20})/U', '/', $url); $url = str_replace($admin_slug, $admin_slug . '-' . $session_key, $url); return $url; } // Sets session on login redirect URL function loginizer_login_csrf_redirect($redirect, $request, $user){ global $loginizer; $admin_slug = 'wp-admin'; if(isset($user->roles) && is_array($user->roles)){ $session_key = get_user_meta($user->ID, 'loginizer_csrf_session', true); if(!empty($loginizer['admin_slug'])){ $admin_slug = $loginizer['admin_slug']; } $redirect = preg_replace('/(?:-?lzs.{20})/U', '/', $redirect); $redirect = str_replace($admin_slug, $admin_slug . '-' . $session_key, $redirect); } return $redirect; } // Updates the .htaccess for the CSRF session function loginizer_update_csrf_mod(){ global $loginizer; check_ajax_referer('loginizer_admin_ajax', 'nonce'); $home_root = parse_url(home_url()); if(isset($home_root['path'])){ $home_root = trailingslashit($home_root['path']); } else { $home_root = '/'; } $admin_slug = 'wp-admin'; if(!empty($loginizer['admin_slug'])){ $admin_slug = $loginizer['admin_slug']; } if(!empty(lz_optpost('admin_name'))){ $admin_slug = lz_optpost('admin_name'); } // Setting the rule $rule = '# BEGIN Loginizer' . "\n"; $rule .= '<IfModule mod_rewrite.c>' . "\n"; $rule .= 'RewriteEngine On' . "\n"; $rule .= 'RewriteBase ' . $home_root . "\n\n"; $rule .= 'RewriteRule ^' . $admin_slug . '(-lzs.{20})?(/?)(.*) wp-admin/$3 [L]' . "\n"; $rule .= '</IfModule>' . "\n"; $rule .= '# END Loginizer'; $htaccess_file = ABSPATH . '/.htaccess'; if(!file_exists($htaccess_file)){ wp_send_json_error(0); } $contents = file_get_contents($htaccess_file); if(strpos($contents, '# BEGIN Loginizer') !== FALSE){ $contents = preg_replace('/# BEGIN Loginizer.*# END Loginizer/ms', '', $contents); } if(!file_put_contents($htaccess_file, trim($rule . "\n" . $contents))){ wp_send_json_error(0); } wp_send_json(array('success' => true)); } // Updates the url if required with the CSRF string function loginizer_csrf_change_url($url, $uid){ global $loginizer; if(!empty($loginizer['enable_csrf_protection']) && loginizer_is_csrf_prot_mod_set()){ $admin_slug = 'wp-admin'; if(!empty($loginizer['admin_slug'])){ $admin_slug = $loginizer['admin_slug']; } $session_key = get_user_meta($uid, 'loginizer_csrf_session', true); if(strpos($url, $session_key) !== FALSE){ return $url; } $url = str_replace($admin_slug, $admin_slug . '-' . $session_key, $url); } return $url; } function loginizer_csrf_admin_bar_shortcut($admin_bar){ $admin_bar->add_node( array( 'id' => 'loginizer-admin-shortcut', 'parent' => null, 'group' => null, 'title' => esc_html__('Open New Tab', 'loginizer'), 'href' => admin_url(), 'meta' => [ 'title' => esc_html__('Opens Dashboard in new tab', 'loginizer'), 'target' => '_blank' ] ) ); } // CSRF Protection Session Functions - End // Restricts user from logging in function loginizer_limit_sessions($user){ if(is_wp_error($user)){ return $user; } $concurrent_sessions = get_option('loginizer_limit_session'); if(empty($concurrent_sessions) || empty($concurrent_sessions['enable']) || !class_exists('WP_Session_Tokens')){ return $user; } // Checks if we have excluded the role if(!empty($concurrent_sessions['roles']) && !empty($user->roles) && is_array($user->roles)){ if(!empty(array_intersect($concurrent_sessions['roles'], $user->roles))){ return $user; } } $concurrent_sessions['count'] = empty($concurrent_sessions['count']) ? $concurrent_sessions['count'] : 1; // if limit is not set then default it to 1 if(!empty($concurrent_sessions['type']) && $concurrent_sessions['type'] == 'block'){ $session = WP_Session_Tokens::get_instance($user->ID); $count = count($session->get_all()); if($count >= $concurrent_sessions['count']){ return new WP_Error('loginizer_session_limit', __('You have reached maximum number of concurrent logins please logout from other devices to access', 'loginizer')); } return $user; } return $user; } // Destroys session when concurrent limit is reached function loginizer_limit_destroy_sessions_handler($check, $password, $hash, $user_id){ if(empty($check)){ return false; } return loginizer_limit_destroy_sessions($user_id); } function loginizer_limit_destroy_sessions($user_id){ if(empty($user_id)){ return false; } if(!class_exists('WP_Session_Tokens')){ return true; } $user = get_userdata($user_id); $concurrent_sessions = get_option('loginizer_limit_session'); if(empty($concurrent_sessions) || empty($concurrent_sessions['enable'])){ return true; } // Checks if we have excluded the role if(!empty($concurrent_sessions['roles']) && !empty($user->roles) && is_array($user->roles)){ if(!empty(array_intersect($concurrent_sessions['roles'], $user->roles))){ return true; } } if(!empty($concurrent_sessions['type']) && $concurrent_sessions['type'] == 'destroy'){ $session = WP_Session_Tokens::get_instance($user_id); $count = count($session->get_all()); if($count >= $concurrent_sessions['count']){ $session->destroy_all(); } return true; } return true; } ////////////////////////// // BEGIN MasterStudy LMS ///////////////////////// // Logins user when it happens via MasterStudy LMS function loginizer_handle_stm_lms_login($res){ global $loginizer; if($res['status'] != 'success'){ return $res; } if(empty(loginizer_is_2fa_enabled())){ return $res; } $request_body = file_get_contents('php://input'); $data = json_decode($request_body, true); // wp_signon sanatizes the data so we don't need to do it here // Login the user again as this is the only way we can get user data which we need to set cookie and transient $user = wp_signon($data, is_ssl()); if(is_wp_error($user)){ wp_logout(); return array('status' => 'error', 'message' => 'Login Failed!'); } if(empty(loginizer_is_2fa_applicable($user))){ return $res; } $user_pref = get_user_meta($user->ID, 'loginizer_user_settings'); // If the user dosent have 2FA method set in My Security then we just let MasterStudy Work normally. if(empty($loginizer['2fa_email_force']) && (empty($user_pref) || (!empty($user_pref[0]['pref']) && $user_pref[0]['pref'] == 'none'))){ return $res; } $admin_slug = 'wp-admin'; if($loginizer['admin_slug']){ $admin_slug = $loginizer['admin_slug']; } @setCookie('loginizer_2fa_' . $user->ID, time(), time() + DAY_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN, true); set_transient('loginizer_2fa_' . $user->ID, time(), 600); $message = __('Redirecting you to verify 2FA', 'loginizer'); $_POST['redirect_to'] = class_exists('STM_LMS_User') ? STM_LMS_User::user_page_url($user->ID, true) : admin_url(); $_REQUEST['redirect_to'] = $_POST['redirect_to']; $url = loginizer_user_redirect($user, '', ''); if(empty($url) || is_a($url, 'WP_User') || filter_var($url, FILTER_VALIDATE_URL) === FALSE){ $message = esc_html__('Something went wrong unable to redirect you to verify your login via 2fa', 'loginizer'); if(is_array($url) && !empty($url['message'])){ $message = $url['message']; } $url = ''; $res['status'] = 'error'; wp_logout(); } else { set_transient('loginizer_2fa_' . $user->ID, $url, 600); } $res['message'] = $message; $res['user_page'] = $url; return $res; } // END MasterStudy LMS // Single Sign ON function loginizer_create_sso($uid, $ttl = 600, $attempts = 1){ $token = loginizer_generate_ssotoken($uid, $ttl, $attempts); $url = wp_login_url().'?uid='.$uid.'&ssotoken='.$token; $sso_links = get_option('loginizer_sso_links', []); $sso_links[$uid] = $url; update_option('loginizer_sso_links', $sso_links); if(!empty($_POST['sso_email'])){ loginizer_sso_send_mail($url, sanitize_email($_POST['sso_email'])); } return $url; } function loginizer_sso_send_mail($url, $email){ $site_name = get_bloginfo('name'); $sub = sprintf(__('Login at %s', 'loginizer'), $site_name); $msg = sprintf(__('Hi, Please find below the Single Sign-On (SSO) link for our platform: %s This link will allow you to access the platform securely without needing to enter your login credentials, this link is valid for 10 minutes. Thank you for using our platform. Best regards, %s', 'loginizer'), $url, $site_name); wp_mail($email, $sub, $msg); } function loginizer_generate_ssotoken($uid = 0, $ttl = 600, $attempts = 1){ global $loginizer; // Variables $time = time(); $expires = ($time + $ttl); $action = 'loginizer_sso_'.$uid; include_once(ABSPATH . '/'.$loginizer['wp-includes'].'/class-phpass.php'); $wp_hasher = new \PasswordHash(8, TRUE); // Create the token with a random salt and the time $token = wp_hash(wp_generate_password(20, false).$action.$time); // Create a hash of the token $stored_hash = $wp_hasher->HashPassword($expires.$token); // Store the hash and when it expires update_user_meta($uid, $action, $stored_hash); update_user_meta($uid, $action.'_expires', $expires); update_user_meta($uid, $action.'_attempts', $attempts); return $token; } function loginizer_verify_sso(){ global $loginizer; if(empty($_GET['uid']) || empty($_GET['ssotoken'])){ return false; } $uid = (int) sanitize_key($_GET['uid']); $token = sanitize_key($_GET['ssotoken']); $action = 'loginizer_sso_'.$uid; $hash = get_user_meta($uid, $action, true); $expires = get_user_meta($uid, $action.'_expires', true); $attempts = (int) get_user_meta($uid, $action.'_attempts', true); include_once(ABSPATH.'/'.$loginizer['wp-includes'].'/class-phpass.php'); $wp_hasher = new \PasswordHash(8, TRUE); $time = time(); if(!$wp_hasher->CheckPassword($expires.$token, $hash) || $expires < $time || $attempts > 15 || $attempts <= 0){ $token_error_msg = __('The token is invalid or has expired.', 'loginizer'); loginizer_update_attempt_stats(0); // Throw an error return new \WP_Error('token_invalid', $token_error_msg, 'loginizer_sso'); }else{ if(file_exists(LOGINIZER_DIR . '/premium.php') && !empty($loginizer['limit_session']) && !empty($loginizer['limit_session']['enable'])){ $limit_session = loginizer_limit_destroy_sessions($uid); if(empty($limit_session)){ return new \WP_Error('loginizer_session_limit', __('User ID not found so can not proceed', 'loginizer'), 'loginizer_epl'); } } // Deducting the count by 1 if(!empty($attempts)){ $attempts = $attempts - 1; update_user_meta($uid, $action.'_attempts', $attempts); } // Login the User wp_set_auth_cookie($uid); if(empty($attempts) || $expires < $time){ // Delete the meta delete_user_meta($uid, $action); delete_user_meta($uid, $action.'_expires'); delete_user_meta($uid, $action.'_attempts'); } $redirect_to = loginizer_csrf_change_url(admin_url(), $uid); loginizer_update_attempt_stats(1); // Redirect and exit wp_safe_redirect($redirect_to); exit; } return false; } function loginizer_sso_authenticate($user, $username, $password){ if(is_wp_error($user)){ // Ignore certain codes $ignore_codes = array('empty_username', 'empty_password'); if(is_wp_error($user) && !in_array($user->get_error_code(), $ignore_codes)) { return $user; } } $verified = loginizer_verify_sso(); if(is_wp_error($verified)){ return $verified; } } function loginizer_social_btn_woocommerce($return = false, $id = ''){ loginizer_social_btn($return, 'woocommerce'); } function loginizer_social_btn_comment($post_id){ loginizer_social_btn(false, 'comment'); } function loginizer_social_shortcode($atts){ global $loginizer; if(is_user_logged_in()){ return; } $atts = shortcode_atts([ 'type' => 'icon', 'divider' => 'above', 'shape' => 'square' ], $atts); $errors = loginizer_social_login_error_handler(); if(!empty($errors) || is_wp_error($errors)){ $error = '<style>.notice{background: #fff;border: 1px solid #c3c4c7;border-left-width: 4px;box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);margin: 5px 15px 2px;padding: 1px 12px;}.notice p,.notice-title {margin: 0.5em 0;padding: 2px;}.notice-error{border-left-color: #d63638;}.login-error-list{list-style: none;}</style><div class="loginizer-social-shortcode-error">'; $args = [ 'type' => 'error', ]; // Add the number of retires left as well if(count($errors->get_error_codes()) > 0 && isset($loginizer['retries_left'])){ $errors->add('retries_left', loginizer_retries_left()); } $messages = $errors->get_error_messages(); $notice = ''; if(count($messages) == 1){ $notice .= '<p>'.wp_kses_post($messages[0]).'</p>'; } else { $notice .= '<ul class="login-error-list">'; foreach($messages as $message) { $notice .= '<li>'.wp_kses_post($message).'</li>'; } $notice .= '</ul>'; } $error .= wp_get_admin_notice($notice, $args); $error .= '</div>'; } if(!empty($error)){ return $error . loginizer_social_btn(true, 'login', $atts); } return loginizer_social_btn(true, 'login', $atts); } function loginizer_social_update_avatar($avatar, $id_or_email, $size, $default, $alt){ global $wpdb, $blog_id; $user = false; if(empty($id_or_email)){ return $avatar; } if(is_numeric($id_or_email)){ $id = (int) $id_or_email; $user = get_user_by('id' , $id); } elseif(is_object($id_or_email)){ if(!empty($id_or_email->user_id)){ $id = (int) $id_or_email->user_id; $user = get_user_by('id' , $id); } } else { $user = get_user_by('email', $id_or_email); } if(empty($user) || !is_object($user) || empty($user->ID)){ return $avatar; } // Fetching the Image now $avatar_id = get_user_meta($user->ID, $wpdb->get_blog_prefix($blog_id) . 'lz_avatar', true); if(!wp_attachment_is_image($avatar_id)){ return $avatar; } $avatar_size = 'thumbnail'; if(!empty($size)){ $avatar_size = is_numeric($size) ? [$size, $size] : $size; } $avatar_url = wp_get_attachment_image_src($avatar_id, $avatar_size); if(empty($avatar_url) || empty($avatar_url[0])){ return $avatar; } $avatar = $avatar_url[0]; $avatar = '<img alt="'.esc_attr($alt).'" src="'.esc_url($avatar).'" class="avatar avatar-'.esc_attr($size).' photo" height="'.esc_attr($size).'" width="'.esc_attr($size).'" />'; return $avatar; }