false, 'error' => 'Nym sender is not available']; } if ($recipient === '' || strlen($recipient) > 512 || preg_match('/\s/', $recipient)) { return ['success' => false, 'error' => 'Nym recipient is not configured']; } if ($entryAddress === '' || strlen($entryAddress) > 320 || preg_match('/[\r\n\0\s]/', $entryAddress)) { return ['success' => false, 'error' => 'YAMN entry address is not configured']; } if ($copies !== 1) { return ['success' => false, 'error' => 'Multiple copies are not enabled for Nym']; } if ($payload === '' || strlen($payload) > 65536 || str_contains($payload, "\0")) { return ['success' => false, 'error' => 'Invalid encrypted YAMN envelope']; } try { $input = json_encode([ 'entry_address' => $entryAddress, 'payload' => $payload, ], JSON_THROW_ON_ERROR); } catch (JsonException $exception) { return ['success' => false, 'error' => 'Unable to encode Nym request']; } $lock = @fopen($lockPath, 'c'); if ($lock === false) { return ['success' => false, 'error' => 'Nym sender lock is not available']; } if (!flock($lock, LOCK_EX | LOCK_NB)) { fclose($lock); return ['success' => false, 'error' => 'Nym sender is busy, please retry later']; } $descriptors = [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']]; $environment = $_ENV; $environment['YAMN_NYM_RECIPIENT'] = $recipient; $environment['YAMN_NYM_STORAGE'] = $storage; $process = proc_open([$sender], $descriptors, $pipes, null, $environment); if (!is_resource($process)) { flock($lock, LOCK_UN); fclose($lock); return ['success' => false, 'error' => 'Unable to start Nym sender']; } $inputLength = strlen($input); $offset = 0; while ($offset < $inputLength) { $written = fwrite($pipes[0], substr($input, $offset)); if ($written === false || $written === 0) { break; } $offset += $written; } if ($offset !== $inputLength) { fclose($pipes[0]); proc_terminate($process); fclose($pipes[1]); fclose($pipes[2]); proc_close($process); flock($lock, LOCK_UN); fclose($lock); return ['success' => false, 'error' => 'Unable to hand envelope to Nym sender']; } fclose($pipes[0]); if ($onHandoff !== null) { $onHandoff(); } $stdout = stream_get_contents($pipes[1]); fclose($pipes[1]); $stderr = stream_get_contents($pipes[2]); fclose($pipes[2]); $status = proc_close($process); flock($lock, LOCK_UN); fclose($lock); if ($status !== 0) { return ['success' => false, 'error' => 'Nym submission failed']; } $response = json_decode($stdout, true); if (!is_array($response) || ($response['success'] ?? false) !== true) { return ['success' => false, 'error' => 'Invalid response from Nym sender']; } return ['success' => true]; }