about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorMichael Vetter <jubalh@iodoru.org>2023-04-18 14:43:01 +0200
committerGitHub <noreply@github.com>2023-04-18 14:43:01 +0200
commit4933d4e4f3d1cc8ee308c1bb6bfc4c13ec64ac57 (patch)
tree1fed6ab534a857572c0732fe5c9dad73af4617dd
parentf51dc019bc08e41fa4564d465136522648a7a663 (diff)
parentbed5c02c0dde0fe3cd8eb6018322a78b4441e22a (diff)
downloadprofani-tty-4933d4e4f3d1cc8ee308c1bb6bfc4c13ec64ac57.tar.gz
Merge pull request #1827 from H3rnand3zzz/feature/sessions-alarm
New Feature: Session Alarm
-rw-r--r--.gitignore1
-rw-r--r--src/command/cmd_ac.c2
-rw-r--r--src/command/cmd_defs.c8
-rw-r--r--src/command/cmd_funcs.c27
-rw-r--r--src/config/account.c4
-rw-r--r--src/config/account.h3
-rw-r--r--src/config/accounts.c34
-rw-r--r--src/config/accounts.h4
-rw-r--r--src/ui/console.c6
-rw-r--r--src/xmpp/connection.c6
-rw-r--r--src/xmpp/presence.c64
-rw-r--r--src/xmpp/xmpp.h1
-rw-r--r--tests/unittests/config/stub_accounts.c8
-rw-r--r--tests/unittests/test_cmd_account.c14
-rw-r--r--tests/unittests/test_cmd_connect.c8
-rw-r--r--tests/unittests/test_cmd_join.c8
-rw-r--r--tests/unittests/test_cmd_otr.c2
-rw-r--r--tests/unittests/test_cmd_rooms.c4
18 files changed, 180 insertions, 24 deletions
diff --git a/.gitignore b/.gitignore
index cc3402a9..eafcb988 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,6 +16,7 @@ compile_commands.json
 .cproject
 .project
 .settings/
+.vscode/
 
 # autotools
 .libs/
diff --git a/src/command/cmd_ac.c b/src/command/cmd_ac.c
index 5678dbff..b29acec5 100644
--- a/src/command/cmd_ac.c
+++ b/src/command/cmd_ac.c
@@ -485,6 +485,7 @@ cmd_ac_init(void)
     autocomplete_add(account_set_ac, "tls");
     autocomplete_add(account_set_ac, "auth");
     autocomplete_add(account_set_ac, "theme");
+    autocomplete_add(account_set_ac, "session_alarm");
 
     account_clear_ac = autocomplete_new();
     autocomplete_add(account_clear_ac, "password");
@@ -498,6 +499,7 @@ cmd_ac_init(void)
     autocomplete_add(account_clear_ac, "theme");
     autocomplete_add(account_clear_ac, "muc");
     autocomplete_add(account_clear_ac, "resource");
+    autocomplete_add(account_clear_ac, "session_alarm");
 
     account_default_ac = autocomplete_new();
     autocomplete_add(account_default_ac, "set");
diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c
index fe993e39..0dd7f10a 100644
--- a/src/command/cmd_defs.c
+++ b/src/command/cmd_defs.c
@@ -2070,6 +2070,7 @@ static const struct cmd_t command_defs[] = {
               "/account set <account> tls force|allow|trust|legacy|disable",
               "/account set <account> auth default|legacy",
               "/account set <account> theme <theme>",
+              "/account set <account> session_alarm <max_sessions>",
               "/account clear <account> password",
               "/account clear <account> eval_password",
               "/account clear <account> server",
@@ -2079,7 +2080,8 @@ static const struct cmd_t command_defs[] = {
               "/account clear <account> startscript",
               "/account clear <account> clientid",
               "/account clear <account> muc",
-              "/account clear <account> resource")
+              "/account clear <account> resource",
+              "/account clear <account> session_alarm")
       CMD_DESC(
               "Commands for creating and managing accounts. "
               "Calling with no arguments will display information for the current account.")
@@ -2116,6 +2118,7 @@ static const struct cmd_t command_defs[] = {
               { "set <account> auth default", "Use default authentication process." },
               { "set <account> auth legacy", "Allow legacy authentication." },
               { "set <account> theme <theme>", "Set the UI theme for the account." },
+              { "set <account> session_alarm <max_sessions>", "Alarm about suspicious activity if sessions count exceeds max_sessions." },
               { "clear <account> server", "Remove the server setting for this account." },
               { "clear <account> port", "Remove the port setting for this account." },
               { "clear <account> password", "Remove the password setting for this account." },
@@ -2126,7 +2129,8 @@ static const struct cmd_t command_defs[] = {
               { "clear <account> clientid", "Reset client's name to default." },
               { "clear <account> theme", "Clear the theme setting for the account, the global theme will be used." },
               { "clear <account> resource", "Remove the resource setting for this account." },
-              { "clear <account> muc", "Remove the default MUC service setting." })
+              { "clear <account> muc", "Remove the default MUC service setting." },
+              { "clear <account> session_alarm", "Disable the session alarm." })
       CMD_EXAMPLES(
               "/account add me",
               "/account set me jid ulfhednar@valhalla.edda",
diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c
index 7c533a45..4a5c7fa1 100644
--- a/src/command/cmd_funcs.c
+++ b/src/command/cmd_funcs.c
@@ -905,6 +905,28 @@ _account_set_auth(char* account_name, char* policy)
 }
 
 gboolean
+_account_set_max_sessions(char* account_name, char* max_sessions_raw)
+{
+    int max_sessions;
+    char* err_msg = NULL;
+    gboolean res = strtoi_range(max_sessions_raw, &max_sessions, 0, INT_MAX, &err_msg);
+    if (!res) {
+        cons_show(err_msg);
+        cons_show("");
+        free(err_msg);
+        return TRUE;
+    }
+    accounts_set_max_sessions(account_name, max_sessions);
+    if (max_sessions < 1) {
+        cons_show("Max sessions alarm for account %s has been disabled.", account_name);
+    } else {
+        cons_show("Max sessions alarm for account %s has been set to %d", account_name, max_sessions);
+    }
+    cons_show("");
+    return TRUE;
+}
+
+gboolean
 _account_set_presence_priority(char* account_name, char* presence, char* priority)
 {
     int intval;
@@ -997,6 +1019,8 @@ cmd_account_set(ProfWin* window, const char* const command, gchar** args)
         return _account_set_tls(account_name, value);
     if (strcmp(property, "auth") == 0)
         return _account_set_auth(account_name, value);
+    if (strcmp(property, "session_alarm") == 0)
+        return _account_set_max_sessions(account_name, value);
 
     if (valid_resource_presence_string(property)) {
         return _account_set_presence_priority(account_name, property, value);
@@ -1057,6 +1081,9 @@ cmd_account_clear(ProfWin* window, const char* const command, gchar** args)
     } else if (strcmp(property, "resource") == 0) {
         accounts_clear_resource(account_name);
         cons_show("Removed resource for account %s", account_name);
+    } else if (strcmp(property, "session_alarm") == 0) {
+        accounts_clear_max_sessions(account_name);
+        cons_show("Disabled session alarm for account %s", account_name);
     } else {
         cons_show("Invalid property: %s", property);
     }
diff --git a/src/config/account.c b/src/config/account.c
index 73740b3a..42fd1cd0 100644
--- a/src/config/account.c
+++ b/src/config/account.c
@@ -57,7 +57,7 @@ account_new(gchar* name, gchar* jid, gchar* password, gchar* eval_password, gboo
             gchar* omemo_policy, GList* omemo_enabled, GList* omemo_disabled,
             GList* ox_enabled, GList* pgp_enabled, gchar* pgp_keyid,
             gchar* startscript, gchar* theme, gchar* tls_policy, gchar* auth_policy,
-            gchar* client)
+            gchar* client, int max_sessions)
 {
     ProfAccount* new_account = calloc(1, sizeof(ProfAccount));
 
@@ -140,6 +140,8 @@ account_new(gchar* name, gchar* jid, gchar* password, gchar* eval_password, gboo
 
     new_account->auth_policy = auth_policy;
 
+    new_account->max_sessions = max_sessions;
+
     return new_account;
 }
 
diff --git a/src/config/account.h b/src/config/account.h
index f82a3e11..e8bda927 100644
--- a/src/config/account.h
+++ b/src/config/account.h
@@ -72,6 +72,7 @@ typedef struct prof_account_t
     gchar* tls_policy;
     gchar* auth_policy;
     gchar* client;
+    int max_sessions;
 } ProfAccount;
 
 ProfAccount* account_new(gchar* name, gchar* jid, gchar* password, gchar* eval_password, gboolean enabled,
@@ -82,7 +83,7 @@ ProfAccount* account_new(gchar* name, gchar* jid, gchar* password, gchar* eval_p
                          gchar* omemo_policy, GList* omemo_enabled, GList* omemo_disabled,
                          GList* ox_enabled, GList* pgp_enabled, gchar* pgp_keyid,
                          gchar* startscript, gchar* theme, gchar* tls_policy, gchar* auth_policy,
-                         gchar* client);
+                         gchar* client, int max_sessions);
 char* account_create_connect_jid(ProfAccount* account);
 gboolean account_eval_password(ProfAccount* account);
 void account_free(ProfAccount* account);
diff --git a/src/config/accounts.c b/src/config/accounts.c
index f7e6e456..d5747cbf 100644
--- a/src/config/accounts.c
+++ b/src/config/accounts.c
@@ -347,13 +347,15 @@ accounts_get_account(const char* const name)
 
         gchar* auth_policy = g_key_file_get_string(accounts, name, "auth.policy", NULL);
 
+        int max_sessions = g_key_file_get_integer(accounts, name, "max.sessions", 0);
+
         ProfAccount* new_account = account_new(g_strdup(name), jid, password, eval_password, enabled,
                                                server, port, resource, last_presence, login_presence,
                                                priority_online, priority_chat, priority_away, priority_xa,
                                                priority_dnd, muc_service, muc_nick, otr_policy, otr_manual,
                                                otr_opportunistic, otr_always, omemo_policy, omemo_enabled,
                                                omemo_disabled, ox_enabled, pgp_enabled, pgp_keyid,
-                                               startscript, theme, tls_policy, auth_policy, client);
+                                               startscript, theme, tls_policy, auth_policy, client, max_sessions);
 
         return new_account;
     }
@@ -569,6 +571,12 @@ accounts_set_theme(const char* const account_name, const char* const value)
 }
 
 void
+accounts_set_max_sessions(const char* const account_name, const int value)
+{
+    _accounts_set_int_option(account_name, "max.sessions", value);
+}
+
+void
 accounts_clear_password(const char* const account_name)
 {
     _accounts_clear_string_option(account_name, "password");
@@ -635,6 +643,12 @@ accounts_clear_otr(const char* const account_name)
 }
 
 void
+accounts_clear_max_sessions(const char* const account_name)
+{
+    _accounts_clear_string_option(account_name, "max.sessions");
+}
+
+void
 accounts_add_otr_policy(const char* const account_name, const char* const contact_jid, const char* const policy)
 {
     if (accounts_account_exists(account_name)) {
@@ -865,6 +879,24 @@ accounts_get_last_activity(const char* const account_name)
     }
 }
 
+char*
+accounts_get_resource(const char* const account_name)
+{
+    if (!accounts_account_exists(account_name)) {
+        return NULL;
+    }
+    return g_key_file_get_string(accounts, account_name, "resource", NULL);
+}
+
+int
+accounts_get_max_sessions(const char* const account_name)
+{
+    if (!accounts_account_exists(account_name)) {
+        return 0;
+    }
+    return g_key_file_get_integer(accounts, account_name, "max.sessions", 0);
+}
+
 void
 accounts_set_login_presence(const char* const account_name, const char* const value)
 {
diff --git a/src/config/accounts.h b/src/config/accounts.h
index c5b829c0..8d111544 100644
--- a/src/config/accounts.h
+++ b/src/config/accounts.h
@@ -61,6 +61,7 @@ void accounts_set_jid(const char* const account_name, const char* const value);
 void accounts_set_server(const char* const account_name, const char* const value);
 void accounts_set_port(const char* const account_name, const int value);
 void accounts_set_resource(const char* const account_name, const char* const value);
+char* accounts_get_resource(const char* const account_name);
 void accounts_set_password(const char* const account_name, const char* const value);
 void accounts_set_eval_password(const char* const account_name, const char* const value);
 void accounts_set_muc_service(const char* const account_name, const char* const value);
@@ -89,6 +90,8 @@ void accounts_set_pgp_keyid(const char* const account_name, const char* const va
 void accounts_set_script_start(const char* const account_name, const char* const value);
 void accounts_set_client(const char* const account_name, const char* const value);
 void accounts_set_theme(const char* const account_name, const char* const value);
+void accounts_set_max_sessions(const char* const account_name, const int value);
+int accounts_get_max_sessions(const char* const account_name);
 void accounts_clear_password(const char* const account_name);
 void accounts_clear_eval_password(const char* const account_name);
 void accounts_clear_server(const char* const account_name);
@@ -100,6 +103,7 @@ void accounts_clear_client(const char* const account_name);
 void accounts_clear_theme(const char* const account_name);
 void accounts_clear_muc(const char* const account_name);
 void accounts_clear_resource(const char* const account_name);
+void accounts_clear_max_sessions(const char* const account_name);
 void accounts_add_otr_policy(const char* const account_name, const char* const contact_jid, const char* const policy);
 void accounts_add_omemo_state(const char* const account_name, const char* const contact_jid, gboolean enabled);
 void accounts_add_ox_state(const char* const account_name, const char* const contact_jid, gboolean enabled);
diff --git a/src/ui/console.c b/src/ui/console.c
index d26e559f..b57ac6f4 100644
--- a/src/ui/console.c
+++ b/src/ui/console.c
@@ -1067,6 +1067,9 @@ cons_show_account(ProfAccount* account)
     if (account->client) {
         cons_show("Client name       : %s", account->client);
     }
+    if (account->max_sessions > 0) {
+        cons_show("Max sessions alarm: %d", account->max_sessions);
+    }
     if (account->theme) {
         cons_show("Theme             : %s", account->theme);
     }
@@ -1123,11 +1126,12 @@ cons_show_account(ProfAccount* account)
 
     if ((connection_get_status() == JABBER_CONNECTED) && (g_strcmp0(session_get_account_name(), account->name) == 0)) {
         GList* resources = connection_get_available_resources();
+        int resources_count = connection_count_available_resources();
         GList* ordered_resources = NULL;
 
         GList* curr = resources;
         if (curr) {
-            win_println(console, THEME_DEFAULT, "-", "Resources:");
+            win_println(console, THEME_DEFAULT, "-", "Resources (%u):", resources_count);
 
             // sort in order of availability
             while (curr) {
diff --git a/src/xmpp/connection.c b/src/xmpp/connection.c
index 9c398c73..eef395f1 100644
--- a/src/xmpp/connection.c
+++ b/src/xmpp/connection.c
@@ -776,6 +776,12 @@ connection_get_available_resources(void)
     return g_hash_table_get_values(conn.available_resources);
 }
 
+int
+connection_count_available_resources(void)
+{
+    return g_hash_table_size(conn.available_resources);
+}
+
 void
 connection_add_available_resource(Resource* resource)
 {
diff --git a/src/xmpp/presence.c b/src/xmpp/presence.c
index 17e30d75..fd265535 100644
--- a/src/xmpp/presence.c
+++ b/src/xmpp/presence.c
@@ -51,6 +51,8 @@
 #include "event/server_events.h"
 #include "plugins/plugins.h"
 #include "ui/ui.h"
+#include "ui/window.h"
+#include "ui/window_list.h"
 #include "xmpp/connection.h"
 #include "xmpp/capabilities.h"
 #include "xmpp/session.h"
@@ -656,6 +658,68 @@ _available_handler(xmpp_stanza_t* const stanza)
 
     if (g_strcmp0(xmpp_presence->jid->barejid, my_jid->barejid) == 0) {
         connection_add_available_resource(resource);
+        const char* account_name = session_get_account_name();
+        int max_sessions = accounts_get_max_sessions(account_name);
+        if (max_sessions > 0) {
+            const char* cur_resource = accounts_get_resource(account_name);
+            int res_count = connection_count_available_resources();
+            if (res_count > max_sessions && g_strcmp0(cur_resource, resource->name)) {
+                ProfWin* console = wins_get_console();
+                ProfWin* current_window = wins_get_current();
+                auto_gchar gchar* message = g_strdup_printf("Max sessions alarm! (%d/%d devices in use)", res_count, max_sessions);
+                win_println(console, THEME_RED, "|", "%s", message);
+                if (console != current_window) {
+                    win_println(current_window, THEME_RED, "|", "%s - check the console for more details!", message);
+                }
+                notify(message, 10000, "Security alert");
+
+                const char* resource_presence = string_from_resource_presence(resource->presence);
+                win_print(console, THEME_DEFAULT, "|", "New device info: \n    %s (%d), %s", resource->name, resource->priority, resource_presence);
+
+                if (resource->status) {
+                    win_append(console, THEME_DEFAULT, ", \"%s\"", resource->status);
+                }
+                win_appendln(console, THEME_DEFAULT, "");
+                auto_jid Jid* jidp = jid_create_from_bare_and_resource(my_jid->barejid, resource->name);
+                EntityCapabilities* caps = caps_lookup(jidp->fulljid);
+
+                if (caps) {
+                    if (caps->identity) {
+                        DiscoIdentity* identity = caps->identity;
+                        win_print(console, THEME_DEFAULT, "|", "    %s %s %s", identity->name, identity->type, identity->category);
+                        win_newline(console);
+                    }
+
+                    if (caps->software_version) {
+                        SoftwareVersion* software_version = caps->software_version;
+                        if (software_version->software) {
+                            win_print(console, THEME_DEFAULT, "|", "    Software: %s", software_version->software);
+                        }
+                        if (software_version->software_version) {
+                            win_append(console, THEME_DEFAULT, ", %s", software_version->software_version);
+                        }
+                        if (software_version->software || software_version->software_version) {
+                            win_newline(console);
+                        }
+                        if (software_version->os) {
+                            win_print(console, THEME_DEFAULT, "|", "    OS: %s", software_version->os);
+                        }
+                        if (software_version->os_version) {
+                            win_append(console, THEME_DEFAULT, ", %s", software_version->os_version);
+                        }
+                        if (software_version->os || software_version->os_version) {
+                            win_newline(console);
+                        }
+                    }
+
+                    caps_destroy(caps);
+                }
+
+                win_println(console, THEME_RED_BOLD, "|", "If it wasn't you, change your password. Use: /changepassword");
+                win_println(console, THEME_GREEN, "|", "If it was you, update the `session_alarm` limit that determines when to trigger this alarm, use: /account set %s session_alarm %d", account_name, res_count);
+                cons_alert(NULL);
+            }
+        }
     } else {
         char* pgpsig = NULL;
         xmpp_stanza_t* x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_SIGNED);
diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h
index 3cbb5227..539126cd 100644
--- a/src/xmpp/xmpp.h
+++ b/src/xmpp/xmpp.h
@@ -199,6 +199,7 @@ TLSCertificate* connection_get_tls_peer_cert(void);
 gboolean connection_is_secured(void);
 gboolean connection_send_stanza(const char* const stanza);
 GList* connection_get_available_resources(void);
+int connection_count_available_resources(void);
 gboolean connection_supports(const char* const feature);
 char* connection_jid_for_feature(const char* const feature);
 
diff --git a/tests/unittests/config/stub_accounts.c b/tests/unittests/config/stub_accounts.c
index cea8a76a..e1f9ed09 100644
--- a/tests/unittests/config/stub_accounts.c
+++ b/tests/unittests/config/stub_accounts.c
@@ -183,6 +183,10 @@ accounts_set_theme(const char* const account_name, const char* const value)
 {
 }
 void
+accounts_set_max_sessions(const char* const account_name, const int value)
+{
+}
+void
 accounts_set_tls_policy(const char* const account_name, const char* const value)
 {
 }
@@ -314,6 +318,10 @@ accounts_clear_resource(const char* const account_name)
 {
 }
 void
+accounts_clear_max_sessions(const char* const account_name)
+{
+}
+void
 accounts_add_otr_policy(const char* const account_name, const char* const contact_jid, const char* const policy)
 {
 }
diff --git a/tests/unittests/test_cmd_account.c b/tests/unittests/test_cmd_account.c
index 2a65a875..76f5a594 100644
--- a/tests/unittests/test_cmd_account.c
+++ b/tests/unittests/test_cmd_account.c
@@ -34,7 +34,7 @@ void
 cmd_account_shows_account_when_connected_and_no_args(void** state)
 {
     ProfAccount* account = account_new(g_strdup("jabber_org"), g_strdup("me@jabber.org"), NULL, NULL,
-                                       TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+                                       TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0);
     gchar* args[] = { NULL };
 
     will_return(connection_get_status, JABBER_CONNECTED);
@@ -98,7 +98,7 @@ cmd_account_show_shows_account_when_exists(void** state)
 {
     gchar* args[] = { "show", "account_name", NULL };
     ProfAccount* account = account_new(g_strdup("jabber_org"), g_strdup("me@jabber.org"), NULL, NULL,
-                                       TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+                                       TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0);
 
     expect_any(accounts_get_account, name);
     will_return(accounts_get_account, account);
@@ -437,7 +437,7 @@ cmd_account_set_password_sets_password(void** state)
 {
     gchar* args[] = { "set", "a_account", "password", "a_password", NULL };
     ProfAccount* account = account_new(g_strdup("a_account"), NULL, NULL, NULL,
-                                       TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+                                       TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0);
 
     expect_any(accounts_account_exists, account_name);
     will_return(accounts_account_exists, TRUE);
@@ -460,7 +460,7 @@ cmd_account_set_eval_password_sets_eval_password(void** state)
 {
     gchar* args[] = { "set", "a_account", "eval_password", "a_password", NULL };
     ProfAccount* account = account_new(g_strdup("a_account"), NULL, NULL, NULL,
-                                       TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+                                       TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0);
 
     expect_any(accounts_account_exists, account_name);
     will_return(accounts_account_exists, TRUE);
@@ -483,7 +483,7 @@ cmd_account_set_password_when_eval_password_set(void** state)
 {
     gchar* args[] = { "set", "a_account", "password", "a_password", NULL };
     ProfAccount* account = account_new(g_strdup("a_account"), NULL, NULL, g_strdup("a_password"),
-                                       TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+                                       TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0);
 
     expect_any(accounts_account_exists, account_name);
     will_return(accounts_account_exists, TRUE);
@@ -502,7 +502,7 @@ cmd_account_set_eval_password_when_password_set(void** state)
 {
     gchar* args[] = { "set", "a_account", "eval_password", "a_password", NULL };
     ProfAccount* account = account_new(g_strdup("a_account"), NULL, g_strdup("a_password"), NULL,
-                                       TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+                                       TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0);
 
     expect_any(accounts_account_exists, account_name);
     will_return(accounts_account_exists, TRUE);
@@ -853,7 +853,7 @@ cmd_account_set_priority_updates_presence_when_account_connected_with_presence(v
 
 #ifdef HAVE_LIBGPGME
     ProfAccount* account = account_new(g_strdup("a_account"), g_strdup("a_jid"), NULL, NULL, TRUE, NULL, 5222, g_strdup("a_resource"),
-                                       NULL, NULL, 10, 10, 10, 10, 10, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+                                       NULL, NULL, 10, 10, 10, 10, 10, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0);
 
     will_return(session_get_account_name, "a_account");
     expect_any(accounts_get_account, name);
diff --git a/tests/unittests/test_cmd_connect.c b/tests/unittests/test_cmd_connect.c
index 8def6b64..98e1884d 100644
--- a/tests/unittests/test_cmd_connect.c
+++ b/tests/unittests/test_cmd_connect.c
@@ -124,7 +124,7 @@ cmd_connect_lowercases_argument_with_account(void** state)
 {
     gchar* args[] = { "Jabber_org", NULL };
     ProfAccount* account = account_new(g_strdup("Jabber_org"), g_strdup("me@jabber.org"), g_strdup("password"), NULL,
-                                       TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+                                       TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0);
 
     will_return(connection_get_status, JABBER_DISCONNECTED);
 
@@ -145,7 +145,7 @@ cmd_connect_asks_password_when_not_in_account(void** state)
 {
     gchar* args[] = { "jabber_org", NULL };
     ProfAccount* account = account_new(g_strdup("jabber_org"), g_strdup("me@jabber.org"), NULL, NULL,
-                                       TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+                                       TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0);
 
     will_return(connection_get_status, JABBER_DISCONNECTED);
 
@@ -408,7 +408,7 @@ cmd_connect_shows_message_when_connecting_with_account(void** state)
 {
     gchar* args[] = { "jabber_org", NULL };
     ProfAccount* account = account_new(g_strdup("jabber_org"), g_strdup("user@jabber.org"), g_strdup("password"), NULL,
-                                       TRUE, NULL, 0, g_strdup("laptop"), NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+                                       TRUE, NULL, 0, g_strdup("laptop"), NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0);
 
     will_return(connection_get_status, JABBER_DISCONNECTED);
 
@@ -429,7 +429,7 @@ cmd_connect_connects_with_account(void** state)
 {
     gchar* args[] = { "jabber_org", NULL };
     ProfAccount* account = account_new(g_strdup("jabber_org"), g_strdup("me@jabber.org"), g_strdup("password"), NULL,
-                                       TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+                                       TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0);
 
     will_return(connection_get_status, JABBER_DISCONNECTED);
 
diff --git a/tests/unittests/test_cmd_join.c b/tests/unittests/test_cmd_join.c
index 9d6c2eeb..77e3dc74 100644
--- a/tests/unittests/test_cmd_join.c
+++ b/tests/unittests/test_cmd_join.c
@@ -71,7 +71,7 @@ cmd_join_uses_account_mucservice_when_no_service_specified(void** state)
     char* expected_room = "room@conference.server.org";
     gchar* args[] = { room, "nick", nick, NULL };
     ProfAccount* account = account_new(account_name, g_strdup("user@server.org"), NULL, NULL,
-                                       TRUE, NULL, 0, g_strdup("laptop"), NULL, NULL, 0, 0, 0, 0, 0, account_service, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+                                       TRUE, NULL, 0, g_strdup("laptop"), NULL, NULL, 0, 0, 0, 0, 0, account_service, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0);
 
     muc_init();
 
@@ -99,7 +99,7 @@ cmd_join_uses_supplied_nick(void** state)
     char* nick = "bob";
     gchar* args[] = { room, "nick", nick, NULL };
     ProfAccount* account = account_new(account_name, g_strdup("user@server.org"), NULL, NULL,
-                                       TRUE, NULL, 0, g_strdup("laptop"), NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+                                       TRUE, NULL, 0, g_strdup("laptop"), NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0);
 
     muc_init();
 
@@ -127,7 +127,7 @@ cmd_join_uses_account_nick_when_not_supplied(void** state)
     char* account_nick = g_strdup("a_nick");
     gchar* args[] = { room, NULL };
     ProfAccount* account = account_new(account_name, g_strdup("user@server.org"), NULL, NULL,
-                                       TRUE, NULL, 0, g_strdup("laptop"), NULL, NULL, 0, 0, 0, 0, 0, NULL, account_nick, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+                                       TRUE, NULL, 0, g_strdup("laptop"), NULL, NULL, 0, 0, 0, 0, 0, NULL, account_nick, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0);
 
     muc_init();
 
@@ -158,7 +158,7 @@ cmd_join_uses_password_when_supplied(void** state)
     char* expected_room = "room@a_service";
     gchar* args[] = { room, "password", password, NULL };
     ProfAccount* account = account_new(account_name, g_strdup("user@server.org"), NULL, NULL,
-                                       TRUE, NULL, 0, g_strdup("laptop"), NULL, NULL, 0, 0, 0, 0, 0, account_service, account_nick, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+                                       TRUE, NULL, 0, g_strdup("laptop"), NULL, NULL, 0, 0, 0, 0, 0, account_service, account_nick, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0);
 
     muc_init();
 
diff --git a/tests/unittests/test_cmd_otr.c b/tests/unittests/test_cmd_otr.c
index ae492cf1..d5136d97 100644
--- a/tests/unittests/test_cmd_otr.c
+++ b/tests/unittests/test_cmd_otr.c
@@ -196,7 +196,7 @@ cmd_otr_gen_generates_key_for_connected_account(void** state)
     gchar* args[] = { "gen", NULL };
     char* account_name = g_strdup("myaccount");
     ProfAccount* account = account_new(account_name, g_strdup("me@jabber.org"), NULL, NULL,
-                                       TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+                                       TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0);
 
     will_return(connection_get_status, JABBER_CONNECTED);
     will_return(session_get_account_name, account_name);
diff --git a/tests/unittests/test_cmd_rooms.c b/tests/unittests/test_cmd_rooms.c
index 60fca1ce..0800bf20 100644
--- a/tests/unittests/test_cmd_rooms.c
+++ b/tests/unittests/test_cmd_rooms.c
@@ -51,7 +51,7 @@ cmd_rooms_uses_account_default_when_no_arg(void** state)
     gchar* args[] = { NULL };
 
     ProfAccount* account = account_new(g_strdup("testaccount"), NULL, NULL, NULL, TRUE, NULL, 0, NULL, NULL, NULL,
-                                       0, 0, 0, 0, 0, g_strdup("default_conf_server"), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+                                       0, 0, 0, 0, 0, g_strdup("default_conf_server"), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0);
 
     will_return(connection_get_status, JABBER_CONNECTED);
     will_return(session_get_account_name, "account_name");
@@ -91,7 +91,7 @@ cmd_rooms_filter_arg_used_when_passed(void** state)
     gchar* args[] = { "filter", "text", NULL };
 
     ProfAccount* account = account_new(g_strdup("testaccount"), NULL, NULL, NULL, TRUE, NULL, 0, NULL, NULL, NULL,
-                                       0, 0, 0, 0, 0, g_strdup("default_conf_server"), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+                                       0, 0, 0, 0, 0, g_strdup("default_conf_server"), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0);
 
     will_return(connection_get_status, JABBER_CONNECTED);
     will_return(session_get_account_name, "account_name");