mirror of
https://gitverse.ru/kpa39l/xmpp-server-prosody.git
synced 2026-09-29 09:45:02 +00:00
4.9 KiB
4.9 KiB
OMEMO (XEP-0384) — проверка и публикация ключей (проверено 2026-08-28, nixg.ru)
Главное: серверный модуль НЕ нужен
OMEMO полностью работает на клиентах. Prosody хранит ключи/девайс-листы через
PEP (pep в modules_enabled — уже включён). Если PEP включён — OMEMO работает
для любого клиента (Gajim, Conversations, Dino, Converse). Серверного
mod_omemo в prosody-modules НЕТ и он не нужен (это норма, не потеря).
Converse v14 (веб-чат)
- OMEMO встроен: в dist лежат
libomemo.esm.min.js+curve25519_compiled.wasm(проверить:grep -c omemo converse.min.js> 0, естьeu.siacs.conversations.axolotl). - ЕДИНСТВЕННАЯ опция в initialize():
omemo_default: true(default false) — «шифровать по умолчанию, когда контакт поддерживает». Опцииallow_omemoв v14 нет (всегда доступен). - При логине с omemo_default:true Converse сам генерит device id и публикует devicelist + bundle в PEP. Проверять НЕ через UI — смотреть на диск.
Авторитетная проверка — файлы PEP на диске (host bigbox)
Каталог данных: data/ из docker-compose (в контейнере /var/lib/prosody),
имена узлов URL-encoded:
- devicelist:
data/<domain-encoded>/pep_eu%2esiacs%2econversations%2eaxolotl%2edevicelist/admin.list→ grep["id"] = "N"— все устройства пользователя (например 4040, 14035). - bundle:
data/<domain>/pep_eu%2esiacs%2econversations%2eaxolotl%2ebundles%3a<deviceid>/admin.list→ должен содержатьidentityKey, 100×preKeyPublic(preKeyId 0..99),signedPreKeyPublic+signedPreKeySignature, имяbundle. - : nixg.ru →
nixg%2eru(старый chin:chat%2enixg%2eru).
slixmpp 1.17: publish в PEP-узел (рабочий рецепт)
Подключение по WebSocket, паттерн 1.17 (нет .process(), connect возвращает Future):
import asyncio, ssl, slixmpp
from slixmpp.xmlstream import ET
ctx = ssl.create_default_context(); ctx.check_hostname=False; ctx.verify_mode=ssl.CERT_NONE
bot = slixmpp.ClientXMPP('user@domain', 'pass')
bot.ssl_context = ctx
bot.register_plugin('xep_0060')
bot.add_event_handler('session_start', ...) # в handler: send_presence(); await get_roster()
fut = bot.connect(('wss://xmpp.example.com/xmpp-websocket',))
await asyncio.wait_for(fut, 20); await asyncio.sleep(6) # дать событиям отработать
Publish (payload — СЫРОЙ lxml-элемент, не высокоуровневый API!):
lst = ET.Element('{eu.siacs.conversations.axolotl}list')
ET.SubElement(lst, '{eu.siacs.conversations.axolotl}device', {'id': '7777'})
await bot['xep_0060'].publish(jid=JID, node='eu.siacs.conversations.axolotl.devicelist',
id='current', payload=lst)
Засады:
iq['pubsub']['publish']['item']...+ElementBase.append('list', {'xmlns':...})падает:TypeError: ElementBase.append() takes 2 positional arguments but 3 were given.get_itemsможет вернуть 0 items даже когда узел НЕ пуст (семантика доступа PEP) — дискadmin.listавторитетнее. Проверять publish через чтение файла.
Проверка веб-клиента headless (camofox)
camofox-browser open https://chat...затемevalсJSON.stringify(...)— иначе возвращается толькоresultType, без значения.- Форма входа:
input[name=jid],input[name=password], чекбоксtrusted; submit-кнопкаbutton.btn-primary(текст «Войти»). Заполнять черезel.value=...; el.dispatchEvent(new Event('input',{bubbles:true})), потом click. - После входа в DOM:
document.body.innerTextсодержит «Я на связи». В DOM появляется строка «OMEMO» (кнопка в чате). - Новый device от сессии виден в devicelist admin.list + каталог bundles:.
Очистка/удаление своего устройства из devicelist
Republish devicelist с оставшимися id (паттерн выше), id='current' — примет, тестовый id исчезает из admin.list.
Сопутствующее
omemo_defaultв доке Converse: https://conversejs.org/docs/configuration/ (redirect с /docs/html/...). Единственная omemo-опция.- Converse api.omemo недоступен из window.converse — проверять по диску, не по JS API.