From: root Date: Thu, 2 Feb 2012 21:44:45 +0000 (+0100) Subject: Merge remote branch 'upstream/master' X-Git-Url: http://git.pk910.de/?p=srvx.git;a=commitdiff_plain;h=fffe459760943b6ed8e0bb736c87ef424ce38fdc;hp=c253a006e0eafc173752e7c77dd706e02073cd20 Merge remote branch 'upstream/master' Conflicts: src/proto-p10.c --- diff --git a/Makefile.am b/Makefile.am index 72f2302..4653746 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 diff --git a/configure.in b/configure.in index 9540a00..a3a8851 100644 --- a/configure.in +++ b/configure.in @@ -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 index 0000000..0f4126c --- /dev/null +++ b/m4/.gitignore @@ -0,0 +1 @@ +*.m4 diff --git a/src/mod-iauth_loc.c b/src/mod-iauth_loc.c new file mode 100644 index 0000000..78668c0 --- /dev/null +++ b/src/mod-iauth_loc.c @@ -0,0 +1,137 @@ +/* IAuth Login-on-Connect module for srvx 1.x + * Copyright 2012 Michael Poole + * + * 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; +} diff --git a/src/proto-bahamut.c b/src/proto-bahamut.c index 99ffa3b..a0c1d98 100644 --- a/src/proto-bahamut.c +++ b/src/proto-bahamut.c @@ -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) { diff --git a/src/proto-common.c b/src/proto-common.c index e690726..bc37f32 100644 --- a/src/proto-common.c +++ b/src/proto-common.c @@ -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) { diff --git a/src/proto-p10.c b/src/proto-p10.c index c48d21b..d08fb18 100644 --- a/src/proto-p10.c +++ b/src/proto-p10.c @@ -105,6 +105,8 @@ #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" @@ -191,6 +193,8 @@ #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 @@ -288,6 +292,8 @@ #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 diff --git a/src/proto.h b/src/proto.h index 54c5e23..2bd70b4 100644 --- a/src/proto.h +++ b/src/proto.h @@ -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);