From bd11137b1d7c449338a2a6a4f3103f18bddc8b37 Mon Sep 17 00:00:00 2001 From: Gab <24553253+gabrix73@users.noreply.github.com> Date: Sat, 25 Oct 2025 02:47:08 +0200 Subject: Update fmt.Println message from 'Hello' to 'Goodbye' --- index.php | 1082 +++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 834 insertions(+), 248 deletions(-) diff --git a/index.php b/index.php index 6f323e5..9d218ca 100644 --- a/index.php +++ b/index.php @@ -1,40 +1,471 @@ getRemailerList(); - -// Parse remailer list to extract remailer names -$remailers = []; -if ($remailerList) { - $lines = explode("\n", $remailerList); - foreach ($lines as $line) { - // Extract remailer names (format: "name ******** time uptime") - if (preg_match('/^([a-zA-Z0-9\-]+)\s+/', $line, $matches)) { - $name = trim($matches[1]); - if (!empty($name) && $name !== 'mixmaster' && strlen($name) > 2) { - $remailers[] = $name; +function getRemailers($type) { + $remailers = ['*']; // Always include Random option + + // Try multiple file locations + $files = [ + '/opt/yamn-data/cache/remailers.txt', + '/var/www/yamnweb/remailers.txt' + ]; + + foreach ($files as $file) { + if (!file_exists($file)) continue; + + $lines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + $inDataSection = false; + + foreach ($lines as $line) { + $line = trim($line); + + // Start parsing after separator line (--------) + if (preg_match('/^-{10,}/', $line)) { + $inDataSection = true; + continue; + } + + // Stop at Remailer-Capabilities section + if (stripos($line, 'Remailer-Capabilities') !== false) { + break; + } + + // Only parse lines after the separator + if (!$inDataSection) continue; + + // Skip empty lines + if (empty($line)) continue; + + // Split line: name latency uptime [flags] + // Example: "middleman 211112111211 :45 ++++++++++++ 100.0% D" + $parts = preg_split('/\s+/', $line); + + // Must have at least name + latency + if (count($parts) < 2) continue; + + // Extract ONLY the remailer name (first field) + $remailerName = $parts[0]; + + // Validate name: lowercase letters, numbers, hyphens only + if (!preg_match('/^[a-z0-9-]+$/', $remailerName)) continue; + + // Check if last field is 'D' (middle capability flag) + $lastField = end($parts); + $isMiddleCapable = ($lastField === 'D'); + + // LOGICA CORRETTA: Mutuamente esclusivi + if ($isMiddleCapable) { + // Remailers CON 'D' = SOLO middle + if ($type === 'middle') { + $remailers[] = $remailerName; + } + } else { + // Remailers SENZA 'D' = SOLO entry/exit + if ($type === 'entry' || $type === 'exit') { + $remailers[] = $remailerName; + } } } + break; // Use first file found } - // Remove duplicates and sort - $remailers = array_unique($remailers); - sort($remailers); + + return array_unique($remailers); } -// If no remailers found, add wildcards -if (empty($remailers)) { - $remailers = ['*']; +/** + * Replace asterisk (*) with random remailer from available list + * @param string $remailer Selected remailer (may be "*") + * @param array $availableRemailers List of available remailers + * @return string Actual remailer name + */ +function resolveRemailer($remailer, $availableRemailers) { + if ($remailer === '*') { + // Filter out the asterisk itself from candidates + $candidates = array_filter($availableRemailers, function($r) { + return $r !== '*'; + }); + + if (empty($candidates)) { + throw new Exception("No remailers available for random selection"); + } + + // Pick random remailer + $randomIndex = array_rand($candidates); + return $candidates[$randomIndex]; + } + return $remailer; +} + +// Load available remailers +$entryRemailers = getRemailers('entry'); +$middleRemailers = getRemailers('middle'); +$exitRemailers = getRemailers('exit'); + +// If no remailers loaded, try to download them +if (count($entryRemailers) <= 1 && class_exists('SecureRemailerDownloader')) { + try { + $downloader = new SecureRemailerDownloader(); + $downloader->downloadRemailers(); + // Reload after download + $entryRemailers = getRemailers('entry'); + $middleRemailers = getRemailers('middle'); + $exitRemailers = getRemailers('exit'); + } catch (Exception $e) { + error_log("Failed to download remailers: " . $e->getMessage()); + } +} + +$message = ''; +$messageType = ''; + +// Check for flash messages from previous redirect (PRG pattern) +if (isset($_SESSION['flash_message'])) { + $message = $_SESSION['flash_message']; + $messageType = isset($_SESSION['flash_type']) ? $_SESSION['flash_type'] : 'info'; + + // Clear flash messages after displaying + unset($_SESSION['flash_message']); + unset($_SESSION['flash_type']); +} + +// Handle form submission +if ($_SERVER['REQUEST_METHOD'] == 'POST') { + // CSRF validation - IMPROVED with better error handling + if (!isset($_POST['csrf_token'])) { + $message = "Security token missing. Please reload the page and try again."; + $messageType = 'error'; + } elseif ($_POST['csrf_token'] !== $currentCsrfToken) { + // DEBUG: Log the mismatch for troubleshooting + error_log("CSRF Mismatch - POST: " . substr($_POST['csrf_token'], 0, 10) . "... SESSION: " . substr($currentCsrfToken, 0, 10) . "..."); + + $message = "Security token mismatch. Please try submitting again."; + $messageType = 'error'; + // DO NOT regenerate token here - let user retry with same token + } else { + try { + // Get and sanitize form data with additional validation + $entryRemailer = isset($_POST['entry_remailer']) ? filter_var($_POST['entry_remailer'], FILTER_SANITIZE_STRING) : ''; + $middleRemailer = isset($_POST['middle_remailer']) ? filter_var($_POST['middle_remailer'], FILTER_SANITIZE_STRING) : ''; + $exitRemailer = isset($_POST['exit_remailer']) ? filter_var($_POST['exit_remailer'], FILTER_SANITIZE_STRING) : ''; + $from = isset($_POST['from']) ? filter_var($_POST['from'], FILTER_SANITIZE_STRING) : ''; + $replyTo = isset($_POST['reply_to']) ? filter_var($_POST['reply_to'], FILTER_SANITIZE_STRING) : ''; + $to = isset($_POST['to']) ? filter_var($_POST['to'], FILTER_SANITIZE_EMAIL) : ''; + $subject = isset($_POST['subject']) ? filter_var($_POST['subject'], FILTER_SANITIZE_STRING) : ''; + $newsgroups = isset($_POST['newsgroups']) ? filter_var($_POST['newsgroups'], FILTER_SANITIZE_STRING) : ''; + $references = isset($_POST['references']) ? filter_var($_POST['references'], FILTER_SANITIZE_STRING) : ''; + $data = isset($_POST['data']) ? $_POST['data'] : ''; // Keep original formatting + $copies = isset($_POST['copies']) ? intval($_POST['copies']) : 1; + + // Validate copies + if ($copies < 1 || $copies > 3) { + throw new Exception("Number of copies must be between 1 and 3."); + } + + // Validate required fields + if (empty($to)) { + throw new Exception("Recipient (To) is required."); + } + + if (empty($from)) { + throw new Exception("Sender (From) is required."); + } + + // Validate remailer chain + if (empty($entryRemailer) || empty($middleRemailer) || empty($exitRemailer)) { + throw new Exception("All three remailers must be specified."); + } + + // Resolve asterisks (*) to actual random remailers + $resolvedEntry = resolveRemailer($entryRemailer, $entryRemailers); + $resolvedMiddle = resolveRemailer($middleRemailer, $middleRemailers); + $resolvedExit = resolveRemailer($exitRemailer, $exitRemailers); + + // Build remailer chain with resolved names + $chain = "$resolvedEntry,$resolvedMiddle,$resolvedExit"; + + // Log the resolved chain for debugging + error_log("Resolved remailer chain: $chain (from: $entryRemailer,$middleRemailer,$exitRemailer)"); + + // Build message headers + $headers = "Content-Type: text/plain; charset=utf-8\n"; + $headers .= "Content-Transfer-Encoding: 8bit\n"; + $headers .= "MIME-Version: 1.0\n"; + + if (!empty($references)) { + $headers .= "References: $references\n"; + } + + // Build complete message + $messageContent = $headers . "From: $from\n"; + + if (!empty($replyTo)) { + $messageContent .= "Reply-To: $replyTo\n"; + } + + $messageContent .= "To: $to\nSubject: $subject\n"; + + if (!empty($newsgroups)) { + $messageContent .= "Newsgroups: $newsgroups\n"; + } + + $messageContent .= "\n$data"; + + // Verify YAMN executable exists + $yamnPath = '/opt/yamn-master/yamn'; + if (!file_exists($yamnPath)) { + throw new Exception("YAMN executable not found at: $yamnPath"); + } + + if (!is_executable($yamnPath)) { + throw new Exception("YAMN executable is not executable. Check permissions."); + } + + // Verify YAMN config file exists + $yamnConfig = '/opt/yamn-master/yamn.yml'; + if (!file_exists($yamnConfig)) { + throw new Exception("YAMN config file not found at: $yamnConfig"); + } + + // Ensure temp directory exists and is writable + $tempDir = '/var/www/yamnweb'; + if (!is_dir($tempDir)) { + throw new Exception("Temp directory does not exist: $tempDir"); + } + + if (!is_writable($tempDir)) { + throw new Exception("Temp directory is not writable: $tempDir"); + } + + // Ensure Maildir exists (required by YAMN) + $maildirBase = '/var/www/yamnweb/Maildir'; + $maildirDirs = [ + $maildirBase, + $maildirBase . '/tmp', + $maildirBase . '/new', + $maildirBase . '/cur' + ]; + + foreach ($maildirDirs as $dir) { + if (!is_dir($dir)) { + if (!@mkdir($dir, 0755, true)) { + throw new Exception("Failed to create Maildir directory: $dir"); + } + error_log("Created Maildir directory: $dir"); + } + } + + // Write message to temp file (use single file as in original) + $tempFile = $tempDir . '/message.txt'; + $writeResult = @file_put_contents($tempFile, $messageContent); + + if ($writeResult === false) { + throw new Exception("Failed to write message to temporary file: $tempFile"); + } + + // Verify file was written + if (!file_exists($tempFile)) { + throw new Exception("Temp file was not created: $tempFile"); + } + + // Send multiple copies via YAMN + $successCount = 0; + $errors = []; + + for ($i = 0; $i < $copies; $i++) { + // Build YAMN command - Use cat pipe for better exec() compatibility + // This avoids shell redirect issues with exec() + $yamnCmd = sprintf( + '%s -config %s -dir %s -chain %s -read-mail', + escapeshellarg($yamnPath), + escapeshellarg($yamnConfig), + escapeshellarg($tempDir), + escapeshellarg($chain) + ); + + // Use cat to pipe file content to YAMN + $cmd = sprintf( + 'cat %s | %s 2>&1', + escapeshellarg($tempFile), + $yamnCmd + ); + + error_log("Executing YAMN command: $cmd"); + + // Execute YAMN + $output = []; + $returnCode = 0; + + // Check if TorExtension class exists and use it, otherwise direct exec + if (class_exists('TorExtension')) { + try { + $torWrapper = new TorExtension(); + $result = $torWrapper->executeWithTor($cmd, $output, $returnCode); + } catch (Exception $torEx) { + // Fallback to direct execution if Tor extension fails + error_log("TorExtension failed: " . $torEx->getMessage() . " - falling back to direct execution"); + exec($cmd, $output, $returnCode); + } + } else { + // TorExtension not available, use direct execution + error_log("TorExtension class not found - using direct execution"); + exec($cmd, $output, $returnCode); + } + + if ($returnCode === 0) { + $successCount++; + } else { + $errorMsg = "Copy " . ($i + 1) . " failed (exit code: $returnCode)"; + if (!empty($output)) { + $errorMsg .= ": " . implode("\n", $output); + } + $errors[] = $errorMsg; + error_log("YAMN execution failed: " . $errorMsg); + } + + // Random delay between copies (300-900ms) + if ($i < $copies - 1) { + usleep(rand(300000, 900000)); + } + } + + // Clean up + @unlink($tempFile); + + // Report results + if ($successCount === $copies) { + // Success - save message in session and redirect (PRG pattern) + $_SESSION['flash_message'] = "✓ Message sent successfully via YAMN network ($copies " . ($copies > 1 ? "copies" : "copy") . ")"; + $_SESSION['flash_type'] = 'success'; + + // Regenerate CSRF token after successful submission + $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); + + // Optional: Clear any sensitive data from session + // unset($_SESSION['last_message_data']); // Uncomment if storing message data + + // Redirect to prevent form resubmission on page reload + header('Location: ' . $_SERVER['PHP_SELF']); + exit; + } elseif ($successCount > 0) { + $_SESSION['flash_message'] = "⚠ Partially successful: $successCount of $copies copies sent\n" . implode("\n", $errors); + $_SESSION['flash_type'] = 'warning'; + + // Regenerate CSRF token + $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); + + header('Location: ' . $_SERVER['PHP_SELF']); + exit; + } else { + throw new Exception("All copies failed:\n" . implode("\n", $errors)); + } + + } catch (Exception $e) { + $message = "✗ Error: " . $e->getMessage(); + $messageType = 'error'; + error_log("YAMN submission error: " . $e->getMessage() . "\nStack: " . $e->getTraceAsString()); + } catch (Error $e) { + // Catch PHP 7+ Error class (for fatal errors) + $message = "✗ Fatal Error: " . $e->getMessage(); + $messageType = 'error'; + error_log("YAMN fatal error: " . $e->getMessage() . "\nStack: " . $e->getTraceAsString()); + } catch (Throwable $e) { + // Catch everything else + $message = "✗ Unexpected error: " . $e->getMessage(); + $messageType = 'error'; + error_log("YAMN unexpected error: " . $e->getMessage()); + } + } } ?> @@ -42,10 +473,46 @@ if (empty($remailers)) { - - - YAMN Gateway + YAMN Web Interface - -
- TOR ACTIVE -
- +
-
-

[ YAMN GATEWAY ]

-
YET ANOTHER MIX NETWORK - SECURE ANONYMOUS EMAIL SYSTEM
-
+ + +
+ +
+
+ +

⚡ YAMN WEB INTERFACE ⚡

+
Tor before Yamn Remailer Network
+ + + +
+ DEBUG INFO: + Session ID: ...
+ CSRF Token: ...
+ PHP Version:
+ Session Save Path:
+ Cookie Params: +
+ -
-

MISSION: This interface provides access to the YAMN anonymous remailer network for secure, untraceable email transmission. Messages are encrypted and routed through a chain of randomly selected mix nodes, making traffic analysis and sender identification computationally infeasible.

- -

OPERATION: All traffic is mandatorily routed through Tor before reaching the YAMN network. The YAMN entry node receives connections only from Tor exit nodes, never learning the true origin IP address. Messages are padded to standard sizes, delayed with random intervals, and protected against replay attacks through cryptographic message-ID verification.

- -

SECURITY: Double-layer anonymization: Tor conceals your identity from the YAMN network, while YAMN's multi-hop mixing (minimum 3 remailers) prevents the final recipient from tracing back to the entry point. No persistent metadata retained.

- -

STATUS: System operational. Tor connection verified. No logs retained.

+ +
+ +
+ + +
+ Security Features Active: +
    +
  • Tor/Onion network before Yamn Mix Network
  • +
  • Onion Smtp Relay with traffic padding and timing randomization
  • +
  • Forward secrecy and metadata protection
  • +
  • No persistent message retention - No logs website
  • +
-
- -
-
[ Chain Configuration ]
- -
+ + + +
+ +
- +
-
- +
-
- +
-
* = Random selection (recommended for maximum security)
- -
-
[ Message Headers ]
- - - - - - - - - - - - - - +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ -
For Usenet posting (leave blank for email only)
- - +
+ +
+ -
For reply threading
- -
-
[ Message Body ]
- - - +
+ +
- -
-
[ Transmission Options ]
- - - -
Multiple copies share same exit node to prevent duplicates
+
+ + + Multiple copies increase reliability through redundancy
- -
- +
+
- - + +
+ + -- cgit v1.2.3