diff -Nur ircu2.10.12.05/doc/example.conf ircu2.10.12.05-fakehosts/doc/example.conf --- ircu2.10.12.05/doc/example.conf 2006-01-12 03:32:44.000000000 +0100 +++ ircu2.10.12.05-fakehosts/doc/example.conf 2006-01-23 17:53:34.000000000 +0100 @@ -213,6 +213,7 @@ # badchan (can issue Gchans to other servers) # force_opmode (can use OPMODE/CLEARMODE on quarantined global channels) # apass_opmode (can use OPMODE/CLEARMODE on +A and +U keys) + # set_fakehost (can set own fakehost with /fakehost) # # For global opers (with propagate = yes or local = no), the default # is to grant all of the above privileges EXCEPT walk_lchan, diff -Nur ircu2.10.12.05/include/class.h ircu2.10.12.05-fakehosts/include/class.h --- ircu2.10.12.05/include/class.h 2005-10-05 03:51:34.000000000 +0200 +++ ircu2.10.12.05-fakehosts/include/class.h 2006-01-23 17:53:34.000000000 +0100 @@ -42,6 +42,8 @@ char *cc_name; /**< Name of connection class. */ char *default_umode; /**< Default usermode for users in this class. */ + char *default_fakehost; /**< Default fakehost for users + in this class */ struct Privs privs; /**< Privilege bits that are set on or off. */ struct Privs privs_dirty; /**< Indication of which bits in @@ -86,6 +88,8 @@ #define ConfLinks(x) ((x)->conn_class->ref_count) /** Get default usermode for ConfItem \a x. */ #define ConfUmode(x) ((x)->conn_class->default_umode) +/** Get default fakehost for ConfItem \a x. */ +#define ConfFakehost(x) ((x)->conn_class->default_fakehost) /** Find a valid configuration class by name. */ #define find_class(name) do_find_class((name), 0) diff -Nur ircu2.10.12.05/include/client.h ircu2.10.12.05-fakehosts/include/client.h --- ircu2.10.12.05/include/client.h 2006-01-04 02:54:48.000000000 +0100 +++ ircu2.10.12.05-fakehosts/include/client.h 2006-01-23 17:53:34.000000000 +0100 @@ -126,6 +126,7 @@ PRIV_FORCE_OPMODE, /**< can hack modes on quarantined channels */ PRIV_FORCE_LOCAL_OPMODE, /**< can hack modes on quarantined local channels */ PRIV_APASS_OPMODE, /**< can hack modes +A/-A/+U/-U */ + PRIV_SET_FAKEHOST, PRIV_LAST_PRIV /**< number of privileges */ }; @@ -167,6 +168,7 @@ FLAG_DEBUG, /**< send global debug/anti-hack info */ FLAG_ACCOUNT, /**< account name has been set */ FLAG_HIDDENHOST, /**< user's host is hidden */ + FLAG_FAKEHOST, /**< user has been assigned a fake host */ FLAG_LAST_FLAG, /**< number of flags */ FLAG_LOCAL_UMODES = FLAG_LOCOP, /**< First local mode flag */ FLAG_GLOBAL_UMODES = FLAG_OPER /**< First global mode flag */ @@ -610,7 +612,8 @@ /** Return non-zero if the client has operator or server privileges. */ #define IsPrivileged(x) (IsAnOper(x) || IsServer(x)) /** Return non-zero if the client's host is hidden. */ -#define HasHiddenHost(x) (IsHiddenHost(x) && IsAccount(x)) +#define HasHiddenHost(x) (IsHiddenHost(x) && (IsAccount(x) || HasFakeHost(x))) +#define HasFakeHost(x) HasFlag(x, FLAG_FAKEHOST) /** Mark a client as having an in-progress net.burst. */ #define SetBurst(x) SetFlag(x, FLAG_BURST) @@ -652,6 +655,8 @@ #define SetAccount(x) SetFlag(x, FLAG_ACCOUNT) /** Mark a client as having mode +x (hidden host). */ #define SetHiddenHost(x) SetFlag(x, FLAG_HIDDENHOST) +/** Mark a client as having a fake host. */ +#define SetFakeHost(x) SetFlag(x, FLAG_FAKEHOST) /** Mark a client as having a pending PING. */ #define SetPingSent(x) SetFlag(x, FLAG_PINGSENT) @@ -685,6 +690,8 @@ #define ClearServNotice(x) ClrFlag(x, FLAG_SERVNOTICE) /** Remove mode +x (hidden host) from the client. */ #define ClearHiddenHost(x) ClrFlag(x, FLAG_HIDDENHOST) +/** Remove fake host flag from the flient. */ +#define ClearFakeHost(x) ClrFlag(x, FLAG_FAKEHOST) /** Clear the client's pending PING flag. */ #define ClearPingSent(x) ClrFlag(x, FLAG_PINGSENT) @@ -753,6 +760,7 @@ extern const char* get_client_name(const struct Client* sptr, int showip); extern const char* client_get_default_umode(const struct Client* sptr); +extern const char* client_get_default_fakehost(const struct Client* sptr); extern int client_get_ping(const struct Client* local_client); extern void client_drop_sendq(struct Connection* con); extern void client_add_sendq(struct Connection* con, diff -Nur ircu2.10.12.05/include/handlers.h ircu2.10.12.05-fakehosts/include/handlers.h --- ircu2.10.12.05/include/handlers.h 2005-04-07 14:11:48.000000000 +0200 +++ ircu2.10.12.05-fakehosts/include/handlers.h 2006-01-23 17:53:34.000000000 +0100 @@ -91,6 +91,7 @@ extern int m_cap(struct Client*, struct Client*, int, char*[]); extern int m_cnotice(struct Client*, struct Client*, int, char*[]); extern int m_cprivmsg(struct Client*, struct Client*, int, char*[]); +extern int m_fakehost(struct Client*, struct Client*, int, char*[]); extern int m_gline(struct Client*, struct Client*, int, char*[]); extern int m_help(struct Client*, struct Client*, int, char*[]); extern int m_ignore(struct Client*, struct Client*, int, char*[]); @@ -187,6 +188,7 @@ extern int ms_end_of_burst(struct Client*, struct Client*, int, char*[]); extern int ms_end_of_burst_ack(struct Client*, struct Client*, int, char*[]); extern int ms_error(struct Client*, struct Client*, int, char*[]); +extern int ms_fakehost(struct Client*, struct Client*, int, char*[]); extern int ms_gline(struct Client*, struct Client*, int, char*[]); extern int ms_info(struct Client*, struct Client*, int, char*[]); extern int ms_invite(struct Client*, struct Client*, int, char*[]); diff -Nur ircu2.10.12.05/include/msg.h ircu2.10.12.05-fakehosts/include/msg.h --- ircu2.10.12.05/include/msg.h 2005-04-07 14:11:48.000000000 +0200 +++ ircu2.10.12.05-fakehosts/include/msg.h 2006-01-23 17:53:34.000000000 +0100 @@ -340,6 +340,14 @@ #define TOK_ASLL "LL" #define CMD_ASLL MSG_ASLL, TOK_ASLL +#define MSG_FAKEHOST "FAKE" /* FAKE */ +#define TOK_FAKEHOST "FA" +#define CMD_FAKEHOST MSG_FAKEHOST, TOK_FAKEHOST + +#define MSG_FAKEHOST2 "FAKEHOST" /* FAKEHOST (for compatibility) */ +#define TOK_FAKEHOST2 "FH" +#define CMD_FAKEHOST2 MSG_FAKEHOST2, TOK_FAKEHOST2 + #define MSG_POST "POST" /* POST */ #define TOK_POST "POST" diff -Nur ircu2.10.12.05/include/s_user.h ircu2.10.12.05-fakehosts/include/s_user.h --- ircu2.10.12.05/include/s_user.h 2004-11-07 20:34:15.000000000 +0100 +++ ircu2.10.12.05-fakehosts/include/s_user.h 2006-01-23 17:53:34.000000000 +0100 @@ -78,7 +78,8 @@ extern void send_user_info(struct Client* to, char* names, int rpl, InfoFormatter fmt); -extern int hide_hostmask(struct Client *cptr, unsigned int flags); +extern void make_hidden_hostmask(char *buffer, struct Client *cptr); +extern int hide_hostmask(struct Client *cptr); extern int set_user_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv[]); extern int is_silenced(struct Client *sptr, struct Client *acptr); diff -Nur ircu2.10.12.05/include/struct.h ircu2.10.12.05-fakehosts/include/struct.h --- ircu2.10.12.05/include/struct.h 2005-04-01 00:03:32.000000000 +0200 +++ ircu2.10.12.05-fakehosts/include/struct.h 2006-01-23 17:53:34.000000000 +0100 @@ -81,6 +81,7 @@ char username[USERLEN + 1]; char host[HOSTLEN + 1]; /**< displayed hostname */ char realhost[HOSTLEN + 1]; /**< actual hostname */ + char fakehost[HOSTLEN + 1]; /**< fake hostname */ char account[ACCOUNTLEN + 1]; /**< IRC account name */ time_t acc_create; /**< IRC account timestamp */ }; diff -Nur ircu2.10.12.05/ircd/Makefile.in ircu2.10.12.05-fakehosts/ircd/Makefile.in --- ircu2.10.12.05/ircd/Makefile.in 2005-11-28 03:21:29.000000000 +0100 +++ ircu2.10.12.05-fakehosts/ircd/Makefile.in 2006-01-23 17:53:34.000000000 +0100 @@ -131,6 +131,7 @@ m_die.c \ m_endburst.c \ m_error.c \ + m_fakehost.c \ m_get.c \ m_gline.c \ m_help.c \ @@ -608,6 +609,13 @@ ../include/ircd_string.h ../include/ircd_chattr.h ../include/numeric.h \ ../include/numnicks.h ../include/match.h ../include/msg.h \ ../include/send.h ../include/s_bsd.h ../include/s_user.h +m_fakehost.o: m_fakehost.c ../config.h ../include/client.h \ + ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ + ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \ + ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \ + ../include/s_user.h ../include/send.h m_away.o: m_away.c ../config.h ../include/client.h ../include/ircd_defs.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ ../config.h ../include/ircd_handler.h ../include/res.h \ diff -Nur ircu2.10.12.05/ircd/channel.c ircu2.10.12.05-fakehosts/ircd/channel.c --- ircu2.10.12.05/ircd/channel.c 2006-01-07 02:08:29.000000000 +0100 +++ ircu2.10.12.05-fakehosts/ircd/channel.c 2006-01-23 17:53:34.000000000 +0100 @@ -374,17 +374,26 @@ char tmphost[HOSTLEN + 1]; char iphost[SOCKIPLEN + 1]; char *hostmask; - char *sr; + char *sr, *sr2; struct Ban *found; /* Build nick!user and alternate host names. */ ircd_snprintf(0, nu, sizeof(nu), "%s!%s", cli_name(cptr), cli_user(cptr)->username); ircd_ntoa_r(iphost, &cli_ip(cptr)); + sr2 = NULL; if (!IsAccount(cptr)) sr = NULL; else if (HasHiddenHost(cptr)) + { sr = cli_user(cptr)->realhost; + if (HasFakeHost(cptr)) + { + ircd_snprintf(0, tmphost, HOSTLEN, "%s.%s", + cli_user(cptr)->account, feature_str(FEAT_HIDDEN_HOST)); + sr2 = tmphost; + } + } else { ircd_snprintf(0, tmphost, HOSTLEN, "%s.%s", @@ -409,7 +418,8 @@ if (!((banlist->flags & BAN_IPMASK) && ipmask_check(&cli_ip(cptr), &banlist->address, banlist->addrbits)) && match(hostmask, cli_user(cptr)->host) - && !(sr && !match(hostmask, sr))) + && !(sr && !match(hostmask, sr)) + && !(sr2 && !match(hostmask, sr2))) continue; /* If an exception matches, no ban can match. */ if (banlist->flags & BAN_EXCEPTION) diff -Nur ircu2.10.12.05/ircd/client.c ircu2.10.12.05-fakehosts/ircd/client.c --- ircu2.10.12.05/ircd/client.c 2005-10-13 01:50:04.000000000 +0200 +++ ircu2.10.12.05-fakehosts/ircd/client.c 2006-01-23 17:53:34.000000000 +0100 @@ -88,6 +88,25 @@ return NULL; } +/* + * client_get_default_fakehost + * returns default fakehost in attached client connection class + */ +const char* client_get_default_fakehost(const struct Client* sptr) +{ + struct ConfItem* aconf; + struct SLink* link; + + assert(cli_verify(sptr)); + + for (link = cli_confs(sptr); link; link = link->next) { + aconf = link->value.aconf; + if ((aconf->status & CONF_CLIENT) && ConfFakehost(aconf)) + return ConfFakehost(aconf); + } + return NULL; +} + /** Remove a connection from the list of connections with queued data. * @param[in] con Connection with no queued data. */ @@ -158,6 +177,7 @@ FlagClr(&privs_global, PRIV_BADCHAN); FlagClr(&privs_global, PRIV_LOCAL_BADCHAN); FlagClr(&privs_global, PRIV_APASS_OPMODE); + FlagClr(&privs_global, PRIV_SET_FAKEHOST); memset(&privs_local, 0, sizeof(privs_local)); FlagSet(&privs_local, PRIV_CHAN_LIMIT); @@ -235,7 +255,7 @@ P(OPMODE), P(LOCAL_OPMODE), P(SET), P(WHOX), P(BADCHAN), P(LOCAL_BADCHAN), P(SEE_CHAN), P(PROPAGATE), P(DISPLAY), P(SEE_OPERS), P(WIDE_GLINE), P(LIST_CHAN), - P(FORCE_OPMODE), P(FORCE_LOCAL_OPMODE), P(APASS_OPMODE), + P(FORCE_OPMODE), P(FORCE_LOCAL_OPMODE), P(APASS_OPMODE), P(SET_FAKEHOST), #undef P { 0, 0 } }; @@ -253,7 +273,7 @@ int i; mb = msgq_make(to, rpl_str(RPL_PRIVS), cli_name(&me), cli_name(to), - cli_name(client)); + cli_name(client)); for (i = 0; privtab[i].name; i++) if (HasPriv(client, privtab[i].priv)) diff -Nur ircu2.10.12.05/ircd/ircd_lexer.l ircu2.10.12.05-fakehosts/ircd/ircd_lexer.l --- ircu2.10.12.05/ircd/ircd_lexer.l 2005-04-27 03:29:53.000000000 +0200 +++ ircu2.10.12.05-fakehosts/ircd/ircd_lexer.l 2006-01-23 17:53:34.000000000 +0100 @@ -100,6 +100,7 @@ TOKEN(PSEUDO), TOKEN(PREPEND), TOKEN(USERMODE), + TOKEN(FAKEHOST), TOKEN(FAST), TOKEN(AUTOCONNECT), #undef TOKEN @@ -138,6 +139,7 @@ { "see_chan", TPRIV_SEE_CHAN }, { "see_opers", TPRIV_SEE_OPERS }, { "set", TPRIV_SET }, + { "set_fakehost", TPRIV_SET_FAKEHOST }, { "show_all_invis", TPRIV_SHOW_ALL_INVIS }, { "show_invis", TPRIV_SHOW_INVIS }, { "tb", TBYTES }, diff -Nur ircu2.10.12.05/ircd/ircd_parser.y ircu2.10.12.05-fakehosts/ircd/ircd_parser.y --- ircu2.10.12.05/ircd/ircd_parser.y 2005-12-14 00:12:41.000000000 +0100 +++ ircu2.10.12.05-fakehosts/ircd/ircd_parser.y 2006-01-23 17:53:34.000000000 +0100 @@ -152,6 +152,7 @@ %token PSEUDO %token PREPEND %token USERMODE +%token FAKEHOST %token IAUTH %token TIMEOUT %token FAST @@ -163,7 +164,7 @@ %token TPRIV_LOCAL_OPMODE TPRIV_OPMODE TPRIV_SET TPRIV_WHOX TPRIV_BADCHAN %token TPRIV_SEE_CHAN TPRIV_SHOW_INVIS TPRIV_SHOW_ALL_INVIS TPRIV_PROPAGATE %token TPRIV_UNLIMIT_QUERY TPRIV_DISPLAY TPRIV_SEE_OPERS TPRIV_WIDE_GLINE -%token TPRIV_FORCE_OPMODE TPRIV_FORCE_LOCAL_OPMODE TPRIV_APASS_OPMODE +%token TPRIV_FORCE_OPMODE TPRIV_FORCE_LOCAL_OPMODE TPRIV_APASS_OPMODE TPRIV_SET_FAKEHOST /* and some types... */ %type sizespec %type timespec timefactor factoredtimes factoredtime @@ -356,6 +357,7 @@ c_class = find_class(name); MyFree(c_class->default_umode); c_class->default_umode = pass; + c_class->default_fakehost = host; memcpy(&c_class->privs, &privs, sizeof(c_class->privs)); memcpy(&c_class->privs_dirty, &privs_dirty, sizeof(c_class->privs_dirty)); } @@ -364,6 +366,7 @@ } name = NULL; pass = NULL; + host = NULL; tconn = 0; maxlinks = 0; sendq = 0; @@ -372,7 +375,7 @@ }; classitems: classitem classitems | classitem; classitem: classname | classpingfreq | classconnfreq | classmaxlinks | - classsendq | classusermode | priv; + classsendq | classusermode | classfakehost | priv; classname: NAME '=' QSTRING ';' { MyFree(name); @@ -399,6 +402,12 @@ MyFree(pass); pass = $3; }; +classfakehost: FAKEHOST '=' QSTRING ';' +{ + if (host) + MyFree(host); + DupString(host, yylval.text); +} connectblock: CONNECT { @@ -585,6 +594,7 @@ TPRIV_MODE_LCHAN { $$ = PRIV_MODE_LCHAN; } | TPRIV_DEOP_LCHAN { $$ = PRIV_DEOP_LCHAN; } | TPRIV_WALK_LCHAN { $$ = PRIV_WALK_LCHAN; } | + TPRIV_SET_FAKEHOST { $$ = PRIV_SET_FAKEHOST; } | KILL { $$ = PRIV_KILL; } | TPRIV_LOCAL_KILL { $$ = PRIV_LOCAL_KILL; } | TPRIV_REHASH { $$ = PRIV_REHASH; } | diff -Nur ircu2.10.12.05/ircd/m_account.c ircu2.10.12.05-fakehosts/ircd/m_account.c --- ircu2.10.12.05/ircd/m_account.c 2004-12-11 12:35:30.000000000 +0100 +++ ircu2.10.12.05-fakehosts/ircd/m_account.c 2006-01-23 17:53:34.000000000 +0100 @@ -106,6 +106,7 @@ char* parv[]) { struct Client *acptr; + int hidden; if (parc < 3) return need_more_params(sptr, "ACCOUNT"); @@ -136,8 +137,11 @@ "timestamp %Tu", parv[2], cli_user(acptr)->acc_create)); } + hidden = HasHiddenHost(acptr); + SetAccount(acptr); ircd_strncpy(cli_user(acptr)->account, parv[2], ACCOUNTLEN); - hide_hostmask(acptr, FLAG_ACCOUNT); + if (!hidden) + hide_hostmask(acptr); sendcmdto_serv_butone(sptr, CMD_ACCOUNT, cptr, cli_user(acptr)->acc_create ? "%C %s %Tu" : "%C %s", diff -Nur ircu2.10.12.05/ircd/m_fakehost.c ircu2.10.12.05-fakehosts/ircd/m_fakehost.c --- ircu2.10.12.05/ircd/m_fakehost.c 1970-01-01 01:00:00.000000000 +0100 +++ ircu2.10.12.05-fakehosts/ircd/m_fakehost.c 2006-01-23 17:54:12.000000000 +0100 @@ -0,0 +1,160 @@ +/* + * IRC - Internet Relay Chat, ircd/m_fakehost.c + * Copyright (C) 2004 Zoot + * + * See file AUTHORS in IRC package for additional names of + * the programmers. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + */ + +/* + * m_functions execute protocol messages on this server: + * + * cptr is always NON-NULL, pointing to a *LOCAL* client + * structure (with an open socket connected!). This + * identifies the physical socket where the message + * originated (or which caused the m_function to be + * executed--some m_functions may call others...). + * + * sptr is the source of the message, defined by the + * prefix part of the message if present. If not + * or prefix not found, then sptr==cptr. + * + * (!IsServer(cptr)) => (cptr == sptr), because + * prefixes are taken *only* from servers... + * + * (IsServer(cptr)) + * (sptr == cptr) => the message didn't + * have the prefix. + * + * (sptr != cptr && IsServer(sptr) means + * the prefix specified servername. (?) + * + * (sptr != cptr && !IsServer(sptr) means + * that message originated from a remote + * user (not local). + * + * combining + * + * (!IsServer(sptr)) means that, sptr can safely + * taken as defining the target structure of the + * message in this server. + * + * *Always* true (if 'parse' and others are working correct): + * + * 1) sptr->from == cptr (note: cptr->from == cptr) + * + * 2) MyConnect(sptr) <=> sptr == cptr (e.g. sptr + * *cannot* be a local connection, unless it's + * actually cptr!). [MyConnect(x) should probably + * be defined as (x == x->from) --msa ] + * + * parc number of variable parameter strings (if zero, + * parv is allowed to be NULL) + * + * parv a NULL terminated list of parameter pointers, + * + * parv[0], sender (prefix string), if not present + * this points to an empty string. + * parv[1]...parv[parc-1] + * pointers to additional parameters + * parv[parc] == NULL, *always* + * + * note: it is guaranteed that parv[0]..parv[parc-1] are all + * non-NULL pointers. + */ +#include "config.h" + +#include "client.h" +#include "hash.h" +#include "ircd.h" +#include "ircd_reply.h" +#include "ircd_string.h" +#include "msg.h" +#include "numeric.h" +#include "numnicks.h" +#include "s_conf.h" +#include "s_user.h" +#include "send.h" +#include + +/* + * m_fakehost - fakehost user message handler + * + * parv[0] = sender prefix + * parv[1] = new fake host + */ +int m_fakehost(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) +{ + if (!HasPriv(sptr, PRIV_SET_FAKEHOST)) + return send_reply(sptr, ERR_NOPRIVILEGES); + + if (parc < 2) + return need_more_params(sptr, "FAKEHOST"); + + /* Ignore the assignment if it changes nothing */ + if (HasFakeHost(cptr) && + ircd_strcmp(cli_user(cptr)->fakehost, parv[1]) == 0) + { + return 0; + } + + /* Assign and propagate the fakehost */ + SetFakeHost(cptr); + ircd_strncpy(cli_user(cptr)->fakehost, parv[1], HOSTLEN); + hide_hostmask(cptr); + + sendcmdto_serv_butone(sptr, CMD_FAKEHOST, cptr, "%C %s", sptr, + cli_user(cptr)->fakehost); + return 0; +} + +/* + * ms_fakehost - fakehost server message handler + * + * parv[0] = sender prefix + * parv[1] = target user numeric + * parv[2] = target user's new fake host + */ +int ms_fakehost(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) +{ + struct Client *target; + + if (parc < 3) + return need_more_params(sptr, "FAKEHOST"); + + /* Locate our target user; ignore the message if we can't */ + if(!(target = findNUser(parv[1]))) + return 0; + + /* Ignore the assignment if it changes nothing */ + if (HasFakeHost(target) && + ircd_strcmp(cli_user(target)->fakehost, parv[2]) == 0) + { + return 0; + } + + /* Assign and propagate the fakehost */ + SetFakeHost(target); + ircd_strncpy(cli_user(target)->fakehost, parv[2], HOSTLEN); + hide_hostmask(target); + + sendcmdto_serv_butone(sptr, CMD_FAKEHOST, cptr, "%C %s", target, + cli_user(target)->fakehost); + return 0; +} diff -Nur ircu2.10.12.05/ircd/parse.c ircu2.10.12.05-fakehosts/ircd/parse.c --- ircu2.10.12.05/ircd/parse.c 2005-09-27 05:54:46.000000000 +0200 +++ ircu2.10.12.05-fakehosts/ircd/parse.c 2006-01-23 17:53:34.000000000 +0100 @@ -626,6 +626,20 @@ { m_cap, m_cap, m_ignore, m_cap, m_ignore } }, #endif + { + MSG_FAKEHOST, + TOK_FAKEHOST, + 0, MAXPARA, MFLG_SLOW, 0, NULL, + /* UNREG, CLIENT, SERVER, OPER, SERVICE */ + { m_ignore, m_fakehost, ms_fakehost, m_fakehost, m_ignore } + }, + { + MSG_FAKEHOST2, + TOK_FAKEHOST2, + 0, MAXPARA, MFLG_SLOW, 0, NULL, + /* UNREG, CLIENT, SERVER, OPER, SERVICE */ + { m_ignore, m_fakehost, ms_fakehost, m_fakehost, m_ignore } + }, /* This command is an alias for QUIT during the unregistered part of * of the server. This is because someone jumping via a broken web * proxy will send a 'POST' as their first command - which we will diff -Nur ircu2.10.12.05/ircd/s_user.c ircu2.10.12.05-fakehosts/ircd/s_user.c --- ircu2.10.12.05/ircd/s_user.c 2006-01-10 03:06:36.000000000 +0100 +++ ircu2.10.12.05-fakehosts/ircd/s_user.c 2006-01-23 17:54:12.000000000 +0100 @@ -256,9 +256,9 @@ * @return One of HUNTED_ISME, HUNTED_NOSUCH or HUNTED_PASS. */ int hunt_server_prio_cmd(struct Client *from, const char *cmd, const char *tok, - struct Client *one, int MustBeOper, - const char *pattern, int server, int parc, - char *parv[]) + struct Client *one, int MustBeOper, + const char *pattern, int server, int parc, + char *parv[]) { struct Client *acptr; char *to; @@ -298,7 +298,7 @@ parv[server] = (char *) acptr; /* HACK! HACK! HACK! ARGH! */ sendcmdto_prio_one(from, cmd, tok, acptr, pattern, parv[1], parv[2], parv[3], - parv[4], parv[5], parv[6], parv[7], parv[8]); + parv[4], parv[5], parv[6], parv[7], parv[8]); return (HUNTED_PASS); } @@ -377,6 +377,7 @@ const char *nick, char *username) { struct ConfItem* aconf; + const char* fakehost; char* parv[4]; char* tmpstr; char* tmpstr2; @@ -393,6 +394,7 @@ struct User* user = cli_user(sptr); int killreason; char ip_base64[25]; + struct Flags setflags; user->last = CurrentTime; parv[0] = cli_name(sptr); @@ -454,6 +456,11 @@ } ircd_strncpy(user->host, cli_sockhost(sptr), HOSTLEN); ircd_strncpy(user->realhost, cli_sockhost(sptr), HOSTLEN); + fakehost = client_get_default_fakehost(sptr); + if (fakehost) { + ircd_strncpy(user->fakehost, fakehost, HOSTLEN); + SetFakeHost(sptr); + } aconf = cli_confs(sptr)->value.aconf; clean_user_id(user->username, @@ -594,6 +601,7 @@ /* * Set user's initial modes */ + setflags = cli_flags(sptr); tmpstr = (char*)client_get_default_umode(sptr); if (tmpstr) for (; *tmpstr; ++tmpstr) { switch (*tmpstr) { @@ -617,6 +625,11 @@ if (!feature_bool(FEAT_HIS_DEBUG_OPER_ONLY)) SetDebug(sptr); break; + case 'x': + SetHiddenHost(sptr); + if (!FlagHas(&setflags, FLAG_HIDDENHOST)) + hide_hostmask(sptr); + break; } } } @@ -718,7 +731,8 @@ { FLAG_CHSERV, 'k' }, { FLAG_DEBUG, 'g' }, { FLAG_ACCOUNT, 'r' }, - { FLAG_HIDDENHOST, 'x' } + { FLAG_HIDDENHOST, 'x' }, + { FLAG_FAKEHOST, 'f' } }; /** Length of #userModeList. */ @@ -744,6 +758,7 @@ { if (IsServer(sptr)) { int i; + const char* fakehost = 0; const char* account = 0; const char* p; @@ -757,6 +772,7 @@ cli_lastnick(new_client) = atoi(parv[3]); if (Protocol(cptr) > 9 && parc > 7 && *parv[6] == '+') { + int argi = 7; for (p = parv[6] + 1; *p; p++) { for (i = 0; i < USERMODELIST_SIZE; ++i) @@ -764,8 +780,10 @@ if (userModeList[i].c == *p) { SetFlag(new_client, userModeList[i].flag); - if (userModeList[i].flag == FLAG_ACCOUNT) - account = parv[7]; + if (userModeList[i].flag == FLAG_ACCOUNT) + account = parv[argi++]; + else if (userModeList[i].flag == FLAG_FAKEHOST) + fakehost = parv[argi++]; break; } } @@ -795,17 +813,20 @@ if (account) { int len = ACCOUNTLEN; if ((p = strchr(account, ':'))) { - len = (p++) - account; - cli_user(new_client)->acc_create = atoi(p); - Debug((DEBUG_DEBUG, "Received timestamped account in user mode; " - "account \"%s\", timestamp %Tu", account, - cli_user(new_client)->acc_create)); + len = (p++) - account; + cli_user(new_client)->acc_create = atoi(p); + Debug((DEBUG_DEBUG, "Received timestamped account in user mode; " + "account \"%s\", timestamp %Tu", account, + cli_user(new_client)->acc_create)); } ircd_strncpy(cli_user(new_client)->account, account, len); } + if (fakehost) { + SetFakeHost(new_client); + ircd_strncpy(cli_user(new_client)->fakehost, fakehost, HOSTLEN); + } if (HasHiddenHost(new_client)) - ircd_snprintf(0, cli_user(new_client)->host, HOSTLEN, "%s.%s", - account, feature_str(FEAT_HIDDEN_HOST)); + make_hidden_hostmask(cli_user(new_client)->host, new_client); return register_user(cptr, new_client, cli_name(new_client), parv[4]); } @@ -850,8 +871,8 @@ } /* Invalidate all bans against the user so we check them again */ for (member = (cli_user(cptr))->channel; member; - member = member->next_channel) - ClearBanValid(member); + member = member->next_channel) + ClearBanValid(member); } /* * Also set 'lastnick' to current time, if changed. @@ -1130,7 +1151,7 @@ for (name = ircd_strtok(&p, names, " "); name; name = ircd_strtok(&p, 0, " ")) { if ((acptr = FindUser(name))) { if (users_found++) - msgq_append(0, mb, " "); + msgq_append(0, mb, " "); (*fmt)(acptr, sptr, mb); } if (5 == ++arg_count) @@ -1140,39 +1161,53 @@ msgq_clean(mb); } +/* + * make_hidden_hostmask() + * + * Generates a user's hidden hostmask based on their account unless + * they have a custom [vanity] host set. This function expects a + * buffer of sufficient size to hold the resulting hostmask. + */ +void make_hidden_hostmask(char *buffer, struct Client *cptr) +{ + assert(HasFakeHost(cptr) || IsAccount(cptr)); + + if (HasFakeHost(cptr)) { + /* The user has a fake host; make that their hidden hostmask. */ + ircd_strncpy(buffer, cli_user(cptr)->fakehost, HOSTLEN); + return; + } + + if (IsAccount(cptr)) { + /* Generate a hidden host based on the user's account name. */ + ircd_snprintf(0, buffer, HOSTLEN, "%s.%s", cli_user(cptr)->account, + feature_str(FEAT_HIDDEN_HOST)); + return; + } +} + /** Set \a flag on \a cptr and possibly hide the client's hostmask. * @param[in,out] cptr User who is getting a new flag. * @param[in] flag Some flag that affects host-hiding (FLAG_HIDDENHOST, FLAG_ACCOUNT). * @return Zero. */ int -hide_hostmask(struct Client *cptr, unsigned int flag) +hide_hostmask(struct Client *cptr) { struct Membership *chan; - switch (flag) { - case FLAG_HIDDENHOST: - /* Local users cannot set +x unless FEAT_HOST_HIDING is true. */ - if (MyConnect(cptr) && !feature_bool(FEAT_HOST_HIDING)) - return 0; - break; - case FLAG_ACCOUNT: - /* Invalidate all bans against the user so we check them again */ - for (chan = (cli_user(cptr))->channel; chan; - chan = chan->next_channel) - ClearBanValid(chan); - break; - default: + if (MyConnect(cptr) && !feature_bool(FEAT_HOST_HIDING)) return 0; - } - SetFlag(cptr, flag); - if (!HasFlag(cptr, FLAG_HIDDENHOST) || !HasFlag(cptr, FLAG_ACCOUNT)) + if (!HasHiddenHost(cptr)) return 0; + /* Invalidate all bans against the user so we check them again */ + for (chan = (cli_user(cptr))->channel; chan; chan = chan->next_channel) + ClearBanValid(chan); + sendcmdto_common_channels_butone(cptr, CMD_QUIT, cptr, ":Registered"); - ircd_snprintf(0, cli_user(cptr)->host, HOSTLEN, "%s.%s", - cli_user(cptr)->account, feature_str(FEAT_HIDDEN_HOST)); + make_hidden_hostmask(cli_user(cptr)->host, cptr); /* ok, the client is now fully hidden, so let them know -- hikari */ if (MyConnect(cptr)) @@ -1186,10 +1221,14 @@ { if (IsZombie(chan)) continue; - /* Send a JOIN unless the user's join has been delayed. */ - if (!IsDelayedJoin(chan)) + /* For a user with no modes in a join-delayed channel, do not show + * the rejoin. */ + if (!IsChanOp(chan) && !HasVoice(chan) && (chan->channel->mode.mode & MODE_DELJOINS)) + SetDelayedJoin(chan); + else sendcmdto_channel_butserv_butone(cptr, CMD_JOIN, chan->channel, cptr, 0, - "%H", chan->channel); + "%H", chan->channel); + if (IsChanOp(chan) && HasVoice(chan)) sendcmdto_channel_butserv_butone(&his, CMD_MODE, chan->channel, cptr, 0, "%H +ov %C %C", chan->channel, cptr, @@ -1256,7 +1295,8 @@ for (i = 0; i < USERMODELIST_SIZE; i++) { if (HasFlag(sptr, userModeList[i].flag) && - userModeList[i].flag != FLAG_ACCOUNT) + (userModeList[i].flag != FLAG_ACCOUNT) && + (userModeList[i].flag != FLAG_FAKEHOST)) *m++ = userModeList[i].c; } *m = '\0'; @@ -1299,9 +1339,9 @@ tmpmask = (what == MODE_ADD) ? (IsAnOper(sptr) ? SNO_OPERDEFAULT : SNO_DEFAULT) : 0; if (tmpmask) - SetServNotice(sptr); + SetServNotice(sptr); else - ClearServNotice(sptr); + ClearServNotice(sptr); break; case 'w': if (what == MODE_ADD) @@ -1361,9 +1401,12 @@ ClearDebug(sptr); break; case 'x': - if (what == MODE_ADD) - do_host_hiding = 1; - break; + if (what == MODE_ADD) { + SetHiddenHost(sptr); + if (!FlagHas(&setflags, FLAG_HIDDENHOST)) + do_host_hiding = 1; + } + break; default: send_reply(sptr, ERR_UMODEUNKNOWNFLAG, *m); break; @@ -1390,7 +1433,7 @@ * only send wallops to opers */ if (feature_bool(FEAT_WALLOPS_OPER_ONLY) && !IsAnOper(sptr) && - !FlagHas(&setflags, FLAG_WALLOP)) + !FlagHas(&setflags, FLAG_WALLOP)) ClearWallops(sptr); if (feature_bool(FEAT_HIS_SNOTICES_OPER_ONLY) && MyConnect(sptr) && !IsAnOper(sptr) && !FlagHas(&setflags, FLAG_SERVNOTICE)) @@ -1411,9 +1454,9 @@ if (SendServNotice(sptr)) { if (tmpmask != cli_snomask(sptr)) - set_snomask(sptr, tmpmask, SNO_SET); + set_snomask(sptr, tmpmask, SNO_SET); if (cli_snomask(sptr) && snomask_given) - send_reply(sptr, RPL_SNOMASK, cli_snomask(sptr), cli_snomask(sptr)); + send_reply(sptr, RPL_SNOMASK, cli_snomask(sptr), cli_snomask(sptr)); } else set_snomask(sptr, 0, SNO_SET); @@ -1441,8 +1484,8 @@ --UserStats.inv_clients; if (!FlagHas(&setflags, FLAG_INVISIBLE) && IsInvisible(sptr)) ++UserStats.inv_clients; - if (!FlagHas(&setflags, FLAG_HIDDENHOST) && do_host_hiding) - hide_hostmask(sptr, FLAG_HIDDENHOST); + if (do_host_hiding) + hide_hostmask(sptr); send_umode_out(cptr, sptr, &setflags, prop); return 0; @@ -1476,17 +1519,26 @@ *m++ = ' '; while ((*m++ = *t++)) ; /* Empty loop */ + m--; /* back up to '\0' */ + } + + if (HasFakeHost(cptr)) { + char* t = cli_user(cptr)->fakehost; + + *m++ = ' '; + while ((*m++ = *t++)) + ; /* Empty loop */ if (cli_user(cptr)->acc_create) { char nbuf[20]; Debug((DEBUG_DEBUG, "Sending timestamped account in user mode for " - "account \"%s\"; timestamp %Tu", cli_user(cptr)->account, - cli_user(cptr)->acc_create)); + "account \"%s\"; timestamp %Tu", cli_user(cptr)->account, + cli_user(cptr)->acc_create)); ircd_snprintf(0, t = nbuf, sizeof(nbuf), ":%Tu", - cli_user(cptr)->acc_create); + cli_user(cptr)->acc_create); m--; /* back up over previous nul-termination */ while ((*m++ = *t++)) - ; /* Empty loop */ + ; /* Empty loop */ } } @@ -1524,6 +1576,8 @@ if (FlagHas(old, flag) == HasFlag(sptr, flag)) continue; + if (flag == FLAG_ACCOUNT || flag == FLAG_FAKEHOST) + continue; switch (sendset) { case ALL_UMODES: