From 7d79d47311c2a9d1678dd8ce0aeea414e06c41f9 Mon Sep 17 00:00:00 2001 From: yggverse Date: Sat, 3 Aug 2024 23:16:44 +0300 Subject: [PATCH] use certificate auth on identity match request --- src/Model/Connection/Gemini.php | 57 ++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/src/Model/Connection/Gemini.php b/src/Model/Connection/Gemini.php index 1f48e044..b1bbf54c 100644 --- a/src/Model/Connection/Gemini.php +++ b/src/Model/Connection/Gemini.php @@ -27,10 +27,27 @@ class Gemini int $timeout = 15 ): void { + // Init request $request = new Request( $address->get() ); + // Get connection settings + $options = $request->getOptions(); + + // Apply identity if available + if ($identity = $this->matchIdentity($address->get())) + { + $options['ssl']['local_cert'] = $identity->crt; + $options['ssl']['local_pk'] = $identity->key; + } + + // Update connection + $request->setOptions( + $options + ); + + // Parse response $response = new Response( $request->getResponse( $timeout @@ -265,7 +282,7 @@ class Gemini default: // Try cache - if ($cache = $this->_connection->getCache($address->get())) + if ($cache = $this->_connection->database->cache->get($address->get())) { $this->_connection->setTitle( $cache->title @@ -330,6 +347,44 @@ class Gemini ); } + /** + * Return identity match request | NULL + * + * https://geminiprotocol.net/docs/protocol-specification.gmi#client-certificates + * + */ + public function matchIdentity( + string $request, + array $identities = [] + ): ?object + { + foreach ($this->_connection->database->auth->like(sprintf('%s%%', $request)) as $auth) + { + $identities[$auth->identity] = $auth->request; + } + + if ($identities) + { + uasort( + $identities, + function ($a, $b) + { + return mb_strlen($b) <=> mb_strlen($a); + } + ); + + return $this->_connection->database->identity->get( + intval( + array_key_first( + $identities + ) + ) + ); + } + + return null; + } + public static function getMimeByMeta( ?string $meta = null ): ?string