nickchars...

- Build in some additional checks (especially for Chinese).
  - Fixed a bug in chinese character range (affecting 3.2*)
  - Relaxed nick character checking from remote servers (rely on NICKCHARS= PROTOCTL
    to deal with problems). This is useful to prevent any kills in case we slightly
    change the characters that are allowed in a language.
This commit is contained in:
Bram Matthys 2005-02-22 16:47:20 +00:00
parent 8ba098a77a
commit 2c500fcf72
5 changed files with 60 additions and 10 deletions

View file

@ -641,3 +641,8 @@
- Removed e' accent from German (used in borrow-words only), reported by Dukat.
- Added 'swiss-german', which is just German without es-zett, reported by Dukat.
- Added 'turkish', supplied by Ayberk Yancatoral.
- Build in some additional checks (especially for Chinese).
- Fixed a bug in chinese character range (affecting 3.2*)
- Relaxed nick character checking from remote servers (rely on NICKCHARS= PROTOCTL
to deal with problems). This is useful to prevent any kills in case we slightly
change the characters that are allowed in a language.

View file

@ -560,7 +560,7 @@ and except tkl::mask (for gzline, gline, and shun). Additionally, CIDR can be us
fe80:0:0:123:0:0:0:0 - fe80:0:0:123:ffff:ffff:ffff:ffff).</p></div>
<p><font size="+2"><b>3.16 - Nick Character Sets</b></font><a name="feature_nickchars"></a></p><div class="desc">
<p>UnrealIRCd has now the ability to specify which charsets/languages should be allowed
<p>UnrealIRCd now has the ability to specify which charsets/languages should be allowed
in nicknames. You do this in <b>set::allowed-nickchars</b>.<br>
A table of all possible choices:<br>
<table border="1">

View file

@ -183,6 +183,7 @@ extern int del_silence(aClient *, char *);
extern void send_user_joins(aClient *, aClient *);
extern void clean_channelname(char *);
extern int do_nick_name(char *);
extern int do_remote_nick_name(char *);
extern int can_send(aClient *, aChannel *, char *, int);
extern long get_access(aClient *, aChannel *);
extern int is_chan_op(aClient *, aChannel *);

View file

@ -119,6 +119,20 @@ ILangList *ilanglist = NULL;
static int do_nick_name_multibyte(char *nick);
static int do_nick_name_standard(char *nick);
/* These characters are ALWAYS disallowed... from remote, in
* multibyte, etc.. even though this might mean a certain
* (legit) character cannot be used (eg: in chinese GBK).
* - no breaking space
* - ! (nick!user seperator)
* - prefix chars: +, %, @, &, ~
* - channel chars: #
* - scary chars: $, :, ', ", ?, *, ',', '.'
* NOTE: the caller should also check for ascii <= 32.
* [CHANGING THIS WILL CAUSE SECURITY/SYNCH PROBLEMS AND WILL
* VIOLATE YOUR ""RIGHT"" ON SUPPORT IMMEDIATELY]
*/
const char *illegalnickchars = "\xA0!+%@&~#$:'\"?*,.";
/** Called on boot and just before config run */
void charsys_reset(void)
{
@ -232,7 +246,16 @@ MBList *m = MyMallocEx(sizeof(m));
void charsys_addallowed(char *s)
{
for (; *s; s++)
{
if ((*s <= 32) || strchr(illegalnickchars, *s))
{
config_error("INTERNAL ERROR: charsys_addallowed() called for illegal characters: %s", s);
#ifdef DEBUGMODE
abort();
#endif
}
char_atribs[(unsigned int)*s] |= ALLOWN;
}
}
int do_nick_name(char *nick)
@ -287,6 +310,9 @@ int firstmbchar = 0;
for (ch=nick,len=0; *ch && len <= NICKLEN; ch++, len++)
{
/* Some characters are ALWAYS illegal, so they have to be disallowed here */
if ((*ch <= 32) || strchr(illegalnickchars, *ch))
return 0;
if (firstmbchar)
{
if (!isvalidmbyte(ch[-1], *ch))
@ -303,6 +329,23 @@ int firstmbchar = 0;
return len;
}
/** Does some very basic checking on remote nickname.
* It's only purpose is not to cause the whole network
* to fall down in pieces, that's all. Display problems
* are not really handled here. They are assumed to have been
* checked by PROTOCTL NICKCHARS= -- Syzop.
*/
int do_remote_nick_name(char *nick)
{
char *c;
for (c=nick; *c; c++)
if ((*c <= 32) || strchr(illegalnickchars, *c))
return 0;
return (c - nick);
}
/** Check if the specified charsets during the TESTING phase can be
* premitted without getting into problems.
* RETURNS: -1 in case of failure, 1 if ok
@ -523,7 +566,9 @@ char latin1=0, latin2=0, chinese=0;
}
if (chinese || !strcmp(name, "chinese-trad"))
{
charsys_addmultibyterange(0x81, 0xa0, 0x40, 0xfe); /* GBK/3 */
charsys_addmultibyterange(0xaa, 0xfe, 0x40, 0xa0); /* GBK/4 */
charsys_addmultibyterange(0x81, 0xa0, 0x40, 0x7e); /* GBK/3 - lower half */
charsys_addmultibyterange(0x81, 0xa0, 0x80, 0xfe); /* GBK/3 - upper half */
charsys_addmultibyterange(0xaa, 0xfe, 0x40, 0x7e); /* GBK/4 - lower half */
charsys_addmultibyterange(0xaa, 0xfe, 0x80, 0xa0); /* GBK/4 - upper half */
}
}

View file

@ -139,14 +139,13 @@ DLLFUNC CMD_FUNC(m_nick)
}
}
/*
* if do_nick_name() returns a null name OR if the server sent a nick
* name and do_nick_name() changed it in some way (due to rules of nick
* creation) then reject it. If from a server and we reject it,
* and KILL it. -avalon 4/4/92
/* For a local clients, do proper nickname checking via do_nick_name()
* and reject the nick if it returns false.
* For remote clients, do a quick check by using do_remote_nick_name(),
* if this returned false then reject and kill it. -- Syzop
*/
if (do_nick_name(nick) == 0 ||
(IsServer(cptr) && strcmp(nick, parv[1])))
if ((IsServer(cptr) && !do_remote_nick_name(nick)) ||
(!IsServer(cptr) && !do_nick_name(nick)))
{
sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME),
me.name, parv[0], parv[1], "Illegal characters");