downloadRemailers()) { error_log('Remailer refresh failed; keeping the locally available data.'); } // Reload after a successful refresh, or continue with the local list. $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'])) { // Save error in session and redirect $_SESSION['flash_message'] = "Security token missing. Please reload the page and try again."; $_SESSION['flash_type'] = 'error'; header('Location: ' . $_SERVER['PHP_SELF']); exit; } elseif ($_POST['csrf_token'] !== $currentCsrfToken) { // Save error in session and redirect $_SESSION['flash_message'] = "Security token mismatch. Please try submitting again."; $_SESSION['flash_type'] = 'error'; header('Location: ' . $_SERVER['PHP_SELF']); exit; } 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."); } if (empty($from)) { throw new Exception("Sender (From) is required."); } $messageKind = trim($newsgroups) === '' ? 'email' : 'usenet'; if ($messageKind === 'email' && empty($to)) { throw new Exception("Email recipient is required when Newsgroup is empty."); } if ($messageKind === 'usenet') { $to = yamnConfig('YAMN_USENET_GATEWAY', 'mail2news@mail2news.tcpreset.net'); if (!filter_var($to, FILTER_VALIDATE_EMAIL)) { throw new Exception("Usenet gateway is not configured correctly."); } } // 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); $encoded = encodeYamnMessage([ 'kind' => $messageKind, 'entry' => $resolvedEntry, 'chain' => [$resolvedEntry, $resolvedMiddle, $resolvedExit], 'from' => $from, 'reply_to' => $replyTo, 'to' => $to, 'subject' => $subject, 'newsgroup' => $newsgroups, 'body' => $data, 'references' => $references, ]); if (!$encoded['success']) { throw new Exception($encoded['error'] ?? 'YAMN encoding failed'); } $responseFinished = false; $onHandoff = null; if (function_exists('fastcgi_finish_request')) { $onHandoff = static function () use (&$responseFinished): void { ignore_user_abort(true); $_SESSION['flash_message'] = 'Message accepted into the local in-memory Nym queue. Delivery continues in the background; YAMN queues may take several hours, and this confirmation does not mean the message has been published or delivered yet.'; $_SESSION['flash_type'] = 'success'; $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); session_write_close(); header('Location: ' . $_SERVER['PHP_SELF']); fastcgi_finish_request(); $responseFinished = true; }; } $result = sendNymEnvelope($encoded['envelope'], 1, $encoded['entry_address'], $onHandoff); if ($responseFinished) { exit; } if (!$result['success']) { throw new Exception($result['error'] ?? 'Nym submission failed'); } $_SESSION['flash_message'] = 'Message accepted into the local in-memory Nym queue. Delivery through the YAMN queues may take several hours; this confirmation does not mean the message has been published or delivered yet.'; $_SESSION['flash_type'] = 'success'; $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); header('Location: ' . $_SERVER['PHP_SELF']); exit; } catch (Exception $e) { // Save error in session and redirect (PRG pattern for errors too) $_SESSION['flash_message'] = "✗ Error: " . $e->getMessage(); $_SESSION['flash_type'] = 'error'; error_log("YAMN submission error: " . $e->getMessage() . "\nStack: " . $e->getTraceAsString()); // Redirect to prevent form resubmission header('Location: ' . $_SERVER['PHP_SELF']); exit; } catch (Error $e) { // Catch PHP 7+ Error class (for fatal errors) $_SESSION['flash_message'] = "✗ Fatal Error: " . $e->getMessage(); $_SESSION['flash_type'] = 'error'; error_log("YAMN fatal error: " . $e->getMessage() . "\nStack: " . $e->getTraceAsString()); // Redirect to prevent form resubmission header('Location: ' . $_SERVER['PHP_SELF']); exit; } catch (Throwable $e) { // Catch everything else $_SESSION['flash_message'] = "✗ Unexpected error: " . $e->getMessage(); $_SESSION['flash_type'] = 'error'; error_log("YAMN unexpected error: " . $e->getMessage()); // Redirect to prevent form resubmission header('Location: ' . $_SERVER['PHP_SELF']); exit; } } } ?> YAMN Web, invio anonimo

⚡ YAMN WEB INTERFACE ⚡

Nym before YAMN: YAMN Web encrypts first, then Nym carries only the opaque envelope
This interface prepares and submits YAMN packets. Read more: detailed architecture and operation
Remailer data

Remailer statistics and public keys are checked automatically when this page loads. Local data no more than 24 hours old is reused without a network connection.

Missing or older data is downloaded through Tor. If a source is unavailable, the existing data remains usable and another download is not attempted until the next daily check.
Entry receives the YAMN packet, Middle forwards it through the chain, and Exit delivers the decoded message.
Used as the From header.
Optional. It is not used to retrieve replies.
Required for email delivery. Leave empty when publishing to a newsgroup.
Optional. When set, the message is routed through the configured Mail-to-News gateway. Leave empty for email.
Optional. Links the article to an existing thread.
The server creates the encrypted YAMN envelope in memory and sends only that packet through Nym. Remailer queues may take several hours.