Вторая запись дневника разработки yah2g: добавлено SNI (исправление)

Дорабатывать yah2g я не планировал, но исправлять баги дело святое.

Предыдущая запись дневника разработки yah2g

В чём, собственно, дело

Сегодня обнаружил, что через yah2g не открываются страницы на сервере offpunk.com

gemini://offpunk.com/

Проявлялось это с не очень информативной ошибкой:

[SSL: TLSV1_ALERT_ACCESS_DENIED] tlsv1 alert access denied (_ssl.c:N).

Как выяснилось, при выполнении клиентского Gemini запроса, я забыл про SNI (Server Name Indication)

https://ru.wikipedia.org/wiki/Server_Name_Indication

Server Name Indication (SNI) — расширение компьютерного протокола TLS, которое позволяет клиенту сообщать имя хоста, с которым он желает соединиться во время процесса «рукопожатия». Это позволяет серверу предоставлять несколько сертификатов на одном IP-адресе и TCP-порту, и, следовательно, позволяет работать нескольким безопасным (HTTPS) сайтам (или другим сервисам поверх TLS) на одном IP-адресе без использования одного и того же сертификата на всех сайтах. Это эквивалентно возможности основанного на имени виртуального хостинга из HTTP/1.1. Запрашиваемое имя хоста не шифруется, что позволяет злоумышленнику его перехватить.

Исправление, благо, тривиальное: в вызов ssl.SSLContext.wrap_socket нужно указать аргумент server_hostname, который будет содержать доменное имя целевого сервера.

https://got.any-key.press/?action=diff&commit=401c2cd43f6a22402e0ad686dce31a6e150d7cdc&headref=HEAD&path=yah2g.git

--- yah2g.py
+++ yah2g.py
@@ -117,7 +117,7 @@ class _RequestHandler(BaseHTTPRequestHandler):
                     context.check_hostname = False
                     context.verify_mode = ssl.CERT_NONE
                     with socket.create_connection((parsed.hostname, parsed.port or 1965)) as raw_s:
-                        with context.wrap_socket(raw_s) as s:
+                        with context.wrap_socket(raw_s, server_hostname=parsed.hostname) as s:
                             s.sendall((url + '\r\n').encode("UTF-8"))
                             fp = s.makefile("rb")
                             splitted = fp.readline().decode("UTF-8").strip().split(maxsplit=1)

Раз такое дело (багфикс), то я стал вести тэги версий. Предыдущую версию (до внесения исправлений) я зафиксировал, как v0.1. А текущая помечена тэгом v0.2.

Ну и не могу не похвалиться: у сервера появился новый экземпляр (спасибо @vlnst@shitpost.poridge.club)!

https://gem.bloat.cat/

Комментарии через ActivityPub (Fediverse) можно оставить здесь:

https://honk.any-key.press/u/continue/h/Rl34QSQmsm6662C97G

Следующая запись дневника разработки yah2g