1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
<?php
// /var/www/mail2usenet/send.php
// Send the post via the "mail2news" transport, enforcing Ed25519 signature.
// Read POST data
$from = $_POST['from'] ?? '';
$newsgroups = $_POST['newsgroups'] ?? '';
$subject = $_POST['subject'] ?? '';
$references = $_POST['references'] ?? '';
$hashcash = $_POST['xhashcash'] ?? '';
$pubkey = $_POST['x-ed25519-pub'] ?? '';
$sig = $_POST['x-ed25519-sig'] ?? '';
$message = $_POST['message'] ?? '';
// Validate required fields
if (!$from || !$newsgroups || !$subject || !$hashcash || !$sig || !$message) {
http_response_code(400);
echo "Missing required fields. Signature is mandatory.";
exit;
}
// Limit to 3 newsgroups
$groups = array_filter(array_map('trim', explode(',', $newsgroups)));
if (count($groups) > 3) {
$groups = array_slice($groups, 0, 3);
}
$newsgroups = implode(', ', $groups);
// Build raw email with dummy To for sendmail -t
$headers = [];
$headers[] = "From: $from";
$headers[] = "To: mail2news@localhost";
$headers[] = "Newsgroups: $newsgroups";
$headers[] = "Subject: $subject";
if ($references) {
$headers[] = "References: $references";
}
// PoW header
$headers[] = "X-Hashcash: $hashcash";
// Enforce signature immediately after PoW
$headers[] = "X-Ed25519-Sig: $sig";
// Optionally include public key header
if ($pubkey) {
$headers[] = "X-Ed25519-Pub: $pubkey";
}
$headers[] = "X-No-Archive: Yes";
$headers[] = "Mime-Version: 1.0";
$headers[] = "Content-Type: text/plain; charset=UTF-8";
$headers[] = "Content-Transfer-Encoding: 7bit";
$headers[] = ""; // end of headers
$rawEmail = implode("\r\n", $headers) . "\r\n" . $message . "\r\n";
// Send via sendmail using mail2news transport
$sendmail = '/usr/sbin/sendmail';
$cmd = escapeshellcmd($sendmail) . ' -i -oTransport=mail2news -t';
$descriptors = [
0 => ['pipe', 'r'], // stdin
1 => ['pipe', 'w'], // stdout
2 => ['pipe', 'w'], // stderr
];
$process = proc_open($cmd, $descriptors, $pipes);
if (!is_resource($process)) {
http_response_code(500);
echo "Failed to invoke sendmail.";
exit;
}
// Write the raw email
fwrite($pipes[0], $rawEmail);
fclose($pipes[0]);
// Capture and close outputs
$stderr = stream_get_contents($pipes[2]);
fclose($pipes[1]);
fclose($pipes[2]);
$returnCode = proc_close($process);
if ($returnCode !== 0) {
http_response_code(500);
echo "Sendmail error (code {$returnCode}):\n" . nl2br(htmlspecialchars($stderr));
exit;
}
// Success page
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Message Sent</title>
<style>
body { font-family: sans-serif; text-align: center; padding: 50px; }
a.button {
display: inline-block;
margin-top: 20px;
padding: 10px 20px;
background: #4caf50;
color: white;
text-decoration: none;
border-radius: 4px;
}
a.button:hover { background: #45a049; }
</style>
</head>
<body>
<h1>Message Sent Successfully</h1>
<p>Your post has been handed off to the mail2news transport.</p>
<a class="button" href="https://m2usenet.virebent.art">Return to Home</a>
</body>
</html>
|