From 8603c2eb71d54492bcdbb7d6080cdbe769b5f2d5 Mon Sep 17 00:00:00 2001 From: Bram Matthys Date: Sat, 25 Sep 2021 14:49:19 +0200 Subject: [PATCH] Update hunt_server() so command is really the command (eg "LUSERS") and not a format string (eg ":%s LUSERS %s"). It now simply concats all parv[]'s. That is, up to parc count. And it automatically does the :stuff for the last parameter if it contains spaces or starts with a : etc. This gets rid of a bit sketchy code with an arbitrary maximum etc. Now it's just: if (hunt_server(client, NULL, "REHASH", 1, parc, parv) != HUNTED_ISME) return; This has one side effect, though: Previously we used the format string, so it may be possible for S2S traffic to now have more arguments then before here and there. Eg: * It could be that the caller was using a format string to intentionally cut off an extra parameter at the end. You can still do that if you call with eg parc-1 instead of parc. I don't think there were any such cases though, but hard to rule out. * Extranous parameters may show up in S2S traffic where it was previously unexpected. --- include/h.h | 2 +- src/modules.c | 4 +-- src/modules/admin.c | 2 +- src/modules/botmotd.c | 2 +- src/modules/connect.c | 2 +- src/modules/lag.c | 2 +- src/modules/lusers.c | 2 +- src/modules/motd.c | 2 +- src/modules/rules.c | 2 +- src/modules/staff.c | 2 +- src/modules/stats.c | 4 +-- src/modules/svslusers.c | 2 +- src/modules/svsnick.c | 2 +- src/modules/svsnoop.c | 2 +- src/modules/svssno.c | 2 +- src/modules/time.c | 2 +- src/modules/trace.c | 4 +-- src/modules/whois.c | 2 +- src/modules/whowas.c | 2 +- src/serv.c | 66 ++++++++++++++++++++++++++++++----------- 20 files changed, 71 insertions(+), 39 deletions(-) diff --git a/include/h.h b/include/h.h index ccf4f33aa..87245b98b 100644 --- a/include/h.h +++ b/include/h.h @@ -326,7 +326,7 @@ extern char *make_nick_user_host(const char *, const char *, const char *); extern char *make_nick_user_host_r(char *namebuf, size_t namebuflen, const char *nick, const char *name, const char *host); extern char *make_user_host(const char *, const char *); extern void parse(Client *cptr, char *buffer, int length); -extern int hunt_server(Client *, MessageTag *, char *, int, int, const char **); +extern int hunt_server(Client *, MessageTag *, const char *, int, int, const char **); extern int cmd_server_estab(Client *); extern void umode_init(void); #define UMODE_GLOBAL 1 diff --git a/src/modules.c b/src/modules.c index 4cf3f514d..ecb2cc9b0 100644 --- a/src/modules.c +++ b/src/modules.c @@ -793,10 +793,10 @@ CMD_FUNC(cmd_module) if (MyUser(client) && !IsOper(client) && all) add_fake_lag(client, 7000); /* Lag them up. Big list. */ - if ((parc > 2) && (hunt_server(client, recv_mtags, ":%s MODULE %s :%s", 2, parc, parv) != HUNTED_ISME)) + if ((parc > 2) && (hunt_server(client, recv_mtags, "MODULE", 2, parc, parv) != HUNTED_ISME)) return; - if ((parc == 2) && (parv[1][0] != '-') && (hunt_server(client, recv_mtags, ":%s MODULE :%s", 1, parc, parv) != HUNTED_ISME)) + if ((parc == 2) && (parv[1][0] != '-') && (hunt_server(client, recv_mtags, "MODULE", 1, parc, parv) != HUNTED_ISME)) return; if (all) diff --git a/src/modules/admin.c b/src/modules/admin.c index e00760201..064dd9b03 100644 --- a/src/modules/admin.c +++ b/src/modules/admin.c @@ -61,7 +61,7 @@ CMD_FUNC(cmd_admin) if (IsUser(client)) { - if (hunt_server(client, recv_mtags, ":%s ADMIN :%s", 1, parc, parv) != HUNTED_ISME) + if (hunt_server(client, recv_mtags, "ADMIN", 1, parc, parv) != HUNTED_ISME) return; } diff --git a/src/modules/botmotd.c b/src/modules/botmotd.c index 366eb34d1..b5dcde229 100644 --- a/src/modules/botmotd.c +++ b/src/modules/botmotd.c @@ -60,7 +60,7 @@ CMD_FUNC(cmd_botmotd) MOTDLine *motdline; ConfigItem_tld *tld; - if (hunt_server(client, recv_mtags, ":%s BOTMOTD :%s", 1, parc, parv) != HUNTED_ISME) + if (hunt_server(client, recv_mtags, "BOTMOTD", 1, parc, parv) != HUNTED_ISME) return; if (!IsUser(client)) diff --git a/src/modules/connect.c b/src/modules/connect.c index ce9042124..59cff3c3d 100644 --- a/src/modules/connect.c +++ b/src/modules/connect.c @@ -76,7 +76,7 @@ CMD_FUNC(cmd_connect) sendnumeric(client, ERR_NOPRIVILEGES); return; } - if (hunt_server(client, recv_mtags, ":%s CONNECT %s %s :%s", 3, parc, parv) != HUNTED_ISME) + if (hunt_server(client, recv_mtags, "CONNECT", 3, parc, parv) != HUNTED_ISME) return; if (parc < 2 || *parv[1] == '\0') diff --git a/src/modules/lag.c b/src/modules/lag.c index b4a680a68..90183038b 100644 --- a/src/modules/lag.c +++ b/src/modules/lag.c @@ -78,7 +78,7 @@ CMD_FUNC(cmd_lag) return; } - if (hunt_server(client, recv_mtags, ":%s LAG :%s", 1, parc, parv) == HUNTED_NOSUCH) + if (hunt_server(client, recv_mtags, "LAG", 1, parc, parv) == HUNTED_NOSUCH) return; sendnotice(client, "Lag reply -- %s %s %lld", me.name, parv[1], (long long)TStime()); diff --git a/src/modules/lusers.c b/src/modules/lusers.c index 75ddc881d..3f0780559 100644 --- a/src/modules/lusers.c +++ b/src/modules/lusers.c @@ -59,7 +59,7 @@ CMD_FUNC(cmd_lusers) { char flatmap; - if (hunt_server(client, recv_mtags, ":%s LUSERS :%s", 1, parc, parv) != HUNTED_ISME) + if (hunt_server(client, recv_mtags, "LUSERS", 1, parc, parv) != HUNTED_ISME) return; flatmap = (FLAT_MAP && !ValidatePermissionsForPath("server:info:lusers",client,NULL,NULL,NULL)) ? 1 : 0; diff --git a/src/modules/motd.c b/src/modules/motd.c index de2581067..80b22a3cc 100644 --- a/src/modules/motd.c +++ b/src/modules/motd.c @@ -66,7 +66,7 @@ CMD_FUNC(cmd_motd) if (IsServer(client)) return; - if (hunt_server(client, recv_mtags, ":%s MOTD :%s", 1, parc, parv) != HUNTED_ISME) + if (hunt_server(client, recv_mtags, "MOTD", 1, parc, parv) != HUNTED_ISME) { if (MyUser(client)) add_fake_lag(client, 15000); diff --git a/src/modules/rules.c b/src/modules/rules.c index 373ea96d7..2845af792 100644 --- a/src/modules/rules.c +++ b/src/modules/rules.c @@ -63,7 +63,7 @@ CMD_FUNC(cmd_rules) temp = NULL; - if (hunt_server(client, recv_mtags, ":%s RULES :%s", 1, parc, parv) != HUNTED_ISME) + if (hunt_server(client, recv_mtags, "RULES", 1, parc, parv) != HUNTED_ISME) return; ptr = find_tld(client); diff --git a/src/modules/staff.c b/src/modules/staff.c index 7973f24d2..af8bc81e4 100644 --- a/src/modules/staff.c +++ b/src/modules/staff.c @@ -158,7 +158,7 @@ CMD_FUNC(cmd_staff) if (!IsUser(client)) return; - if (hunt_server(client, recv_mtags, ":%s STAFF", 1, parc, parv) != HUNTED_ISME) + if (hunt_server(client, recv_mtags, "STAFF", 1, parc, parv) != HUNTED_ISME) return; if (!staff.lines) diff --git a/src/modules/stats.c b/src/modules/stats.c index d426fd6a2..9e0fd5563 100644 --- a/src/modules/stats.c +++ b/src/modules/stats.c @@ -294,12 +294,12 @@ CMD_FUNC(cmd_stats) if (parc == 3 && parv[2][0] != '+' && parv[2][0] != '-') { - if (hunt_server(client, recv_mtags, ":%s STATS %s :%s", 2, parc, parv) != HUNTED_ISME) + if (hunt_server(client, recv_mtags, "STATS", 2, parc, parv) != HUNTED_ISME) return; } else if (parc == 4 && parv[2][0] != '+' && parv[2][0] != '-') { - if (hunt_server(client, recv_mtags, ":%s STATS %s %s %s", 2, parc, parv) != HUNTED_ISME) + if (hunt_server(client, recv_mtags, "STATS", 2, parc, parv) != HUNTED_ISME) return; } if (parc < 2 || !*parv[1]) diff --git a/src/modules/svslusers.c b/src/modules/svslusers.c index 1e35d97ed..9d9e0696e 100644 --- a/src/modules/svslusers.c +++ b/src/modules/svslusers.c @@ -66,7 +66,7 @@ CMD_FUNC(cmd_svslusers) { if (!IsULine(client) || parc < 4) return; - if (hunt_server(client, NULL, ":%s SVSLUSERS %s %s :%s", 1, parc, parv) == HUNTED_ISME) + if (hunt_server(client, NULL, "SVSLUSERS", 1, parc, parv) == HUNTED_ISME) { int temp; temp = atoi(parv[2]); diff --git a/src/modules/svsnick.c b/src/modules/svsnick.c index f8643c593..89cd2a73b 100644 --- a/src/modules/svsnick.c +++ b/src/modules/svsnick.c @@ -69,7 +69,7 @@ CMD_FUNC(cmd_svsnick) if (!IsULine(client) || parc < 4 || (strlen(parv[2]) > NICKLEN)) return; /* This looks like an error anyway -Studded */ - if (hunt_server(client, NULL, ":%s SVSNICK %s %s :%s", 1, parc, parv) != HUNTED_ISME) + if (hunt_server(client, NULL, "SVSNICK", 1, parc, parv) != HUNTED_ISME) return; /* Forwarded, done */ strlcpy(nickname, parv[2], sizeof(nickname)); diff --git a/src/modules/svsnoop.c b/src/modules/svsnoop.c index 2d23a9b8a..c86d02232 100644 --- a/src/modules/svsnoop.c +++ b/src/modules/svsnoop.c @@ -62,7 +62,7 @@ CMD_FUNC(cmd_svsnoop) if (!(IsULine(client) && parc > 2)) return; - if (hunt_server(client, NULL, ":%s SVSNOOP %s :%s", 1, parc, parv) == HUNTED_ISME) + if (hunt_server(client, NULL, "SVSNOOP", 1, parc, parv) == HUNTED_ISME) { if (parv[2][0] == '+') { diff --git a/src/modules/svssno.c b/src/modules/svssno.c index 3efe6856e..085f69949 100644 --- a/src/modules/svssno.c +++ b/src/modules/svssno.c @@ -79,7 +79,7 @@ void do_svssno(Client *client, int parc, const char *parv[], int show_change) if (!(target = find_person(parv[1], NULL))) return; - if (hunt_server(client, NULL, show_change ? ":%s SVS2SNO %s %s" : ":%s SVSSNO %s %s", 1, parc, parv) != HUNTED_ISME) + if (hunt_server(client, NULL, show_change ? "SVS2SNO" : "SVSSNO", 1, parc, parv) != HUNTED_ISME) return; if (MyUser(target)) diff --git a/src/modules/time.c b/src/modules/time.c index e78c16469..945aa4714 100644 --- a/src/modules/time.c +++ b/src/modules/time.c @@ -61,6 +61,6 @@ MOD_UNLOAD() */ CMD_FUNC(cmd_time) { - if (hunt_server(client, recv_mtags, ":%s TIME :%s", 1, parc, parv) == HUNTED_ISME) + if (hunt_server(client, recv_mtags, "TIME", 1, parc, parv) == HUNTED_ISME) sendnumeric(client, RPL_TIME, me.name, long_date(0)); } diff --git a/src/modules/trace.c b/src/modules/trace.c index ea292eaab..1df322ac6 100644 --- a/src/modules/trace.c +++ b/src/modules/trace.c @@ -73,7 +73,7 @@ CMD_FUNC(cmd_trace) labeled_response_inhibit = 1; if (parc > 2) - if (hunt_server(client, NULL, ":%s TRACE %s :%s", 2, parc, parv)) + if (hunt_server(client, NULL, "TRACE", 2, parc, parv)) return; if (parc > 1) @@ -98,7 +98,7 @@ CMD_FUNC(cmd_trace) } } - switch (hunt_server(client, NULL, ":%s TRACE :%s", 1, parc, parv)) + switch (hunt_server(client, NULL, "TRACE", 1, parc, parv)) { case HUNTED_PASS: /* note: gets here only if parv[1] exists */ { diff --git a/src/modules/whois.c b/src/modules/whois.c index 20df15cdb..0149fec53 100644 --- a/src/modules/whois.c +++ b/src/modules/whois.c @@ -80,7 +80,7 @@ CMD_FUNC(cmd_whois) if (parc > 2) { - if (hunt_server(client, recv_mtags, ":%s WHOIS %s :%s", 1, parc, parv) != HUNTED_ISME) + if (hunt_server(client, recv_mtags, "WHOIS", 1, parc, parv) != HUNTED_ISME) return; parv[1] = parv[2]; } diff --git a/src/modules/whowas.c b/src/modules/whowas.c index 67398627e..2ab48a09e 100644 --- a/src/modules/whowas.c +++ b/src/modules/whowas.c @@ -76,7 +76,7 @@ CMD_FUNC(cmd_whowas) if (parc > 2) max = atoi(parv[2]); if (parc > 3) - if (hunt_server(client, recv_mtags, ":%s WHOWAS %s %s :%s", 3, parc, parv)) + if (hunt_server(client, recv_mtags, "WHOWAS", 3, parc, parv)) return; if (!MyConnect(client) && (max > 20)) diff --git a/src/serv.c b/src/serv.c index 8db8756d7..c30c0a71e 100644 --- a/src/serv.c +++ b/src/serv.c @@ -71,13 +71,24 @@ void reread_motdsandrules(); * @param server This indicates parv[server] contains the destination * @param parc Parameter count (MAX 8!!) * @param parv Parameter values (MAX 8!!) - * @note Command can have only max 8 parameters (parv[8]) - * @note parv[server] is replaced with the name of the matched client. + * @note While sending parv[server] is replaced with the name of the matched client + * (virtually, as parv[] is not actually written to) */ -int hunt_server(Client *client, MessageTag *mtags, char *command, int server, int parc, const char *parv[]) +int hunt_server(Client *client, MessageTag *mtags, const char *command, int server, int parc, const char *parv[]) { Client *acptr; const char *saved; + int i; + char buf[1024]; + + if (strchr(command, '%') || strchr(command, ' ')) + { + unreal_log(ULOG_ERROR, "main", "BUG_HUNT_SERVER", client, + "[BUG] hunt_server called with command '$command' but it may not contain " + "spaces or percentage signs nowadays, it must be ONLY the command.", + log_data_string("command", command)); + abort(); + } /* This would be strange and bad. Previous version assumed "it's for me". Hmm.. okay. */ if (parc <= server || BadPtr(parv[server])) @@ -105,17 +116,38 @@ int hunt_server(Client *client, MessageTag *mtags, char *command, int server, in return HUNTED_NOSUCH; } - /* Replace "server" part with actual servername (eg: 'User' -> 'x.y.net') - * Ugly. Previous version didn't even restore the state, now we do. + /* This puts all parv[] arguments in 'buf' + * Taken from concat_params() but this one is + * with parv[server] magic replacement. */ - saved = parv[server]; - parv[server] = acptr->id; + *buf = '\0'; + for (i = 1; i < parc; i++) + { + const char *param = parv[i]; - sendto_one(acptr, mtags, command, client->id, - parv[1], parv[2], parv[3], parv[4], - parv[5], parv[6], parv[7], parv[8]); + if (!param) + break; - parv[server] = saved; + /* The magic parv[server] replacement: + * this replaces eg 'User' with '001' in S2S traffic. + */ + if (i == server) + param = acptr->id; + + if (*buf) + strlcat(buf, " ", sizeof(buf)); + + if (strchr(param, ' ') || (*param == ':')) + { + /* Last parameter, with : */ + strlcat(buf, ":", sizeof(buf)); + strlcat(buf, parv[i], sizeof(buf)); + break; + } + strlcat(buf, parv[i], sizeof(buf)); + } + + sendto_one(acptr, mtags, ":%s %s %s", client->id, command, buf); return HUNTED_PASS; } @@ -178,7 +210,7 @@ CMD_FUNC(cmd_version) return; } - if (hunt_server(client, recv_mtags, ":%s VERSION :%s", 1, parc, parv) == HUNTED_ISME) + if (hunt_server(client, recv_mtags, "VERSION", 1, parc, parv) == HUNTED_ISME) { sendnumeric(client, RPL_VERSION, version, debugmode, me.name, (ValidatePermissionsForPath("server:info",client,NULL,NULL,NULL) ? serveropts : "0"), @@ -312,7 +344,7 @@ CMD_FUNC(cmd_info) if (remotecmdfilter(client, parc, parv)) return; - if (hunt_server(client, recv_mtags, ":%s INFO :%s", 1, parc, parv) == HUNTED_ISME) + if (hunt_server(client, recv_mtags, "INFO", 1, parc, parv) == HUNTED_ISME) cmd_info_send(client); } @@ -326,7 +358,7 @@ CMD_FUNC(cmd_license) if (remotecmdfilter(client, parc, parv)) return; - if (hunt_server(client, recv_mtags, ":%s LICENSE :%s", 1, parc, parv) == HUNTED_ISME) + if (hunt_server(client, recv_mtags, "LICENSE", 1, parc, parv) == HUNTED_ISME) { while (*text) sendnumeric(client, RPL_INFO, *text++); @@ -346,7 +378,7 @@ CMD_FUNC(cmd_credits) if (remotecmdfilter(client, parc, parv)) return; - if (hunt_server(client, recv_mtags, ":%s CREDITS :%s", 1, parc, parv) == HUNTED_ISME) + if (hunt_server(client, recv_mtags, "CREDITS", 1, parc, parv) == HUNTED_ISME) { while (*text) sendnumeric(client, RPL_INFO, *text++); @@ -509,13 +541,13 @@ CMD_FUNC(cmd_rehash) if (parv[1] && (parv[1][0] == '-')) x = HUNTED_ISME; else - x = hunt_server(client, recv_mtags, ":%s REHASH :%s", 1, parc, parv); + x = hunt_server(client, recv_mtags, "REHASH", 1, parc, parv); } else { if (match_simple("-glob*", parv[1])) /* This is really ugly... hack to make /rehash -global -something work */ { x = HUNTED_ISME; } else { - x = hunt_server(client, NULL, ":%s REHASH %s :%s", 1, parc, parv); + x = hunt_server(client, NULL, "REHASH", 1, parc, parv); } } if (x != HUNTED_ISME)