From: Michael Poole Date: Fri, 20 Jan 2012 02:29:15 +0000 (-0500) Subject: Add a login-on-connect module using XQUERY/XRESPONSE. X-Git-Url: http://git.pk910.de/?p=srvx.git;a=commitdiff_plain;h=4e6b0e24b2f4b6e00df70bd5c2badda8d56fab77 Add a login-on-connect module using XQUERY/XRESPONSE. --- 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; +}