Summary
On an account hosted on Prosody, lurch never publishes its bundle or devicelist,
but reports success in the debug log. No <iq type='set'> publish ever reaches the
wire, and there is no error anywhere. The account ends up with no bundle node and
no entry in its own devicelist, so contacts cannot encrypt to it at all.
A second account in the same Pidgin instance, hosted on ejabberd, works correctly.
That gives a clean control: same plugin build, same Pidgin process, same session.
Environment
- lurch: 0.7.0
- Pidgin: 2.14.14
- OS: Windows 11 Pro 25H2 build 26200.8875 Windows Feature Experience Pack 1000.26100.334.0
- Failing account: Prosody (xmpp.xyz)
- Working account: ejabberd (xmpp.jp)
Expected behaviour
On connect, lurch publishes its bundle to
eu.siacs.conversations.axolotl.bundles:<device id> and adds its device ID to
eu.siacs.conversations.axolotl.devicelist.
Actual behaviour
Neither node is ever written. The debug log reports the publish as successful.
Fetching the bundle node for the device ID that /lurch id show reports:
<iq type='get' id='b1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<items node='eu.siacs.conversations.axolotl.bundles:DEVICE_ID'/>
</pubsub>
</iq>
<iq to='USER@PROSODY_SERVER/RESOURCE' id='b1' type='error'>
<error type='cancel'>
<item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
Manually publishing the devicelist via the XMPP console works and persists, so the
server accepts these writes, they simply never leave Pidgin.
Steps to reproduce
- Add an account on a Prosody server that advertises the
pubsub/pep identity on
the account JID rather than on the server JID (see the disco comparison below).
- Enable lurch and connect.
- Fetch
eu.siacs.conversations.axolotl.bundles:<device id> for that account
→ item-not-found.
- Grep the debug log for
Sending and publish → no publish stanza for that account.
Debug log
lurch decides correctly and logs success, but nothing is sent:
lurch: lurch_pep_own_devicelist_request_handler: own id was missing, adding it
lurch: lurch_pep_own_devicelist_request_handler: devicelist needs publishing...
lurch: lurch_pep_own_devicelist_request_handler: ...done:
lurch: [AXC DEBUG] axc_bundle_collect: entered
lurch: [AXC DEBUG] axc_bundle_collect: leaving
lurch: lurch_bundle_publish_own: published own bundle for USER@PROSODY_SERVER
For the ejabberd account in the same log, the corresponding Sending (ssl) ... <iq type='set'> ... <publish node='eu.siacs.conversations.axolotl.bundles:...'> line is
present. For the Prosody account there is no such line, in either the
needs publishing or the already contained branch.
(The xmlns: URI eu.siacs.conversations.axolotl is not absolute parser warnings
appear for both accounts, including the working one, so they are unrelated, as the
README notes.)
Likely cause
jabber_pep_publish() returns void, so lurch cannot detect failure, and
src/lurch.c logs success unconditionally on the following line:
publish_node_bundle_p = xmlnode_from_str(bundle_xml, -1);
jabber_pep_publish(js_p, publish_node_bundle_p);
purple_debug_info("lurch", "%s: published own bundle for %s\n", __func__, uname);
The same pattern appears at the devicelist publish in src/lurch.c and in
lurch_api_id_remove_handler() in src/lurch_api.c.
As for why nothing is sent: libpurple gates PEP writes on JabberStream.pep, which
headers/jabber/jabber.h:232 documents as "does the local server support PEP?"
i.e. it is set from the server's disco#info. XEP-0163 places the pubsub/pep
identity on the account JID, which is where Prosody advertises it. Comparing the
two servers:
ejabberd, server JID (works):
<identity category='pubsub' type='pep'/>
<identity name='ejabberd' category='server' type='im'/>
<feature var='http://jabber.org/protocol/pubsub#publish'/>
Prosody, server JID (fails) no pubsub identity, no pubsub features at all:
<identity category='server' name='Prosody' type='im'/>
Prosody, account JID full PEP support, including #publish and #auto-create:
<identity category='account' type='registered'/>
<identity category='pubsub' type='pep'/>
<feature var='http://jabber.org/protocol/pubsub#publish'/>
<feature var='http://jabber.org/protocol/pubsub#auto-create'/>
I was not able to dive into libpurple's pep.c myself to confirm the early return on
!js->pep, so please treat that last step as inference. The unconditional success
log and the missing stanzas are directly observable either way.
Suggested fix
Send the publish IQ directly instead of going through jabber_pep_publish(), using
jabber_iq_new() / jabber_iq_send() which lurch already does for bundle
requests in lurch_bundle_request_do(). That avoids the flag entirely and allows
reporting server-side rejections instead of assuming success.
Possibly related
#193 reports the same user-visible symptom (empty devicelist, cannot send
encrypted) on ejabberd. It may or may not share this cause.
Summary
On an account hosted on Prosody, lurch never publishes its bundle or devicelist,
but reports success in the debug log. No
<iq type='set'>publish ever reaches thewire, and there is no error anywhere. The account ends up with no bundle node and
no entry in its own devicelist, so contacts cannot encrypt to it at all.
A second account in the same Pidgin instance, hosted on ejabberd, works correctly.
That gives a clean control: same plugin build, same Pidgin process, same session.
Environment
Expected behaviour
On connect, lurch publishes its bundle to
eu.siacs.conversations.axolotl.bundles:<device id>and adds its device ID toeu.siacs.conversations.axolotl.devicelist.Actual behaviour
Neither node is ever written. The debug log reports the publish as successful.
Fetching the bundle node for the device ID that
/lurch id showreports:Manually publishing the devicelist via the XMPP console works and persists, so the
server accepts these writes, they simply never leave Pidgin.
Steps to reproduce
pubsub/pepidentity onthe account JID rather than on the server JID (see the disco comparison below).
eu.siacs.conversations.axolotl.bundles:<device id>for that account→
item-not-found.Sendingandpublish→ no publish stanza for that account.Debug log
lurch decides correctly and logs success, but nothing is sent:
For the ejabberd account in the same log, the corresponding
Sending (ssl) ... <iq type='set'> ... <publish node='eu.siacs.conversations.axolotl.bundles:...'>line ispresent. For the Prosody account there is no such line, in either the
needs publishingor thealready containedbranch.(The
xmlns: URI eu.siacs.conversations.axolotl is not absoluteparser warningsappear for both accounts, including the working one, so they are unrelated, as the
README notes.)
Likely cause
jabber_pep_publish()returnsvoid, so lurch cannot detect failure, andsrc/lurch.clogs success unconditionally on the following line:The same pattern appears at the devicelist publish in
src/lurch.cand inlurch_api_id_remove_handler()insrc/lurch_api.c.As for why nothing is sent: libpurple gates PEP writes on
JabberStream.pep, whichheaders/jabber/jabber.h:232documents as "does the local server support PEP?"i.e. it is set from the server's disco#info. XEP-0163 places the
pubsub/pepidentity on the account JID, which is where Prosody advertises it. Comparing the
two servers:
ejabberd, server JID (works):
Prosody, server JID (fails) no pubsub identity, no pubsub features at all:
Prosody, account JID full PEP support, including
#publishand#auto-create:I was not able to dive into libpurple's
pep.cmyself to confirm the early return on!js->pep, so please treat that last step as inference. The unconditional successlog and the missing stanzas are directly observable either way.
Suggested fix
Send the publish IQ directly instead of going through
jabber_pep_publish(), usingjabber_iq_new()/jabber_iq_send()which lurch already does for bundlerequests in
lurch_bundle_request_do(). That avoids the flag entirely and allowsreporting server-side rejections instead of assuming success.
Possibly related
#193 reports the same user-visible symptom (empty devicelist, cannot send
encrypted) on ejabberd. It may or may not share this cause.