Merge pull request #302 from edk0/sasl-usercloak
Import extensions/sasl_usercloak from ircd-seven
This commit is contained in:
commit
6cac5cce0f
2 changed files with 137 additions and 0 deletions
|
@ -68,6 +68,7 @@ extension_LTLIBRARIES = \
|
||||||
no_kill_services.la \
|
no_kill_services.la \
|
||||||
no_locops.la \
|
no_locops.la \
|
||||||
no_oper_invis.la \
|
no_oper_invis.la \
|
||||||
|
sasl_usercloak.la \
|
||||||
spy_admin_notice.la \
|
spy_admin_notice.la \
|
||||||
spy_info_notice.la \
|
spy_info_notice.la \
|
||||||
spy_links_notice.la \
|
spy_links_notice.la \
|
||||||
|
|
136
extensions/sasl_usercloak.c
Normal file
136
extensions/sasl_usercloak.c
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
#include "stdinc.h"
|
||||||
|
#include "modules.h"
|
||||||
|
#include "hook.h"
|
||||||
|
#include "client.h"
|
||||||
|
#include "hostmask.h"
|
||||||
|
#include "ircd.h"
|
||||||
|
#include "send.h"
|
||||||
|
#include "hash.h"
|
||||||
|
#include "s_conf.h"
|
||||||
|
#include "s_user.h"
|
||||||
|
#include "s_serv.h"
|
||||||
|
#include "numeric.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
static const char sasl_usercloak_desc[] =
|
||||||
|
"Insert the SASL account name into certain iline spoofed hosts";
|
||||||
|
|
||||||
|
static void check_new_user(void *data);
|
||||||
|
mapi_hfn_list_av1 sasl_usercloak_hfnlist[] = {
|
||||||
|
{ "new_local_user", check_new_user },
|
||||||
|
{ NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int fnv_hash_string(char *str)
|
||||||
|
{
|
||||||
|
unsigned int hash = 0x811c9dc5; // Magic value for 32-bit fnv1 hash initialisation.
|
||||||
|
unsigned char *p = (unsigned char *)str;
|
||||||
|
while (*p)
|
||||||
|
{
|
||||||
|
hash += (hash<<1) + (hash<<4) + (hash<<7) + (hash<<8) + (hash<<24);
|
||||||
|
hash ^= *p++;
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
check_new_user(void *vdata)
|
||||||
|
{
|
||||||
|
struct Client *source_p = vdata;
|
||||||
|
|
||||||
|
if (!IsIPSpoof(source_p))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (EmptyString(source_p->user->suser))
|
||||||
|
return;
|
||||||
|
|
||||||
|
char *accountpart = strstr(source_p->orighost, "/account");
|
||||||
|
if (!accountpart || accountpart[8] != '\0')
|
||||||
|
return;
|
||||||
|
|
||||||
|
accountpart += 1;
|
||||||
|
|
||||||
|
char buf[HOSTLEN];
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
char *dst = buf;
|
||||||
|
|
||||||
|
strncpy(buf, source_p->orighost, accountpart - source_p->orighost);
|
||||||
|
dst += accountpart - source_p->orighost;
|
||||||
|
|
||||||
|
int needhash = 0;
|
||||||
|
|
||||||
|
for (char *src = source_p->user->suser; *src ; src++ )
|
||||||
|
{
|
||||||
|
if (dst >= buf + sizeof(buf))
|
||||||
|
{
|
||||||
|
/* Doesn't fit. Warn opers and bail. */
|
||||||
|
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
|
||||||
|
"Couldn't fit account name part %s in hostname for %s!%s@%s",
|
||||||
|
source_p->user->suser, source_p->name, source_p->username, source_p->orighost);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char c = tolower(*src);
|
||||||
|
|
||||||
|
if (IsHostChar(c))
|
||||||
|
*dst++ = c;
|
||||||
|
else
|
||||||
|
needhash = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needhash)
|
||||||
|
{
|
||||||
|
if (dst > buf + sizeof(buf) - 12) /* '/x-' plus eight digit hash plus null terminator */
|
||||||
|
{
|
||||||
|
/* Doesn't fit. Warn opers and bail. */
|
||||||
|
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
|
||||||
|
"Couldn't fit account name part %s in hostname for %s!%s@%s",
|
||||||
|
source_p->user->suser, source_p->name, source_p->username, source_p->orighost);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*dst++ = '/';
|
||||||
|
*dst++ = 'x';
|
||||||
|
*dst++ = '-';
|
||||||
|
|
||||||
|
unsigned int hashval = fnv_hash_string(source_p->user->suser);
|
||||||
|
hashval %= 100000000; // eight digits only please.
|
||||||
|
snprintf(dst, 9, "%08u", hashval);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* just in case */
|
||||||
|
buf[HOSTLEN-1] = '\0';
|
||||||
|
|
||||||
|
/* If hostname has been changed already (probably by services cloak on SASL login), then
|
||||||
|
* leave it intact. If not, change it. In either case, update the original hostname.
|
||||||
|
*/
|
||||||
|
if (0 == irccmp(source_p->host, source_p->orighost))
|
||||||
|
change_nick_user_host(source_p, source_p->name, source_p->username, buf, 0, "Changing host");
|
||||||
|
strncpy(source_p->orighost, buf, HOSTLEN);
|
||||||
|
|
||||||
|
{
|
||||||
|
struct ConfItem *aconf = find_kline(source_p);
|
||||||
|
|
||||||
|
if(aconf == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(IsExemptKline(source_p))
|
||||||
|
{
|
||||||
|
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
|
||||||
|
"KLINE over-ruled for %s, client is kline_exempt [%s@%s]",
|
||||||
|
get_client_name(source_p, HIDE_IP),
|
||||||
|
aconf->user, aconf->host);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
||||||
|
"KLINE active for %s",
|
||||||
|
get_client_name(source_p, HIDE_IP));
|
||||||
|
|
||||||
|
notify_banned_client(source_p, aconf, K_LINED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLARE_MODULE_AV2(sasl_usercloak, NULL, NULL, NULL, NULL, sasl_usercloak_hfnlist, NULL, NULL, sasl_usercloak_desc);
|
Loading…
Reference in a new issue