Code: Select all
/*
* f_auth.c
* by fez (c) 2007 - provides authentication requirement for IRC
* this module is only a proof of concept. It should be expanded for
* specific authentication schema. f_auth_local_connect() and
* f_auth_command() would be the places to do those.
*/
// includes
#include "config.h"
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "numeric.h"
#include "msg.h"
#include "proto.h"
#include "channel.h"
#include <time.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <io.h>
#endif
#include <fcntl.h>
#include "h.h"
#ifdef STRIPBADWORDS
#include "badwords.h"
#endif
#ifdef _WIN32
#include "version.h"
#endif
// ***** module-specific defines *****
#define MOD_AUTH_NAME "f_auth"
#define MOD_AUTH_VERS "$Id: f_auth.c, v1.0.2 2007/10/16 20:43:00 fez Exp $"
#define MOD_AUTH_DESC "require AUTH before registering"
// defines:
#define MSG_AUTH "AUTH"
#define TOK_AUTH NULL
#define AUTH_DIRECTIVE "require-auth"
#define MSG_NOTICE "NOTICE"
// ***** Function Declarations *****
// config loading hook functions
DLLFUNC int f_auth_config_test(ConfigFile *cf, ConfigEntry *ce, int type, int *errs);
DLLFUNC int f_auth_config_posttest(int *errs);
DLLFUNC int f_auth_config_run(ConfigFile *cf, ConfigEntry *ce, int type);
DLLFUNC int f_auth_config_rehash();
// Hook functions:
DLLFUNC int f_auth_local_connect(aClient *sptr);
// commands:
DLLFUNC int f_auth_command(aClient *cptr, aClient *sptr, int parc, char *parv[]);
// ***** Global Variables *****
ModuleInfo *AuthModInfo = NULL; // for local storage of modinfo
static int auth_conf_counter = 0; // for config file
static Hook *AuthHookTest = NULL; // for config hashiing
static Hook *AuthHookPosttest = NULL; //
static Hook *AuthHookRun = NULL; //
static Hook *AuthHookRehash = NULL; //
static Hook *AuthHookLocalConnect = NULL; // for local connection hook
static Command *AuthCmd; // to store command hook status
static int auth_require = 0; // whether to require AUTH
// a description of this module
ModuleHeader MOD_HEADER(f_auth)
= {
MOD_AUTH_NAME,
MOD_AUTH_VERS,
MOD_AUTH_DESC,
"3.2.3",
NULL
};
// called before config test
DLLFUNC int MOD_TEST(f_auth)(ModuleInfo *modinfo)
{
int ret = MOD_SUCCESS;
AuthHookTest = HookAddEx(modinfo->handle, HOOKTYPE_CONFIGTEST, f_auth_config_test);
AuthHookPosttest = HookAddEx(modinfo->handle, HOOKTYPE_CONFIGPOSTTEST, f_auth_config_posttest);
auth_conf_counter = 0;
return ret;
}
// called during module initialization
DLLFUNC int MOD_INIT(f_auth)(ModuleInfo *modinfo)
{
int ret = MOD_SUCCESS;
AuthModInfo = modinfo;
AuthHookRun = HookAddEx(modinfo->handle, HOOKTYPE_CONFIGRUN, f_auth_config_run);
AuthHookRehash = HookAddEx(modinfo->handle, HOOKTYPE_REHASH, f_auth_config_rehash);
AuthHookLocalConnect = HookAddEx(modinfo->handle, HOOKTYPE_LOCAL_CONNECT, f_auth_local_connect);
AuthCmd = CommandAdd(modinfo->handle, MSG_AUTH, TOK_AUTH, f_auth_command, MAXPARA, M_UNREGISTERED|M_USER);
if (!AuthCmd)
ret = MOD_FAILED;
return ret;
}
// called when ircd is 100% ready
DLLFUNC int MOD_LOAD(f_auth)(int module_load)
{
int ret = MOD_SUCCESS;
return ret;
}
// called when unloading a module
DLLFUNC int MOD_UNLOAD(f_auth)(int module_unload)
{
int ret = MOD_SUCCESS;
CommandDel(AuthCmd);
HookDel(AuthHookTest);
HookDel(AuthHookPosttest);
HookDel(AuthHookRun);
HookDel(AuthHookRehash);
HookDel(AuthHookLocalConnect);
AuthCmd = NULL;
AuthHookLocalConnect =
AuthHookTest = AuthHookPosttest = AuthHookRun = AuthHookRehash = NULL;
return ret;
}
// this is where we TEST the config file
DLLFUNC int f_auth_config_test(ConfigFile *cf, ConfigEntry *ce, int type, int *errs)
{
int errors = 0;
if (type != CONFIG_SET)
return 0;
if (!strcmp(ce->ce_varname, AUTH_DIRECTIVE))
{
if (ce->ce_vardata)
{
config_error("%s:%i: set::%s with unnecessary value",
ce->ce_fileptr->cf_filename,
ce->ce_varlinenum, ce->ce_varname );
errors++;
}
else if (auth_conf_counter)
{
config_error("%s:%i: set::%s already defined on line %i",
ce->ce_fileptr->cf_filename,
ce->ce_varlinenum, ce->ce_varname,
auth_conf_counter );
errors++;
}
else
{
auth_conf_counter = ce->ce_varlinenum;
!auth_conf_counter && ++auth_conf_counter;
}
*errs = errors;
return errors ? -1 : 1;
}
return 0;
}
// this is run AFTER testing the config file
DLLFUNC int f_auth_config_posttest(int *errs)
{
int errors = 0;
if (!auth_conf_counter)
{
//config_error("set::%s not set.", AUTH_DIRECTIVE );
//errors++;
////or...
auth_require = 0;
}
*errs = errors;
return errors ? -1 : 1;
}
// this is run WHEN LOADING SETTINGS from the config file
DLLFUNC int f_auth_config_run(ConfigFile *cf, ConfigEntry *ce, int type)
{
if (type != CONFIG_SET)
return 0;
if (!strcmp(ce->ce_varname, AUTH_DIRECTIVE))
{
auth_require = 1;
return 1;
}
return 0;
}
// this is run when REHASHING the config file
DLLFUNC int f_auth_config_rehash()
{
auth_conf_counter = 0;
return 1;
}
// this is the local connect hook function
DLLFUNC int f_auth_local_connect(aClient *sptr)
{
if (!auth_require || !MyConnect(sptr) || !IsClient(sptr))
return 0;
sendto_one(sptr, "%s %s %s :To connect please type /quote %s %X",
me.name, MSG_NOTICE, sptr->name,
MSG_AUTH, sptr->firsttime );
SetUnknown(sptr);
IRCstats.unknown++;
IRCstats.clients--;
IRCstats.me_clients--;
me.serv->users--;
return 0;
}
// this is the AUTH command
DLLFUNC int f_auth_command(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
char authcode[32];
if (!auth_require || !MyConnect(sptr) || !IsUnknown(sptr))
return 0;
sprintf(authcode, "%X", sptr->firsttime);
if (parc > 1 && !strcmp(parv[1], authcode))
{
sendto_one(sptr, "%s %s %s :%s code accepted.",
me.name, MSG_NOTICE, sptr->name, MSG_AUTH );
SetClient(sptr);
IRCstats.unknown--;
IRCstats.clients++;
IRCstats.me_clients++;
me.serv->users++;
}
else
{
sendto_one(sptr, "%s %s %s :%s code invalid.",
me.name, MSG_NOTICE, sptr->name, MSG_AUTH );
}
return 0;
}
/* end of code */