about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/command/commands.c7
-rw-r--r--src/muc.c17
-rw-r--r--src/muc.h3
-rw-r--r--src/server_events.c4
-rw-r--r--src/server_events.h2
-rw-r--r--src/xmpp/message.c17
-rw-r--r--tests/test_muc.c14
7 files changed, 47 insertions, 17 deletions
diff --git a/src/command/commands.c b/src/command/commands.c
index c7edeb7b..1d1b10e3 100644
--- a/src/command/commands.c
+++ b/src/command/commands.c
@@ -2129,10 +2129,15 @@ cmd_join(gchar **args, struct cmd_help_t help)
     options_destroy(options);
 
     // In the case that a nick wasn't provided by the optional args...
-    if (nick == NULL) {
+    if (!nick) {
         nick = account->muc_nick;
     }
 
+    // When no password, check for invite with password
+    if (!passwd) {
+        passwd = muc_invite_password(room);
+    }
+
     if (!muc_active(room)) {
         presence_join_room(room, nick, passwd);
         muc_join(room, nick, passwd, FALSE);
diff --git a/src/muc.c b/src/muc.c
index ae48d66b..6fd09de3 100644
--- a/src/muc.c
+++ b/src/muc.c
@@ -66,6 +66,7 @@ typedef struct _muc_room_t {
 } ChatRoom;
 
 GHashTable *rooms = NULL;
+GHashTable *invite_passwords = NULL;
 Autocomplete invite_ac;
 
 static void _free_room(ChatRoom *room);
@@ -83,6 +84,7 @@ muc_init(void)
 {
     invite_ac = autocomplete_new();
     rooms = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)_free_room);
+    invite_passwords = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
 }
 
 void
@@ -90,19 +92,25 @@ muc_close(void)
 {
     autocomplete_free(invite_ac);
     g_hash_table_destroy(rooms);
+    g_hash_table_destroy(invite_passwords);
     rooms = NULL;
+    invite_passwords = NULL;
 }
 
 void
-muc_invites_add(const char * const room)
+muc_invites_add(const char * const room, const char * const password)
 {
     autocomplete_add(invite_ac, room);
+    if (password) {
+        g_hash_table_replace(invite_passwords, strdup(room), strdup(password));
+    }
 }
 
 void
 muc_invites_remove(const char * const room)
 {
     autocomplete_remove(invite_ac, room);
+    g_hash_table_remove(invite_passwords, room);
 }
 
 gint
@@ -117,6 +125,12 @@ muc_invites(void)
     return autocomplete_create_list(invite_ac);
 }
 
+char *
+muc_invite_password(const char * const room)
+{
+    return g_hash_table_lookup(invite_passwords, room);
+}
+
 gboolean
 muc_invites_contain(const char * const room)
 {
@@ -151,6 +165,7 @@ void
 muc_invites_clear(void)
 {
     autocomplete_clear(invite_ac);
+    g_hash_table_remove_all(invite_passwords);
 }
 
 void
diff --git a/src/muc.h b/src/muc.h
index 2c7b3e7e..cdaa10bd 100644
--- a/src/muc.h
+++ b/src/muc.h
@@ -116,7 +116,7 @@ GSList * muc_occupants_by_affiliation(const char * const room, muc_affiliation_t
 void muc_occupant_nick_change_start(const char * const room, const char * const new_nick, const char * const old_nick);
 char* muc_roster_nick_change_complete(const char * const room, const char * const nick);
 
-void muc_invites_add(const char * const room);
+void muc_invites_add(const char * const room, const char * const password);
 void muc_invites_remove(const char * const room);
 gint muc_invites_count(void);
 GSList* muc_invites(void);
@@ -124,6 +124,7 @@ gboolean muc_invites_contain(const char * const room);
 void muc_invites_reset_ac(void);
 char* muc_invites_find(const char * const search_str);
 void muc_invites_clear(void);
+char* muc_invite_password(const char * const room);
 
 void muc_set_subject(const char * const room, const char * const subject);
 char* muc_subject(const char * const room);
diff --git a/src/server_events.c b/src/server_events.c
index bab6cb13..fe942680 100644
--- a/src/server_events.c
+++ b/src/server_events.c
@@ -257,11 +257,11 @@ handle_disco_items(GSList *items, const char *jid)
 void
 handle_room_invite(jabber_invite_t invite_type,
     const char * const invitor, const char * const room,
-    const char * const reason)
+    const char * const reason, const char * const password)
 {
     if (!muc_active(room) && !muc_invites_contain(room)) {
         cons_show_room_invite(invitor, room, reason);
-        muc_invites_add(room);
+        muc_invites_add(room, password);
     }
 }
 
diff --git a/src/server_events.h b/src/server_events.h
index b03e11be..85d75ac3 100644
--- a/src/server_events.h
+++ b/src/server_events.h
@@ -48,7 +48,7 @@ void handle_room_list(GSList *rooms, const char *conference_node);
 void handle_disco_items(GSList *items, const char *jid);
 void handle_room_invite(jabber_invite_t invite_type,
     const char * const invitor, const char * const room,
-    const char * const reason);
+    const char * const reason, const char * const password);
 void handle_room_broadcast(const char *const room_jid,
     const char * const message);
 void handle_room_subject(const char * const room, const char * const nick, const char * const subject);
diff --git a/src/xmpp/message.c b/src/xmpp/message.c
index 1817d5ab..4ecb334b 100644
--- a/src/xmpp/message.c
+++ b/src/xmpp/message.c
@@ -368,11 +368,18 @@ _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
             reason = xmpp_stanza_get_text(reason_st);
         }
 
-        handle_room_invite(INVITE_MEDIATED, invitor, room, reason);
+        char *password = NULL;
+        xmpp_stanza_t *password_st = xmpp_stanza_get_child_by_name(xns_muc_user, STANZA_NAME_PASSWORD);
+        password = xmpp_stanza_get_text(password_st);
+
+        handle_room_invite(INVITE_MEDIATED, invitor, room, reason, password);
         jid_destroy(jidp);
-        if (reason != NULL) {
+        if (reason) {
             xmpp_free(ctx, reason);
         }
+        if (password) {
+            xmpp_free(ctx, password);
+        }
     }
 
     return 1;
@@ -387,13 +394,14 @@ _conference_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
     char *room = NULL;
     char *invitor = NULL;
     char *reason = NULL;
+    char *password = NULL;
 
     if (from == NULL) {
         log_warning("Message received with no from attribute, ignoring");
         return 1;
     }
 
-    // XEP-0429
+    // XEP-0249
     room = xmpp_stanza_get_attribute(xns_conference, STANZA_ATTR_JID);
     if (room == NULL) {
         return 1;
@@ -406,8 +414,9 @@ _conference_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
     invitor = jidp->barejid;
 
     reason = xmpp_stanza_get_attribute(xns_conference, STANZA_ATTR_REASON);
+    password = xmpp_stanza_get_attribute(xns_conference, STANZA_ATTR_PASSWORD);
 
-    handle_room_invite(INVITE_DIRECT, invitor, room, reason);
+    handle_room_invite(INVITE_DIRECT, invitor, room, reason, password);
 
     jid_destroy(jidp);
 
diff --git a/tests/test_muc.c b/tests/test_muc.c
index 5566c17e..e3b7f9b0 100644
--- a/tests/test_muc.c
+++ b/tests/test_muc.c
@@ -19,7 +19,7 @@ void muc_after_test(void **state)
 void test_muc_invites_add(void **state)
 {
     char *room = "room@conf.server";
-    muc_invites_add(room);
+    muc_invites_add(room, NULL);
 
     gboolean invite_exists = muc_invites_contain(room);
 
@@ -29,7 +29,7 @@ void test_muc_invites_add(void **state)
 void test_muc_remove_invite(void **state)
 {
     char *room = "room@conf.server";
-    muc_invites_add(room);
+    muc_invites_add(room, NULL);
     muc_invites_remove(room);
 
     gboolean invite_exists = muc_invites_contain(room);
@@ -46,11 +46,11 @@ void test_muc_invites_count_0(void **state)
 
 void test_muc_invites_count_5(void **state)
 {
-    muc_invites_add("room1@conf.server");
-    muc_invites_add("room2@conf.server");
-    muc_invites_add("room3@conf.server");
-    muc_invites_add("room4@conf.server");
-    muc_invites_add("room5@conf.server");
+    muc_invites_add("room1@conf.server", NULL);
+    muc_invites_add("room2@conf.server", NULL);
+    muc_invites_add("room3@conf.server", NULL);
+    muc_invites_add("room4@conf.server", NULL);
+    muc_invites_add("room5@conf.server", NULL);
 
     int invite_count = muc_invites_count();