diff options
-rw-r--r-- | .clang-format | 1 | ||||
-rw-r--r-- | src/command/cmd_funcs.c | 2 | ||||
-rw-r--r-- | src/database.c | 2 | ||||
-rw-r--r-- | src/event/server_events.c | 2 | ||||
-rw-r--r-- | src/omemo/crypto.h | 178 | ||||
-rw-r--r-- | src/omemo/omemo.c | 4 | ||||
-rw-r--r-- | src/otr/otr.c | 2 | ||||
-rw-r--r-- | src/pgp/gpg.c | 28 | ||||
-rw-r--r-- | src/tools/clipboard.c | 2 | ||||
-rw-r--r-- | src/ui/chatwin.c | 10 | ||||
-rw-r--r-- | src/ui/console.c | 4 | ||||
-rw-r--r-- | src/ui/notifier.c | 4 | ||||
-rw-r--r-- | src/ui/occupantswin.c | 4 | ||||
-rw-r--r-- | src/ui/window.c | 2 | ||||
-rw-r--r-- | src/xmpp/avatar.c | 2 | ||||
-rw-r--r-- | src/xmpp/connection.c | 110 | ||||
-rw-r--r-- | src/xmpp/omemo.c | 2 | ||||
-rw-r--r-- | src/xmpp/ox.c | 2 | ||||
-rw-r--r-- | src/xmpp/ox.h | 10 | ||||
-rw-r--r-- | src/xmpp/session.c | 53 | ||||
-rw-r--r-- | src/xmpp/session.h | 2 | ||||
-rw-r--r-- | src/xmpp/stanza.c | 2 | ||||
-rw-r--r-- | src/xmpp/stanza.h | 2 | ||||
-rw-r--r-- | src/xmpp/xmpp.h | 5 | ||||
-rw-r--r-- | tests/unittests/test_callbacks.c | 4 |
25 files changed, 291 insertions, 148 deletions
diff --git a/.clang-format b/.clang-format index a59cb616..d16e045c 100644 --- a/.clang-format +++ b/.clang-format @@ -22,6 +22,7 @@ AlignOperands: true AlignTrailingComments: true AllowAllArgumentsOnNextLine: true AllowShortBlocksOnASingleLine: true +IndentGotoLabels: false IndentWidth: 4 BreakBeforeBraces: Custom BraceWrapping: diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index d9a61727..ba06d59e 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -1144,7 +1144,7 @@ cmd_export(ProfWin* window, const char* const command, gchar** args) g_slist_free(list); close(fd); return TRUE; - write_error: +write_error: cons_show("error: write failed: %s", strerror(errno)); cons_show(""); g_slist_free(list); diff --git a/src/database.c b/src/database.c index 6d8e79d4..c04dcff9 100644 --- a/src/database.c +++ b/src/database.c @@ -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->plain = message ? strdup(message) : 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; Jid* myjid = jid_create(connection_get_fulljid()); diff --git a/src/event/server_events.c b/src/event/server_events.c index a61aecf6..0b7858a3 100644 --- a/src/event/server_events.c +++ b/src/event/server_events.c @@ -522,7 +522,7 @@ _sv_ev_incoming_ox(ProfChatWin* chatwin, gboolean new_win, ProfMessage* message, chat_log_pgp_msg_in(message); } chatwin->pgp_recv = TRUE; - //p_gpg_free_decrypted(message->plain); + // p_gpg_free_decrypted(message->plain); message->plain = NULL; #endif } diff --git a/src/omemo/crypto.h b/src/omemo/crypto.h index 5adbffd8..d3f775dd 100644 --- a/src/omemo/crypto.h +++ b/src/omemo/crypto.h @@ -43,110 +43,110 @@ int omemo_crypto_init(void); /** -* Callback for a secure random number generator. -* This function shall fill the provided buffer with random bytes. -* -* @param data pointer to the output buffer -* @param len size of the output buffer -* @return 0 on success, negative on failure -*/ + * Callback for a secure random number generator. + * This function shall fill the provided buffer with random bytes. + * + * @param data pointer to the output buffer + * @param len size of the output buffer + * @return 0 on success, negative on failure + */ int omemo_random_func(uint8_t* data, size_t len, void* user_data); /** -* Callback for an HMAC-SHA256 implementation. -* This function shall initialize an HMAC context with the provided key. -* -* @param hmac_context private HMAC context pointer -* @param key pointer to the key -* @param key_len length of the key -* @return 0 on success, negative on failure -*/ + * Callback for an HMAC-SHA256 implementation. + * This function shall initialize an HMAC context with the provided key. + * + * @param hmac_context private HMAC context pointer + * @param key pointer to the key + * @param key_len length of the key + * @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); /** -* Callback for an HMAC-SHA256 implementation. -* This function shall update the HMAC context with the provided data -* -* @param hmac_context private HMAC context pointer -* @param data pointer to the data -* @param data_len length of the data -* @return 0 on success, negative on failure -*/ + * Callback for an HMAC-SHA256 implementation. + * This function shall update the HMAC context with the provided data + * + * @param hmac_context private HMAC context pointer + * @param data pointer to the data + * @param data_len length of the data + * @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); /** -* Callback for an HMAC-SHA256 implementation. -* This function shall finalize an HMAC calculation and populate the output -* buffer with the result. -* -* @param hmac_context private HMAC context pointer -* @param output buffer to be allocated and populated with the result -* @return 0 on success, negative on failure -*/ + * Callback for an HMAC-SHA256 implementation. + * This function shall finalize an HMAC calculation and populate the output + * buffer with the result. + * + * @param hmac_context private HMAC context pointer + * @param output buffer to be allocated and populated with the result + * @return 0 on success, negative on failure + */ int omemo_hmac_sha256_final_func(void* hmac_context, signal_buffer** output, void* user_data); /** -* Callback for an HMAC-SHA256 implementation. -* This function shall free the private context allocated in -* hmac_sha256_init_func. -* -* @param hmac_context private HMAC context pointer -*/ + * Callback for an HMAC-SHA256 implementation. + * This function shall free the private context allocated in + * hmac_sha256_init_func. + * + * @param hmac_context private HMAC context pointer + */ void omemo_hmac_sha256_cleanup_func(void* hmac_context, void* user_data); /** -* Callback for a SHA512 message digest implementation. -* This function shall initialize a digest context. -* -* @param digest_context private digest context pointer -* @return 0 on success, negative on failure -*/ + * Callback for a SHA512 message digest implementation. + * This function shall initialize a digest context. + * + * @param digest_context private digest context pointer + * @return 0 on success, negative on failure + */ int omemo_sha512_digest_init_func(void** digest_context, void* user_data); /** -* Callback for a SHA512 message digest implementation. -* This function shall update the digest context with the provided data. -* -* @param digest_context private digest context pointer -* @param data pointer to the data -* @param data_len length of the data -* @return 0 on success, negative on failure -*/ + * Callback for a SHA512 message digest implementation. + * This function shall update the digest context with the provided data. + * + * @param digest_context private digest context pointer + * @param data pointer to the data + * @param data_len length of the data + * @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); /** -* Callback for a SHA512 message digest implementation. -* This function shall finalize the digest calculation, populate the -* output buffer with the result, and prepare the context for reuse. -* -* @param digest_context private digest context pointer -* @param output buffer to be allocated and populated with the result -* @return 0 on success, negative on failure -*/ + * Callback for a SHA512 message digest implementation. + * This function shall finalize the digest calculation, populate the + * output buffer with the result, and prepare the context for reuse. + * + * @param digest_context private digest context pointer + * @param output buffer to be allocated and populated with the result + * @return 0 on success, negative on failure + */ int omemo_sha512_digest_final_func(void* digest_context, signal_buffer** output, void* user_data); /** -* Callback for a SHA512 message digest implementation. -* This function shall free the private context allocated in -* sha512_digest_init_func. -* -* @param digest_context private digest context pointer -*/ + * Callback for a SHA512 message digest implementation. + * This function shall free the private context allocated in + * sha512_digest_init_func. + * + * @param digest_context private digest context pointer + */ void omemo_sha512_digest_cleanup_func(void* digest_context, void* user_data); /** -* Callback for an AES encryption implementation. -* -* @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 key the encryption key -* @param key_len length of the encryption key -* @param iv the initialization vector -* @param iv_len length of the initialization vector -* @param plaintext the plaintext to encrypt -* @param plaintext_len length of the plaintext -* @return 0 on success, negative on failure -*/ + * Callback for an AES encryption implementation. + * + * @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 key the encryption key + * @param key_len length of the encryption key + * @param iv the initialization vector + * @param iv_len length of the initialization vector + * @param plaintext the plaintext to encrypt + * @param plaintext_len length of the plaintext + * @return 0 on success, negative on failure + */ int omemo_encrypt_func(signal_buffer** output, int cipher, const uint8_t* key, size_t key_len, @@ -155,18 +155,18 @@ int omemo_encrypt_func(signal_buffer** output, void* user_data); /** -* Callback for an AES decryption implementation. -* -* @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 key the encryption key -* @param key_len length of the encryption key -* @param iv the initialization vector -* @param iv_len length of the initialization vector -* @param ciphertext the ciphertext to decrypt -* @param ciphertext_len length of the ciphertext -* @return 0 on success, negative on failure -*/ + * Callback for an AES decryption implementation. + * + * @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 key the encryption key + * @param key_len length of the encryption key + * @param iv the initialization vector + * @param iv_len length of the initialization vector + * @param ciphertext the ciphertext to decrypt + * @param ciphertext_len length of the ciphertext + * @return 0 on success, negative on failure + */ int omemo_decrypt_func(signal_buffer** output, int cipher, const uint8_t* key, size_t key_len, diff --git a/src/omemo/omemo.c b/src/omemo/omemo.c index 4d53ad0c..87599de0 100644 --- a/src/omemo/omemo.c +++ b/src/omemo/omemo.c @@ -388,7 +388,9 @@ omemo_publish_crypto_materials(void) omemo_bundle_publish(true); } -static void _acquire_sender_devices_list(void) { +static void +_acquire_sender_devices_list(void) +{ char* barejid = connection_get_barejid(); g_hash_table_insert(omemo_ctx.device_list_handler, strdup(barejid), _handle_own_device_list); diff --git a/src/otr/otr.c b/src/otr/otr.c index 1cf1072c..5f45e23c 100644 --- a/src/otr/otr.c +++ b/src/otr/otr.c @@ -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); 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 (whitespace_base) { if (strstr(message, OTRL_MESSAGE_TAG_V2) || strstr(message, OTRL_MESSAGE_TAG_V1)) { diff --git a/src/pgp/gpg.c b/src/pgp/gpg.c index d4863492..549f9d3b 100644 --- a/src/pgp/gpg.c +++ b/src/pgp/gpg.c @@ -871,15 +871,15 @@ ox_gpg_public_keys(void) } gpgme_release(ctx); - //autocomplete_clear(key_ac); - // GList *ids = g_hash_table_get_keys(result); - // GList *curr = ids; - // while (curr) { - // ProfPGPKey *key = g_hash_table_lookup(result, curr->data); - // autocomplete_add(key_ac, key->id); - // curr = curr->next; - // } - // g_list_free(ids); + // autocomplete_clear(key_ac); + // GList *ids = g_hash_table_get_keys(result); + // GList *curr = ids; + // while (curr) { + // ProfPGPKey *key = g_hash_table_lookup(result, curr->data); + // autocomplete_add(key_ac, key->id); + // curr = curr->next; + // } + // g_list_free(ids); return result; } @@ -1210,14 +1210,14 @@ p_ox_gpg_decrypt(char* base64) * * This function is used to read a key and push it on PEP. There are some checks * in this function: - * + * * Key is not - * - gkey->revoked - * - gkey->expired + * - gkey->revoked + * - gkey->expired * - gkey->disabled - * - gkey->invalid + * - gkey->invalid * - gkey->secret - * + * * Only one key in the file. * * \param filename filename to read the file. diff --git a/src/tools/clipboard.c b/src/tools/clipboard.c index b2ea1bf3..a9f67eac 100644 --- a/src/tools/clipboard.c +++ b/src/tools/clipboard.c @@ -63,7 +63,7 @@ clipboard_get(void) 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); return clip; diff --git a/src/ui/chatwin.c b/src/ui/chatwin.c index 1c33e6c3..0224d720 100644 --- a/src/ui/chatwin.c +++ b/src/ui/chatwin.c @@ -298,11 +298,11 @@ chatwin_incoming_msg(ProfChatWin* chatwin, ProfMessage* message, gboolean win_cr chatwin->unread++; - //TODO: so far we don't ask for MAM when incoming message occurs. - //Need to figure out: - //1) only send IQ once - //2) sort incoming messages on timestamp - //for now if experimental MAM is enabled we dont show no history from sql either + // TODO: so far we don't ask for MAM when incoming message occurs. + // Need to figure out: + // 1) only send IQ once + // 2) sort incoming messages on timestamp + // 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 // (and if we do we need to check the resourcepart) diff --git a/src/ui/console.c b/src/ui/console.c index 61c1f1c2..8d3e13a3 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -2159,8 +2159,8 @@ cons_executable_setting(void) cons_show("Default '/avatar open' command (/executable avatar) : %s", avatar); g_free(avatar); - //TODO: there needs to be a way to get all the "locales"/schemes so we can - //display the default openers for all filetypes + // TODO: there needs to be a way to get all the "locales"/schemes so we can + // display the default openers for all filetypes gchar* urlopen = prefs_get_string(PREF_URL_OPEN_CMD); cons_show("Default '/url open' command (/executable urlopen) : %s", urlopen); g_free(urlopen); diff --git a/src/ui/notifier.c b/src/ui/notifier.c index 9a0eb291..92ebf835 100644 --- a/src/ui/notifier.c +++ b/src/ui/notifier.c @@ -234,10 +234,10 @@ notify(const char* const message, int timeout, const char* const category) NOTIFYICONDATA nid; memset(&nid, 0, sizeof(nid)); nid.cbSize = sizeof(NOTIFYICONDATA); - //nid.hWnd = hWnd; + // nid.hWnd = hWnd; nid.uID = 100; nid.uVersion = NOTIFYICON_VERSION; - //nid.uCallbackMessage = WM_MYMESSAGE; + // nid.uCallbackMessage = WM_MYMESSAGE; nid.hIcon = LoadIcon(NULL, IDI_APPLICATION); strcpy(nid.szTip, "Tray Icon"); nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; diff --git a/src/ui/occupantswin.c b/src/ui/occupantswin.c index 1524de3f..04150e25 100644 --- a/src/ui/occupantswin.c +++ b/src/ui/occupantswin.c @@ -46,8 +46,8 @@ static void _occuptantswin_occupant(ProfLayoutSplit* layout, GList* item, gboolean showjid, gboolean isoffline) { - int colour = 0; //init to workaround compiler warning - theme_item_t presence_colour = THEME_ROSTER_ONLINE; //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 Occupant* occupant = item->data; if (isoffline) { diff --git a/src/ui/window.c b/src/ui/window.c index 7442ce9c..54932f21 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -1439,7 +1439,7 @@ win_print_outgoing_with_receipt(ProfWin* window, const char* show_char, const ch const char* myjid = connection_get_fulljid(); if (replace_id) { _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 { 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); diff --git a/src/xmpp/avatar.c b/src/xmpp/avatar.c index 89d34fbc..346e85ba 100644 --- a/src/xmpp/avatar.c +++ b/src/xmpp/avatar.c @@ -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_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) { g_hash_table_destroy(looking_for); diff --git a/src/xmpp/connection.c b/src/xmpp/connection.c index 516006a9..c04f9df2 100644 --- a/src/xmpp/connection.c +++ b/src/xmpp/connection.c @@ -872,6 +872,106 @@ connection_set_priority(const int 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 _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) @@ -924,6 +1024,14 @@ _connection_handler(xmpp_conn_t* const xmpp_conn, const xmpp_conn_event_t status // login attempt failed } 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"); session_login_failed(); } @@ -1074,7 +1182,7 @@ _random_bytes_close(void) static void _compute_identifier(const char* barejid) { - //in case of reconnect (lost connection) + // in case of reconnect (lost connection) free(prof_identifier); prof_identifier = g_compute_hmac_for_string(G_CHECKSUM_SHA256, diff --git a/src/xmpp/omemo.c b/src/xmpp/omemo.c index 26cd6b37..c4d82e42 100644 --- a/src/xmpp/omemo.c +++ b/src/xmpp/omemo.c @@ -437,7 +437,7 @@ omemo_receive_message(xmpp_stanza_t* const stanza, gboolean* trusted) keys = g_list_append(keys, key); continue; - skip: +skip: free(key); } diff --git a/src/xmpp/ox.c b/src/xmpp/ox.c index b8a0a41e..c4efa5d6 100644 --- a/src/xmpp/ox.c +++ b/src/xmpp/ox.c @@ -222,7 +222,7 @@ ox_request_public_key(const char* const jid, const char* const fingerprint) </item> </publish> </pubsub> -</iq> +</iq> </pre> * */ diff --git a/src/xmpp/ox.h b/src/xmpp/ox.h index 143cce95..06acd119 100644 --- a/src/xmpp/ox.h +++ b/src/xmpp/ox.h @@ -2,7 +2,7 @@ * ox.h * vim: expandtab:ts=4:sts=4:sw=4 * - * Copyright (C) 2020 Stefan Kropp <stefan@debxwoody.de> + * Copyright (C) 2020 Stefan Kropp <stefan@debxwoody.de> * * This file is part of Profanity. * @@ -35,10 +35,10 @@ /*! * \page OX OX Implementation - * + * * \section OX XEP-0373: OpenPGP for XMPP * XEP-0373: OpenPGP for XMPP (OX) is the implementation of OpenPGP for XMPP - * replace the XEP-0027. + * replace the XEP-0027. * * https://xmpp.org/extensions/xep-0373.html */ @@ -48,10 +48,10 @@ * * Reads the public key from the given file. Checks the key-information and * pushes the key on PEP. - * + * * https://xmpp.org/extensions/xep-0373.html#announcing-pubkey * - * \param filename name of the file with the public key + * \param filename name of the file with the public key * \return TRUE: success; FALSE: failed */ diff --git a/src/xmpp/session.c b/src/xmpp/session.c index 4a19e211..ce3c557a 100644 --- a/src/xmpp/session.c +++ b/src/xmpp/session.c @@ -98,7 +98,7 @@ static char* saved_status; 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); void @@ -117,8 +117,7 @@ session_connect_with_account(const ProfAccount* const account) log_info("Connecting using account: %s", account->name); - _session_free_saved_account(); - _session_free_saved_details(); + _session_free_internals(); // save account name and password for reconnect 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(passwd != NULL); - _session_free_saved_account(); - _session_free_saved_details(); + _session_free_internals(); // save details for reconnect, remember name for account creating on success saved_details.name = strdup(jid); @@ -240,8 +238,7 @@ session_disconnect(void) void session_shutdown(void) { - _session_free_saved_account(); - _session_free_saved_details(); + _session_free_internals(); chat_sessions_clear(); presence_clear_sub_requests(); @@ -275,6 +272,9 @@ session_process_events(void) } } break; + case JABBER_RECONNECT: + _session_reconnect(); + break; default: break; } @@ -371,8 +371,7 @@ session_login_failed(void) if (reconnect_timer == NULL) { log_debug("Connection handler: No reconnect timer"); sv_ev_failed_login(); - _session_free_saved_account(); - _session_free_saved_details(); + _session_free_internals(); } else { log_debug("Connection handler: Restarting reconnect timer"); if (prefs_get_reconnect() != 0) { @@ -394,8 +393,7 @@ session_lost_connection(void) assert(reconnect_timer == NULL); reconnect_timer = g_timer_new(); } else { - _session_free_saved_account(); - _session_free_saved_details(); + _session_free_internals(); } } @@ -537,6 +535,24 @@ session_check_autoaway(void) 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 _session_reconnect(void) { @@ -553,19 +569,30 @@ _session_reconnect(void) } else { 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); - 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); account_free(account); g_timer_start(reconnect_timer); } static void -_session_free_saved_account(void) +_session_free_internals(void) { FREE_SET_NULL(saved_account.name); FREE_SET_NULL(saved_account.passwd); + GFREE_SET_NULL(reconnect.altdomain); + _session_free_saved_details(); } static void diff --git a/src/xmpp/session.h b/src/xmpp/session.h index 62ee9b10..d8565fa4 100644 --- a/src/xmpp/session.h +++ b/src/xmpp/session.h @@ -46,4 +46,6 @@ void session_autoping_fail(void); void session_init_activity(void); void session_check_autoaway(void); +void session_reconnect(gchar* altdomain, unsigned short altport); + #endif diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c index d28ed3d2..bfb782da 100644 --- a/src/xmpp/stanza.c +++ b/src/xmpp/stanza.c @@ -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(); xmpp_stanza_t* iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, 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_set_name(query, STANZA_NAME_QUERY); diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h index 9e957749..07d1f395 100644 --- a/src/xmpp/stanza.h +++ b/src/xmpp/stanza.h @@ -245,6 +245,8 @@ #define STANZA_NS_REPORTING "urn:xmpp:reporting:1" #define STANZA_NS_MOOD "http://jabber.org/protocol/mood" #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" diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index 8a2d2eb2..6aaa0cb9 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -72,7 +72,8 @@ typedef enum { JABBER_DISCONNECTING, JABBER_DISCONNECTED, JABBER_RAW_CONNECTING, - JABBER_RAW_CONNECTED + JABBER_RAW_CONNECTED, + JABBER_RECONNECT } jabber_conn_status_t; typedef enum { @@ -99,7 +100,7 @@ typedef struct bookmark_t char* password; char* name; 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; typedef struct disco_identity_t diff --git a/tests/unittests/test_callbacks.c b/tests/unittests/test_callbacks.c index 3c5267fe..a9b1138b 100644 --- a/tests/unittests/test_callbacks.c +++ b/tests/unittests/test_callbacks.c @@ -61,6 +61,6 @@ returns_commands(void** state) assert_true(foundCommand1 && foundCommand2 && foundCommand3); g_list_free(names); - //TODO: why does this make the test fail? - //callbacks_close(); + // TODO: why does this make the test fail? + // callbacks_close(); } |