X-Git-Url: https://jfr.im/git/irc/evilnet/x3.git/blobdiff_plain/2c4ce77b32befc04ff82690681c051f747cf9f3e..5512b580eb0f7cd1827e6f0eb0623b6fedfb1be9:/src/proto-p10.c diff --git a/src/proto-p10.c b/src/proto-p10.c index 8909ea8..f59039c 100644 --- a/src/proto-p10.c +++ b/src/proto-p10.c @@ -22,7 +22,6 @@ #include "chanserv.h" #include "hash.h" #include "helpfile.h" -#include "hosthiding.h" #include "proto-common.c" #include "opserv.h" @@ -106,6 +105,7 @@ #define CMD_SVSPART "SVSPART" #define CMD_SVSQUIT "SVSQUIT" #define CMD_SWHOIS "SWHOIS" +#define CMD_TEMPSHUN "TEMPSHUN" #define CMD_TIME "TIME" #define CMD_TOPIC "TOPIC" #define CMD_TRACE "TRACE" @@ -206,6 +206,7 @@ #define TOK_SVSPART "SP" #define TOK_SVSQUIT "SX" #define TOK_SWHOIS "SW" +#define TOK_TEMPSHUN "TS" #define TOK_TIME "TI" #define TOK_TOPIC "T" #define TOK_TRACE "TR" @@ -315,6 +316,7 @@ #define P10_SVSPART TYPE(SVSPART) #define P10_SVSQUIT TYPE(SVSQUIT) #define P10_SWHOIS TYPE(SWHOIS) +#define P10_TEMPSHUN TYPE(TEMPSHUN) #define P10_TIME TYPE(TIME) #define P10_TOPIC TYPE(TOPIC) #define P10_TRACE TYPE(TRACE) @@ -837,8 +839,8 @@ irc_gline(struct server *srv, struct gline *gline, int silent) void irc_shun(struct server *srv, struct shun *shun) { - putsock("%s " P10_SHUN " %s +%s " FMT_TIME_T " :<%s> %s", - self->numeric, (srv ? srv->numeric : "*"), shun->target, shun->expires-now, shun->issuer, shun->reason); + putsock("%s " P10_SHUN " %s +%s " FMT_TIME_T " " FMT_TIME_T " :<%s> %s", + self->numeric, (srv ? srv->numeric : "*"), shun->target, shun->expires-now, now, shun->issuer, shun->reason); } void @@ -853,13 +855,13 @@ irc_settime(const char *srv_name_mask, time_t new_time) void irc_ungline(const char *mask) { - putsock("%s " P10_GLINE " * -%s", self->numeric, mask); + putsock("%s " P10_GLINE " * -%s " FMT_TIME_T, self->numeric, mask, now); } void irc_unshun(const char *mask) { - putsock("%s " P10_SHUN " * -%s", self->numeric, mask); + putsock("%s " P10_SHUN " * -%s " FMT_TIME_T, self->numeric, mask, now); } void @@ -909,6 +911,10 @@ irc_burst(struct chanNode *chan) if ((n+1)members.used) burst_line[pos++] = ','; } + + if (len > 0 && (chan->banlist.used > 0 || chan->exemptlist.used > 0)) + burst_line[pos++] = ' '; + if (chan->banlist.used) { /* dump the bans */ first_ban = 1; @@ -934,13 +940,18 @@ irc_burst(struct chanNode *chan) } } } + if (chan->exemptlist.used) { /* dump the exempts */ first_exempt = 1; for (n=0; nexemptlist.used; ) { if (first_exempt && (pos < 500)) { - burst_line[pos++] = ' '; + if (chan->banlist.used < 1) { + burst_line[pos++] = ':'; + burst_line[pos++] = '%'; + burst_line[pos++] = ' '; + } burst_line[pos++] = '~'; burst_line[pos++] = ' '; } @@ -1083,6 +1094,12 @@ irc_swhois(struct userNode *from, struct userNode *target, const char *message) } +void +irc_tempshun(struct userNode *from, struct userNode *target, int remove, const char *reason) +{ + putsock("%s " P10_TEMPSHUN " %s %s :%s", from->numeric, (remove ? "-" : "+"), target->numeric, reason); +} + void irc_part(struct userNode *who, struct chanNode *what, const char *reason) { @@ -1131,9 +1148,9 @@ irc_topic(struct userNode *service, struct userNode *who, struct chanNode *what, safestrncpy(sident, who->ident, sizeof(shost)); safestrncpy(shost, host, sizeof(shost)); - } else if (IsHiddenHost(who) && (hhtype == 1) && who->handle_info && hhstr) { + } else if (IsHiddenHost(who) && ((hhtype == 1) || (hhtype == 3)) && who->handle_info && hhstr) { snprintf(shost, sizeof(shost), "%s.%s", who->handle_info->handle, hhstr); - } else if (IsHiddenHost(who) && (hhtype == 2) && who->crypthost[0]) { + } else if (IsHiddenHost(who) && ((hhtype == 2) || (hhtype == 3)) && who->crypthost[0]) { safestrncpy(shost, who->crypthost, sizeof(shost)); } else safestrncpy(shost, who->hostname, sizeof(shost)); @@ -1172,6 +1189,34 @@ void irc_mark(struct userNode *user, char *mark) { char *host = user->hostname; + int type = 4; + const char *tstr = NULL; + unsigned int ii = 0; + int markfound = 0; + + tstr = conf_get_data("server/type", RECDB_QSTRING); + if(tstr) + type = atoi(tstr); + else + type = 4; + + if (user->marks) + for (ii=0; iimarks->used; ii++) + if (!irccasecmp(user->marks->list[ii], mark)) + markfound = 1; + + if (!markfound) + { + if (!user->marks) + user->marks = alloc_string_list(1); + string_list_append(user->marks, strdup(mark)); + } + + if (type >= 9) + { + putsock("%s " CMD_MARK " %s MARK %s", self->numeric, user->nick, mark); + return; + } /* TODO: Allow mark overwrite. If they are marked, and their fakehost is oldmark.hostname, update it to newmark.hostname so mark can be called multiple times. Probably requires ircd modification also */ if(user->mark) @@ -1454,7 +1499,7 @@ static CMD_FUNC(cmd_sasl) if (!serv) return 0; - call_sasl_input_func(serv, argv[2], argv[3], argv[4], (argc>5 ? argv[5] : NULL)); + call_sasl_input_func(serv, argv[2], argv[3], argv[4], (argc>5 ? argv[argc-1] : NULL)); return 1; } @@ -1582,7 +1627,6 @@ static CMD_FUNC(cmd_nick) NickChange(user, argv[1], 1); } else { struct server *serv; - struct userNode *nuser; char modes[MAXLEN]; /* new nick */ if (argc < 9) @@ -1592,7 +1636,7 @@ static CMD_FUNC(cmd_nick) unsplit_string(argv+6, argc-9, modes); else strcpy(modes, "+"); - nuser = AddUser(serv, argv[1], argv[4], argv[5], modes, argv[argc-2], argv[argc-1], atoi(argv[3]), argv[argc-3]); + AddUser(serv, argv[1], argv[4], argv[5], modes, argv[argc-2], argv[argc-1], atoi(argv[3]), argv[argc-3]); } return 1; } @@ -1693,7 +1737,8 @@ static struct { P(SHUN), P(LOCAL_SHUN), P(WIDE_SHUN), P(ZLINE), P(LOCAL_ZLINE), P(WIDE_ZLINE), P(LIST_CHAN), P(WHOIS_NOTICE), P(HIDE_IDLE), P(XTRAOP), P(HIDE_CHANNELS), P(DISPLAY_MODE), - P(FREEFORM), P(REMOVE), P(SPAMFILTER), + P(FREEFORM), P(REMOVE), P(SPAMFILTER), P(ADMIN), + P(APASS_OPMODE), P(HIDE_OPER), P(REMOTE), P(SERVICE), #undef P { 0, 0 } }; @@ -1963,33 +2008,55 @@ static CMD_FUNC(cmd_burst) return res; } -/* TODO: +/* TODO: * This is a stub that doesn't actually do anything. It should be completed * so that bans on *!*@markname.* match users as it does in nefarious */ static CMD_FUNC(cmd_mark) { + const char *tstr; + int type = 4; struct userNode *target; - /* + /* * log_module(MAIN_LOG, LOG_ERROR, "DEBUG: mark, user %s, type %s, arg %s", argv[1], argv[2], argv[3]); */ + tstr = conf_get_data("server/type", RECDB_QSTRING); + if(tstr) + type = atoi(tstr); + else + type = 4;/* default to 040 style topics */ + if(argc < 4) return 0; if(!strcasecmp(argv[2], "DNSBL")) { /* DNSBL */ return 1; } - else if(!strcasecmp(argv[2], "DNSBL_DATA")) { + else if(!strcasecmp(argv[2], "DNSBL_DATA") || !strcasecmp(argv[2], "MARK")) { + int markfound = 0; + unsigned int ii = 0; /* DNSBL_DATA name */ target = GetUserH(argv[1]); if(!target) { log_module(MAIN_LOG, LOG_ERROR, "Unable to find user %s whose dnsbl mark is changing.", argv[1]); return 0; } - target->mark = strdup(argv[3]); + if (type >= 9) { + if (target->marks) + for (ii=0; iimarks->used; ii++) + if (!irccasecmp(target->marks->list[ii], argv[3])) + markfound = 1; + if (!markfound) + { + if (!target->marks) + target->marks = alloc_string_list(1); + string_list_append(target->marks, strdup(argv[3])); + } + } else + target->mark = strdup(argv[3]); return 1; - + } else if(!strcasecmp(argv[2], "CVERSION")) { /* CTCP VERSION mark */ @@ -2024,6 +2091,8 @@ static CMD_FUNC(cmd_mark) target->sslfp = strdup(sslfp); + nickserv_do_autoauth(target); + return 1; } /* unknown type of mark */ @@ -2147,7 +2216,7 @@ static CMD_FUNC(cmd_clearmode) static CMD_FUNC(cmd_topic) { struct chanNode *cn; - time_t chan_ts, topic_ts; + time_t topic_ts; struct userNode *user; if (argc < 3) @@ -2160,15 +2229,12 @@ static CMD_FUNC(cmd_topic) if (argc == 5) { /* Asuka / Topic Bursting IRCu's */ user = GetUserH(origin); - chan_ts = atoi(argv[2]); topic_ts = atoi(argv[3]); } else if (argc >= 6) { /* Nefarious 0.5.0 */ user = GetUserH(strtok(argv[2], "!")); - chan_ts = atoi(argv[3]); topic_ts = atoi(argv[4]); } else { /* Regular IRCu (No Topic Bursting)*/ user = GetUserH(origin); - chan_ts = cn->timestamp; topic_ts = now; } @@ -2304,7 +2370,15 @@ static CMD_FUNC(cmd_silence) if (argc < 2) return 0; - user = GetUserN(argv[1]); + if (strncmp(argv[1], "*", 2) == 0) + { + if (!(user = GetUserH(origin))) { + log_module(MAIN_LOG, LOG_ERROR, "Could not find SILENCE origin user %s", origin); + return 0; + } + } + else + user = GetUserN(argv[1]); /* Sanity, go nuts if this happens */ if (!user) @@ -2404,14 +2478,11 @@ static CMD_FUNC(cmd_notice) { struct privmsg_desc pd; struct server *srv; - int nuser = 0; if (argc != 3) return 0; pd.user = GetUserH(origin); - if(!pd.user) - nuser = 1; if (!pd.user || (IsGagged(pd.user) && !IsOper(pd.user))) { } else { @@ -2670,6 +2741,8 @@ init_parse(void) dict_insert(irc_func_dict, TOK_SVSPART, cmd_svspart); dict_insert(irc_func_dict, CMD_SWHOIS, cmd_dummy); dict_insert(irc_func_dict, TOK_SWHOIS, cmd_dummy); + dict_insert(irc_func_dict, CMD_TEMPSHUN, cmd_dummy); + dict_insert(irc_func_dict, TOK_TEMPSHUN, cmd_dummy); dict_insert(irc_func_dict, CMD_WHOIS, cmd_whois); dict_insert(irc_func_dict, TOK_WHOIS, cmd_whois); dict_insert(irc_func_dict, CMD_GLINE, cmd_gline); @@ -3018,7 +3091,7 @@ AddLocalUser(const char *nick, const char *ident, const char *hostname, const ch if (!hostname) hostname = self->name; make_numeric(self, local_num, numeric); - return AddUser(self, nick, ident, hostname, modes, numeric, desc, now, "AAAAAA"); + return AddUser(self, nick, ident, hostname, modes, numeric, desc, timestamp, "AAAAAA"); } struct userNode * @@ -3062,8 +3135,6 @@ AddUser(struct server* uplink, const char *nick, const char *ident, const char * { struct userNode *oldUser, *uNode; unsigned int ignore_user, dummy; - char *tstr; - int type; if ((strlen(numeric) < 3) || (strlen(numeric) > 5)) { log_module(MAIN_LOG, LOG_WARNING, "AddUser(%p, %s, ...): numeric %s wrong length!", (void*)uplink, nick, numeric); @@ -3121,17 +3192,6 @@ AddUser(struct server* uplink, const char *nick, const char *ident, const char * safestrncpy(uNode->numeric, numeric, sizeof(uNode->numeric)); irc_p10_pton(&uNode->ip, realip); - tstr = conf_get_data("server/type", RECDB_QSTRING); - type = atoi(tstr); - if (type == 7) { - if (irc_in_addr_is_ipv4(uNode->ip)) { - make_virtip((char*)irc_ntoa(&uNode->ip), (char*)irc_ntoa(&uNode->ip), uNode->cryptip); - make_virthost((char*)irc_ntoa(&uNode->ip), uNode->hostname, uNode->crypthost); - } else if (irc_in_addr_is_ipv6(uNode->ip)) { - make_ipv6virthost((char*)irc_ntoa(&uNode->ip), uNode->hostname, uNode->crypthost); - } - } - if (!uNode->crypthost && uNode->cryptip) snprintf(uNode->crypthost, sizeof(uNode->crypthost), "%s", strdup(uNode->cryptip)); uNode->idle_since = timestamp; @@ -3190,8 +3250,11 @@ DelUser(struct userNode* user, struct userNode *killer, int announce, const char user->uplink->clients--; user->uplink->users[user->num_local] = NULL; - if (IsOper(user)) + if (IsOper(user)) { userList_remove(&curr_opers, user); + if (count_opers > 0 && !IsBotM(user) && !IsService(user) && !IsHideOper(user)) + count_opers--; + } /* remove from global dictionary, but not if after a collide */ if (user == dict_find(clients, user->nick, NULL)) dict_remove(clients, user->nick); @@ -3233,6 +3296,8 @@ DelUser(struct userNode* user, struct userNode *killer, int announce, const char free(user->mark); user->mark = NULL; } + free_string_list(user->marks); + user->marks = NULL; /* clean up geoip data if any */ if(user->country_code) free(user->country_code); @@ -3254,6 +3319,8 @@ static void call_oper_funcs(struct userNode *user); void mod_usermode(struct userNode *user, const char *mode_change) { int add = 1; + long setmodes = 0; + int donemodes = 0; const char *word = mode_change; if (!user || !mode_change) @@ -3261,12 +3328,16 @@ void mod_usermode(struct userNode *user, const char *mode_change) { call_user_mode_funcs(user, mode_change); + setmodes = user->modes; + while (*word != ' ' && *word) word++; while (*word == ' ') word++; - while (1) { + while (!donemodes) { #define do_user_mode(FLAG) do { if (add) user->modes |= FLAG; else user->modes &= ~FLAG; } while (0) switch (*mode_change++) { - case 0: case ' ': return; + case 0: case ' ': + donemodes = 1; + break; case '+': add = 1; break; case '-': add = 0; break; case 'o': @@ -3291,6 +3362,7 @@ void mod_usermode(struct userNode *user, const char *mode_change) { case 'g': do_user_mode(FLAGS_GLOBAL); break; case 'B': do_user_mode(FLAGS_BOT); break; case 'n': do_user_mode(FLAGS_HIDECHANS); break; + case 'p': do_user_mode(FLAGS_HIDECHANS); break; case 'I': do_user_mode(FLAGS_HIDEIDLE); break; case 'X': do_user_mode(FLAGS_XTRAOP); break; case 'C': do_user_mode(FLAGS_CLOAKHOST); @@ -3369,6 +3441,37 @@ void mod_usermode(struct userNode *user, const char *mode_change) { } #undef do_user_mode } + + // Set user mode +o + if (!(setmodes & FLAGS_OPER) && IsOper(user)) { + if (!IsBotM(user) && !IsService(user) && !IsHideOper(user)) + count_opers++; + } + + // Set user mode -o + if ((setmodes & FLAGS_OPER) && !IsOper(user)) { + if (count_opers > 1 && !(setmodes & FLAGS_BOT) && + !(setmodes & FLAGS_SERVICE) && !(setmodes & FLAGS_HIDEOPER)) + count_opers--; + } + + // Set +H, +k or +B + if (!(setmodes & FLAGS_HIDEOPER) && + !(setmodes & FLAGS_SERVICE) && + !(setmodes & FLAGS_BOT) && + (IsHideOper(user) || IsService(user) || IsBotM(user))) { + if ((setmodes & FLAGS_OPER) && IsOper(user) && count_opers > 0) + count_opers--; + } + + // Set -H, -k or -B + if (((setmodes & FLAGS_HIDEOPER) || + (setmodes & FLAGS_SERVICE) || + (setmodes & FLAGS_BOT)) && + !IsHideOper(user) && !IsService(user) && !IsBotM(user)) { + if ((setmodes & FLAGS_OPER) && IsOper(user)) + count_opers++; + } } static int