summaryrefslogtreecommitdiffstats
path: root/katzenpost_sender.php
diff options
context:
space:
mode:
authorGab <24553253+gabrix73@users.noreply.github.com>2026-08-13 14:04:30 +0200
committerGab <24553253+gabrix73@users.noreply.github.com>2026-08-13 14:04:30 +0200
commit994071243fc80990cf09e820b671006e9bd31c76 (patch)
treeb65e02724b98033240aa6f9d153acea021abc456 /katzenpost_sender.php
parent47d903de3bca4165e96d6ec8830eafbacf524cd2 (diff)
downloadyamnweb-994071243fc80990cf09e820b671006e9bd31c76.tar.gz
yamnweb-994071243fc80990cf09e820b671006e9bd31c76.tar.xz
yamnweb-994071243fc80990cf09e820b671006e9bd31c76.zip
Separate active YAMN code from Katzenpost PoC
Diffstat (limited to 'katzenpost_sender.php')
-rw-r--r--katzenpost_sender.php32
1 files changed, 32 insertions, 0 deletions
diff --git a/katzenpost_sender.php b/katzenpost_sender.php
new file mode 100644
index 0000000..88ce2ae
--- /dev/null
+++ b/katzenpost_sender.php
@@ -0,0 +1,32 @@
+<?php
+/** Send an already prepared YAMN payload through the local Katzenpost sender. */
+function sendKatzenpostEnvelope(string $entryAddress, string $payload, int $copies = 1): array
+{
+ $sender = getenv('YAMN_KP_SENDER') ?: '/usr/local/bin/yamn-submit';
+ $config = getenv('YAMN_KP_CONFIG') ?: '/etc/yamnweb/thinclient.toml';
+ if (!is_executable($sender)) {
+ return ['success' => false, 'error' => 'Katzenpost sender is not available'];
+ }
+ if (!filter_var($entryAddress, FILTER_VALIDATE_EMAIL) || !str_ends_with(strtolower($entryAddress), '@remailer.example')) {
+ return ['success' => false, 'error' => 'Invalid YAMN entry address'];
+ }
+ if ($payload === '' || strlen($payload) > 65536) {
+ return ['success' => false, 'error' => 'Invalid YAMN payload'];
+ }
+
+ $message = "To: {$entryAddress}\n" . $payload;
+ if (!str_contains($message, "-----BEGIN REMAILER MESSAGE-----\n")) {
+ $message = "To: {$entryAddress}\n\n-----BEGIN REMAILER MESSAGE-----\n" . $payload;
+ }
+ if ($copies !== 1) return ['success' => false, 'error' => 'Multiple copies are not enabled in the PoC'];
+ $input = json_encode(['entry_address' => $entryAddress, 'message' => $message], JSON_THROW_ON_ERROR);
+ $descriptor = [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
+ $process = proc_open([$sender, '-config', $config, '-settle', '2s'], $descriptor, $pipes);
+ if (!is_resource($process)) return ['success' => false, 'error' => 'Unable to start Katzenpost sender'];
+ fwrite($pipes[0], $input);
+ fclose($pipes[0]);
+ $stdout = stream_get_contents($pipes[1]); fclose($pipes[1]);
+ $stderr = stream_get_contents($pipes[2]); fclose($pipes[2]);
+ $status = proc_close($process);
+ return $status === 0 ? ['success' => true] : ['success' => false, 'error' => 'Katzenpost submission failed'];
+}