mirror of
https://github.com/profanity-im/profanity.git
synced 2025-01-03 14:57:42 -05:00
Merge pull request #1496 from mwuttke97/omemo-bugfixes
[OMEMO]: Fix bundle publishing
This commit is contained in:
commit
96580f917b
@ -195,10 +195,6 @@ sv_ev_roster_received(void)
|
|||||||
|
|
||||||
const char* fulljid = connection_get_fulljid();
|
const char* fulljid = connection_get_fulljid();
|
||||||
plugins_on_connect(account_name, fulljid);
|
plugins_on_connect(account_name, fulljid);
|
||||||
|
|
||||||
#ifdef HAVE_OMEMO
|
|
||||||
omemo_start_sessions();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -118,7 +118,7 @@ static omemo_context omemo_ctx;
|
|||||||
void
|
void
|
||||||
omemo_init(void)
|
omemo_init(void)
|
||||||
{
|
{
|
||||||
log_info("OMEMO: initialising");
|
log_info("[OMEMO] initialising");
|
||||||
if (omemo_crypto_init() != 0) {
|
if (omemo_crypto_init() != 0) {
|
||||||
cons_show("Error initializing OMEMO crypto: gcry_check_version() failed");
|
cons_show("Error initializing OMEMO crypto: gcry_check_version() failed");
|
||||||
}
|
}
|
||||||
@ -244,9 +244,9 @@ omemo_on_connect(ProfAccount* account)
|
|||||||
if (res == -1) {
|
if (res == -1) {
|
||||||
const char* errmsg = strerror(errno);
|
const char* errmsg = strerror(errno);
|
||||||
if (errmsg) {
|
if (errmsg) {
|
||||||
log_error("OMEMO: error creating directory: %s, %s", omemo_dir, errmsg);
|
log_error("[OMEMO] error creating directory: %s, %s", omemo_dir, errmsg);
|
||||||
} else {
|
} else {
|
||||||
log_error("OMEMO: creating directory: %s", omemo_dir);
|
log_error("[OMEMO] creating directory: %s", omemo_dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,7 +264,7 @@ omemo_on_connect(ProfAccount* account)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (error->code != G_FILE_ERROR_NOENT) {
|
} else if (error->code != G_FILE_ERROR_NOENT) {
|
||||||
log_warning("OMEMO: error loading identity from: %s, %s", omemo_ctx.identity_filename->str, error->message);
|
log_warning("[OMEMO] error loading identity from: %s, %s", omemo_ctx.identity_filename->str, error->message);
|
||||||
g_error_free(error);
|
g_error_free(error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -273,7 +273,7 @@ omemo_on_connect(ProfAccount* account)
|
|||||||
if (g_key_file_load_from_file(omemo_ctx.trust_keyfile, omemo_ctx.trust_filename->str, G_KEY_FILE_KEEP_COMMENTS, &error)) {
|
if (g_key_file_load_from_file(omemo_ctx.trust_keyfile, omemo_ctx.trust_filename->str, G_KEY_FILE_KEEP_COMMENTS, &error)) {
|
||||||
_load_trust();
|
_load_trust();
|
||||||
} else if (error->code != G_FILE_ERROR_NOENT) {
|
} else if (error->code != G_FILE_ERROR_NOENT) {
|
||||||
log_warning("OMEMO: error loading trust from: %s, %s", omemo_ctx.trust_filename->str, error->message);
|
log_warning("[OMEMO] error loading trust from: %s, %s", omemo_ctx.trust_filename->str, error->message);
|
||||||
g_error_free(error);
|
g_error_free(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,7 +281,7 @@ omemo_on_connect(ProfAccount* account)
|
|||||||
if (g_key_file_load_from_file(omemo_ctx.sessions_keyfile, omemo_ctx.sessions_filename->str, G_KEY_FILE_KEEP_COMMENTS, &error)) {
|
if (g_key_file_load_from_file(omemo_ctx.sessions_keyfile, omemo_ctx.sessions_filename->str, G_KEY_FILE_KEEP_COMMENTS, &error)) {
|
||||||
_load_sessions();
|
_load_sessions();
|
||||||
} else if (error->code != G_FILE_ERROR_NOENT) {
|
} else if (error->code != G_FILE_ERROR_NOENT) {
|
||||||
log_warning("OMEMO: error loading sessions from: %s, %s", omemo_ctx.sessions_filename->str, error->message);
|
log_warning("[OMEMO] error loading sessions from: %s, %s", omemo_ctx.sessions_filename->str, error->message);
|
||||||
g_error_free(error);
|
g_error_free(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,7 +289,7 @@ omemo_on_connect(ProfAccount* account)
|
|||||||
if (g_key_file_load_from_file(omemo_ctx.known_devices_keyfile, omemo_ctx.known_devices_filename->str, G_KEY_FILE_KEEP_COMMENTS, &error)) {
|
if (g_key_file_load_from_file(omemo_ctx.known_devices_keyfile, omemo_ctx.known_devices_filename->str, G_KEY_FILE_KEEP_COMMENTS, &error)) {
|
||||||
_load_known_devices();
|
_load_known_devices();
|
||||||
} else if (error->code != G_FILE_ERROR_NOENT) {
|
} else if (error->code != G_FILE_ERROR_NOENT) {
|
||||||
log_warning("OMEMO: error loading known devices from: %s, %s", omemo_ctx.known_devices_filename->str, error->message);
|
log_warning("[OMEMO] error loading known devices from: %s, %s", omemo_ctx.known_devices_filename->str, error->message);
|
||||||
g_error_free(error);
|
g_error_free(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -329,7 +329,7 @@ omemo_generate_crypto_materials(ProfAccount* account)
|
|||||||
gcry_randomize(&omemo_ctx.device_id, 4, GCRY_VERY_STRONG_RANDOM);
|
gcry_randomize(&omemo_ctx.device_id, 4, GCRY_VERY_STRONG_RANDOM);
|
||||||
omemo_ctx.device_id &= 0x7fffffff;
|
omemo_ctx.device_id &= 0x7fffffff;
|
||||||
g_key_file_set_uint64(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_DEVICE_ID, omemo_ctx.device_id);
|
g_key_file_set_uint64(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_DEVICE_ID, omemo_ctx.device_id);
|
||||||
log_info("OMEMO: device id: %d", omemo_ctx.device_id);
|
log_info("[OMEMO] device id: %d", omemo_ctx.device_id);
|
||||||
|
|
||||||
/* Identity key */
|
/* Identity key */
|
||||||
signal_protocol_key_helper_generate_identity_key_pair(&omemo_ctx.identity_key_pair, omemo_ctx.signal);
|
signal_protocol_key_helper_generate_identity_key_pair(&omemo_ctx.identity_key_pair, omemo_ctx.signal);
|
||||||
@ -366,7 +366,8 @@ void
|
|||||||
omemo_publish_crypto_materials(void)
|
omemo_publish_crypto_materials(void)
|
||||||
{
|
{
|
||||||
if (loaded != TRUE) {
|
if (loaded != TRUE) {
|
||||||
log_error("OMEMO: cannot publish crypto materials before they are generated");
|
cons_show("OMEMO: cannot publish crypto materials before they are generated");
|
||||||
|
log_error("[OMEMO] cannot publish crypto materials before they are generated");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,10 +402,10 @@ void
|
|||||||
omemo_start_session(const char* const barejid)
|
omemo_start_session(const char* const barejid)
|
||||||
{
|
{
|
||||||
if (omemo_loaded()) {
|
if (omemo_loaded()) {
|
||||||
log_info("OMEMO: start session with %s", barejid);
|
log_info("[OMEMO] start session with %s", barejid);
|
||||||
GList* device_list = g_hash_table_lookup(omemo_ctx.device_list, barejid);
|
GList* device_list = g_hash_table_lookup(omemo_ctx.device_list, barejid);
|
||||||
if (!device_list) {
|
if (!device_list) {
|
||||||
log_info("OMEMO: missing device list for %s", barejid);
|
log_info("[OMEMO] missing device list for %s", barejid);
|
||||||
omemo_devicelist_request(barejid);
|
omemo_devicelist_request(barejid);
|
||||||
g_hash_table_insert(omemo_ctx.device_list_handler, strdup(barejid), _handle_device_list_start_session);
|
g_hash_table_insert(omemo_ctx.device_list_handler, strdup(barejid), _handle_device_list_start_session);
|
||||||
return;
|
return;
|
||||||
@ -554,7 +555,7 @@ omemo_identity_keyfile_save(void)
|
|||||||
GError* error = NULL;
|
GError* error = NULL;
|
||||||
|
|
||||||
if (!g_key_file_save_to_file(omemo_ctx.identity_keyfile, omemo_ctx.identity_filename->str, &error)) {
|
if (!g_key_file_save_to_file(omemo_ctx.identity_keyfile, omemo_ctx.identity_filename->str, &error)) {
|
||||||
log_error("OMEMO: error saving identity to: %s, %s", omemo_ctx.identity_filename->str, error->message);
|
log_error("[OMEMO] error saving identity to: %s, %s", omemo_ctx.identity_filename->str, error->message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -570,7 +571,7 @@ omemo_trust_keyfile_save(void)
|
|||||||
GError* error = NULL;
|
GError* error = NULL;
|
||||||
|
|
||||||
if (!g_key_file_save_to_file(omemo_ctx.trust_keyfile, omemo_ctx.trust_filename->str, &error)) {
|
if (!g_key_file_save_to_file(omemo_ctx.trust_keyfile, omemo_ctx.trust_filename->str, &error)) {
|
||||||
log_error("OMEMO: error saving trust to: %s, %s", omemo_ctx.trust_filename->str, error->message);
|
log_error("[OMEMO] error saving trust to: %s, %s", omemo_ctx.trust_filename->str, error->message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -586,7 +587,7 @@ omemo_sessions_keyfile_save(void)
|
|||||||
GError* error = NULL;
|
GError* error = NULL;
|
||||||
|
|
||||||
if (!g_key_file_save_to_file(omemo_ctx.sessions_keyfile, omemo_ctx.sessions_filename->str, &error)) {
|
if (!g_key_file_save_to_file(omemo_ctx.sessions_keyfile, omemo_ctx.sessions_filename->str, &error)) {
|
||||||
log_error("OMEMO: error saving sessions to: %s, %s", omemo_ctx.sessions_filename->str, error->message);
|
log_error("[OMEMO] error saving sessions to: %s, %s", omemo_ctx.sessions_filename->str, error->message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -596,7 +597,7 @@ omemo_known_devices_keyfile_save(void)
|
|||||||
GError* error = NULL;
|
GError* error = NULL;
|
||||||
|
|
||||||
if (!g_key_file_save_to_file(omemo_ctx.known_devices_keyfile, omemo_ctx.known_devices_filename->str, &error)) {
|
if (!g_key_file_save_to_file(omemo_ctx.known_devices_keyfile, omemo_ctx.known_devices_filename->str, &error)) {
|
||||||
log_error("OMEMO: error saving known devices to: %s, %s", omemo_ctx.known_devices_filename->str, error->message);
|
log_error("[OMEMO] error saving known devices to: %s, %s", omemo_ctx.known_devices_filename->str, error->message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -636,7 +637,7 @@ omemo_start_device_session(const char* const jid, uint32_t device_id,
|
|||||||
session_builder* builder;
|
session_builder* builder;
|
||||||
res = session_builder_create(&builder, omemo_ctx.store, address, omemo_ctx.signal);
|
res = session_builder_create(&builder, omemo_ctx.store, address, omemo_ctx.signal);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
log_error("OMEMO: cannot create session builder for %s device %d", jid, device_id);
|
log_error("[OMEMO] cannot create session builder for %s device %d", jid, device_id);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -652,17 +653,17 @@ omemo_start_device_session(const char* const jid, uint32_t device_id,
|
|||||||
|
|
||||||
res = session_pre_key_bundle_create(&bundle, 0, device_id, prekey->id, prekey_public, signed_prekey_id, signed_prekey, signature, signature_len, identity_key);
|
res = session_pre_key_bundle_create(&bundle, 0, device_id, prekey->id, prekey_public, signed_prekey_id, signed_prekey, signature, signature_len, identity_key);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
log_error("OMEMO: cannot create pre key bundle for %s device %d", jid, device_id);
|
log_error("[OMEMO] cannot create pre key bundle for %s device %d", jid, device_id);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = session_builder_process_pre_key_bundle(builder, bundle);
|
res = session_builder_process_pre_key_bundle(builder, bundle);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
log_error("OMEMO: cannot process pre key bundle for %s device %d", jid, device_id);
|
log_error("[OMEMO] cannot process pre key bundle for %s device %d", jid, device_id);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_info("OMEMO: create session with %s device %d", jid, device_id);
|
log_info("[OMEMO] create session with %s device %d", jid, device_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@ -695,7 +696,7 @@ omemo_on_message_send(ProfWin* win, const char* const message, gboolean request_
|
|||||||
|
|
||||||
res = aes128gcm_encrypt(ciphertext, &ciphertext_len, tag, &tag_len, (const unsigned char* const)message, strlen(message), iv, key);
|
res = aes128gcm_encrypt(ciphertext, &ciphertext_len, tag, &tag_len, (const unsigned char* const)message, strlen(message), iv, key);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
log_error("OMEMO: cannot encrypt message");
|
log_error("[OMEMO] cannot encrypt message");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -729,7 +730,7 @@ omemo_on_message_send(ProfWin* win, const char* const message, gboolean request_
|
|||||||
GList* recipient_device_id = NULL;
|
GList* recipient_device_id = NULL;
|
||||||
recipient_device_id = g_hash_table_lookup(omemo_ctx.device_list, recipients_iter->data);
|
recipient_device_id = g_hash_table_lookup(omemo_ctx.device_list, recipients_iter->data);
|
||||||
if (!recipient_device_id) {
|
if (!recipient_device_id) {
|
||||||
log_warning("OMEMO: cannot find device ids for %s", recipients_iter->data);
|
log_warning("[OMEMO] cannot find device ids for %s", recipients_iter->data);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -745,14 +746,14 @@ omemo_on_message_send(ProfWin* win, const char* const message, gboolean request_
|
|||||||
|
|
||||||
res = session_cipher_create(&cipher, omemo_ctx.store, &address, omemo_ctx.signal);
|
res = session_cipher_create(&cipher, omemo_ctx.store, &address, omemo_ctx.signal);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
log_error("OMEMO: cannot create cipher for %s device id %d", address.name, address.device_id);
|
log_error("[OMEMO] cannot create cipher for %s device id %d", address.name, address.device_id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = session_cipher_encrypt(cipher, key_tag, AES128_GCM_KEY_LENGTH + AES128_GCM_TAG_LENGTH, &ciphertext);
|
res = session_cipher_encrypt(cipher, key_tag, AES128_GCM_KEY_LENGTH + AES128_GCM_TAG_LENGTH, &ciphertext);
|
||||||
session_cipher_free(cipher);
|
session_cipher_free(cipher);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
log_error("OMEMO: cannot encrypt key for %s device id %d", address.name, address.device_id);
|
log_error("[OMEMO] cannot encrypt key for %s device id %d", address.name, address.device_id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
signal_buffer* buffer = ciphertext_message_get_serialized(ciphertext);
|
signal_buffer* buffer = ciphertext_message_get_serialized(ciphertext);
|
||||||
@ -783,14 +784,14 @@ omemo_on_message_send(ProfWin* win, const char* const message, gboolean request_
|
|||||||
|
|
||||||
res = session_cipher_create(&cipher, omemo_ctx.store, &address, omemo_ctx.signal);
|
res = session_cipher_create(&cipher, omemo_ctx.store, &address, omemo_ctx.signal);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
log_error("OMEMO: cannot create cipher for %s device id %d", address.name, address.device_id);
|
log_error("[OMEMO] cannot create cipher for %s device id %d", address.name, address.device_id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = session_cipher_encrypt(cipher, key_tag, AES128_GCM_KEY_LENGTH + AES128_GCM_TAG_LENGTH, &ciphertext);
|
res = session_cipher_encrypt(cipher, key_tag, AES128_GCM_KEY_LENGTH + AES128_GCM_TAG_LENGTH, &ciphertext);
|
||||||
session_cipher_free(cipher);
|
session_cipher_free(cipher);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
log_error("OMEMO: cannot encrypt key for %s device id %d", address.name, address.device_id);
|
log_error("[OMEMO] cannot encrypt key for %s device id %d", address.name, address.device_id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
signal_buffer* buffer = ciphertext_message_get_serialized(ciphertext);
|
signal_buffer* buffer = ciphertext_message_get_serialized(ciphertext);
|
||||||
@ -851,7 +852,7 @@ omemo_on_message_recv(const char* const from_jid, uint32_t sid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!key) {
|
if (!key) {
|
||||||
log_warning("OMEMO: received a message with no corresponding key");
|
log_warning("[OMEMO] received a message with no corresponding key");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -867,7 +868,7 @@ omemo_on_message_recv(const char* const from_jid, uint32_t sid,
|
|||||||
}
|
}
|
||||||
g_list_free(roster);
|
g_list_free(roster);
|
||||||
if (!sender) {
|
if (!sender) {
|
||||||
log_warning("OMEMO: cannot find MUC message sender fulljid");
|
log_warning("[OMEMO] cannot find MUC message sender fulljid");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -884,12 +885,12 @@ omemo_on_message_recv(const char* const from_jid, uint32_t sid,
|
|||||||
|
|
||||||
res = session_cipher_create(&cipher, omemo_ctx.store, &address, omemo_ctx.signal);
|
res = session_cipher_create(&cipher, omemo_ctx.store, &address, omemo_ctx.signal);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
log_error("OMEMO: cannot create session cipher");
|
log_error("[OMEMO] cannot create session cipher");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key->prekey) {
|
if (key->prekey) {
|
||||||
log_debug("OMEMO: decrypting message with prekey");
|
log_debug("[OMEMO] decrypting message with prekey");
|
||||||
pre_key_signal_message* message;
|
pre_key_signal_message* message;
|
||||||
ec_public_key* their_identity_key;
|
ec_public_key* their_identity_key;
|
||||||
signal_buffer* identity_buffer = NULL;
|
signal_buffer* identity_buffer = NULL;
|
||||||
@ -925,13 +926,13 @@ omemo_on_message_recv(const char* const from_jid, uint32_t sid,
|
|||||||
omemo_bundle_request(sender->barejid, sid, omemo_start_device_session_handle_bundle, free, strdup(sender->barejid));
|
omemo_bundle_request(sender->barejid, sid, omemo_start_device_session_handle_bundle, free, strdup(sender->barejid));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log_debug("OMEMO: decrypting message with existing session");
|
log_debug("[OMEMO] decrypting message with existing session");
|
||||||
signal_message* message = NULL;
|
signal_message* message = NULL;
|
||||||
|
|
||||||
res = signal_message_deserialize(&message, key->data, key->length, omemo_ctx.signal);
|
res = signal_message_deserialize(&message, key->data, key->length, omemo_ctx.signal);
|
||||||
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
log_error("OMEMO: cannot deserialize message");
|
log_error("[OMEMO] cannot deserialize message");
|
||||||
} else {
|
} else {
|
||||||
res = session_cipher_decrypt_signal_message(cipher, message, NULL, &plaintext_key);
|
res = session_cipher_decrypt_signal_message(cipher, message, NULL, &plaintext_key);
|
||||||
*trusted = true;
|
*trusted = true;
|
||||||
@ -941,12 +942,12 @@ omemo_on_message_recv(const char* const from_jid, uint32_t sid,
|
|||||||
|
|
||||||
session_cipher_free(cipher);
|
session_cipher_free(cipher);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
log_error("OMEMO: cannot decrypt message key");
|
log_error("[OMEMO] cannot decrypt message key");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (signal_buffer_len(plaintext_key) != AES128_GCM_KEY_LENGTH + AES128_GCM_TAG_LENGTH) {
|
if (signal_buffer_len(plaintext_key) != AES128_GCM_KEY_LENGTH + AES128_GCM_TAG_LENGTH) {
|
||||||
log_error("OMEMO: invalid key length");
|
log_error("[OMEMO] invalid key length");
|
||||||
signal_buffer_free(plaintext_key);
|
signal_buffer_free(plaintext_key);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -958,7 +959,7 @@ omemo_on_message_recv(const char* const from_jid, uint32_t sid,
|
|||||||
signal_buffer_data(plaintext_key) + AES128_GCM_KEY_LENGTH);
|
signal_buffer_data(plaintext_key) + AES128_GCM_KEY_LENGTH);
|
||||||
signal_buffer_free(plaintext_key);
|
signal_buffer_free(plaintext_key);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
log_error("OMEMO: cannot decrypt message: %s", gcry_strerror(res));
|
log_error("[OMEMO] cannot decrypt message: %s", gcry_strerror(res));
|
||||||
free(plaintext);
|
free(plaintext);
|
||||||
plaintext = NULL;
|
plaintext = NULL;
|
||||||
goto out;
|
goto out;
|
||||||
@ -1132,7 +1133,7 @@ omemo_trust(const char* const jid, const char* const fingerprint_formatted)
|
|||||||
|
|
||||||
GHashTable* known_identities = g_hash_table_lookup(omemo_ctx.known_devices, jid);
|
GHashTable* known_identities = g_hash_table_lookup(omemo_ctx.known_devices, jid);
|
||||||
if (!known_identities) {
|
if (!known_identities) {
|
||||||
log_warning("OMEMO: cannot trust unknown device: %s", fingerprint_formatted);
|
log_warning("[OMEMO] cannot trust unknown device: %s", fingerprint_formatted);
|
||||||
cons_show("Cannot trust unknown device: %s", fingerprint_formatted);
|
cons_show("Cannot trust unknown device: %s", fingerprint_formatted);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1143,7 +1144,7 @@ omemo_trust(const char* const jid, const char* const fingerprint_formatted)
|
|||||||
free(fingerprint);
|
free(fingerprint);
|
||||||
|
|
||||||
if (!device_id) {
|
if (!device_id) {
|
||||||
log_warning("OMEMO: cannot trust unknown device: %s", fingerprint_formatted);
|
log_warning("[OMEMO] cannot trust unknown device: %s", fingerprint_formatted);
|
||||||
cons_show("Cannot trust unknown device: %s", fingerprint_formatted);
|
cons_show("Cannot trust unknown device: %s", fingerprint_formatted);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1200,13 +1201,13 @@ omemo_untrust(const char* const jid, const char* const fingerprint_formatted)
|
|||||||
/* Remove existing session */
|
/* Remove existing session */
|
||||||
GHashTable* known_identities = g_hash_table_lookup(omemo_ctx.known_devices, jid);
|
GHashTable* known_identities = g_hash_table_lookup(omemo_ctx.known_devices, jid);
|
||||||
if (!known_identities) {
|
if (!known_identities) {
|
||||||
log_error("OMEMO: cannot find known device while untrusting a fingerprint");
|
log_error("[OMEMO] cannot find known device while untrusting a fingerprint");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t device_id = GPOINTER_TO_INT(g_hash_table_lookup(known_identities, fingerprint));
|
uint32_t device_id = GPOINTER_TO_INT(g_hash_table_lookup(known_identities, fingerprint));
|
||||||
if (!device_id) {
|
if (!device_id) {
|
||||||
log_error("OMEMO: cannot find device id while untrusting a fingerprint");
|
log_error("[OMEMO] cannot find device id while untrusting a fingerprint");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
signal_protocol_address address = {
|
signal_protocol_address address = {
|
||||||
@ -1246,17 +1247,17 @@ _omemo_log(int level, const char* message, size_t len, void* user_data)
|
|||||||
{
|
{
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case SG_LOG_ERROR:
|
case SG_LOG_ERROR:
|
||||||
log_error("OMEMO: %s", message);
|
log_error("[OMEMO] %s", message);
|
||||||
break;
|
break;
|
||||||
case SG_LOG_WARNING:
|
case SG_LOG_WARNING:
|
||||||
log_warning("OMEMO: %s", message);
|
log_warning("[OMEMO] %s", message);
|
||||||
break;
|
break;
|
||||||
case SG_LOG_NOTICE:
|
case SG_LOG_NOTICE:
|
||||||
case SG_LOG_INFO:
|
case SG_LOG_INFO:
|
||||||
log_info("OMEMO: %s", message);
|
log_info("[OMEMO] %s", message);
|
||||||
break;
|
break;
|
||||||
case SG_LOG_DEBUG:
|
case SG_LOG_DEBUG:
|
||||||
log_debug("OMEMO: %s", message);
|
log_debug("[OMEMO] %s", message);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1393,16 +1394,16 @@ _load_identity(void)
|
|||||||
error = NULL;
|
error = NULL;
|
||||||
omemo_ctx.device_id = g_key_file_get_uint64(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_DEVICE_ID, &error);
|
omemo_ctx.device_id = g_key_file_get_uint64(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_DEVICE_ID, &error);
|
||||||
if (error != NULL) {
|
if (error != NULL) {
|
||||||
log_error("OMEMO: cannot load device id: %s", error->message);
|
log_error("[OMEMO] cannot load device id: %s", error->message);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
log_info("OMEMO: device id: %d", omemo_ctx.device_id);
|
log_info("[OMEMO] device id: %d", omemo_ctx.device_id);
|
||||||
|
|
||||||
/* Registration ID */
|
/* Registration ID */
|
||||||
error = NULL;
|
error = NULL;
|
||||||
omemo_ctx.registration_id = g_key_file_get_uint64(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_REGISTRATION_ID, &error);
|
omemo_ctx.registration_id = g_key_file_get_uint64(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_REGISTRATION_ID, &error);
|
||||||
if (error != NULL) {
|
if (error != NULL) {
|
||||||
log_error("OMEMO: cannot load registration id: %s", error->message);
|
log_error("[OMEMO] cannot load registration id: %s", error->message);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1410,7 +1411,7 @@ _load_identity(void)
|
|||||||
error = NULL;
|
error = NULL;
|
||||||
char* identity_key_public_b64 = g_key_file_get_string(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_IDENTITY_KEY_PUBLIC, &error);
|
char* identity_key_public_b64 = g_key_file_get_string(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_IDENTITY_KEY_PUBLIC, &error);
|
||||||
if (!identity_key_public_b64) {
|
if (!identity_key_public_b64) {
|
||||||
log_error("OMEMO: cannot load identity public key: %s", error->message);
|
log_error("[OMEMO] cannot load identity public key: %s", error->message);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1422,7 +1423,7 @@ _load_identity(void)
|
|||||||
error = NULL;
|
error = NULL;
|
||||||
char* identity_key_private_b64 = g_key_file_get_string(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_IDENTITY_KEY_PRIVATE, &error);
|
char* identity_key_private_b64 = g_key_file_get_string(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_IDENTITY_KEY_PRIVATE, &error);
|
||||||
if (!identity_key_private_b64) {
|
if (!identity_key_private_b64) {
|
||||||
log_error("OMEMO: cannot load identity private key: %s", error->message);
|
log_error("[OMEMO] cannot load identity private key: %s", error->message);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1599,7 +1600,7 @@ _cache_device_identity(const char* const jid, uint32_t device_id, ec_public_key*
|
|||||||
}
|
}
|
||||||
|
|
||||||
char* fingerprint = _omemo_fingerprint(identity, FALSE);
|
char* fingerprint = _omemo_fingerprint(identity, FALSE);
|
||||||
log_info("OMEMO: cache identity for %s:%d: %s", jid, device_id, fingerprint);
|
log_info("[OMEMO] cache identity for %s:%d: %s", jid, device_id, fingerprint);
|
||||||
g_hash_table_insert(known_identities, strdup(fingerprint), GINT_TO_POINTER(device_id));
|
g_hash_table_insert(known_identities, strdup(fingerprint), GINT_TO_POINTER(device_id));
|
||||||
|
|
||||||
char* device_id_str = g_strdup_printf("%d", device_id);
|
char* device_id_str = g_strdup_printf("%d", device_id);
|
||||||
|
@ -454,6 +454,7 @@ connection_get_barejid(void)
|
|||||||
void
|
void
|
||||||
connection_features_received(const char* const jid)
|
connection_features_received(const char* const jid)
|
||||||
{
|
{
|
||||||
|
log_info("[CONNECTION] connection_features_received %s", jid);
|
||||||
if (g_hash_table_remove(conn.requested_features, jid) && g_hash_table_size(conn.requested_features) == 0) {
|
if (g_hash_table_remove(conn.requested_features, jid) && g_hash_table_size(conn.requested_features) == 0) {
|
||||||
sv_ev_connection_features_received();
|
sv_ev_connection_features_received();
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,8 @@ omemo_devicelist_publish(GList* device_list)
|
|||||||
xmpp_ctx_t* const ctx = connection_get_ctx();
|
xmpp_ctx_t* const ctx = connection_get_ctx();
|
||||||
xmpp_stanza_t* iq = stanza_create_omemo_devicelist_publish(ctx, device_list);
|
xmpp_stanza_t* iq = stanza_create_omemo_devicelist_publish(ctx, device_list);
|
||||||
|
|
||||||
|
log_info("[OMEMO] publish device list");
|
||||||
|
|
||||||
if (connection_supports(XMPP_FEATURE_PUBSUB_PUBLISH_OPTIONS)) {
|
if (connection_supports(XMPP_FEATURE_PUBSUB_PUBLISH_OPTIONS)) {
|
||||||
stanza_attach_publish_options(ctx, iq, "pubsub#access_model", "open");
|
stanza_attach_publish_options(ctx, iq, "pubsub#access_model", "open");
|
||||||
}
|
}
|
||||||
@ -77,6 +79,8 @@ omemo_devicelist_request(const char* const jid)
|
|||||||
xmpp_ctx_t* const ctx = connection_get_ctx();
|
xmpp_ctx_t* const ctx = connection_get_ctx();
|
||||||
char* id = connection_create_stanza_id();
|
char* id = connection_create_stanza_id();
|
||||||
|
|
||||||
|
log_info("[OMEMO] request device list for jid: %s", jid);
|
||||||
|
|
||||||
xmpp_stanza_t* iq = stanza_create_omemo_devicelist_request(ctx, id, jid);
|
xmpp_stanza_t* iq = stanza_create_omemo_devicelist_request(ctx, id, jid);
|
||||||
iq_id_handler_add(id, _omemo_receive_devicelist, NULL, NULL);
|
iq_id_handler_add(id, _omemo_receive_devicelist, NULL, NULL);
|
||||||
|
|
||||||
@ -89,6 +93,7 @@ omemo_devicelist_request(const char* const jid)
|
|||||||
void
|
void
|
||||||
omemo_bundle_publish(gboolean first)
|
omemo_bundle_publish(gboolean first)
|
||||||
{
|
{
|
||||||
|
log_info("[OMEMO] publish own OMEMO bundle");
|
||||||
xmpp_ctx_t* const ctx = connection_get_ctx();
|
xmpp_ctx_t* const ctx = connection_get_ctx();
|
||||||
unsigned char* identity_key = NULL;
|
unsigned char* identity_key = NULL;
|
||||||
size_t identity_key_length;
|
size_t identity_key_length;
|
||||||
@ -114,7 +119,10 @@ omemo_bundle_publish(gboolean first)
|
|||||||
g_list_free(ids);
|
g_list_free(ids);
|
||||||
|
|
||||||
if (connection_supports(XMPP_FEATURE_PUBSUB_PUBLISH_OPTIONS)) {
|
if (connection_supports(XMPP_FEATURE_PUBSUB_PUBLISH_OPTIONS)) {
|
||||||
stanza_attach_publish_options(ctx, iq, "pubsub#access_model", "open");
|
stanza_attach_publish_options_va(ctx, iq,
|
||||||
|
4, // 2 * number of key-value pairs
|
||||||
|
"pubsub#persist_items", "true",
|
||||||
|
"pubsub#access_model", "open");
|
||||||
}
|
}
|
||||||
|
|
||||||
iq_id_handler_add(id, _omemo_bundle_publish_result, NULL, GINT_TO_POINTER(first));
|
iq_id_handler_add(id, _omemo_bundle_publish_result, NULL, GINT_TO_POINTER(first));
|
||||||
@ -134,6 +142,8 @@ omemo_bundle_request(const char* const jid, uint32_t device_id, ProfIqCallback f
|
|||||||
xmpp_ctx_t* const ctx = connection_get_ctx();
|
xmpp_ctx_t* const ctx = connection_get_ctx();
|
||||||
char* id = connection_create_stanza_id();
|
char* id = connection_create_stanza_id();
|
||||||
|
|
||||||
|
log_info("[OMEMO] request omemo bundle (jid: %s, deivce: %d)", jid, device_id);
|
||||||
|
|
||||||
xmpp_stanza_t* iq = stanza_create_omemo_bundle_request(ctx, id, jid, device_id);
|
xmpp_stanza_t* iq = stanza_create_omemo_bundle_request(ctx, id, jid, device_id);
|
||||||
iq_id_handler_add(id, func, free_func, userdata);
|
iq_id_handler_add(id, func, free_func, userdata);
|
||||||
|
|
||||||
@ -459,7 +469,7 @@ _omemo_receive_devicelist(xmpp_stanza_t* const stanza, void* const userdata)
|
|||||||
if (current) {
|
if (current) {
|
||||||
item = current;
|
item = current;
|
||||||
} else if (first) {
|
} else if (first) {
|
||||||
log_warning("OMEMO: User %s has a non 'current' device item list: %s.", from, xmpp_stanza_get_id(first));
|
log_warning("[OMEMO] User %s has a non 'current' device item list: %s.", from, xmpp_stanza_get_id(first));
|
||||||
item = first;
|
item = first;
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return 1;
|
||||||
@ -480,7 +490,7 @@ _omemo_receive_devicelist(xmpp_stanza_t* const stanza, void* const userdata)
|
|||||||
if (id != NULL) {
|
if (id != NULL) {
|
||||||
device_list = g_list_append(device_list, GINT_TO_POINTER(strtoul(id, NULL, 10)));
|
device_list = g_list_append(device_list, GINT_TO_POINTER(strtoul(id, NULL, 10)));
|
||||||
} else {
|
} else {
|
||||||
log_error("OMEMO: received device without ID");
|
log_error("[OMEMO] received device without ID");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -489,25 +499,31 @@ _omemo_receive_devicelist(xmpp_stanza_t* const stanza, void* const userdata)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_omemo_bundle_publish_result(xmpp_stanza_t* const stanza, void* const userdata)
|
_omemo_bundle_publish_result(xmpp_stanza_t* const stanza, void* const userdata)
|
||||||
{
|
{
|
||||||
|
log_debug("[OMEMO] _omemo_bundle_publish_result()");
|
||||||
|
|
||||||
const char* type = xmpp_stanza_get_type(stanza);
|
const char* type = xmpp_stanza_get_type(stanza);
|
||||||
|
|
||||||
if (g_strcmp0(type, STANZA_TYPE_ERROR) != 0) {
|
if (g_strcmp0(type, STANZA_TYPE_RESULT) == 0) {
|
||||||
|
log_info("[OMEMO] bundle published successfully");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GPOINTER_TO_INT(userdata)) {
|
if (!GPOINTER_TO_INT(userdata)) {
|
||||||
log_error("OMEMO: definitely cannot publish bundle with an open access model");
|
log_error("[OMEMO] definitely cannot publish bundle with an open access model");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_info("OMEMO: cannot publish bundle with open access model, trying to configure node");
|
log_info("[OMEMO] cannot publish bundle with open access model, trying to configure node");
|
||||||
xmpp_ctx_t* const ctx = connection_get_ctx();
|
xmpp_ctx_t* const ctx = connection_get_ctx();
|
||||||
Jid* jid = jid_create(connection_get_fulljid());
|
Jid* jid = jid_create(connection_get_fulljid());
|
||||||
char* id = connection_create_stanza_id();
|
char* id = connection_create_stanza_id();
|
||||||
char* node = g_strdup_printf("%s:%d", STANZA_NS_OMEMO_BUNDLES, omemo_device_id());
|
char* node = g_strdup_printf("%s:%d", STANZA_NS_OMEMO_BUNDLES, omemo_device_id());
|
||||||
|
log_info("[OMEMO] node: %s", node);
|
||||||
|
|
||||||
xmpp_stanza_t* iq = stanza_create_pubsub_configure_request(ctx, id, jid->barejid, node);
|
xmpp_stanza_t* iq = stanza_create_pubsub_configure_request(ctx, id, jid->barejid, node);
|
||||||
g_free(node);
|
g_free(node);
|
||||||
|
|
||||||
@ -524,18 +540,30 @@ _omemo_bundle_publish_result(xmpp_stanza_t* const stanza, void* const userdata)
|
|||||||
static int
|
static int
|
||||||
_omemo_bundle_publish_configure(xmpp_stanza_t* const stanza, void* const userdata)
|
_omemo_bundle_publish_configure(xmpp_stanza_t* const stanza, void* const userdata)
|
||||||
{
|
{
|
||||||
/* TODO handle error */
|
log_debug("[OMEMO] _omemo_bundle_publish_configure()");
|
||||||
|
|
||||||
xmpp_stanza_t* pubsub = xmpp_stanza_get_child_by_name(stanza, "pubsub");
|
xmpp_stanza_t* pubsub = xmpp_stanza_get_child_by_name(stanza, "pubsub");
|
||||||
|
if (!pubsub) {
|
||||||
|
log_error("[OMEMO] The stanza doesn't contain a 'pubsub' child");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
xmpp_stanza_t* configure = xmpp_stanza_get_child_by_name(pubsub, STANZA_NAME_CONFIGURE);
|
xmpp_stanza_t* configure = xmpp_stanza_get_child_by_name(pubsub, STANZA_NAME_CONFIGURE);
|
||||||
|
if (!configure) {
|
||||||
|
log_error("[OMEMO] The stanza doesn't contain a 'configure' child");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
xmpp_stanza_t* x = xmpp_stanza_get_child_by_name(configure, "x");
|
xmpp_stanza_t* x = xmpp_stanza_get_child_by_name(configure, "x");
|
||||||
|
if (!x) {
|
||||||
|
log_error("[OMEMO] The stanza doesn't contain an 'x' child");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
DataForm* form = form_create(x);
|
DataForm* form = form_create(x);
|
||||||
char* tag = g_hash_table_lookup(form->var_to_tag, "pubsub#access_model");
|
char* tag = g_hash_table_lookup(form->var_to_tag, "pubsub#access_model");
|
||||||
if (!tag) {
|
if (!tag) {
|
||||||
log_info("OMEMO: cannot configure bundle to an open access model");
|
log_error("[OMEMO] cannot configure bundle to an open access model");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
form_set_value(form, tag, "open");
|
|
||||||
|
|
||||||
xmpp_ctx_t* const ctx = connection_get_ctx();
|
xmpp_ctx_t* const ctx = connection_get_ctx();
|
||||||
Jid* jid = jid_create(connection_get_fulljid());
|
Jid* jid = jid_create(connection_get_fulljid());
|
||||||
@ -560,10 +588,13 @@ _omemo_bundle_publish_configure_result(xmpp_stanza_t* const stanza, void* const
|
|||||||
const char* type = xmpp_stanza_get_type(stanza);
|
const char* type = xmpp_stanza_get_type(stanza);
|
||||||
|
|
||||||
if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
|
if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
|
||||||
log_error("OMEMO: cannot configure bundle to an open access model");
|
log_error("[OMEMO] cannot configure bundle to an open access model: Result error");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log_info("[OMEMO] node configured");
|
||||||
|
|
||||||
|
// Try to publish again
|
||||||
omemo_bundle_publish(TRUE);
|
omemo_bundle_publish(TRUE);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1940,8 +1940,9 @@ stanza_get_error_message(xmpp_stanza_t* stanza)
|
|||||||
return strdup("unknown");
|
return strdup("unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note that the `count' must be 2 * number of key/value pairs
|
||||||
void
|
void
|
||||||
stanza_attach_publish_options(xmpp_ctx_t* const ctx, xmpp_stanza_t* const iq, const char* const option, const char* const value)
|
stanza_attach_publish_options_va(xmpp_ctx_t* const ctx, xmpp_stanza_t* const iq, int count, ...)
|
||||||
{
|
{
|
||||||
xmpp_stanza_t* publish_options = xmpp_stanza_new(ctx);
|
xmpp_stanza_t* publish_options = xmpp_stanza_new(ctx);
|
||||||
xmpp_stanza_set_name(publish_options, STANZA_NAME_PUBLISH_OPTIONS);
|
xmpp_stanza_set_name(publish_options, STANZA_NAME_PUBLISH_OPTIONS);
|
||||||
@ -1964,23 +1965,34 @@ stanza_attach_publish_options(xmpp_ctx_t* const ctx, xmpp_stanza_t* const iq, co
|
|||||||
xmpp_stanza_add_child(form_type, form_type_value);
|
xmpp_stanza_add_child(form_type, form_type_value);
|
||||||
xmpp_stanza_add_child(x, form_type);
|
xmpp_stanza_add_child(x, form_type);
|
||||||
|
|
||||||
xmpp_stanza_t* access_model = xmpp_stanza_new(ctx);
|
|
||||||
xmpp_stanza_set_name(access_model, STANZA_NAME_FIELD);
|
|
||||||
xmpp_stanza_set_attribute(access_model, STANZA_ATTR_VAR, option);
|
|
||||||
xmpp_stanza_t* access_model_value = xmpp_stanza_new(ctx);
|
|
||||||
xmpp_stanza_set_name(access_model_value, STANZA_NAME_VALUE);
|
|
||||||
xmpp_stanza_t* access_model_value_text = xmpp_stanza_new(ctx);
|
|
||||||
xmpp_stanza_set_text(access_model_value_text, value);
|
|
||||||
xmpp_stanza_add_child(access_model_value, access_model_value_text);
|
|
||||||
xmpp_stanza_add_child(access_model, access_model_value);
|
|
||||||
xmpp_stanza_add_child(x, access_model);
|
|
||||||
|
|
||||||
xmpp_stanza_t* pubsub = xmpp_stanza_get_child_by_ns(iq, STANZA_NS_PUBSUB);
|
xmpp_stanza_t* pubsub = xmpp_stanza_get_child_by_ns(iq, STANZA_NS_PUBSUB);
|
||||||
xmpp_stanza_add_child(pubsub, publish_options);
|
xmpp_stanza_add_child(pubsub, publish_options);
|
||||||
|
|
||||||
xmpp_stanza_release(access_model_value_text);
|
va_list ap;
|
||||||
xmpp_stanza_release(access_model_value);
|
va_start(ap, count);
|
||||||
xmpp_stanza_release(access_model);
|
int j;
|
||||||
|
for (j = 0; j < count; j += 2) {
|
||||||
|
const char* const option = va_arg(ap, char* const);
|
||||||
|
const char* const value = va_arg(ap, char* const);
|
||||||
|
|
||||||
|
xmpp_stanza_t* field = xmpp_stanza_new(ctx);
|
||||||
|
xmpp_stanza_set_name(field, STANZA_NAME_FIELD);
|
||||||
|
xmpp_stanza_set_attribute(field, STANZA_ATTR_VAR, option);
|
||||||
|
xmpp_stanza_t* field_value = xmpp_stanza_new(ctx);
|
||||||
|
xmpp_stanza_set_name(field_value, STANZA_NAME_VALUE);
|
||||||
|
xmpp_stanza_t* field_value_text = xmpp_stanza_new(ctx);
|
||||||
|
xmpp_stanza_set_text(field_value_text, value);
|
||||||
|
xmpp_stanza_add_child(field_value, field_value_text);
|
||||||
|
xmpp_stanza_add_child(field, field_value);
|
||||||
|
xmpp_stanza_add_child(x, field);
|
||||||
|
|
||||||
|
xmpp_stanza_release(field_value_text);
|
||||||
|
xmpp_stanza_release(field_value);
|
||||||
|
xmpp_stanza_release(field);
|
||||||
|
}
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
|
||||||
xmpp_stanza_release(form_type_value_text);
|
xmpp_stanza_release(form_type_value_text);
|
||||||
xmpp_stanza_release(form_type_value);
|
xmpp_stanza_release(form_type_value);
|
||||||
xmpp_stanza_release(form_type);
|
xmpp_stanza_release(form_type);
|
||||||
@ -1988,6 +2000,13 @@ stanza_attach_publish_options(xmpp_ctx_t* const ctx, xmpp_stanza_t* const iq, co
|
|||||||
xmpp_stanza_release(publish_options);
|
xmpp_stanza_release(publish_options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
stanza_attach_publish_options(xmpp_ctx_t* const ctx, xmpp_stanza_t* const iq, const char* const option, const char* const value)
|
||||||
|
{
|
||||||
|
stanza_attach_publish_options_va(ctx, iq, 2, option, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
stanza_attach_priority(xmpp_ctx_t* const ctx, xmpp_stanza_t* const presence, const int pri)
|
stanza_attach_priority(xmpp_ctx_t* const ctx, xmpp_stanza_t* const presence, const int pri)
|
||||||
{
|
{
|
||||||
|
@ -326,7 +326,9 @@ xmpp_stanza_t* stanza_create_room_kick_iq(xmpp_ctx_t* const ctx, const char* con
|
|||||||
xmpp_stanza_t* stanza_create_command_exec_iq(xmpp_ctx_t* ctx, const char* const target, const char* const node);
|
xmpp_stanza_t* stanza_create_command_exec_iq(xmpp_ctx_t* ctx, const char* const target, const char* const node);
|
||||||
xmpp_stanza_t* stanza_create_command_config_submit_iq(xmpp_ctx_t* ctx, const char* const room, const char* const node, const char* const sessionid, DataForm* form);
|
xmpp_stanza_t* stanza_create_command_config_submit_iq(xmpp_ctx_t* ctx, const char* const room, const char* const node, const char* const sessionid, DataForm* form);
|
||||||
|
|
||||||
void stanza_attach_publish_options(xmpp_ctx_t* const ctx, xmpp_stanza_t* const publish, const char* const option, const char* const value);
|
void stanza_attach_publish_options_va(xmpp_ctx_t* const ctx, xmpp_stanza_t* const iq, int count, ...);
|
||||||
|
void stanza_attach_publish_options(xmpp_ctx_t* const ctx, xmpp_stanza_t* const iq, const char* const option, const char* const value);
|
||||||
|
|
||||||
|
|
||||||
xmpp_stanza_t* stanza_create_omemo_devicelist_request(xmpp_ctx_t* ctx, const char* const id, const char* const jid);
|
xmpp_stanza_t* stanza_create_omemo_devicelist_request(xmpp_ctx_t* ctx, const char* const id, const char* const jid);
|
||||||
xmpp_stanza_t* stanza_create_omemo_devicelist_subscribe(xmpp_ctx_t* ctx, const char* const jid);
|
xmpp_stanza_t* stanza_create_omemo_devicelist_subscribe(xmpp_ctx_t* ctx, const char* const jid);
|
||||||
|
Loading…
Reference in New Issue
Block a user