diff --git a/src/command/commands.c b/src/command/commands.c index 27b03c53..45e1c730 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -2689,6 +2689,10 @@ cmd_otr(gchar **args, struct cmd_help_t help) cons_show("OTR policy is now set to: %s", choice); return TRUE; } else { + if (jabber_get_connection_status() != JABBER_CONNECTED) { + cons_show("You must be connected to set the OTR policy for a contact."); + return TRUE; + } char *contact_jid = roster_barejid_from_name(contact); if (contact_jid == NULL) { contact_jid = contact; diff --git a/src/config/account.c b/src/config/account.c index d982fb88..e019bf83 100644 --- a/src/config/account.c +++ b/src/config/account.c @@ -34,7 +34,9 @@ account_new(const gchar * const name, const gchar * const jid, int port, const gchar * const resource, const gchar * const last_presence, const gchar * const login_presence, int priority_online, int priority_chat, int priority_away, int priority_xa, int priority_dnd, - const gchar * const muc_service, const gchar * const muc_nick, const gchar * const otr_policy) + const gchar * const muc_service, const gchar * const muc_nick, + const gchar * const otr_policy, GList *otr_manual, GList *otr_opportunistic, + GList *otr_always) { ProfAccount *new_account = malloc(sizeof(ProfAccount)); @@ -117,6 +119,10 @@ account_new(const gchar * const name, const gchar * const jid, new_account->otr_policy = NULL; } + new_account->otr_manual = otr_manual; + new_account->otr_opportunistic = otr_opportunistic; + new_account->otr_always = otr_always; + return new_account; } @@ -144,6 +150,9 @@ account_free(ProfAccount *account) free(account->muc_service); free(account->muc_nick); free(account->otr_policy); + g_list_free_full(account->otr_manual, g_free); + g_list_free_full(account->otr_opportunistic, g_free); + g_list_free_full(account->otr_always, g_free); free(account); } } \ No newline at end of file diff --git a/src/config/account.h b/src/config/account.h index 549e9124..9943538f 100644 --- a/src/config/account.h +++ b/src/config/account.h @@ -43,6 +43,9 @@ typedef struct prof_account_t { gchar *muc_nick; gboolean enabled; gchar *otr_policy; + GList *otr_manual; + GList *otr_opportunistic; + GList *otr_always; } ProfAccount; ProfAccount* account_new(const gchar * const name, const gchar * const jid, @@ -50,7 +53,9 @@ ProfAccount* account_new(const gchar * const name, const gchar * const jid, int port, const gchar * const resource, const gchar * const last_presence, const gchar * const login_presence, int priority_online, int priority_chat, int priority_away, int priority_xa, int priority_dnd, - const gchar * const muc_service, const gchar * const muc_nick, const gchar * const otr_policy); + const gchar * const muc_service, const gchar * const muc_nick, + const gchar * const otr_policy, GList *otr_manual, GList *otr_opportunistic, + GList *otr_always); char* account_create_full_jid(ProfAccount *account); diff --git a/src/config/accounts.c b/src/config/accounts.c index 79b9eceb..56c1b5c8 100644 --- a/src/config/accounts.c +++ b/src/config/accounts.c @@ -220,10 +220,42 @@ _accounts_get_account(const char * const name) otr_policy = g_key_file_get_string(accounts, name, "otr.policy", NULL); } + gsize length; + GList *otr_manual = NULL; + gchar **manual = g_key_file_get_string_list(accounts, name, "otr.manual", &length, NULL); + if (manual != NULL) { + int i = 0; + for (i = 0; i < length; i++) { + otr_manual = g_list_append(otr_manual, strdup(manual[i])); + } + g_strfreev(manual); + } + + GList *otr_opportunistic = NULL; + gchar **opportunistic = g_key_file_get_string_list(accounts, name, "otr.opportunistic", &length, NULL); + if (opportunistic != NULL) { + int i = 0; + for (i = 0; i < length; i++) { + otr_opportunistic = g_list_append(otr_opportunistic, strdup(opportunistic[i])); + } + g_strfreev(opportunistic); + } + + GList *otr_always = NULL; + gchar **always = g_key_file_get_string_list(accounts, name, "otr.always", &length, NULL); + if (always != NULL) { + int i = 0; + for (i = 0; i < length; i++) { + otr_always = g_list_append(otr_always, strdup(always[i])); + } + g_strfreev(always); + } + ProfAccount *new_account = account_new(name, jid, 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); + priority_dnd, muc_service, muc_nick, otr_policy, otr_manual, + otr_opportunistic, otr_always); g_free(jid); g_free(password); diff --git a/src/otr/otr.c b/src/otr/otr.c index 72e6817a..58b401d7 100644 --- a/src/otr/otr.c +++ b/src/otr/otr.c @@ -519,15 +519,44 @@ _otr_get_their_fingerprint(const char * const recipient) static char * _otr_get_policy(const char * const recipient) { - // check account setting ProfAccount *account = accounts_get_account(jabber_get_account_name()); - if (account->otr_policy != NULL) { + // check contact specific setting + if (g_list_find_custom(account->otr_manual, recipient, (GCompareFunc)g_strcmp0)) { + cons_debug("Using contact setting manual"); account_free(account); - return account->otr_policy; + return "manual"; + } + if (g_list_find_custom(account->otr_opportunistic, recipient, (GCompareFunc)g_strcmp0)) { + cons_debug("Using contact setting opportunistic"); + account_free(account); + return "opportunistic"; + } + if (g_list_find_custom(account->otr_always, recipient, (GCompareFunc)g_strcmp0)) { + cons_debug("Using contact setting always"); + account_free(account); + return "always"; + } + + // check default account setting + if (account->otr_policy != NULL) { + cons_debug("Using account setting %s", account->otr_policy); + char *result; + if (g_strcmp0(account->otr_policy, "manual") == 0) { + result = "manual"; + } + if (g_strcmp0(account->otr_policy, "opportunistic") == 0) { + result = "opportunistic"; + } + if (g_strcmp0(account->otr_policy, "always") == 0) { + result = "always"; + } + account_free(account); + return result; } account_free(account); // check global setting + cons_debug("Using global setting %s", prefs_get_string(PREF_OTR_POLICY)); return prefs_get_string(PREF_OTR_POLICY); } diff --git a/tests/test_cmd_account.c b/tests/test_cmd_account.c index d03d757b..ea8ecc93 100644 --- a/tests/test_cmd_account.c +++ b/tests/test_cmd_account.c @@ -40,7 +40,7 @@ void cmd_account_shows_account_when_connected_and_no_args(void **state) mock_accounts_get_account(); CommandHelp *help = malloc(sizeof(CommandHelp)); ProfAccount *account = account_new("jabber_org", "me@jabber.org", NULL, - TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL); + TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL); gchar *args[] = { NULL }; mock_connection_status(JABBER_CONNECTED); @@ -119,7 +119,7 @@ void cmd_account_show_shows_account_when_exists(void **state) CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "show", "account_name", NULL }; ProfAccount *account = account_new("jabber_org", "me@jabber.org", NULL, - TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL); + TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL); accounts_get_account_return(account); diff --git a/tests/test_cmd_connect.c b/tests/test_cmd_connect.c index 1007c034..831db3a4 100644 --- a/tests/test_cmd_connect.c +++ b/tests/test_cmd_connect.c @@ -424,7 +424,7 @@ void cmd_connect_asks_password_when_not_in_account(void **state) CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "jabber_org", NULL }; ProfAccount *account = account_new("jabber_org", "me@jabber.org", NULL, - TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL); + TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL); mock_connection_status(JABBER_DISCONNECTED); @@ -448,7 +448,7 @@ void cmd_connect_shows_message_when_connecting_with_account(void **state) CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "jabber_org", NULL }; ProfAccount *account = account_new("jabber_org", "user@jabber.org", "password", - TRUE, NULL, 0, "laptop", NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL); + TRUE, NULL, 0, "laptop", NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL); mock_connection_status(JABBER_DISCONNECTED); @@ -472,7 +472,7 @@ void cmd_connect_connects_with_account(void **state) CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "jabber_org", NULL }; ProfAccount *account = account_new("jabber_org", "me@jabber.org", "password", - TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL); + TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL); mock_connection_status(JABBER_DISCONNECTED); diff --git a/tests/test_cmd_join.c b/tests/test_cmd_join.c index 134a99ab..8fddd551 100644 --- a/tests/test_cmd_join.c +++ b/tests/test_cmd_join.c @@ -98,7 +98,7 @@ void cmd_join_uses_account_mucservice_when_no_service_specified(void **state) CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { room, "nick", nick, NULL }; ProfAccount *account = account_new(account_name, "user@server.org", NULL, - TRUE, NULL, 0, "laptop", NULL, NULL, 0, 0, 0, 0, 0, account_service, NULL, NULL); + TRUE, NULL, 0, "laptop", NULL, NULL, 0, 0, 0, 0, 0, account_service, NULL, NULL, NULL, NULL, NULL); muc_init(); @@ -124,7 +124,7 @@ void cmd_join_uses_supplied_nick(void **state) CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { room, "nick", nick, NULL }; ProfAccount *account = account_new(account_name, "user@server.org", NULL, - TRUE, NULL, 0, "laptop", NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL); + TRUE, NULL, 0, "laptop", NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL); muc_init(); @@ -150,7 +150,7 @@ void cmd_join_uses_account_nick_when_not_supplied(void **state) CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { room, NULL }; ProfAccount *account = account_new(account_name, "user@server.org", NULL, - TRUE, NULL, 0, "laptop", NULL, NULL, 0, 0, 0, 0, 0, NULL, account_nick, NULL); + TRUE, NULL, 0, "laptop", NULL, NULL, 0, 0, 0, 0, 0, NULL, account_nick, NULL, NULL, NULL, NULL); muc_init(); @@ -179,7 +179,7 @@ void cmd_join_uses_password_when_supplied(void **state) CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { room, "password", password, NULL }; ProfAccount *account = account_new(account_name, "user@server.org", NULL, - TRUE, NULL, 0, "laptop", NULL, NULL, 0, 0, 0, 0, 0, account_service, account_nick, NULL); + TRUE, NULL, 0, "laptop", NULL, NULL, 0, 0, 0, 0, 0, account_service, account_nick, NULL, NULL, NULL, NULL); muc_init(); diff --git a/tests/test_cmd_otr.c b/tests/test_cmd_otr.c index e6c87941..1c00a057 100644 --- a/tests/test_cmd_otr.c +++ b/tests/test_cmd_otr.c @@ -325,7 +325,7 @@ void cmd_otr_gen_generates_key_for_connected_account(void **state) gchar *args[] = { "gen", NULL }; char *account_name = "myaccount"; ProfAccount *account = account_new(account_name, "me@jabber.org", NULL, - TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL); + TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL); stub_cons_show(); mock_connection_status(JABBER_CONNECTED);