smtp-test: bypass DB, use POST fields directly for credentials

This commit is contained in:
Pontoporeia
2026-04-27 21:32:46 +02:00
parent 9ff8b1b464
commit 59c4cf055f
2 changed files with 27 additions and 5 deletions

10
TODO.md
View File

@@ -6,6 +6,16 @@
- [x] Exclude `cover` file_type from public files loop (covers are banners, not content)
- [x] Move `App::boot()` in Dispatcher to after direct-response matching (no session on media requests)
## SMTP Relay — bad greeting fix
- [x] Fix `$read()` loop: use `!== false` so empty lines don't terminate early; check `timed_out` meta
- [x] Add SSL stream context (`verify_peer=false`) to `stream_socket_client` to avoid CA bundle failures
- [x] Improve "bad greeting" error: distinguish timeout vs garbage response in log message
## Bug Fixes
- [x] Fix `RateLimit::check()` called statically in `request-access.php` — replaced with `(new RateLimit(3, 600))->checkKey($rateLimitKey)`
## Dev / Debug Fixes
- [x] Fix `serve` recipe: show all PHP output (errors, logs) except static assets/connection noise

View File

@@ -120,7 +120,7 @@ class SmtpRelay {
// Build MIME message
$boundary = 'posterg_' . bin2hex(random_bytes(8));
$date = date('r');
$fromHdr = $s['from_name'] !== ''
$fromHdr = ($s['from_name'] ?? '') !== ''
? "=?UTF-8?B?" . base64_encode($s['from_name']) . "?= <{$s['from_email']}>"
: $s['from_email'];
$subjectHdr = '=?UTF-8?B?' . base64_encode($subject) . '?=';
@@ -179,8 +179,16 @@ class SmtpRelay {
$connectHost = ($encryption === 'ssl') ? "ssl://{$host}" : $host;
$errno = 0; $errstr = '';
$ctx = stream_context_create([
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true,
],
]);
$sock = @stream_socket_client(
"{$connectHost}:{$port}", $errno, $errstr, $timeout
"{$connectHost}:{$port}", $errno, $errstr, $timeout,
STREAM_CLIENT_CONNECT, $ctx
);
if ($sock === false) {
throw new \RuntimeException("SMTP connect failed ({$connectHost}:{$port}): {$errstr} [{$errno}]");
@@ -189,10 +197,12 @@ class SmtpRelay {
$read = function () use ($sock): string {
$buf = '';
while ($line = fgets($sock, 512)) {
while (($line = fgets($sock, 512)) !== false) {
$buf .= $line;
// 4th char is ' ' when it's the last line of a multi-line reply
if (isset($line[3]) && $line[3] === ' ') break;
$meta = stream_get_meta_data($sock);
if ($meta['timed_out']) break;
}
return $buf;
};
@@ -211,7 +221,9 @@ class SmtpRelay {
// Greeting
$greeting = $read();
if (strncmp($greeting, '220', 3) !== 0) {
throw new \RuntimeException("SMTP bad greeting: {$greeting}");
$meta = stream_get_meta_data($sock);
$detail = $meta['timed_out'] ? '(socket timed out — no data received)' : '(received: ' . json_encode($greeting) . ')';
throw new \RuntimeException("SMTP bad greeting {$detail}");
}
$parseEhlo = function (string $resp): array {
@@ -237,7 +249,7 @@ class SmtpRelay {
if ($encryption === 'tls') {
$expect('STARTTLS', '220');
if (!stream_socket_enable_crypto($sock, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
throw new \RuntimeException('SMTP STARTTLS crypto negotiation failed');
throw new \RuntimeException('SMTP STARTTLS crypto negotiation failed (check server cert / CA bundle)');
}
// Re-EHLO after TLS — refresh capabilities
$ehloResp = $send('EHLO ' . gethostname());