--- a/mcabber/src/commands.c Mon Sep 26 00:27:56 2005 +0200
+++ b/mcabber/src/commands.c Mon Sep 26 22:08:48 2005 +0200
@@ -459,9 +459,14 @@
while (*st && *st == ' ')
st++;
- // FIXME check id =~ jabber id
- scr_LogPrint(LPRINT_LOGNORM, "Sending to <%s> /status %s", id, st);
- setstatus(id, st);
+ if (check_jid_syntax(id)) {
+ scr_LogPrint(LPRINT_NORMAL, "<%s> is not a valid Jabber id", id);
+ } else {
+ mc_strtolower(id);
+ scr_LogPrint(LPRINT_LOGNORM, "Sending to <%s> /status %s", id, st);
+ setstatus(id, st);
+ }
+ g_free(id);
}
static void do_add(char *arg)
@@ -480,11 +485,15 @@
nick++;
}
- // FIXME check id =~ jabber id
- // 2nd parameter = optional nickname
- jb_addbuddy(id, nick, NULL);
- scr_LogPrint(LPRINT_LOGNORM, "Sent presence notification request to <%s>",
- id);
+ if (check_jid_syntax(id)) {
+ scr_LogPrint(LPRINT_NORMAL, "<%s> is not a valid Jabber id", id);
+ } else {
+ mc_strtolower(id);
+ // 2nd parameter = optional nickname
+ jb_addbuddy(id, nick, NULL);
+ scr_LogPrint(LPRINT_LOGNORM, "Sent presence notification request to <%s>",
+ id);
+ }
g_free(id);
}
@@ -943,12 +952,22 @@
return;
}
// room syntax: "room@server/nick"
- // FIXME: check roomid is a jid
roomid = g_strdup_printf("%s/%s", roomname, nick);
+ if (check_jid_syntax(roomid)) {
+ scr_LogPrint(LPRINT_NORMAL, "<%s> is not a valid Jabber room", roomid);
+ g_free(roomname);
+ g_free(roomid);
+ return;
+ }
+
+ mc_strtolower(roomid);
jb_room_join(roomid);
+
+ // We need to save the nickname for future use
roster_usr = roster_add_user(roomname, NULL, NULL, ROSTER_TYPE_ROOM);
if (roster_usr)
buddy_setnickname(roster_usr->data, nick);
+
g_free(roomname);
g_free(roomid);
buddylist_build();
--- a/mcabber/src/utils.c Mon Sep 26 00:27:56 2005 +0200
+++ b/mcabber/src/utils.c Mon Sep 26 22:08:48 2005 +0200
@@ -29,6 +29,7 @@
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <ctype.h>
#include <config.h>
#include "logprint.h"
@@ -248,3 +249,73 @@
req.tv_nsec = (long)usec * 1000L;
nanosleep(&req, NULL);
}
+
+/**
+ * Derived from libjabber/jid.c, because the libjabber version is not
+ * really convenient for our usage.
+ *
+ * Check if the full JID is valid
+ * Return 0 if it is valid, non zero otherwise
+ */
+int check_jid_syntax(char *jid)
+{
+ char *str;
+ char *domain, *resource;
+ int domlen;
+
+ if (!jid) return 1;
+
+ domain = strchr(jid, '@');
+ if (!domain) return 1;
+
+ /* node identifiers may not be longer than 1023 bytes */
+ if ((domain == jid) || (domain-jid > 1023))
+ return 1;
+ domain++;
+
+ /* check for low and invalid ascii characters in the username */
+ for (str = jid; *str != '@'; str++) {
+ if (*str <= 32 || *str == ':' || *str == '@' ||
+ *str == '<' || *str == '>' || *str == '\'' ||
+ *str == '"' || *str == '&') {
+ return 1;
+ }
+ }
+
+ /* the username is okay as far as we can tell without LIBIDN */
+
+ resource = strchr(domain, '/');
+
+ /* the resource is optional */
+ if (resource) {
+ domlen = resource - domain;
+ resource++;
+ /* resources may not be longer than 1023 bytes */
+ if ((*resource == '\0') || strlen(resource) > 1023)
+ return 1;
+ } else {
+ domlen = strlen(domain);
+ }
+
+ /* there must be a domain identifier */
+ if (domlen == 0) return 1;
+
+ /* and it must not be longer than 1023 bytes */
+ if (domlen > 1023) return 1;
+
+ /* make sure the hostname is valid characters */
+ for (str = domain; *str != '\0' && *str != '/'; str++) {
+ if (!(isalnum(*str) || *str == '.' || *str == '-' || *str == '_'))
+ return 1;
+ }
+
+ /* it's okay as far as we can tell without LIBIDN */
+ return 0;
+}
+
+void mc_strtolower(char *str)
+{
+ if (!str) return;
+ for ( ; *str; str++)
+ *str = tolower(*str);
+}
--- a/mcabber/src/utils.h Mon Sep 26 00:27:56 2005 +0200
+++ b/mcabber/src/utils.h Mon Sep 26 22:08:48 2005 +0200
@@ -11,4 +11,8 @@
inline void safe_usleep(unsigned int usec); /* Only for delays < 1s */
+int check_jid_syntax(char *jid);
+
+void mc_strtolower(char *str);
+
#endif