mirror of
https://github.com/profanity-im/profanity.git
synced 2025-02-02 15:08:15 -05:00
commit
9a1311a826
@ -22,6 +22,7 @@ AlignOperands: true
|
|||||||
AlignTrailingComments: true
|
AlignTrailingComments: true
|
||||||
AllowAllArgumentsOnNextLine: true
|
AllowAllArgumentsOnNextLine: true
|
||||||
AllowShortBlocksOnASingleLine: true
|
AllowShortBlocksOnASingleLine: true
|
||||||
|
IndentGotoLabels: false
|
||||||
IndentWidth: 4
|
IndentWidth: 4
|
||||||
BreakBeforeBraces: Custom
|
BreakBeforeBraces: Custom
|
||||||
BraceWrapping:
|
BraceWrapping:
|
||||||
|
@ -1144,7 +1144,7 @@ cmd_export(ProfWin* window, const char* const command, gchar** args)
|
|||||||
g_slist_free(list);
|
g_slist_free(list);
|
||||||
close(fd);
|
close(fd);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
write_error:
|
write_error:
|
||||||
cons_show("error: write failed: %s", strerror(errno));
|
cons_show("error: write failed: %s", strerror(errno));
|
||||||
cons_show("");
|
cons_show("");
|
||||||
g_slist_free(list);
|
g_slist_free(list);
|
||||||
|
@ -178,7 +178,7 @@ _log_database_add_outgoing(char* type, const char* const id, const char* const b
|
|||||||
msg->from_jid = jid_create(barejid);
|
msg->from_jid = jid_create(barejid);
|
||||||
msg->plain = message ? strdup(message) : NULL;
|
msg->plain = message ? strdup(message) : NULL;
|
||||||
msg->replace_id = replace_id ? strdup(replace_id) : NULL;
|
msg->replace_id = replace_id ? strdup(replace_id) : NULL;
|
||||||
msg->timestamp = g_date_time_new_now_local(); //TODO: get from outside. best to have whole ProfMessage from outside
|
msg->timestamp = g_date_time_new_now_local(); // TODO: get from outside. best to have whole ProfMessage from outside
|
||||||
msg->enc = enc;
|
msg->enc = enc;
|
||||||
|
|
||||||
Jid* myjid = jid_create(connection_get_fulljid());
|
Jid* myjid = jid_create(connection_get_fulljid());
|
||||||
|
@ -522,7 +522,7 @@ _sv_ev_incoming_ox(ProfChatWin* chatwin, gboolean new_win, ProfMessage* message,
|
|||||||
chat_log_pgp_msg_in(message);
|
chat_log_pgp_msg_in(message);
|
||||||
}
|
}
|
||||||
chatwin->pgp_recv = TRUE;
|
chatwin->pgp_recv = TRUE;
|
||||||
//p_gpg_free_decrypted(message->plain);
|
// p_gpg_free_decrypted(message->plain);
|
||||||
message->plain = NULL;
|
message->plain = NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -43,110 +43,110 @@
|
|||||||
|
|
||||||
int omemo_crypto_init(void);
|
int omemo_crypto_init(void);
|
||||||
/**
|
/**
|
||||||
* Callback for a secure random number generator.
|
* Callback for a secure random number generator.
|
||||||
* This function shall fill the provided buffer with random bytes.
|
* This function shall fill the provided buffer with random bytes.
|
||||||
*
|
*
|
||||||
* @param data pointer to the output buffer
|
* @param data pointer to the output buffer
|
||||||
* @param len size of the output buffer
|
* @param len size of the output buffer
|
||||||
* @return 0 on success, negative on failure
|
* @return 0 on success, negative on failure
|
||||||
*/
|
*/
|
||||||
int omemo_random_func(uint8_t* data, size_t len, void* user_data);
|
int omemo_random_func(uint8_t* data, size_t len, void* user_data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for an HMAC-SHA256 implementation.
|
* Callback for an HMAC-SHA256 implementation.
|
||||||
* This function shall initialize an HMAC context with the provided key.
|
* This function shall initialize an HMAC context with the provided key.
|
||||||
*
|
*
|
||||||
* @param hmac_context private HMAC context pointer
|
* @param hmac_context private HMAC context pointer
|
||||||
* @param key pointer to the key
|
* @param key pointer to the key
|
||||||
* @param key_len length of the key
|
* @param key_len length of the key
|
||||||
* @return 0 on success, negative on failure
|
* @return 0 on success, negative on failure
|
||||||
*/
|
*/
|
||||||
int omemo_hmac_sha256_init_func(void** hmac_context, const uint8_t* key, size_t key_len, void* user_data);
|
int omemo_hmac_sha256_init_func(void** hmac_context, const uint8_t* key, size_t key_len, void* user_data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for an HMAC-SHA256 implementation.
|
* Callback for an HMAC-SHA256 implementation.
|
||||||
* This function shall update the HMAC context with the provided data
|
* This function shall update the HMAC context with the provided data
|
||||||
*
|
*
|
||||||
* @param hmac_context private HMAC context pointer
|
* @param hmac_context private HMAC context pointer
|
||||||
* @param data pointer to the data
|
* @param data pointer to the data
|
||||||
* @param data_len length of the data
|
* @param data_len length of the data
|
||||||
* @return 0 on success, negative on failure
|
* @return 0 on success, negative on failure
|
||||||
*/
|
*/
|
||||||
int omemo_hmac_sha256_update_func(void* hmac_context, const uint8_t* data, size_t data_len, void* user_data);
|
int omemo_hmac_sha256_update_func(void* hmac_context, const uint8_t* data, size_t data_len, void* user_data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for an HMAC-SHA256 implementation.
|
* Callback for an HMAC-SHA256 implementation.
|
||||||
* This function shall finalize an HMAC calculation and populate the output
|
* This function shall finalize an HMAC calculation and populate the output
|
||||||
* buffer with the result.
|
* buffer with the result.
|
||||||
*
|
*
|
||||||
* @param hmac_context private HMAC context pointer
|
* @param hmac_context private HMAC context pointer
|
||||||
* @param output buffer to be allocated and populated with the result
|
* @param output buffer to be allocated and populated with the result
|
||||||
* @return 0 on success, negative on failure
|
* @return 0 on success, negative on failure
|
||||||
*/
|
*/
|
||||||
int omemo_hmac_sha256_final_func(void* hmac_context, signal_buffer** output, void* user_data);
|
int omemo_hmac_sha256_final_func(void* hmac_context, signal_buffer** output, void* user_data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for an HMAC-SHA256 implementation.
|
* Callback for an HMAC-SHA256 implementation.
|
||||||
* This function shall free the private context allocated in
|
* This function shall free the private context allocated in
|
||||||
* hmac_sha256_init_func.
|
* hmac_sha256_init_func.
|
||||||
*
|
*
|
||||||
* @param hmac_context private HMAC context pointer
|
* @param hmac_context private HMAC context pointer
|
||||||
*/
|
*/
|
||||||
void omemo_hmac_sha256_cleanup_func(void* hmac_context, void* user_data);
|
void omemo_hmac_sha256_cleanup_func(void* hmac_context, void* user_data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for a SHA512 message digest implementation.
|
* Callback for a SHA512 message digest implementation.
|
||||||
* This function shall initialize a digest context.
|
* This function shall initialize a digest context.
|
||||||
*
|
*
|
||||||
* @param digest_context private digest context pointer
|
* @param digest_context private digest context pointer
|
||||||
* @return 0 on success, negative on failure
|
* @return 0 on success, negative on failure
|
||||||
*/
|
*/
|
||||||
int omemo_sha512_digest_init_func(void** digest_context, void* user_data);
|
int omemo_sha512_digest_init_func(void** digest_context, void* user_data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for a SHA512 message digest implementation.
|
* Callback for a SHA512 message digest implementation.
|
||||||
* This function shall update the digest context with the provided data.
|
* This function shall update the digest context with the provided data.
|
||||||
*
|
*
|
||||||
* @param digest_context private digest context pointer
|
* @param digest_context private digest context pointer
|
||||||
* @param data pointer to the data
|
* @param data pointer to the data
|
||||||
* @param data_len length of the data
|
* @param data_len length of the data
|
||||||
* @return 0 on success, negative on failure
|
* @return 0 on success, negative on failure
|
||||||
*/
|
*/
|
||||||
int omemo_sha512_digest_update_func(void* digest_context, const uint8_t* data, size_t data_len, void* user_data);
|
int omemo_sha512_digest_update_func(void* digest_context, const uint8_t* data, size_t data_len, void* user_data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for a SHA512 message digest implementation.
|
* Callback for a SHA512 message digest implementation.
|
||||||
* This function shall finalize the digest calculation, populate the
|
* This function shall finalize the digest calculation, populate the
|
||||||
* output buffer with the result, and prepare the context for reuse.
|
* output buffer with the result, and prepare the context for reuse.
|
||||||
*
|
*
|
||||||
* @param digest_context private digest context pointer
|
* @param digest_context private digest context pointer
|
||||||
* @param output buffer to be allocated and populated with the result
|
* @param output buffer to be allocated and populated with the result
|
||||||
* @return 0 on success, negative on failure
|
* @return 0 on success, negative on failure
|
||||||
*/
|
*/
|
||||||
int omemo_sha512_digest_final_func(void* digest_context, signal_buffer** output, void* user_data);
|
int omemo_sha512_digest_final_func(void* digest_context, signal_buffer** output, void* user_data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for a SHA512 message digest implementation.
|
* Callback for a SHA512 message digest implementation.
|
||||||
* This function shall free the private context allocated in
|
* This function shall free the private context allocated in
|
||||||
* sha512_digest_init_func.
|
* sha512_digest_init_func.
|
||||||
*
|
*
|
||||||
* @param digest_context private digest context pointer
|
* @param digest_context private digest context pointer
|
||||||
*/
|
*/
|
||||||
void omemo_sha512_digest_cleanup_func(void* digest_context, void* user_data);
|
void omemo_sha512_digest_cleanup_func(void* digest_context, void* user_data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for an AES encryption implementation.
|
* Callback for an AES encryption implementation.
|
||||||
*
|
*
|
||||||
* @param output buffer to be allocated and populated with the ciphertext
|
* @param output buffer to be allocated and populated with the ciphertext
|
||||||
* @param cipher specific cipher variant to use, either SG_CIPHER_AES_CTR_NOPADDING or SG_CIPHER_AES_CBC_PKCS5
|
* @param cipher specific cipher variant to use, either SG_CIPHER_AES_CTR_NOPADDING or SG_CIPHER_AES_CBC_PKCS5
|
||||||
* @param key the encryption key
|
* @param key the encryption key
|
||||||
* @param key_len length of the encryption key
|
* @param key_len length of the encryption key
|
||||||
* @param iv the initialization vector
|
* @param iv the initialization vector
|
||||||
* @param iv_len length of the initialization vector
|
* @param iv_len length of the initialization vector
|
||||||
* @param plaintext the plaintext to encrypt
|
* @param plaintext the plaintext to encrypt
|
||||||
* @param plaintext_len length of the plaintext
|
* @param plaintext_len length of the plaintext
|
||||||
* @return 0 on success, negative on failure
|
* @return 0 on success, negative on failure
|
||||||
*/
|
*/
|
||||||
int omemo_encrypt_func(signal_buffer** output,
|
int omemo_encrypt_func(signal_buffer** output,
|
||||||
int cipher,
|
int cipher,
|
||||||
const uint8_t* key, size_t key_len,
|
const uint8_t* key, size_t key_len,
|
||||||
@ -155,18 +155,18 @@ int omemo_encrypt_func(signal_buffer** output,
|
|||||||
void* user_data);
|
void* user_data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for an AES decryption implementation.
|
* Callback for an AES decryption implementation.
|
||||||
*
|
*
|
||||||
* @param output buffer to be allocated and populated with the plaintext
|
* @param output buffer to be allocated and populated with the plaintext
|
||||||
* @param cipher specific cipher variant to use, either SG_CIPHER_AES_CTR_NOPADDING or SG_CIPHER_AES_CBC_PKCS5
|
* @param cipher specific cipher variant to use, either SG_CIPHER_AES_CTR_NOPADDING or SG_CIPHER_AES_CBC_PKCS5
|
||||||
* @param key the encryption key
|
* @param key the encryption key
|
||||||
* @param key_len length of the encryption key
|
* @param key_len length of the encryption key
|
||||||
* @param iv the initialization vector
|
* @param iv the initialization vector
|
||||||
* @param iv_len length of the initialization vector
|
* @param iv_len length of the initialization vector
|
||||||
* @param ciphertext the ciphertext to decrypt
|
* @param ciphertext the ciphertext to decrypt
|
||||||
* @param ciphertext_len length of the ciphertext
|
* @param ciphertext_len length of the ciphertext
|
||||||
* @return 0 on success, negative on failure
|
* @return 0 on success, negative on failure
|
||||||
*/
|
*/
|
||||||
int omemo_decrypt_func(signal_buffer** output,
|
int omemo_decrypt_func(signal_buffer** output,
|
||||||
int cipher,
|
int cipher,
|
||||||
const uint8_t* key, size_t key_len,
|
const uint8_t* key, size_t key_len,
|
||||||
|
@ -388,7 +388,9 @@ omemo_publish_crypto_materials(void)
|
|||||||
omemo_bundle_publish(true);
|
omemo_bundle_publish(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _acquire_sender_devices_list(void) {
|
static void
|
||||||
|
_acquire_sender_devices_list(void)
|
||||||
|
{
|
||||||
char* barejid = connection_get_barejid();
|
char* barejid = connection_get_barejid();
|
||||||
|
|
||||||
g_hash_table_insert(omemo_ctx.device_list_handler, strdup(barejid), _handle_own_device_list);
|
g_hash_table_insert(omemo_ctx.device_list_handler, strdup(barejid), _handle_own_device_list);
|
||||||
|
@ -292,7 +292,7 @@ otr_on_message_recv(const char* const barejid, const char* const resource, const
|
|||||||
prof_otrpolicy_t policy = otr_get_policy(barejid);
|
prof_otrpolicy_t policy = otr_get_policy(barejid);
|
||||||
char* whitespace_base = strstr(message, OTRL_MESSAGE_TAG_BASE);
|
char* whitespace_base = strstr(message, OTRL_MESSAGE_TAG_BASE);
|
||||||
|
|
||||||
//check for OTR whitespace (opportunistic or always)
|
// check for OTR whitespace (opportunistic or always)
|
||||||
if (policy == PROF_OTRPOLICY_OPPORTUNISTIC || policy == PROF_OTRPOLICY_ALWAYS) {
|
if (policy == PROF_OTRPOLICY_OPPORTUNISTIC || policy == PROF_OTRPOLICY_ALWAYS) {
|
||||||
if (whitespace_base) {
|
if (whitespace_base) {
|
||||||
if (strstr(message, OTRL_MESSAGE_TAG_V2) || strstr(message, OTRL_MESSAGE_TAG_V1)) {
|
if (strstr(message, OTRL_MESSAGE_TAG_V2) || strstr(message, OTRL_MESSAGE_TAG_V1)) {
|
||||||
|
@ -871,15 +871,15 @@ ox_gpg_public_keys(void)
|
|||||||
}
|
}
|
||||||
gpgme_release(ctx);
|
gpgme_release(ctx);
|
||||||
|
|
||||||
//autocomplete_clear(key_ac);
|
// autocomplete_clear(key_ac);
|
||||||
// GList *ids = g_hash_table_get_keys(result);
|
// GList *ids = g_hash_table_get_keys(result);
|
||||||
// GList *curr = ids;
|
// GList *curr = ids;
|
||||||
// while (curr) {
|
// while (curr) {
|
||||||
// ProfPGPKey *key = g_hash_table_lookup(result, curr->data);
|
// ProfPGPKey *key = g_hash_table_lookup(result, curr->data);
|
||||||
// autocomplete_add(key_ac, key->id);
|
// autocomplete_add(key_ac, key->id);
|
||||||
// curr = curr->next;
|
// curr = curr->next;
|
||||||
// }
|
// }
|
||||||
// g_list_free(ids);
|
// g_list_free(ids);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ clipboard_get(void)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//while(!gtk_clipboard_wait_is_text_available(cld)) {}
|
// while(!gtk_clipboard_wait_is_text_available(cld)) {}
|
||||||
|
|
||||||
clip = gtk_clipboard_wait_for_text(cl);
|
clip = gtk_clipboard_wait_for_text(cl);
|
||||||
return clip;
|
return clip;
|
||||||
|
@ -298,11 +298,11 @@ chatwin_incoming_msg(ProfChatWin* chatwin, ProfMessage* message, gboolean win_cr
|
|||||||
|
|
||||||
chatwin->unread++;
|
chatwin->unread++;
|
||||||
|
|
||||||
//TODO: so far we don't ask for MAM when incoming message occurs.
|
// TODO: so far we don't ask for MAM when incoming message occurs.
|
||||||
//Need to figure out:
|
// Need to figure out:
|
||||||
//1) only send IQ once
|
// 1) only send IQ once
|
||||||
//2) sort incoming messages on timestamp
|
// 2) sort incoming messages on timestamp
|
||||||
//for now if experimental MAM is enabled we dont show no history from sql either
|
// for now if experimental MAM is enabled we dont show no history from sql either
|
||||||
|
|
||||||
// MUCPMs also get printed here. In their case we don't save any logs (because nick owners can change) and thus we shouldn't read logs
|
// MUCPMs also get printed here. In their case we don't save any logs (because nick owners can change) and thus we shouldn't read logs
|
||||||
// (and if we do we need to check the resourcepart)
|
// (and if we do we need to check the resourcepart)
|
||||||
|
@ -2159,8 +2159,8 @@ cons_executable_setting(void)
|
|||||||
cons_show("Default '/avatar open' command (/executable avatar) : %s", avatar);
|
cons_show("Default '/avatar open' command (/executable avatar) : %s", avatar);
|
||||||
g_free(avatar);
|
g_free(avatar);
|
||||||
|
|
||||||
//TODO: there needs to be a way to get all the "locales"/schemes so we can
|
// TODO: there needs to be a way to get all the "locales"/schemes so we can
|
||||||
//display the default openers for all filetypes
|
// display the default openers for all filetypes
|
||||||
gchar* urlopen = prefs_get_string(PREF_URL_OPEN_CMD);
|
gchar* urlopen = prefs_get_string(PREF_URL_OPEN_CMD);
|
||||||
cons_show("Default '/url open' command (/executable urlopen) : %s", urlopen);
|
cons_show("Default '/url open' command (/executable urlopen) : %s", urlopen);
|
||||||
g_free(urlopen);
|
g_free(urlopen);
|
||||||
|
@ -234,10 +234,10 @@ notify(const char* const message, int timeout, const char* const category)
|
|||||||
NOTIFYICONDATA nid;
|
NOTIFYICONDATA nid;
|
||||||
memset(&nid, 0, sizeof(nid));
|
memset(&nid, 0, sizeof(nid));
|
||||||
nid.cbSize = sizeof(NOTIFYICONDATA);
|
nid.cbSize = sizeof(NOTIFYICONDATA);
|
||||||
//nid.hWnd = hWnd;
|
// nid.hWnd = hWnd;
|
||||||
nid.uID = 100;
|
nid.uID = 100;
|
||||||
nid.uVersion = NOTIFYICON_VERSION;
|
nid.uVersion = NOTIFYICON_VERSION;
|
||||||
//nid.uCallbackMessage = WM_MYMESSAGE;
|
// nid.uCallbackMessage = WM_MYMESSAGE;
|
||||||
nid.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
nid.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||||
strcpy(nid.szTip, "Tray Icon");
|
strcpy(nid.szTip, "Tray Icon");
|
||||||
nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
|
nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
|
||||||
|
@ -46,8 +46,8 @@
|
|||||||
static void
|
static void
|
||||||
_occuptantswin_occupant(ProfLayoutSplit* layout, GList* item, gboolean showjid, gboolean isoffline)
|
_occuptantswin_occupant(ProfLayoutSplit* layout, GList* item, gboolean showjid, gboolean isoffline)
|
||||||
{
|
{
|
||||||
int colour = 0; //init to workaround compiler warning
|
int colour = 0; // init to workaround compiler warning
|
||||||
theme_item_t presence_colour = THEME_ROSTER_ONLINE; //init to workaround compiler warning
|
theme_item_t presence_colour = THEME_ROSTER_ONLINE; // init to workaround compiler warning
|
||||||
Occupant* occupant = item->data;
|
Occupant* occupant = item->data;
|
||||||
|
|
||||||
if (isoffline) {
|
if (isoffline) {
|
||||||
|
@ -1439,7 +1439,7 @@ win_print_outgoing_with_receipt(ProfWin* window, const char* show_char, const ch
|
|||||||
const char* myjid = connection_get_fulljid();
|
const char* myjid = connection_get_fulljid();
|
||||||
if (replace_id) {
|
if (replace_id) {
|
||||||
_win_correct(window, message, id, replace_id, myjid);
|
_win_correct(window, message, id, replace_id, myjid);
|
||||||
free(receipt); //TODO: probably we should use this in _win_correct()
|
free(receipt); // TODO: probably we should use this in _win_correct()
|
||||||
} else {
|
} else {
|
||||||
buffer_append(window->layout->buffer, show_char, 0, time, 0, THEME_TEXT_ME, from, myjid, message, receipt, id);
|
buffer_append(window->layout->buffer, show_char, 0, time, 0, THEME_TEXT_ME, from, myjid, message, receipt, id);
|
||||||
_win_print_internal(window, show_char, 0, time, 0, THEME_TEXT_ME, from, message, receipt);
|
_win_print_internal(window, show_char, 0, time, 0, THEME_TEXT_ME, from, message, receipt);
|
||||||
|
@ -79,7 +79,7 @@ avatar_pep_subscribe(void)
|
|||||||
message_pubsub_event_handler_add(STANZA_NS_USER_AVATAR_METADATA, _avatar_metadata_handler, NULL, NULL);
|
message_pubsub_event_handler_add(STANZA_NS_USER_AVATAR_METADATA, _avatar_metadata_handler, NULL, NULL);
|
||||||
message_pubsub_event_handler_add(STANZA_NS_USER_AVATAR_DATA, _avatar_metadata_handler, NULL, NULL);
|
message_pubsub_event_handler_add(STANZA_NS_USER_AVATAR_DATA, _avatar_metadata_handler, NULL, NULL);
|
||||||
|
|
||||||
//caps_add_feature(XMPP_FEATURE_USER_AVATAR_METADATA_NOTIFY);
|
// caps_add_feature(XMPP_FEATURE_USER_AVATAR_METADATA_NOTIFY);
|
||||||
|
|
||||||
if (looking_for) {
|
if (looking_for) {
|
||||||
g_hash_table_destroy(looking_for);
|
g_hash_table_destroy(looking_for);
|
||||||
|
@ -872,6 +872,106 @@ connection_set_priority(const int priority)
|
|||||||
conn.priority = priority;
|
conn.priority = priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(LIBXMPP_VERSION_MAJOR) && defined(LIBXMPP_VERSION_MINOR) \
|
||||||
|
&& ((LIBXMPP_VERSION_MAJOR > 0) || (LIBXMPP_VERSION_MINOR >= 12))
|
||||||
|
static xmpp_stanza_t*
|
||||||
|
_get_soh_error(xmpp_stanza_t* error_stanza)
|
||||||
|
{
|
||||||
|
return xmpp_stanza_get_child_by_path(error_stanza,
|
||||||
|
XMPP_STANZA_NAME_IN_NS("error", STANZA_NS_STREAMS),
|
||||||
|
XMPP_STANZA_NAME_IN_NS("see-other-host", STANZA_NS_XMPP_STREAMS),
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static xmpp_stanza_t*
|
||||||
|
_get_soh_error(xmpp_stanza_t* error_stanza)
|
||||||
|
{
|
||||||
|
const char* name = xmpp_stanza_get_name(error_stanza);
|
||||||
|
const char* ns = xmpp_stanza_get_ns(error_stanza);
|
||||||
|
if (!name || !ns || strcmp(name, "error") || strcmp(ns, STANZA_NS_STREAMS)) {
|
||||||
|
log_debug("_get_soh_error: could not find error stanza");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return xmpp_stanza_get_child_by_name_and_ns(error_stanza, "see-other-host", STANZA_NS_XMPP_STREAMS);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if GLIB_CHECK_VERSION(2, 66, 0)
|
||||||
|
static gboolean
|
||||||
|
_split_url(const char* alturi, gchar** host, gint* port)
|
||||||
|
{
|
||||||
|
/* Construct a valid URI with `schema://` as `g_uri_split_network()`
|
||||||
|
* requires this to be there.
|
||||||
|
*/
|
||||||
|
const char* xmpp = "xmpp://";
|
||||||
|
char* xmpp_uri = malloc(strlen(xmpp) + strlen(alturi) + 1);
|
||||||
|
if (!xmpp_uri) {
|
||||||
|
log_debug("_get_other_host: malloc failed \"%s\"", alturi);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memcpy(xmpp_uri, xmpp, strlen(xmpp));
|
||||||
|
memcpy(xmpp_uri + strlen(xmpp), alturi, strlen(alturi) + 1);
|
||||||
|
gboolean ret = g_uri_split_network(xmpp_uri, 0, NULL, host, port, NULL);
|
||||||
|
free(xmpp_uri);
|
||||||
|
/* fix-up `port` as g_uri_split_network() sets port to `-1` if it's missing
|
||||||
|
* in the passed-in URI, but libstrophe expects a "missing port"
|
||||||
|
* to be passed as `0` (which then results in connecting to the standard port).
|
||||||
|
*/
|
||||||
|
if (*port == -1)
|
||||||
|
*port = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* poor-mans URL splitting */
|
||||||
|
static gboolean
|
||||||
|
_split_url(const char* alturi, gchar** host, gint* port)
|
||||||
|
{
|
||||||
|
ptrdiff_t hostlen;
|
||||||
|
/* search ':' from start and end
|
||||||
|
* if `first` matches `last` it's a `hostname:port` combination
|
||||||
|
* if `first` is different than `last` it's `[ip:v6]:port`
|
||||||
|
*/
|
||||||
|
char* first = strchr(alturi, ':');
|
||||||
|
char* last = strrchr(alturi, ':');
|
||||||
|
if (first && first == last) {
|
||||||
|
hostlen = last - alturi;
|
||||||
|
if (!strtoi_range(last + 1, port, 1, 65535, NULL))
|
||||||
|
return FALSE;
|
||||||
|
} else {
|
||||||
|
hostlen = strlen(alturi) + 1;
|
||||||
|
*port = 0;
|
||||||
|
}
|
||||||
|
gchar* buf = g_malloc(hostlen);
|
||||||
|
if (!buf)
|
||||||
|
return FALSE;
|
||||||
|
memcpy(buf, alturi, hostlen);
|
||||||
|
buf[hostlen - 1] = '\0';
|
||||||
|
*host = buf;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static bool
|
||||||
|
_get_other_host(xmpp_stanza_t* error_stanza, gchar** host, int* port)
|
||||||
|
{
|
||||||
|
xmpp_stanza_t* soh_error = _get_soh_error(error_stanza);
|
||||||
|
if (!soh_error || !xmpp_stanza_get_children(soh_error)) {
|
||||||
|
log_debug("_get_other_host: stream-error contains no see-other-host");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const char* alturi = xmpp_stanza_get_text_ptr(xmpp_stanza_get_children(soh_error));
|
||||||
|
if (!alturi) {
|
||||||
|
log_debug("_get_other_host: see-other-host contains no text");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_split_url(alturi, host, port)) {
|
||||||
|
log_debug("_get_other_host: Could not split \"%s\"", alturi);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_connection_handler(xmpp_conn_t* const xmpp_conn, const xmpp_conn_event_t status, const int error,
|
_connection_handler(xmpp_conn_t* const xmpp_conn, const xmpp_conn_event_t status, const int error,
|
||||||
xmpp_stream_error_t* const stream_error, void* const userdata)
|
xmpp_stream_error_t* const stream_error, void* const userdata)
|
||||||
@ -924,6 +1024,14 @@ _connection_handler(xmpp_conn_t* const xmpp_conn, const xmpp_conn_event_t status
|
|||||||
|
|
||||||
// login attempt failed
|
// login attempt failed
|
||||||
} else if (conn.conn_status != JABBER_DISCONNECTING) {
|
} else if (conn.conn_status != JABBER_DISCONNECTING) {
|
||||||
|
gchar* host;
|
||||||
|
int port;
|
||||||
|
if (stream_error && stream_error->stanza && _get_other_host(stream_error->stanza, &host, &port)) {
|
||||||
|
session_reconnect(host, port);
|
||||||
|
log_debug("Connection handler: Forcing a re-connect to \"%s\"", host);
|
||||||
|
conn.conn_status = JABBER_RECONNECT;
|
||||||
|
return;
|
||||||
|
}
|
||||||
log_debug("Connection handler: Login failed");
|
log_debug("Connection handler: Login failed");
|
||||||
session_login_failed();
|
session_login_failed();
|
||||||
}
|
}
|
||||||
@ -1074,7 +1182,7 @@ _random_bytes_close(void)
|
|||||||
static void
|
static void
|
||||||
_compute_identifier(const char* barejid)
|
_compute_identifier(const char* barejid)
|
||||||
{
|
{
|
||||||
//in case of reconnect (lost connection)
|
// in case of reconnect (lost connection)
|
||||||
free(prof_identifier);
|
free(prof_identifier);
|
||||||
|
|
||||||
prof_identifier = g_compute_hmac_for_string(G_CHECKSUM_SHA256,
|
prof_identifier = g_compute_hmac_for_string(G_CHECKSUM_SHA256,
|
||||||
|
@ -437,7 +437,7 @@ omemo_receive_message(xmpp_stanza_t* const stanza, gboolean* trusted)
|
|||||||
keys = g_list_append(keys, key);
|
keys = g_list_append(keys, key);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
skip:
|
skip:
|
||||||
free(key);
|
free(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ static char* saved_status;
|
|||||||
|
|
||||||
static void _session_reconnect(void);
|
static void _session_reconnect(void);
|
||||||
|
|
||||||
static void _session_free_saved_account(void);
|
static void _session_free_internals(void);
|
||||||
static void _session_free_saved_details(void);
|
static void _session_free_saved_details(void);
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -117,8 +117,7 @@ session_connect_with_account(const ProfAccount* const account)
|
|||||||
|
|
||||||
log_info("Connecting using account: %s", account->name);
|
log_info("Connecting using account: %s", account->name);
|
||||||
|
|
||||||
_session_free_saved_account();
|
_session_free_internals();
|
||||||
_session_free_saved_details();
|
|
||||||
|
|
||||||
// save account name and password for reconnect
|
// save account name and password for reconnect
|
||||||
saved_account.name = strdup(account->name);
|
saved_account.name = strdup(account->name);
|
||||||
@ -152,8 +151,7 @@ session_connect_with_details(const char* const jid, const char* const passwd, co
|
|||||||
assert(jid != NULL);
|
assert(jid != NULL);
|
||||||
assert(passwd != NULL);
|
assert(passwd != NULL);
|
||||||
|
|
||||||
_session_free_saved_account();
|
_session_free_internals();
|
||||||
_session_free_saved_details();
|
|
||||||
|
|
||||||
// save details for reconnect, remember name for account creating on success
|
// save details for reconnect, remember name for account creating on success
|
||||||
saved_details.name = strdup(jid);
|
saved_details.name = strdup(jid);
|
||||||
@ -240,8 +238,7 @@ session_disconnect(void)
|
|||||||
void
|
void
|
||||||
session_shutdown(void)
|
session_shutdown(void)
|
||||||
{
|
{
|
||||||
_session_free_saved_account();
|
_session_free_internals();
|
||||||
_session_free_saved_details();
|
|
||||||
|
|
||||||
chat_sessions_clear();
|
chat_sessions_clear();
|
||||||
presence_clear_sub_requests();
|
presence_clear_sub_requests();
|
||||||
@ -275,6 +272,9 @@ session_process_events(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case JABBER_RECONNECT:
|
||||||
|
_session_reconnect();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -371,8 +371,7 @@ session_login_failed(void)
|
|||||||
if (reconnect_timer == NULL) {
|
if (reconnect_timer == NULL) {
|
||||||
log_debug("Connection handler: No reconnect timer");
|
log_debug("Connection handler: No reconnect timer");
|
||||||
sv_ev_failed_login();
|
sv_ev_failed_login();
|
||||||
_session_free_saved_account();
|
_session_free_internals();
|
||||||
_session_free_saved_details();
|
|
||||||
} else {
|
} else {
|
||||||
log_debug("Connection handler: Restarting reconnect timer");
|
log_debug("Connection handler: Restarting reconnect timer");
|
||||||
if (prefs_get_reconnect() != 0) {
|
if (prefs_get_reconnect() != 0) {
|
||||||
@ -394,8 +393,7 @@ session_lost_connection(void)
|
|||||||
assert(reconnect_timer == NULL);
|
assert(reconnect_timer == NULL);
|
||||||
reconnect_timer = g_timer_new();
|
reconnect_timer = g_timer_new();
|
||||||
} else {
|
} else {
|
||||||
_session_free_saved_account();
|
_session_free_internals();
|
||||||
_session_free_saved_details();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -537,6 +535,24 @@ session_check_autoaway(void)
|
|||||||
g_free(mode);
|
g_free(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct
|
||||||
|
{
|
||||||
|
gchar* altdomain;
|
||||||
|
unsigned short altport;
|
||||||
|
} reconnect;
|
||||||
|
|
||||||
|
/* This takes ownership of `altdomain`, i.e. the caller must not
|
||||||
|
* free the value after calling this function.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
session_reconnect(gchar* altdomain, unsigned short altport)
|
||||||
|
{
|
||||||
|
reconnect.altdomain = altdomain;
|
||||||
|
reconnect.altport = altport;
|
||||||
|
assert(reconnect_timer == NULL);
|
||||||
|
reconnect_timer = g_timer_new();
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_session_reconnect(void)
|
_session_reconnect(void)
|
||||||
{
|
{
|
||||||
@ -553,19 +569,30 @@ _session_reconnect(void)
|
|||||||
} else {
|
} else {
|
||||||
jid = strdup(account->jid);
|
jid = strdup(account->jid);
|
||||||
}
|
}
|
||||||
|
const char* server;
|
||||||
|
unsigned short port;
|
||||||
|
if (reconnect.altdomain) {
|
||||||
|
server = reconnect.altdomain;
|
||||||
|
port = reconnect.altport;
|
||||||
|
} else {
|
||||||
|
server = account->server;
|
||||||
|
port = account->port;
|
||||||
|
}
|
||||||
|
|
||||||
log_debug("Attempting reconnect with account %s", account->name);
|
log_debug("Attempting reconnect with account %s", account->name);
|
||||||
connection_connect(jid, saved_account.passwd, account->server, account->port, account->tls_policy, account->auth_policy);
|
connection_connect(jid, saved_account.passwd, server, port, account->tls_policy, account->auth_policy);
|
||||||
free(jid);
|
free(jid);
|
||||||
account_free(account);
|
account_free(account);
|
||||||
g_timer_start(reconnect_timer);
|
g_timer_start(reconnect_timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_session_free_saved_account(void)
|
_session_free_internals(void)
|
||||||
{
|
{
|
||||||
FREE_SET_NULL(saved_account.name);
|
FREE_SET_NULL(saved_account.name);
|
||||||
FREE_SET_NULL(saved_account.passwd);
|
FREE_SET_NULL(saved_account.passwd);
|
||||||
|
GFREE_SET_NULL(reconnect.altdomain);
|
||||||
|
_session_free_saved_details();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -46,4 +46,6 @@ void session_autoping_fail(void);
|
|||||||
void session_init_activity(void);
|
void session_init_activity(void);
|
||||||
void session_check_autoaway(void);
|
void session_check_autoaway(void);
|
||||||
|
|
||||||
|
void session_reconnect(gchar* altdomain, unsigned short altport);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -2605,7 +2605,7 @@ stanza_create_mam_iq(xmpp_ctx_t* ctx, const char* const jid, const char* const s
|
|||||||
char* id = connection_create_stanza_id();
|
char* id = connection_create_stanza_id();
|
||||||
xmpp_stanza_t* iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id);
|
xmpp_stanza_t* iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id);
|
||||||
free(id);
|
free(id);
|
||||||
//xmpp_stanza_set_to(iq, jid);
|
// xmpp_stanza_set_to(iq, jid);
|
||||||
|
|
||||||
xmpp_stanza_t* query = xmpp_stanza_new(ctx);
|
xmpp_stanza_t* query = xmpp_stanza_new(ctx);
|
||||||
xmpp_stanza_set_name(query, STANZA_NAME_QUERY);
|
xmpp_stanza_set_name(query, STANZA_NAME_QUERY);
|
||||||
|
@ -245,6 +245,8 @@
|
|||||||
#define STANZA_NS_REPORTING "urn:xmpp:reporting:1"
|
#define STANZA_NS_REPORTING "urn:xmpp:reporting:1"
|
||||||
#define STANZA_NS_MOOD "http://jabber.org/protocol/mood"
|
#define STANZA_NS_MOOD "http://jabber.org/protocol/mood"
|
||||||
#define STANZA_NS_MOOD_NOTIFY "http://jabber.org/protocol/mood+notify"
|
#define STANZA_NS_MOOD_NOTIFY "http://jabber.org/protocol/mood+notify"
|
||||||
|
#define STANZA_NS_STREAMS "http://etherx.jabber.org/streams"
|
||||||
|
#define STANZA_NS_XMPP_STREAMS "urn:ietf:params:xml:ns:xmpp-streams"
|
||||||
|
|
||||||
#define STANZA_DATAFORM_SOFTWARE "urn:xmpp:dataforms:softwareinfo"
|
#define STANZA_DATAFORM_SOFTWARE "urn:xmpp:dataforms:softwareinfo"
|
||||||
|
|
||||||
|
@ -72,7 +72,8 @@ typedef enum {
|
|||||||
JABBER_DISCONNECTING,
|
JABBER_DISCONNECTING,
|
||||||
JABBER_DISCONNECTED,
|
JABBER_DISCONNECTED,
|
||||||
JABBER_RAW_CONNECTING,
|
JABBER_RAW_CONNECTING,
|
||||||
JABBER_RAW_CONNECTED
|
JABBER_RAW_CONNECTED,
|
||||||
|
JABBER_RECONNECT
|
||||||
} jabber_conn_status_t;
|
} jabber_conn_status_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -99,7 +100,7 @@ typedef struct bookmark_t
|
|||||||
char* password;
|
char* password;
|
||||||
char* name;
|
char* name;
|
||||||
gboolean autojoin;
|
gboolean autojoin;
|
||||||
int ext_gajim_minimize; //0 - non existent, 1 - true, 2 - false
|
int ext_gajim_minimize; // 0 - non existent, 1 - true, 2 - false
|
||||||
} Bookmark;
|
} Bookmark;
|
||||||
|
|
||||||
typedef struct disco_identity_t
|
typedef struct disco_identity_t
|
||||||
|
@ -61,6 +61,6 @@ returns_commands(void** state)
|
|||||||
assert_true(foundCommand1 && foundCommand2 && foundCommand3);
|
assert_true(foundCommand1 && foundCommand2 && foundCommand3);
|
||||||
|
|
||||||
g_list_free(names);
|
g_list_free(names);
|
||||||
//TODO: why does this make the test fail?
|
// TODO: why does this make the test fail?
|
||||||
//callbacks_close();
|
// callbacks_close();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user