yazrkisvs3vvvsv33svrhetrjsvyvsvvyjsvsvs
tavsuysvssvvjvvyjyjkvsvqd
qfogsvvsvsegjdgdfgdskhgdksvqsvshdqsd
<?php
// api/ssl-check.php — Verifica vencimiento del certificado SSL del sitio
header('Content-Type: application/json');
require_once __DIR__ . '/../config.php';
require_once __DIR__ . '/../db.php';
require_once __DIR__ . '/../auth.php';
require_once __DIR__ . '/../credentials.php';
dm_require_login();

$client_id = (int)($_GET['client_id'] ?? 0);
if (!$client_id) { echo json_encode(['ok'=>false,'error'=>'client_id requerido']); exit; }
dm_require_client_access($client_id);

// Cache 6 horas
$cache_key = "ssl_check_{$client_id}";
if (empty($_GET['force'])) {
    $cached = dm_cache_get($cache_key);
    if ($cached) { echo json_encode($cached); exit; }
}

// URL desde parámetro o credenciales WP
$url = trim($_GET['url'] ?? '');
if (!$url) {
    $wc  = dm_get_credentials($client_id, 'wordpress');
    $url = rtrim($wc['wp_url'] ?? '', '/');
}
if (!$url) {
    echo json_encode(['ok'=>false,'error'=>'No hay URL configurada para este cliente.']); exit;
}

$parsed = parse_url($url);
$host   = $parsed['host'] ?? '';
$port   = $parsed['port'] ?? 443;
$scheme = strtolower($parsed['scheme'] ?? 'https');

if (!$host) {
    echo json_encode(['ok'=>false,'error'=>'URL inválida.']); exit;
}
if ($scheme !== 'https') {
    echo json_encode(['ok'=>false,'error'=>'El sitio no usa HTTPS.', 'no_ssl'=>true]); exit;
}

// FASE 2: verify_peer=false es INTENCIONAL aquí — este endpoint inspecciona el cert
// del cliente (incluso expirados/self-signed) para diagnosticar el estado SSL.
// El cert capturado se valida explícitamente abajo via openssl_x509_parse().
$context = stream_context_create([
    'ssl' => [
        'capture_peer_cert' => true,
        'verify_peer'       => false,
        'verify_peer_name'  => false,
        'allow_self_signed' => true,
    ],
]);

$stream = @stream_socket_client(
    "ssl://{$host}:{$port}",
    $errno, $errstr, 10,
    STREAM_CLIENT_CONNECT,
    $context
);

if (!$stream) {
    echo json_encode(['ok'=>false,'error'=>"No se pudo conectar a {$host}:{$port}."]); exit;
}

$params = stream_context_get_params($stream);
fclose($stream);

$peer_cert = $params['options']['ssl']['peer_certificate'] ?? null;
if (!$peer_cert) {
    echo json_encode(['ok'=>false,'error'=>'No se pudo leer el certificado SSL.']); exit;
}

$cert = openssl_x509_parse($peer_cert);
if (!$cert) {
    echo json_encode(['ok'=>false,'error'=>'Error al parsear el certificado SSL.']); exit;
}

$valid_to_ts  = $cert['validTo_time_t']   ?? 0;
$valid_from_ts= $cert['validFrom_time_t'] ?? 0;
$days_left    = max(0, (int)(($valid_to_ts - time()) / 86400));
$issuer       = $cert['issuer']['O'] ?? ($cert['issuer']['CN'] ?? 'Desconocido');
$subject_cn   = $cert['subject']['CN'] ?? $host;

// SANs (Subject Alternative Names)
$sans = [];
$ext  = $cert['extensions']['subjectAltName'] ?? '';
if ($ext) {
    preg_match_all('/DNS:([^\s,]+)/', $ext, $m);
    $sans = $m[1] ?? [];
}

$status = $days_left > 30 ? 'ok' : ($days_left > 7 ? 'warning' : 'critical');

$result = [
    'ok'         => true,
    'days_left'  => $days_left,
    'status'     => $status,
    'issuer'     => $issuer,
    'subject'    => $subject_cn,
    'sans'       => array_slice($sans, 0, 5),
    'valid_from' => date('Y-m-d', $valid_from_ts),
    'valid_to'   => date('Y-m-d', $valid_to_ts),
    'host'       => $host,
];
dm_cache_set($cache_key, $result, 360);
echo json_encode($result);
