#!/usr/bin/php 
<?php
/**
 * AdminCentral Client
 * 
 * Integrates AdminCentral with Fail2ban
 * 
 * Version 1.1 (22/05/2024)
 * 
 * Todolist:
 * - 
 * 
 */

define ('VERSION', '1.0.2');

// Log file path
$logFile = "/var/log/admincentral.log";

// URL to call with the last ID as a query parameter
$query_url = "https://admincentral.clickmedia.gr/api/banned_ips?last_id=";
$ok_url    = "https://admincentral.clickmedia.gr//api/blocked/{server}/{method}/{ip}";
$fail_url  = "https://admincentral.clickmedia.gr/api//api/blocked/{server}/{method}/{ip}";

// Make sure that curl is available
if (!function_exists('curl_init')) {
    exit(1);
}

// The server name
$server = explode(".", gethostname())[0];

// Read the last ID from the log file or assume it is 0
$lastId = 0;
if (file_exists($logFile)) {
    $lastLine = trim(exec("tail -n 1 $logFile"));
    $lastLineParts = explode(" ", $lastLine);
    if (isset($lastLineParts[1])) {
        $lastId = (int)$lastLineParts[1];
    }
}
else {
    exit(2);
}

date_default_timezone_set('Europe/Athens');

$data = mini_http_client($query_url . $lastId);

// Check if data is not empty
if (!empty($data)) {
    // Iterate over each item in the array
    foreach ($data as $item) {
        perform_action($item['action'], $item['method'], $item['ip'], $item['id'], $item['reason']);        
    }
}

function write_log($logLine)
{
    global $logFile;

    debug_echo("Logging $logLine\n");
    file_put_contents($logFile, $logLine . " v.".VERSION."\n", FILE_APPEND);    
}

function perform_action($action, $method, $ip, $id, $reason) 
{
    global $server, $ok_url, $fail_url;

	if ($method == 'blackhole') {
        if ($action == 'block') {
	        $cmd = '/usr/sbin/ip ro add blackhole ' . $ip;
        }
        elseif ($action == 'unblock') {
            $cmd = '/usr/sbin/ip ro de ' . $ip;
        }
        else {
            return;
        }
        $return_value = 99999;
	    system($cmd, $return_value);

        $api_vars = ['server' => $server, 'method' => $method, 'ip' => $ip];

        $logLine = "$ip $id [" . date('c') . "] $action $method $return_value \"$reason\"";
        // OK
        if ($return_value == 0) {            
            mini_http_client($ok_url, $api_vars);
            write_log($logLine);
        }

        // 2 = Already exists / Not found
        elseif ($return_value == 2) {            
            mini_http_client($fail_url, $api_vars);
            write_log($logLine);
        }

        // Other error
        else {            
            mini_http_client($fail_url, $api_vars);
            write_log($logLine);
        }        
	}

}

function mini_http_client($url, $params = [])
{
    foreach ($params as $key => $value) {
        $url = str_replace('{{'.$key.'}}', $value, $url);
    }
    debug_echo("Connecting to $url...\n");

    // Initialize cURL session
    $ch = curl_init();

    // Set cURL options
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    // Execute cURL request
    $response = curl_exec($ch);

    // Close cURL session
    curl_close($ch);

    // Decode JSON response
    $data = json_decode($response, true);
    debug_echo("Returning\n" . print_r($data, true) . "\n");

    return $data;
}

function debug_echo($s)
{
    echo $s;
}
