Skip to content

Instantly share code, notes, and snippets.

@szbl
Created October 14, 2017 18:58
Show Gist options
  • Save szbl/589a56430e6f9ec7ad9cb4e2696fbcba to your computer and use it in GitHub Desktop.
Save szbl/589a56430e6f9ec7ad9cb4e2696fbcba to your computer and use it in GitHub Desktop.
<?php
/*
Plugin Name: Sizeable Whitelist Login
Author: Sizeable Interactive
Author URI: https://www.sizeableinteractive.com
Version: 0.1
Description: Server agnostic plugin to white list WordPress login screen to IP addresses using a self-authenticating secret URL.
**** NOTE ***
You must define the SZBL_SECRET_LOGIN_URL or set a login URL in the settings page for this plugin to take affect.
*/
class SZBL_Login_Restriction
{
public static $instance;
public static $file_path = ABSPATH . '/.ip_whitelist';
public static function init()
{
null === self::$instance && self::$instance = new self();
return self::$instance;
}
private function __construct()
{
if ( !file_exists( self::$file_path ) )
{
touch( self::$file_path );
}
add_action( 'init', array( $this, 'login_whitelist' ) );
add_action( 'login_init', array( $this, 'login_restriction' ) );
add_action( 'admin_menu', array( $this, 'admin_menu' ) );
add_action( 'admin_notices', array( $this, 'admin_notices' ) );
}
public function admin_notices()
{
if ( !defined( 'SZBL_SECRET_LOGIN_URL' ) && !get_option( 'szbl_secret_login' ) )
{
echo '<div class="notice notice-warning"><p>You must set the <code>SZBL_SECRET_LOGIN_URL</code> constant in <code>wp-config.php</code> or update the <a href="options-general.php?page=szbl-ip-whitelist">IP Whitelist plugin settings</a> to whitelist your WP Login screen.</p></div>';
}
}
public function admin_menu()
{
add_submenu_page( 'options-general.php', 'Whitelist Login', 'Whitelist Login', 'edit_users', 'szbl-ip-whitelist', array( $this, 'settings' ) );
}
public function settings()
{
if ( isset( $_POST['szbl-nonce'] ) && wp_verify_nonce( $_POST['szbl-nonce'], 'ip-whitelist-settings' ) )
{
file_put_contents( self::$file_path, trim( $_POST['szbl_whitelist' ] ) );
update_option( 'szbl_secret_login', sanitize_title( $_POST['szbl_whitelist_url'] ) );
$success = '<div class="notice notice-success"><p>Your settings have been saved.</p></div>';
}
$whitelist = file_get_contents( self::$file_path );
?>
<div class="wrap">
<h2>IP Whitelist Login Settings</h2>
<?php if ( isset( $success ) ) echo $success; ?>
<form method="post" action="">
<p>
<label for="szbl-whitelist-url">Whitelist URL Slug</label>
<br>
<input type="text" id="szbl-whitelist-url" name="szbl_whitelist_url" value="<?php
echo esc_attr( get_option( 'szbl_secret_login' ) );
?>">
<br><small>You should make this cryptic and hard to guess. Invalid URL characters will be sanitized.</small>
</p>
<p>
<label for="szbl-whitelist">Whitelisted IP Addresses (One Per Line)</label>
<br>
<textarea id="szbl-whitelist" name="szbl_whitelist" rows="10" class="widefat"><?php
echo esc_textarea( $whitelist );
?></textarea>
</p>
<p>
<input type="submit" class="button-primary" value="Save Settings">
<?php wp_nonce_field( 'ip-whitelist-settings', 'szbl-nonce' ); ?>
</p>
</div>
<?php
}
public function login_restriction()
{
if ( !defined( 'SZBL_SECRET_LOGIN_URL' ) && !get_option( 'szbl_secret_login' ) )
return;
$ips = explode( "\n", file_get_contents( self::$file_path ) );
if ( !in_array( $_SERVER['REMOTE_ADDR'], $ips ) )
{
wp_die( 'You are not authorized to access this page.' );
}
}
public function login_whitelist()
{
$entries = array();
if ( defined( 'SZBL_SECRET_LOGIN_URL' ) )
{
}
if ( $additional = get_option( 'szbl_secret_login' ) )
{
$entries[] = $additional;
}
if ( in_array( trim( $_SERVER['REQUEST_URI'], '/' ), $entries ) )
{
if (
sizeof( $_POST )
&& isset( $_POST['bb_ip'] )
&& $_POST['bb_ip'] == $_SERVER['REMOTE_ADDR']
&& isset( $_POST['szbl-nonce'] )
&& wp_verify_nonce( $_POST['szbl-nonce'], 'ip-whitelist' )
)
{
$ips = explode( "\n", file_get_contents( self::$file_path ) );
if ( !in_array( $_SERVER['REMOTE_ADDR'], $ips ) )
{
$ips[] = $_SERVER['REMOTE_ADDR'];
file_put_contents( self::$file_path, implode( "\n", $ips ) );
}
header( 'HTTP/1.1 303 See Other' );
header( 'Location: /wp-login.php' );
die;
echo 'An unexpected error occured.';
die;
}
?><!doctype html>
<html>
<head>
<meta name="viewport" content="device-width">
<title>Authenticate</title>
<style type="text/css">
body { text-align: center; font: 16px 'Helvetica Neue',Helvetica,Arial,Sans-serif; }
input.button { font: 2em 'Helvetica Neue',Helvetica,Arial,Sans-serif; font-weight:bold; padding: .5em 1em; border-radius: .3333em; border: 0; border-bottom: .15em solid #888; background: #ccc; color: #000; }
</style>
</head>
<body>
<form method="post" action="">
<p>
<input class="button" type="submit" value="Authenticate Your IP &rarr;">
<?php wp_nonce_field( 'ip-whitelist', 'szbl-nonce' ); ?>
<input type="hidden" name="bb_ip" value="<?php echo $_SERVER['REMOTE_ADDR']; ?>">
</p>
<p>
Your IP address is logged as <?php echo $_SERVER['REMOTE_ADDR']; ?>
</p>
</form>
</body>
</html>
<?php
die;
}
}
}
SZBL_Login_Restriction::init();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment