Ejemplo n.º 1
0
int _register_user(aClient *cptr, aClient *sptr, char *nick, char *username, char *umode, char *virthost, char *ip)
{
	ConfigItem_ban *bconf;
	char *parv[3], *tmpstr;
#ifdef HOSTILENAME
	char stripuser[USERLEN + 1], *u1 = stripuser, *u2, olduser[USERLEN + 1],
	    userbad[USERLEN * 2 + 1], *ubad = userbad, noident = 0;
#endif
	int  xx;
	anUser *user = sptr->user;
	aClient *nsptr;
	int  i;
	char mo[256];
	char *tkllayer[9] = {
		me.name,	/*0  server.name */
		"+",		/*1  +|- */
		"z",		/*2  G   */
		"*",		/*3  user */
		NULL,		/*4  host */
		NULL,
		NULL,		/*6  expire_at */
		NULL,		/*7  set_at */
		NULL		/*8  reason */
	};
	aTKline *savetkl = NULL;
	ConfigItem_tld *tlds;
	cptr->last = TStime();
	parv[0] = sptr->name;
	parv[1] = parv[2] = NULL;
	nick = sptr->name; /* <- The data is always the same, but the pointer is sometimes not,
	                    *    I need this for one of my modules, so do not remove! ;) -- Syzop */
	
	if (MyConnect(sptr))
	{
		if ((i = check_client(sptr, username))) {
			/* This had return i; before -McSkaf */
			if (i == -5)
				return FLUSH_BUFFER;

			sendto_snomask(SNO_CLIENT,
			    "*** Notice -- %s from %s.",
			    i == -3 ? "Too many connections" :
			    "Unauthorized connection", get_client_host(sptr));
			ircstp->is_ref++;
			ircsprintf(mo, "This server is full.");
			return
			    exit_client(cptr, sptr, &me,
			    i ==
			    -3 ? mo :
			    "You are not authorized to connect to this server");
		}

		if (sptr->hostp)
		{
			/* reject ascci < 32 and ascii >= 127 (note: upper resolver might be even more strict) */
			for (tmpstr = sptr->sockhost; *tmpstr > ' ' && *tmpstr < 127; tmpstr++);
			
			/* if host contained invalid ASCII _OR_ the DNS reply is an IP-like reply
			 * (like: 1.2.3.4), then reject it and use IP instead.
			 */
			if (*tmpstr || !*user->realhost || (isdigit(*sptr->sockhost) && isdigit(*tmpstr - 1)))
				strncpyzt(sptr->sockhost, (char *)Inet_ia2p((struct IN_ADDR*)&sptr->ip), sizeof(sptr->sockhost));
		}
		strncpyzt(user->realhost, sptr->sockhost, sizeof(sptr->sockhost)); /* SET HOSTNAME */

		/*
		 * I do not consider *, ~ or ! 'hostile' in usernames,
		 * as it is easy to differentiate them (Use \*, \? and \\)
		 * with the possible?
		 * exception of !. With mIRC etc. ident is easy to fake
		 * to contain @ though, so if that is found use non-ident
		 * username. -Donwulff
		 *
		 * I do, We only allow a-z A-Z 0-9 _ - and . now so the
		 * !strchr(sptr->username, '@') check is out of date. -Cabal95
		 *
		 * Moved the noident stuff here. -OnyxDragon
		 */
		if (!(sptr->flags & FLAGS_DOID)) 
			strncpyzt(user->username, username, USERLEN + 1);
		else if (sptr->flags & FLAGS_GOTID) 
			strncpyzt(user->username, sptr->username, USERLEN + 1);
		else
		{

			/* because username may point to user->username */
			char temp[USERLEN + 1];
			strncpyzt(temp, username, USERLEN + 1);
			if (IDENT_CHECK == 0) {
				strncpyzt(user->username, temp, USERLEN + 1);
			}
			else {
				*user->username = '******';
				strncpyzt((user->username + 1), temp, USERLEN);
#ifdef HOSTILENAME
				noident = 1;
#endif
			}

		}
#ifdef HOSTILENAME
		/*
		 * Limit usernames to just 0-9 a-z A-Z _ - and .
		 * It strips the "bad" chars out, and if nothing is left
		 * changes the username to the first 8 characters of their
		 * nickname. After the MOTD is displayed it sends numeric
		 * 455 to the user telling them what(if anything) happened.
		 * -Cabal95
		 *
		 * Moved the noident thing to the right place - see above
		 * -OnyxDragon
		 * 
		 * No longer use nickname if the entire ident is invalid,
                 * if thats the case, it is likely the user is trying to cause
		 * problems so just ban them. (Using the nick could introduce
		 * hostile chars) -- codemastr
		 */
		for (u2 = user->username + noident; *u2; u2++)
		{
			if (isallowed(*u2))
				*u1++ = *u2;
			else if (*u2 < 32)
			{
				/*
				 * Make sure they can read what control
				 * characters were in their username.
				 */
				*ubad++ = '^';
				*ubad++ = *u2 + '@';
			}
			else
				*ubad++ = *u2;
		}
		*u1 = '\0';
		*ubad = '\0';
		if (strlen(stripuser) != strlen(user->username + noident))
		{
			if (stripuser[0] == '\0')
			{
				return exit_client(cptr, cptr, cptr, "Hostile username. Please use only 0-9 a-z A-Z _ - and . in your username.");
			}

			strcpy(olduser, user->username + noident);
			strncpy(user->username + 1, stripuser, USERLEN - 1);
			user->username[0] = '~';
			user->username[USERLEN] = '\0';
		}
		else
			u1 = NULL;
#endif

		/*
		 * following block for the benefit of time-dependent K:-lines
		 */
		if ((bconf =
		    Find_ban(sptr, make_user_host(user->username, user->realhost),
		    CONF_BAN_USER)))
		{
			ircstp->is_ref++;
			sendto_one(cptr,
			    ":%s %d %s :*** You are not welcome on this server (%s)"
			    " Email %s for more information.",
			    me.name, ERR_YOUREBANNEDCREEP,
			    cptr->name, bconf->reason ? bconf->reason : "",
			    KLINE_ADDRESS);
			return exit_client(cptr, cptr, cptr, "You are banned");
		}
		if ((bconf = Find_ban(NULL, sptr->info, CONF_BAN_REALNAME)))
		{
			ircstp->is_ref++;
			sendto_one(cptr,
			    ":%s %d %s :*** Your GECOS (real name) is not allowed on this server (%s)"
			    " Please change it and reconnect",
			    me.name, ERR_YOUREBANNEDCREEP,
			    cptr->name, bconf->reason ? bconf->reason : "");

			return exit_client(cptr, sptr, &me,
			    "Your GECOS (real name) is banned from this server");
		}
		tkl_check_expire(NULL);
		/* Check G/Z lines before shuns -- kill before quite -- codemastr */
		if ((xx = find_tkline_match(sptr, 0)) < 0)
		{
			ircstp->is_ref++;
			return xx;
		}
		find_shun(sptr);

		/* Technical note regarding next few lines of code:
		 * If the spamfilter matches, depending on the action:
		 *  If it's block/dccblock/whatever the retval is -1 ===> we return, client stays "locked forever".
		 *  If it's kill/tklline the retval is -2 ==> we return with -2 (aka: FLUSH_BUFFER)
		 *  If it's action is viruschan the retval is -5 ==> we continue, and at the end of this return
		 *    take special actions. We cannot do that directly here since the user is not fully registered
		 *    yet (at all).
		 *  -- Syzop
		 */
		spamfilter_build_user_string(spamfilter_user, sptr->name, sptr);
		xx = dospamfilter(sptr, spamfilter_user, SPAMF_USER, NULL, 0, &savetkl);
		if ((xx < 0) && (xx != -5))
			return xx;

		RunHookReturnInt(HOOKTYPE_PRE_LOCAL_CONNECT, sptr, !=0);
	}
	else
	{
Ejemplo n.º 2
0
/*	m_gqline - Global Q:Line
**	parv[0] = sender
**	parv[1] = nickname mask
**	parv[2] = Optional expiration time
**	parv[3] = reason
*/
static int m_gqline(aClient *cptr, aClient *sptr, int parc, char* parv[])
{
    TS secs;
    int whattodo = 0;
    int i;
    aClient *acptr = NULL;
    char *mask = NULL;
    char mo[1024], mo2[1024];
    char *p;
    char *tkllayer[9] = {
        me.name,	/* 0 = Server Name */
        NULL,		/* 1 = + / - */
        "Q",		/* 2 = Q - Global Q:Line */
        "*",		/* 3 = * = normal qline, H = hold */
        NULL,		/* 4 = Nickname mask */
        NULL,		/* 5 = setby */
        "0",		/* 6 = expire ts */
        NULL,		/* 7 = set ts */
        "no reason"	/* 8 = reason */
    };
    struct tm *t = NULL;
    if (IsServer(sptr)) return 0;
    if (!OPCanTKL(sptr) || !IsOper(sptr))
    {
        sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, sptr->name);
        return 0;
    }
    if (parc == 1)
    {
        tkl_stats(sptr, TKL_NICK|TKL_GLOBAL, NULL);
        sendto_one(sptr, rpl_str(RPL_ENDOFSTATS), me.name, sptr->name, 'Q');
        return 0;
    }
    mask = parv[1];
    if (*mask == '-') {
        whattodo = 1;
        mask++;
    }
    else if (*mask == '+') {
        whattodo = 0;
        mask++;
    }
    if (!whattodo) {
        char c;
        i = 0;
        for (p = mask; *p; p++) if (*p != '*' && *p != '?') i++;
        if (i < 4) {
            sendto_one(sptr, ":%s NOTICE %s :*** [error] Too broad mask", me.name, sptr->name);
            return 0;
        }
    }
    tkl_check_expire(NULL);
    secs = 0;
    if (whattodo == 0 && (parc > 3))
    {
        secs = atime(parv[2]);
        if (secs < 0) {
            sendto_one(sptr, ":%s NOTICE %s :*** [error] Specified time out of range", me.name, sptr->name);
            return 0;
        }
    }
    tkllayer[1] = whattodo == 0 ? "+" : "-";
    tkllayer[4] = mask;
    tkllayer[5] = make_nick_user_host(sptr->name, sptr->user->username, GetHost(sptr));
    if (whattodo == 0)
    {
        if (secs == 0)
        {
            if (DEFAULT_BANTIME && (parc <= 3))
                ircsprintf(mo, "%li", DEFAULT_BANTIME + TStime());
            else
                ircsprintf(mo, "%li", secs);
        }
        else
            ircsprintf(mo, "%li", secs + TStime());
        ircsprintf(mo2, "%li", TStime());
        tkllayer[6] = mo;
        tkllayer[7] = mo2;
        if (parc > 3) {
            tkllayer[8] = parv[3];
        } else if (parc > 2) {
            tkllayer[8] = parv[2];
        }
        i = atol(mo);
        t = gmtime((TS*)&i);
        if (!t)
        {
            sendto_one(sptr, ":%s NOTICE %s :*** [error] Specified time is out of range", me.name, sptr->name);
            return 0;
        }
        m_tkl(&me, &me, 9, tkllayer);
    }
    else {
        m_tkl(&me, &me, 6, tkllayer);
    }
    return 0;
}