Merge remote branch 'upstream/master'
authorroot <root@localhost>
Thu, 2 Feb 2012 21:44:45 +0000 (22:44 +0100)
committerroot <root@localhost>
Thu, 2 Feb 2012 21:44:45 +0000 (22:44 +0100)
Conflicts:
src/proto-p10.c

Makefile.am
configure.in
m4/.gitignore [new file with mode: 0644]
src/mod-iauth_loc.c [new file with mode: 0644]
src/proto-bahamut.c
src/proto-common.c
src/proto-p10.c
src/proto.h

index 72f2302f1d5b359aa1d806c191a8d151333b89ab..46537468b6acfcd43d6bf64167e8d8372b42f4f2 100644 (file)
@@ -1,6 +1,7 @@
 EXTRA_DIST = FAQ UPGRADE srvx.conf.example sockcheck.conf.example Makefile.win32
 SUBDIRS = @MY_SUBDIRS@
 DIST_SUBDIRS = src rx
+ACLOCAL_AMFLAGS = -I m4
 
 all: srvx
 
index 9540a00373dbddae5d06372010055601abca051b..a3a885165a080b602c80af02da02b311a5ace647 100644 (file)
@@ -8,7 +8,8 @@ AC_CONFIG_HEADERS(src/config.h)
 AC_CONFIG_SRCDIR(src/opserv.c)
 dnl AM_CANONICAL_TARGET must be before AM_INIT_AUTOMAKE() or autoconf whines
 AC_CANONICAL_TARGET
-AM_INIT_AUTOMAKE([gnu 1.6])
+AC_CONFIG_MACRO_DIR([m4])
+AM_INIT_AUTOMAKE([gnu 1.10 silent-rules])
 AM_MAINTAINER_MODE
 LT_INIT
 
@@ -333,7 +334,7 @@ AC_ARG_ENABLE(modules,
   module_list=""
   dnl Must use a separate file because autoconf can't stand newlines in an AC_SUBSTed variable.
   for module in $enableval ; do
-    module=`echo $module | sed -e s/^mod-// -e s/\.c\$//`
+    module=`echo $module | sed -e s/^mod-// -e s/\\\.c\\\$//`
     EXTRA_MODULE_OBJS="$EXTRA_MODULE_OBJS mod-$module.\$(OBJEXT)"
     module_list="$module_list $module"
     echo "WITH_MODULE($module)" >> $MODULE_DEFINES
diff --git a/m4/.gitignore b/m4/.gitignore
new file mode 100644 (file)
index 0000000..0f4126c
--- /dev/null
@@ -0,0 +1 @@
+*.m4
diff --git a/src/mod-iauth_loc.c b/src/mod-iauth_loc.c
new file mode 100644 (file)
index 0000000..78668c0
--- /dev/null
@@ -0,0 +1,137 @@
+/* IAuth Login-on-Connect module for srvx 1.x
+ * Copyright 2012 Michael Poole <mdpoole@troilus.org>
+ *
+ * This file is part of srvx.
+ *
+ * srvx is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with srvx; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+ */
+
+#include "conf.h"
+#include "log.h"
+#include "nickserv.h"
+
+const char *iauth_loc_module_deps[] = { NULL };
+
+static struct log_type *loc_log;
+
+static struct {
+    struct userNode *debug_bot;
+    struct chanNode *debug_channel;
+} conf;
+
+#if defined(GCC_VARMACROS)
+# define loc_debug(ARGS...) do { if (conf.debug_bot && conf.debug_channel) send_channel_notice(conf.debug_channel, conf.debug_bot, ARGS); } while (0)
+#elif defined(C99_VARMACROS)
+# define loc_debug(...) do { if (conf.debug_bot && conf.debug_channel) send_channel_notice(conf.debug_channel, conf.debug_bot, __VA_ARGS__); } while (0)
+#endif
+
+static void
+iauth_loc_xquery(struct server *source, const char routing[], const char query[])
+{
+    if (!strncmp(query, "LOGIN2 ", strlen("LOGIN2 "))) {
+        /* Make "user" static for better valgrind tests. */
+        static struct userNode user;
+        const char *ip_str, *hostname, *username, *account, *password;
+        struct handle_info *hi = NULL;
+        char *qdup, *saveptr;
+        unsigned int ii;
+        int valid = 0;
+
+        /* Parse the arguments. */
+        qdup = strdup(query + strlen("LOGIN2 "));
+        ip_str   = strtok_r(qdup, " ", &saveptr);
+        hostname = strtok_r(NULL, " ", &saveptr);
+        username = strtok_r(NULL, " ", &saveptr);
+        account  = strtok_r(NULL, " ", &saveptr);
+        password = strtok_r(NULL, " ", &saveptr);
+        if (!password) {
+        login2_bad_syntax:
+            irc_xresponse(source, routing, "NO Bad LOGIN2 syntax");
+            free(qdup);
+            return;
+        }
+
+        /* Set up (the rest of) the fake user. */
+        user.nick = "?";
+        if (!irc_pton(&user.ip, NULL, ip_str))
+            goto login2_bad_syntax;
+        strncpy(user.ident, username, sizeof(user.ident));
+        strncpy(user.hostname, hostname, sizeof(user.hostname));
+
+        /* Check against the account. */
+        hi = get_handle_info(account);
+        if (hi->masks->used == 0)
+            valid = 1;
+        for (ii = 0; ii < hi->masks->used; ++ii) {
+            if (user_matches_glob(&user, hi->masks->list[ii], 0))
+                valid = 1;
+        }
+        if (!checkpass(password, hi ? hi->passwd : ""))
+            valid = 0;
+
+        /* Send our response. */
+        free(qdup);
+        if (valid) {
+            char response[68];
+            snprintf(response, sizeof(response), "OK %s:%lu", hi->handle, hi->registered);
+            irc_xresponse(source, routing, response);
+        } else {
+            irc_xresponse(source, routing, "NO Bad username, account or source");
+        }
+    } /* else unknown or unsupported command */
+}
+
+static void
+iauth_loc_conf_read(void)
+{
+    dict_t node;
+    const char *str1;
+    const char *str2;
+
+
+    node = conf_get_data("modules/blacklist", RECDB_OBJECT);
+    if (node == NULL)
+        return;
+
+    str1 = database_get_data(node, "debug_bot", RECDB_QSTRING);
+    if (str1)
+        conf.debug_bot = GetUserH(str1);
+
+    str1 = database_get_data(node, "debug_channel", RECDB_QSTRING);
+    if (conf.debug_bot && str1) {
+        str2 = database_get_data(node, "debug_channel_modes", RECDB_QSTRING);
+        if (!str2)
+            str2 = "+tinms";
+        conf.debug_channel = AddChannel(str1, now, str2, NULL);
+        AddChannelUser(conf.debug_bot, conf.debug_channel)->modes |= MODE_CHANOP;
+    } else {
+        conf.debug_channel = NULL;
+    }
+}
+
+int
+iauth_loc_init(void)
+{
+    loc_log = log_register_type("iauth_loc", "file:iauth_loc.log");
+    conf_register_reload(iauth_loc_conf_read);
+    reg_xquery_func(iauth_loc_xquery);
+    return 1;
+}
+
+int
+iauth_loc_finalize(void)
+{
+    return 1;
+}
index 99ffa3bf9800a778a3469e44f0e6f7199494c4c5..a0c1d98ef102d5f80004c0a05aa3cb8dc21a2f79 100644 (file)
@@ -1105,6 +1105,7 @@ void init_parse(void) {
 
     userList_init(&dead_users);
     reg_exit_func(parse_cleanup);
+    (void)call_xquery_funcs;
 }
 
 int parse_line(char *line, int recursive) {
index e690726116d06cbe36b2d30ef9da9fc223fb5fea..bc37f32a13aa945940a109cba3d627f620120c43 100644 (file)
@@ -577,6 +577,34 @@ call_oper_funcs(struct userNode *user)
     }
 }
 
+static xquery_func_t *xqf_list;
+static unsigned int xqf_size = 0, xqf_used = 0;
+
+void
+reg_xquery_func(xquery_func_t handler)
+{
+    if (xqf_used == xqf_size) {
+        if (xqf_size) {
+            xqf_size <<= 1;
+            xqf_list = realloc(xqf_list, xqf_size*sizeof(xquery_func_t));
+        } else {
+            xqf_size = 8;
+            xqf_list = malloc(xqf_size*sizeof(xquery_func_t));
+        }
+    }
+    xqf_list[xqf_used++] = handler;
+}
+
+static void
+call_xquery_funcs(struct server *source, const char routing[], const char query[])
+{
+    unsigned int n;
+    for (n=0; n < xqf_used; n++)
+    {
+        xqf_list[n](source, routing, query);
+    }
+}
+
 struct mod_chanmode *
 mod_chanmode_alloc(unsigned int argc)
 {
index c48d21b45125fc6431c1d3413e7b1c2f3c3c60f3..d08fb1804fd82c48aaf5a3f9ffcd624d1a48d05a 100644 (file)
 #define CMD_WHO                 "WHO"
 #define CMD_WHOIS               "WHOIS"
 #define CMD_WHOWAS              "WHOWAS"
+#define CMD_XQUERY              "XQUERY"
+#define CMD_XRESPONSE           "XRESPONSE"
 
 /* Tokenized commands. */
 #define TOK_ACCOUNT             "AC"
 #define TOK_WHO                 "H"
 #define TOK_WHOIS               "W"
 #define TOK_WHOWAS              "X"
+#define TOK_XQUERY              "XQ"
+#define TOK_XRESPONSE           "XR"
 
 /* Protocol messages; aliased to full commands or tokens depending
    on compile-time configuration. ircu prefers tokens WITH THE
 #define P10_WHO                 TYPE(WHO)
 #define P10_WHOIS               TYPE(WHOIS)
 #define P10_WHOWAS              TYPE(WHOWAS)
+#define P10_XQUERY              TYPE(XQUERY)
+#define P10_XRESPONSE           TYPE(XRESPONSE)
 
 /* Servers claiming to have a boot or link time before PREHISTORY
  * trigger errors to the log.  We hope no server has been running
@@ -961,6 +967,12 @@ irc_numeric(struct userNode *user, unsigned int num, const char *format, ...)
     putsock(":%s %03d %s %s", self->name, num, user->nick, buffer);
 }
 
+void
+irc_xresponse(struct server *target, const char *routing, const char *response)
+{
+    putsock("%s " P10_XRESPONSE " %s %s :%s", self->numeric, target->numeric, routing, response);
+}
+
 static void send_burst(void);
 
 static void
@@ -1822,6 +1834,16 @@ static CMD_FUNC(cmd_relay)
     return 1;
 }
 
+static CMD_FUNC(cmd_xquery)
+{
+    struct server *source;
+    if ((argc < 4)
+        || !(source = GetServerH(origin)))
+        return 0;
+    call_xquery_funcs(source, argv[2], argv[3]);
+    return 1;
+}
+
 void
 free_user(struct userNode *user)
 {
@@ -1965,6 +1987,8 @@ init_parse(void)
     dict_insert(irc_func_dict, TOK_ADMIN, cmd_admin);
     dict_insert(irc_func_dict, CMD_TIME, cmd_time);
     dict_insert(irc_func_dict, TOK_TIME, cmd_time);
+    /* We don't handle XR or the (not really defined) XQUERY. */
+    dict_insert(irc_func_dict, TOK_XQUERY, cmd_xquery);
 
     /* In P10, DESTRUCT doesn't do anything except be broadcast to servers.
      * Apparently to obliterate channels from any servers that think they
index 54c5e23a420a924f632bf61208e55fb46f422d89..2bd70b496e4a41bb42fd86ccae92a3e2c3d8bcfa 100644 (file)
@@ -104,6 +104,9 @@ void unreg_notice_func(struct userNode *user);
 typedef void (*oper_func_t) (struct userNode *user);
 void reg_oper_func(oper_func_t handler);
 
+typedef void (*xquery_func_t) (struct server *source, const char routing[], const char query[]);
+void reg_xquery_func(xquery_func_t handler);
+
 /* replay silliness */
 void replay_read_line(void);
 void replay_event_loop(void);
@@ -142,6 +145,7 @@ void irc_kill(struct userNode *from, struct userNode *target, const char *messag
 void irc_raw(const char *what);
 void irc_stats(struct userNode *from, struct server *target, char type);
 void irc_svsnick(struct userNode *from, struct userNode *target, const char *newnick);
+void irc_xresponse(struct server *target, const char *routing, const char *response);
 
 /* account maintenance */
 void irc_account(struct userNode *user, const char *stamp, unsigned long timestamp, unsigned long serial);