From 4ad6904216fa5917f202a0f1bfe3d4712559aeae Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Mon, 8 Apr 2019 20:29:25 +0320 Subject: Wait for discovery end to publish omemo devicelist and bundle Add sv_ev_connection_features_received for that purpose --- src/event/server_events.c | 8 ++++++++ src/event/server_events.h | 1 + src/omemo/omemo.c | 21 ++++++++++++++------- src/omemo/omemo.h | 1 + src/xmpp/connection.c | 23 +++++++++++++++++++++++ src/xmpp/connection.h | 2 ++ src/xmpp/iq.c | 2 ++ src/xmpp/omemo.c | 8 ++++++-- src/xmpp/session.c | 2 +- 9 files changed, 58 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/event/server_events.c b/src/event/server_events.c index f6c640f3..7c1cfd78 100644 --- a/src/event/server_events.c +++ b/src/event/server_events.c @@ -176,6 +176,14 @@ sv_ev_roster_received(void) plugins_on_connect(account_name, fulljid); } +void +sv_ev_connection_features_received(void) +{ +#ifdef HAVE_OMEMO + omemo_publish_crypto_materials(); +#endif +} + void sv_ev_lost_connection(void) { diff --git a/src/event/server_events.h b/src/event/server_events.h index 713e50f5..74016ceb 100644 --- a/src/event/server_events.h +++ b/src/event/server_events.h @@ -85,6 +85,7 @@ void sv_ev_muc_occupant_online(const char *const room, const char *const nick, c void sv_ev_roster_update(const char *const barejid, const char *const name, GSList *groups, const char *const subscription, gboolean pending_out); void sv_ev_roster_received(void); +void sv_ev_connection_features_received(void); int sv_ev_certfail(const char *const errormsg, TLSCertificate *cert); void sv_ev_lastactivity_response(const char *const from, const int seconds, const char *const msg); void sv_ev_bookmark_autojoin(Bookmark *bookmark); diff --git a/src/omemo/omemo.c b/src/omemo/omemo.c index d580ed51..a20dc109 100644 --- a/src/omemo/omemo.c +++ b/src/omemo/omemo.c @@ -27,7 +27,6 @@ static gboolean loaded; -static void _omemo_publish_crypto_materials(ProfAccount *account); static void _generate_pre_keys(int count); static void _generate_signed_pre_key(void); static void _load_identity(void); @@ -212,7 +211,6 @@ omemo_on_connect(ProfAccount *account) if (g_key_file_load_from_file(omemo_ctx.identity_keyfile, omemo_ctx.identity_filename->str, G_KEY_FILE_KEEP_COMMENTS, &error)) { _load_identity(); - _omemo_publish_crypto_materials(account); } else if (error->code != G_FILE_ERROR_NOENT) { log_warning("OMEMO: error loading identity from: %s, %s", omemo_ctx.identity_filename->str, error->message); return; @@ -291,18 +289,27 @@ omemo_generate_crypto_materials(ProfAccount *account) loaded = TRUE; - _omemo_publish_crypto_materials(account); + omemo_publish_crypto_materials(); } -static void -_omemo_publish_crypto_materials(ProfAccount *account) +void +omemo_publish_crypto_materials(void) { + if (loaded != TRUE) { + log_error("OMEMO: cannot publish crypto materials before they are generated"); + return; + } + + Jid *jid = jid_create(connection_get_fulljid()); + /* Ensure we get our current device list, and it gets updated with our * device_id */ - g_hash_table_insert(omemo_ctx.device_list_handler, strdup(account->jid), _handle_own_device_list); - omemo_devicelist_request(account->jid); + g_hash_table_insert(omemo_ctx.device_list_handler, strdup(jid->barejid), _handle_own_device_list); + omemo_devicelist_request(jid->barejid); omemo_bundle_publish(true); + + jid_destroy(jid); } void diff --git a/src/omemo/omemo.h b/src/omemo/omemo.h index bbd59b77..72e27429 100644 --- a/src/omemo/omemo.h +++ b/src/omemo/omemo.h @@ -21,6 +21,7 @@ void omemo_on_connect(ProfAccount *account); void omemo_on_disconnect(void); void omemo_generate_crypto_materials(ProfAccount *account); void omemo_key_free(omemo_key_t *key); +void omemo_publish_crypto_materials(void); uint32_t omemo_device_id(void); void omemo_identity_key(unsigned char **output, size_t *length); diff --git a/src/xmpp/connection.c b/src/xmpp/connection.c index 2adda46e..afcd8199 100644 --- a/src/xmpp/connection.c +++ b/src/xmpp/connection.c @@ -63,6 +63,7 @@ typedef struct prof_conn_t { char *domain; GHashTable *available_resources; GHashTable *features_by_jid; + GHashTable *requested_features; } ProfConnection; static ProfConnection conn; @@ -89,6 +90,7 @@ connection_init(void) conn.domain = NULL; conn.features_by_jid = NULL; conn.available_resources = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)resource_destroy); + conn.requested_features = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL); } void @@ -231,6 +233,10 @@ connection_clear_data(void) if (conn.available_resources) { g_hash_table_remove_all(conn.available_resources); } + + if (conn.requested_features) { + g_hash_table_remove_all(conn.requested_features); + } } #ifdef HAVE_LIBMESODE @@ -313,12 +319,21 @@ connection_jid_for_feature(const char *const feature) return NULL; } +void +connection_request_features(void) +{ + /* We don't record it as a requested feature to avoid triggering th + * sv_ev_connection_features_received too soon */ + iq_disco_info_request_onconnect(conn.domain); +} + void connection_set_disco_items(GSList *items) { GSList *curr = items; while (curr) { DiscoItem *item = curr->data; + g_hash_table_insert(conn.requested_features, strdup(item->jid), NULL); g_hash_table_insert(conn.features_by_jid, strdup(item->jid), g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL)); @@ -357,6 +372,14 @@ connection_get_fulljid(void) } } +void +connection_features_received(const char *const jid) +{ + if (g_hash_table_remove(conn.requested_features, jid) && g_hash_table_size(conn.requested_features) == 0) { + sv_ev_connection_features_received(); + } +} + GHashTable* connection_get_features(const char *const jid) { diff --git a/src/xmpp/connection.h b/src/xmpp/connection.h index 170bc2bf..044cf368 100644 --- a/src/xmpp/connection.h +++ b/src/xmpp/connection.h @@ -53,6 +53,8 @@ void connection_set_disco_items(GSList *items); xmpp_conn_t* connection_get_conn(void); xmpp_ctx_t* connection_get_ctx(void); char *connection_get_domain(void); +void connection_request_features(void); +void connection_features_received(const char *const jid); GHashTable* connection_get_features(const char *const jid); void connection_clear_data(void); diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index e1c3c281..d6e4c153 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -2291,6 +2291,8 @@ _disco_info_response_id_handler_onconnect(xmpp_stanza_t *const stanza, void *con } } + connection_features_received(from); + return 0; } diff --git a/src/xmpp/omemo.c b/src/xmpp/omemo.c index 8c8d56e0..4b77ef23 100644 --- a/src/xmpp/omemo.c +++ b/src/xmpp/omemo.c @@ -28,7 +28,9 @@ omemo_devicelist_publish(GList *device_list) xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_stanza_t *iq = stanza_create_omemo_devicelist_publish(ctx, device_list); - stanza_attach_publish_options(ctx, iq, "pubsub#access_model", "open"); + if (connection_supports(XMPP_FEATURE_PUBSUB_PUBLISH_OPTIONS)) { + stanza_attach_publish_options(ctx, iq, "pubsub#access_model", "open"); + } iq_send_stanza(iq); xmpp_stanza_release(iq); @@ -76,7 +78,9 @@ omemo_bundle_publish(gboolean first) g_list_free(lengths); g_list_free(ids); - stanza_attach_publish_options(ctx, iq, "pubsub#access_model", "open"); + if (connection_supports(XMPP_FEATURE_PUBSUB_PUBLISH_OPTIONS)) { + stanza_attach_publish_options(ctx, iq, "pubsub#access_model", "open"); + } iq_id_handler_add(id, _omemo_bundle_publish_result, NULL, GINT_TO_POINTER(first)); diff --git a/src/xmpp/session.c b/src/xmpp/session.c index 786b1cd5..675f23af 100644 --- a/src/xmpp/session.c +++ b/src/xmpp/session.c @@ -320,8 +320,8 @@ session_login_success(gboolean secured) blocking_request(); // items discovery + connection_request_features(); char *domain = connection_get_domain(); - iq_disco_info_request_onconnect(domain); iq_disco_items_request_onconnect(domain); if (prefs_get_boolean(PREF_CARBONS)){ -- cgit 1.4.1-2-gfad0