181 lines
4.8 KiB
PHP
181 lines
4.8 KiB
PHP
<?php
|
|
if ( file_exists( 'ip.conf' ) )
|
|
{
|
|
$ips = file_get_contents( 'ip.conf' );
|
|
$ips = preg_split( "/\\r\\n|\\r|\\n/", $ips );
|
|
$ips = array_filter( $ips );
|
|
if ( is_array( $ips ) and !empty( $ips ) )
|
|
{
|
|
if ( !in_array( $_SERVER['REMOTE_ADDR'], $ips ) )
|
|
die( 'Brak dostępu.' );
|
|
}
|
|
}
|
|
|
|
error_reporting( E_ALL ^ E_NOTICE ^ E_WARNING ^ E_DEPRECATED );
|
|
|
|
function __admin_client_ip(): string
|
|
{
|
|
$candidates = [
|
|
$_SERVER['HTTP_CF_CONNECTING_IP'] ?? null,
|
|
$_SERVER['HTTP_X_REAL_IP'] ?? null,
|
|
$_SERVER['HTTP_X_FORWARDED_FOR'] ?? null,
|
|
$_SERVER['REMOTE_ADDR'] ?? null,
|
|
];
|
|
|
|
foreach ( $candidates as $candidate )
|
|
{
|
|
if ( !$candidate )
|
|
continue;
|
|
|
|
// X-Forwarded-For can be a comma separated list: client, proxy1, proxy2...
|
|
$ip = trim( explode( ',', $candidate )[0] );
|
|
if ( filter_var( $ip, FILTER_VALIDATE_IP ) )
|
|
return $ip;
|
|
}
|
|
|
|
return '';
|
|
}
|
|
|
|
function __admin_cookie_scope(): array
|
|
{
|
|
$host = $_SERVER['HTTP_HOST'] ?? ( $_SERVER['SERVER_NAME'] ?? '' );
|
|
$host = strtolower( preg_replace( '/:\d+$/', '', $host ) );
|
|
$host = preg_replace( '/^www\./', '', $host );
|
|
|
|
$https = (
|
|
( !empty( $_SERVER['HTTPS'] ) && strtolower( (string)$_SERVER['HTTPS'] ) !== 'off' ) ||
|
|
( !empty( $_SERVER['SERVER_PORT'] ) && (int)$_SERVER['SERVER_PORT'] === 443 ) ||
|
|
( !empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && strtolower( (string)$_SERVER['HTTP_X_FORWARDED_PROTO'] ) === 'https' )
|
|
);
|
|
|
|
return [
|
|
'host' => $host,
|
|
'secure' => $https,
|
|
];
|
|
}
|
|
function __autoload_my_classes( $classname )
|
|
{
|
|
$q = explode( '\\' , $classname );
|
|
$c = array_pop( $q );
|
|
$f = '../autoload/' . implode( '/' , $q ) . '/class.' . $c . '.php';
|
|
if ( file_exists( $f ) )
|
|
require_once( $f );
|
|
}
|
|
spl_autoload_register( '__autoload_my_classes' );
|
|
|
|
require_once '../config.php';
|
|
require_once '../libraries/medoo/medoo.php';
|
|
require_once '../libraries/grid/config.php';
|
|
date_default_timezone_set( 'Europe/Warsaw' );
|
|
|
|
$settings = \front\factory\Settings::settings_details();
|
|
|
|
if ( file_exists( 'config.php' ) )
|
|
include 'config.php';
|
|
|
|
$session_secure = __admin_cookie_scope()['secure'];
|
|
if ( PHP_VERSION_ID >= 70300 )
|
|
{
|
|
session_set_cookie_params( [
|
|
'lifetime' => 0,
|
|
'path' => '/',
|
|
'secure' => $session_secure,
|
|
'httponly' => true,
|
|
'samesite' => 'Lax',
|
|
] );
|
|
}
|
|
|
|
session_start();
|
|
|
|
$client_ip = __admin_client_ip();
|
|
|
|
if ( !isset( $_SESSION['check'] ) )
|
|
{
|
|
session_regenerate_id();
|
|
$_SESSION['check'] = true;
|
|
$_SESSION['ip'] = $client_ip;
|
|
}
|
|
|
|
if ( isset( $_SESSION['ip'] ) && $_SESSION['ip'] !== $client_ip )
|
|
{
|
|
// Reverse proxy/load balancer can change REMOTE_ADDR between requests.
|
|
// Do not invalidate login session only due to IP hop after migration.
|
|
$_SESSION['ip'] = $client_ip;
|
|
}
|
|
|
|
$mdb = new medoo( [
|
|
'database_type' => 'mysql',
|
|
'database_name' => $database['name'],
|
|
'server' => $database['host'],
|
|
'username' => $database['user'],
|
|
'password' => $database['password'],
|
|
'charset' => 'utf8'
|
|
] );
|
|
|
|
$user = \S::get_session( 'user' , true );
|
|
|
|
\admin\Site::special_actions();
|
|
|
|
$cookie_scope = __admin_cookie_scope();
|
|
$domain = $cookie_scope['host'];
|
|
$cookie_name = str_replace( '.', '-', $domain );
|
|
|
|
if ( isset( $_COOKIE[$cookie_name] ) && !isset( $_SESSION['user'] ) )
|
|
{
|
|
$cookie_raw = (string)$_COOKIE[$cookie_name];
|
|
$login = null;
|
|
$password = null;
|
|
|
|
// New format: base64( json . "." . hmac_sha256(json, APP_SECRET_KEY) )
|
|
$decoded = base64_decode( $cookie_raw, true );
|
|
if ( $decoded !== false && strpos( $decoded, '.' ) !== false )
|
|
{
|
|
$dotPos = strrpos( $decoded, '.' );
|
|
$json = substr( $decoded, 0, $dotPos );
|
|
$sig = substr( $decoded, $dotPos + 1 );
|
|
$expected = hash_hmac( 'sha256', $json, \admin\Site::APP_SECRET_KEY );
|
|
|
|
if ( hash_equals( $expected, $sig ) )
|
|
{
|
|
$payload = json_decode( $json, true );
|
|
if ( is_array( $payload ) && !empty( $payload['login'] ) )
|
|
$login = $payload['login'];
|
|
}
|
|
}
|
|
|
|
// Legacy format: JSON {login, hash}
|
|
if ( !$login )
|
|
{
|
|
$legacy = json_decode( $cookie_raw, true );
|
|
if ( is_array( $legacy ) && !empty( $legacy['login'] ) && !empty( $legacy['hash'] ) )
|
|
{
|
|
$login = $legacy['login'];
|
|
$password = $legacy['hash'];
|
|
}
|
|
}
|
|
|
|
if ( $login )
|
|
{
|
|
$where = [
|
|
'AND' => [
|
|
'login' => $login,
|
|
'status' => 1,
|
|
'OR' => [ 'active_to[>=]' => date( 'Y-m-d' ), 'active_to' => null ],
|
|
],
|
|
];
|
|
|
|
// For legacy cookie we still check saved password hash.
|
|
if ( $password )
|
|
$where['AND']['password'] = $password;
|
|
|
|
if ( $mdb->get( 'pp_users', '*', $where ) )
|
|
{
|
|
\S::set_session( 'user', \admin\factory\Users::details( $login ) );
|
|
header( 'Location: /admin/articles/view_list/' );
|
|
exit;
|
|
}
|
|
}
|
|
}
|
|
echo \admin\view\Page::show();
|
|
?>
|