/* ChanServ SENDPASS module. * * IRC Services is copyright (c) 1996-2007 Andrew Church. * E-mail: * Parts written by Andrew Kempe and others. * This program is free but copyrighted software; see the file COPYING for * details. */ #include "services.h" #include "modules.h" #include "conffile.h" #include "commands.h" #include "language.h" #include "encrypt.h" #include "modules/mail/mail.h" #include "modules/nickserv/nickserv.h" #include "chanserv.h" #include "cs-local.h" /*************************************************************************/ /*************************** Local variables *****************************/ /*************************************************************************/ static Module *module; static Module *module_chanserv; static Module *module_nickserv; static Module *module_nickserv_mail_auth; static Module *module_mail; static time_t CSSendpassDelay = 0; /*************************************************************************/ static void do_sendpass(User *u); static Command commands[] = { { "SENDPASS", do_sendpass, NULL, CHAN_HELP_SENDPASS, -1,-1 }, { NULL } }; /*************************************************************************/ /**************************** Command handler ****************************/ /*************************************************************************/ /* Handle the SENDPASS command. */ static void do_sendpass(User *u) { char *chan = strtok(NULL, " "); char *s = strtok_remaining(); NickInfo *ni; NickGroupInfo *ngi; ChannelInfo *ci; time_t now = time(NULL); char passbuf[PASSMAX]; int res; if (!chan || s) { syntax_error(s_ChanServ, u, "SENDPASS", CHAN_SENDPASS_SYNTAX); } else if (!(ni = u->ni)) { notice_lang(s_ChanServ, u, NICK_NOT_REGISTERED); } else if (!(ngi = u->ngi) || ngi == NICKGROUPINFO_INVALID) { notice_lang(s_ChanServ, u, INTERNAL_ERROR); } else if (!(ci = get_channelinfo(chan))) { notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan); } else if (ngi->id != ci->founder) { notice_lang(s_ChanServ, u, CHAN_SENDPASS_FOUNDER_ONLY); } else if (!user_identified(u)) { notice_lang(s_ChanServ, u, CHAN_MUST_IDENTIFY_NICK, s_NickServ, s_NickServ); } else if (!ngi->email) { notice_lang(s_ChanServ, u, CHAN_SENDPASS_NO_EMAIL); } else if (ci->last_sendpass && now - ci->last_sendpass < CSSendpassDelay) { notice_lang(s_ChanServ, u, CHAN_SENDPASS_TOO_SOON, maketime(ngi,CSSendpassDelay-(now-ci->last_sendpass),0)); } else if ((res = decrypt(ci->founderpass,passbuf,sizeof(passbuf))) != 1) { if (res == 0) { module_log("BUG: trapdoor algorithm in use (should have been" " caught at load time)"); } notice_lang(s_ChanServ, u, CHAN_SENDPASS_FAILED); } else { char subject[BUFSIZE], body[BUFSIZE]; snprintf(subject, sizeof(subject), getstring(ngi,CHAN_SENDPASS_MAIL_SUBJECT), ci->name); snprintf(body, sizeof(body), getstring(ngi,CHAN_SENDPASS_MAIL_BODY), ci->name, passbuf, s_ChanServ, u->username, u->host); res = sendmail(ngi->email, subject, body); if (res == 0) { ci->last_sendpass = now; notice_lang(s_ChanServ, u, CHAN_SENDPASS_SENT, ci->name, ngi->email); } else if (res == 1) { notice_lang(s_ChanServ, u, SENDMAIL_NO_RESOURCES); } else { module_log("Valid SENDPASS for %s by %s!%s@%s failed", ci->name, u->nick, u->username, u->host); notice_lang(s_ChanServ, u, CHAN_SENDPASS_FAILED); } } } /*************************************************************************/ /***************************** Module stuff ******************************/ /*************************************************************************/ const int32 module_version = MODULE_VERSION_CODE; ConfigDirective module_config[] = { { "CSSendpassDelay", { { CD_TIME, 0, &CSSendpassDelay } } }, { NULL } }; /*************************************************************************/ static int do_reconfigure(int after_configure) { if (after_configure) { Command *cmd; if ((cmd = lookup_cmd(module_chanserv, "SENDPASS")) != NULL) cmd->help_param1 = s_NickServ; else module_log("BUG: reconfigure: SENDPASS command entry not found"); } return 0; } /*************************************************************************/ int init_module(Module *module_) { char testbuf[PASSMAX], testbuf2[PASSMAX]; Command *cmd; module = module_; if (encrypt("a", 1, testbuf, PASSMAX) < 0) { module_log("Couldn't encrypt string to test for trapdoor encryption"); return 0; } if (decrypt(testbuf, testbuf2, sizeof(testbuf2)) == 0) { module_log("Trapdoor (one-way) encryption in use; SENDPASS cannot" " be used"); return 0; } module_chanserv = find_module("chanserv/main"); if (!module_chanserv) { module_log("Main ChanServ module not loaded"); exit_module(0); return 0; } use_module(module_chanserv); module_nickserv = find_module("nickserv/main"); if (!module_nickserv) { module_log("Main NickServ module not loaded"); exit_module(0); return 0; } use_module(module_nickserv); module_nickserv_mail_auth = find_module("nickserv/mail-auth"); if (!module_nickserv_mail_auth) { module_log("NickServ AUTH module (mail-auth) required for SENDPASS"); exit_module(0); return 0; } use_module(module_nickserv_mail_auth); module_mail = find_module("mail/main"); if (!module_mail) { module_log("Mail module not loaded"); exit_module(0); return 0; } use_module(module_mail); if (!register_commands(module_chanserv, commands)) { module_log("Unable to register commands"); exit_module(0); return 0; } if (!add_callback(NULL, "reconfigure", do_reconfigure)) { module_log("Unable to add callbacks"); exit_module(0); return 0; } if ((cmd = lookup_cmd(module_chanserv, "SENDPASS")) != NULL) { cmd->help_param1 = s_NickServ; } else { module_log("BUG: init: SENDPASS command entry not found"); exit_module(0); return 0; } return 1; } /*************************************************************************/ int exit_module(int shutdown_unused) { #ifdef CLEAN_COMPILE shutdown_unused = shutdown_unused; #endif remove_callback(NULL, "reconfigure", do_reconfigure); if (module_mail) { unuse_module(module_mail); module_mail = NULL; } if (module_nickserv_mail_auth) { unuse_module(module_nickserv_mail_auth); module_nickserv_mail_auth = NULL; } if (module_nickserv) { unuse_module(module_nickserv); module_nickserv = NULL; } if (module_chanserv) { unregister_commands(module_chanserv, commands); unuse_module(module_chanserv); module_chanserv = NULL; } return 1; } /*************************************************************************/