diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/command/command.c | 12 | ||||
-rw-r--r-- | src/command/commands.c | 85 | ||||
-rw-r--r-- | src/config/preferences.c | 14 | ||||
-rw-r--r-- | src/muc.c | 30 | ||||
-rw-r--r-- | src/muc.h | 4 | ||||
-rw-r--r-- | src/otr/otrlibv3.c | 2 | ||||
-rw-r--r-- | src/server_events.c | 74 | ||||
-rw-r--r-- | src/server_events.h | 2 | ||||
-rw-r--r-- | src/ui/core.c | 12 | ||||
-rw-r--r-- | src/ui/ui.h | 3 | ||||
-rw-r--r-- | src/xmpp/bookmark.c | 2 | ||||
-rw-r--r-- | src/xmpp/presence.c | 22 | ||||
-rw-r--r-- | src/xmpp/stanza.h | 1 |
13 files changed, 158 insertions, 105 deletions
diff --git a/src/command/command.c b/src/command/command.c index 902ef19a..82e53c05 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -596,7 +596,7 @@ static struct cmd_t command_defs[] = cmd_otr, parse_args, 1, 2, NULL, { "/otr gen|myfp|theirfp|start|end|trust|untrust|log|warn|libver|policy", "Off The Record encryption commands.", { "/otr gen|myfp|theirfp|start|end|trust|untrust|log|warn|libver|policy", - "-------------------------------------------------------------", + "--------------------------------------------------------------------", "gen - Generate your private key.", "myfp - Show your fingerprint.", "theirfp - Show contacts fingerprint.", @@ -607,7 +607,7 @@ static struct cmd_t command_defs[] = "log - How to log OTR messages, options are 'on', 'off' and 'redact', with redaction being the default.", "warn - Show when unencrypted messaging is being used in the title bar, options are 'on' and 'off' with 'on' being the default.", "libver - Show which version of the libotr library is being used.", - "policy - manual, opportunistic or always.", + "policy - manual, opportunistic or always.", NULL } } }, { "/outtype", @@ -1328,10 +1328,10 @@ cmd_execute_default(const char * const inp) ui_current_print_line("You are not currently connected."); } else { #ifdef HAVE_LIBOTR - if ((strcmp(prefs_get_string(PREF_OTR_POLICY), "always") == 0) && !otr_is_secure(recipient)) { - cons_show_error("Failed to send message. Please check OTR policy"); - return TRUE; - } + if ((strcmp(prefs_get_string(PREF_OTR_POLICY), "always") == 0) && !otr_is_secure(recipient)) { + cons_show_error("Failed to send message. Please check OTR policy"); + return TRUE; + } if (otr_is_secure(recipient)) { char *encrypted = otr_encrypt_message(recipient, inp); if (encrypted != NULL) { diff --git a/src/command/commands.c b/src/command/commands.c index 54310c76..c0729630 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -968,25 +968,24 @@ cmd_msg(gchar **args, struct cmd_help_t help) cons_show_error("Failed to encrypt and send message,"); } } else { - char *policy = prefs_get_string(PREF_OTR_POLICY); - - if (strcmp(policy, "always") == 0) - { - cons_show_error("Failed to send message. Please check OTR policy"); - return TRUE; - } else if (strcmp(policy, "opportunistic") == 0) { - char *otr_base_tag = OTRL_MESSAGE_TAG_BASE; - char *otr_v2_tag = OTRL_MESSAGE_TAG_V2; - int N = strlen(otr_base_tag) + strlen(otr_v2_tag) + strlen(msg) + 1; - char *temp = (char *) malloc( (unsigned) N*sizeof(char *) ); - strcpy( temp , msg ); - strcat( temp , otr_base_tag); - strcat( temp, otr_v2_tag); - message_send(temp, usr_jid); - free(temp); - } else { - message_send(msg, usr_jid); - } + char *policy = prefs_get_string(PREF_OTR_POLICY); + + if (strcmp(policy, "always") == 0) { + cons_show_error("Failed to send message. Please check OTR policy"); + return TRUE; + } else if (strcmp(policy, "opportunistic") == 0) { + char *otr_base_tag = OTRL_MESSAGE_TAG_BASE; + char *otr_v2_tag = OTRL_MESSAGE_TAG_V2; + int N = strlen(otr_base_tag) + strlen(otr_v2_tag) + strlen(msg) + 1; + char *temp = (char *) malloc( (unsigned) N*sizeof(char *) ); + strcpy( temp , msg ); + strcat( temp , otr_base_tag); + strcat( temp, otr_v2_tag); + message_send(temp, usr_jid); + free(temp); + } else { + message_send(msg, usr_jid); + } ui_outgoing_msg("me", usr_jid, msg); if (((win_type == WIN_CHAT) || (win_type == WIN_CONSOLE)) && prefs_get_boolean(PREF_CHLOG)) { @@ -1610,9 +1609,10 @@ cmd_join(gchar **args, struct cmd_help_t help) if (!muc_room_is_active(room)) { presence_join_room(room, nick, passwd); + muc_join_room(room, nick, passwd, FALSE); + } else if (muc_get_roster_received(room)) { + ui_room_join(room, TRUE); } - ui_room_join(room, TRUE); - muc_remove_invite(room); jid_destroy(room_arg); g_string_free(room_str, TRUE); @@ -2629,29 +2629,26 @@ cmd_otr(gchar **args, struct cmd_help_t help) cons_show("Using libotr version %s", version); return TRUE; } else if (strcmp(args[0], "policy") == 0) { - if (args[1] == NULL) { - char *policy = prefs_get_string(PREF_OTR_POLICY); - cons_show("OTR policy is now set to: %s", policy); - return TRUE; - } - - char *choice = args[1]; - if (g_strcmp0(choice, "manual") == 0) { - prefs_set_string(PREF_OTR_POLICY, "manual"); - cons_show("OTR policy is now set to: manual"); - } else - if (g_strcmp0(choice, "opportunistic") == 0) { - prefs_set_string(PREF_OTR_POLICY, "opportunistic"); - cons_show("OTR policy is now set to: opportunistic"); - } else - if (g_strcmp0(choice, "always") == 0) { - prefs_set_string(PREF_OTR_POLICY, "always"); - cons_show("OTR policy is now set to: always"); - } else - { - cons_show("OTR policy can be set to: manual, opportunistic or always."); - } - return TRUE; + if (args[1] == NULL) { + char *policy = prefs_get_string(PREF_OTR_POLICY); + cons_show("OTR policy is now set to: %s", policy); + return TRUE; + } + + char *choice = args[1]; + if (g_strcmp0(choice, "manual") == 0) { + prefs_set_string(PREF_OTR_POLICY, "manual"); + cons_show("OTR policy is now set to: manual"); + } else if (g_strcmp0(choice, "opportunistic") == 0) { + prefs_set_string(PREF_OTR_POLICY, "opportunistic"); + cons_show("OTR policy is now set to: opportunistic"); + } else if (g_strcmp0(choice, "always") == 0) { + prefs_set_string(PREF_OTR_POLICY, "always"); + cons_show("OTR policy is now set to: always"); + } else { + cons_show("OTR policy can be set to: manual, opportunistic or always."); + } + return TRUE; } if (jabber_get_connection_status() != JABBER_CONNECTED) { diff --git a/src/config/preferences.c b/src/config/preferences.c index f4133413..2d6aee79 100644 --- a/src/config/preferences.c +++ b/src/config/preferences.c @@ -397,8 +397,8 @@ _get_group(preference_t pref) case PREF_LOG_ROTATE: case PREF_LOG_SHARED: return PREF_GROUP_LOGGING; - case PREF_OTR_POLICY: - return PREF_GROUP_OTR_POLICY; + case PREF_OTR_POLICY: + return PREF_GROUP_OTR_POLICY; case PREF_AUTOAWAY_CHECK: case PREF_AUTOAWAY_MODE: case PREF_AUTOAWAY_MESSAGE: @@ -469,8 +469,8 @@ _get_key(preference_t pref) return "otr"; case PREF_OTR_WARN: return "otr.warn"; - case PREF_OTR_POLICY: - return "otr.policy"; + case PREF_OTR_POLICY: + return "otr.policy"; case PREF_LOG_ROTATE: return "rotate"; case PREF_LOG_SHARED: @@ -505,8 +505,8 @@ _get_default_string(preference_t pref) return "off"; case PREF_OTR_LOG: return "redact"; - case PREF_OTR_POLICY: - return "manual"; + case PREF_OTR_POLICY: + return "manual"; case PREF_STATUSES_CONSOLE: case PREF_STATUSES_CHAT: case PREF_STATUSES_MUC: @@ -514,4 +514,4 @@ _get_default_string(preference_t pref) default: return NULL; } -} +} \ No newline at end of file diff --git a/src/muc.c b/src/muc.c index 9ee94755..4ba88191 100644 --- a/src/muc.c +++ b/src/muc.c @@ -32,7 +32,9 @@ typedef struct _muc_room_t { char *room; // e.g. test@conference.server char *nick; // e.g. Some User + char *password; char *subject; + gboolean autojoin; gboolean pending_nick_change; GHashTable *roster; Autocomplete nick_ac; @@ -125,7 +127,8 @@ muc_clear_invites(void) * Join the chat room with the specified nickname */ void -muc_join_room(const char * const room, const char * const nick) +muc_join_room(const char * const room, const char * const nick, + const char * const password, gboolean autojoin) { if (rooms == NULL) { rooms = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, @@ -135,6 +138,11 @@ muc_join_room(const char * const room, const char * const nick) ChatRoom *new_room = malloc(sizeof(ChatRoom)); new_room->room = strdup(room); new_room->nick = strdup(nick); + if (password != NULL) { + new_room->password = strdup(password); + } else { + new_room->password = NULL; + } new_room->subject = NULL; new_room->roster = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)p_contact_free); @@ -143,6 +151,7 @@ muc_join_room(const char * const room, const char * const nick) g_free, g_free); new_room->roster_received = FALSE; new_room->pending_nick_change = FALSE; + new_room->autojoin = autojoin; g_hash_table_insert(rooms, strdup(room), new_room); } @@ -177,6 +186,22 @@ muc_room_is_active(const char * const room) } } +gboolean +muc_room_is_autojoin(const char * const room) +{ + if (rooms != NULL) { + ChatRoom *chat_room = g_hash_table_lookup(rooms, room); + + if (chat_room != NULL) { + return chat_room->autojoin; + } else { + return FALSE; + } + } else { + return FALSE; + } +} + char * muc_get_old_nick(const char * const room, const char * const new_nick) { @@ -469,6 +494,7 @@ _free_room(ChatRoom *room) free(room->room); free(room->nick); free(room->subject); + free(room->password); if (room->roster != NULL) { g_hash_table_remove_all(room->roster); } @@ -497,4 +523,4 @@ gint _compare_participants(PContact a, PContact b) g_free(key_b); return result; -} +} \ No newline at end of file diff --git a/src/muc.h b/src/muc.h index e28e048a..34058bfe 100644 --- a/src/muc.h +++ b/src/muc.h @@ -31,9 +31,11 @@ void muc_init(void); void muc_close(void); -void muc_join_room(const char * const room, const char * const nick); +void muc_join_room(const char * const room, const char * const nick, + const char * const password, gboolean autojoin); void muc_leave_room(const char * const room); gboolean muc_room_is_active(const char * const room); +gboolean muc_room_is_autojoin(const char * const room); GList* muc_get_active_room_list(void); char * muc_get_room_nick(const char * const room); diff --git a/src/otr/otrlibv3.c b/src/otr/otrlibv3.c index 4605f614..d1495c9a 100644 --- a/src/otr/otrlibv3.c +++ b/src/otr/otrlibv3.c @@ -34,7 +34,7 @@ otrlib_policy(void) char * otrlib_start_query(void) { - return "?OTR?v2? This user has requested an Off-the-Record private conversation. However, you do not have a plugin to support that. See http://otr.cypherpunks.ca/ for more information."; + return "?OTR?v2? This user has requested an Off-the-Record private conversation. However, you do not have a plugin to support that. See http://otr.cypherpunks.ca/ for more information."; } static int diff --git a/src/server_events.c b/src/server_events.c index 3935bfbc..bd63de82 100644 --- a/src/server_events.c +++ b/src/server_events.c @@ -37,23 +37,22 @@ #include "ui/ui.h" +void +handle_room_join_error(const char * const room, const char * const err) +{ + if (muc_room_is_active(room)) { + muc_leave_room(room); + } + ui_handle_room_join_error(room, err); +} + // handle presence stanza errors void handle_presence_error(const char *from, const char * const type, const char *err_msg) { - // handle nickname conflict on entering room - if ((from != NULL) && g_strcmp0(err_msg, "conflict") == 0) { - // remove the room from muc - Jid *room_jid = jid_create(from); - if (!muc_get_roster_received(room_jid->barejid)) { - muc_leave_room(room_jid->barejid); - ui_handle_recipient_error(room_jid->barejid, err_msg); - } - jid_destroy(room_jid); - - // handle any other error from recipient - } else if (from != NULL) { + // handle error from recipient + if (from != NULL) { ui_handle_recipient_error(from, err_msg); // handle errors from no recipient @@ -210,24 +209,26 @@ handle_incoming_message(char *from, char *message, gboolean priv) char *newmessage; if (!priv) { -//check for OTR whitespace (opportunistic or always) - char *policy = prefs_get_string(PREF_OTR_POLICY); - if (strcmp(policy, "opportunistic") == 0 || strcmp(policy, "always") == 0) { - char *whitespace_base = strstr(message,OTRL_MESSAGE_TAG_BASE); - if (whitespace_base) { - if (strstr(message, OTRL_MESSAGE_TAG_V2) || strstr(message, OTRL_MESSAGE_TAG_V1)) { - // Remove whitespace pattern for proper display in UI - // Handle both BASE+TAGV1/2(16+8) and BASE+TAGV1+TAGV2(16+8+8) - int tag_length = 24; - if (strstr(message, OTRL_MESSAGE_TAG_V2) && strstr(message, OTRL_MESSAGE_TAG_V1)) tag_length = 32; - memmove(whitespace_base, whitespace_base+tag_length, tag_length); - log_debug("<%s>", message); - char *otr_query_message = otr_start_query(); - cons_show("OTR Whitespace pattern detected. Attempting to start OTR session..."); - message_send(otr_query_message, from); - } - } - } + //check for OTR whitespace (opportunistic or always) + char *policy = prefs_get_string(PREF_OTR_POLICY); + if (strcmp(policy, "opportunistic") == 0 || strcmp(policy, "always") == 0) { + char *whitespace_base = strstr(message,OTRL_MESSAGE_TAG_BASE); + if (whitespace_base) { + if (strstr(message, OTRL_MESSAGE_TAG_V2) || strstr(message, OTRL_MESSAGE_TAG_V1)) { + // Remove whitespace pattern for proper display in UI + // Handle both BASE+TAGV1/2(16+8) and BASE+TAGV1+TAGV2(16+8+8) + int tag_length = 24; + if (strstr(message, OTRL_MESSAGE_TAG_V2) && strstr(message, OTRL_MESSAGE_TAG_V1)) { + tag_length = 32; + } + memmove(whitespace_base, whitespace_base+tag_length, tag_length); + log_debug("<%s>", message); + char *otr_query_message = otr_start_query(); + cons_show("OTR Whitespace pattern detected. Attempting to start OTR session..."); + message_send(otr_query_message, from); + } + } + } newmessage = otr_decrypt_message(from, message, &was_decrypted); // internal OTR message @@ -424,6 +425,12 @@ handle_room_nick_change(const char * const room, void handle_room_roster_complete(const char * const room) { + if (muc_room_is_autojoin(room)) { + ui_room_join(room, FALSE); + } else { + ui_room_join(room, TRUE); + } + muc_remove_invite(room); muc_set_roster_received(room); GList *roster = muc_get_roster(room); ui_room_roster(room, roster, NULL); @@ -520,13 +527,6 @@ handle_autoping_cancel(void) } void -handle_bookmark_autojoin(char *jid) -{ - ui_room_join(jid, FALSE); - muc_remove_invite(jid); -} - -void handle_xmpp_stanza(const char * const msg) { ui_handle_stanza(msg); diff --git a/src/server_events.h b/src/server_events.h index ea49e1f1..98e00731 100644 --- a/src/server_events.h +++ b/src/server_events.h @@ -43,6 +43,7 @@ void handle_room_history(const char * const room_jid, const char * const nick, GTimeVal tv_stamp, const char * const message); void handle_room_message(const char * const room_jid, const char * const nick, const char * const message); +void handle_room_join_error(const char * const room, const char * const err); void handle_duck_result(const char * const result); void handle_incoming_message(char *from, char *message, gboolean priv); void handle_delayed_message(char *from, char *message, GTimeVal tv_stamp, @@ -78,7 +79,6 @@ void handle_message_error(const char * const from, const char * const type, const char * const err_msg); void handle_presence_error(const char *from, const char * const type, const char *err_msg); -void handle_bookmark_autojoin(char *jid); void handle_xmpp_stanza(const char * const msg); #endif diff --git a/src/ui/core.c b/src/ui/core.c index a84d5856..8f385cf2 100644 --- a/src/ui/core.c +++ b/src/ui/core.c @@ -1272,7 +1272,7 @@ _ui_outgoing_msg(const char * const from, const char * const to, } static void -_ui_room_join(char *room, gboolean focus) +_ui_room_join(const char * const room, gboolean focus) { ProfWin *window = wins_get_by_recipient(room); int num = 0; @@ -1289,7 +1289,8 @@ _ui_room_join(char *room, gboolean focus) } else { status_bar_active(num); ProfWin *console = wins_get_console(); - win_vprint_line(console, '!', COLOUR_ONLINE, "-> Autojoined %s (%d).", room, num); + char *nick = muc_get_room_nick(room); + win_vprint_line(console, '!', COLOUR_TYPING, "-> Autojoined %s as %s (%d).", room, nick, num); win_update_virtual(console); } } @@ -1350,6 +1351,12 @@ _ui_room_roster(const char * const room, GList *roster, const char * const prese } static void +_ui_handle_room_join_error(const char * const room, const char * const err) +{ + cons_show_error("Error joining room %s, reason: %s", room, err); +} + +static void _ui_room_member_offline(const char * const room, const char * const nick) { ProfWin *window = wins_get_by_recipient(room); @@ -1979,4 +1986,5 @@ ui_init_module(void) ui_handle_stanza = _ui_handle_stanza; ui_create_xmlconsole_win = _ui_create_xmlconsole_win; ui_xmlconsole_exists = _ui_xmlconsole_exists; + ui_handle_room_join_error = _ui_handle_room_join_error; } diff --git a/src/ui/ui.h b/src/ui/ui.h index a93cc3d0..14f7137c 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -102,7 +102,7 @@ void (*ui_disconnected)(void); void (*ui_recipient_gone)(const char * const barejid); void (*ui_outgoing_msg)(const char * const from, const char * const to, const char * const message); -void (*ui_room_join)(char *room, gboolean focus); +void (*ui_room_join)(const char * const room, gboolean focus); void (*ui_room_roster)(const char * const room, GList *roster, const char * const presence); void (*ui_room_history)(const char * const room_jid, const char * const nick, GTimeVal tv_stamp, const char * const message); @@ -132,6 +132,7 @@ void (*ui_handle_recipient_not_found)(const char * const recipient, const char * void (*ui_handle_recipient_error)(const char * const recipient, const char * const err_msg); void (*ui_handle_error)(const char * const err_msg); void (*ui_clear_win_title)(void); +void (*ui_handle_room_join_error)(const char * const room, const char * const err); // contact status functions void (*ui_status_room)(const char * const contact); diff --git a/src/xmpp/bookmark.c b/src/xmpp/bookmark.c index 2e4f70db..c73f3db3 100644 --- a/src/xmpp/bookmark.c +++ b/src/xmpp/bookmark.c @@ -260,7 +260,7 @@ _bookmark_handle_result(xmpp_conn_t * const conn, room_jid = jid_create_from_bare_and_resource(jid, name); if (!muc_room_is_active(room_jid->barejid)) { presence_join_room(jid, name, NULL); - handle_bookmark_autojoin(jid); + muc_join_room(jid, name, NULL, TRUE); } jid_destroy(room_jid); } else { diff --git a/src/xmpp/presence.c b/src/xmpp/presence.c index 46467b2e..1cb86645 100644 --- a/src/xmpp/presence.c +++ b/src/xmpp/presence.c @@ -283,7 +283,6 @@ _presence_join_room(char *room, char *nick, char * passwd) xmpp_send(conn, presence); xmpp_stanza_release(presence); - muc_join_room(jid->barejid, jid->resourcepart); jid_destroy(jid); } @@ -342,11 +341,31 @@ _presence_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, char *id = xmpp_stanza_get_id(stanza); char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); xmpp_stanza_t *error_stanza = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR); + xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_X); + char *xmlns = xmpp_stanza_get_ns(x); char *type = NULL; if (error_stanza != NULL) { type = xmpp_stanza_get_attribute(error_stanza, STANZA_ATTR_TYPE); } + // handle MUC join errors + if (g_strcmp0(xmlns, STANZA_NS_MUC) == 0) { + Jid *fulljid = jid_create(from); + + char *error_cond = NULL; + xmpp_stanza_t *reason_st = xmpp_stanza_get_child_by_ns(error_stanza, STANZA_NS_STANZAS); + if (reason_st != NULL) { + error_cond = xmpp_stanza_get_name(reason_st); + } + if (error_cond == NULL) { + error_cond = "unknown"; + } + + log_info("Error joining room: %s, reason: %s", fulljid->barejid, error_cond); + handle_room_join_error(fulljid->barejid, error_cond); + return 1; + } + // stanza_get_error never returns NULL char *err_msg = stanza_get_error_message(stanza); @@ -676,7 +695,6 @@ _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, // handle roster complete } else if (!muc_get_roster_received(room)) { handle_room_roster_complete(room); - } // handle presence from room members diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h index d71d3ea1..486421a2 100644 --- a/src/xmpp/stanza.h +++ b/src/xmpp/stanza.h @@ -124,6 +124,7 @@ #define STANZA_TEXT_XA "xa" #define STANZA_TEXT_ONLINE "online" +#define STANZA_NS_STANZAS "urn:ietf:params:xml:ns:xmpp-stanzas" #define STANZA_NS_CHATSTATES "http://jabber.org/protocol/chatstates" #define STANZA_NS_MUC "http://jabber.org/protocol/muc" #define STANZA_NS_MUC_USER "http://jabber.org/protocol/muc#user" |