X-Git-Url: https://jfr.im/git/irc/evilnet/x3.git/blobdiff_plain/3e06ac80fc4ebc46916da348f8056840461f352d..b208a99e5d964b573b641cf0bd543aadd43580b5:/src/proto-p10.c?ds=sidebyside diff --git a/src/proto-p10.c b/src/proto-p10.c index 5067985..0cb2609 100644 --- a/src/proto-p10.c +++ b/src/proto-p10.c @@ -85,6 +85,7 @@ #define CMD_RESTART "RESTART" #define CMD_RPING "RPING" #define CMD_RPONG "RPONG" +#define CMD_SASL "SASL" #define CMD_SERVER "SERVER" #define CMD_SERVLIST "SERVLIST" #define CMD_SERVSET "SERVSET" @@ -184,6 +185,7 @@ #define TOK_RESTART "RESTART" #define TOK_RPING "RI" #define TOK_RPONG "RO" +#define TOK_SASL "SASL" #define TOK_SERVER "S" #define TOK_SERVLIST "SERVSET" #define TOK_SERVSET "SERVSET" @@ -292,6 +294,7 @@ #define P10_RESTART TYPE(RESTART) #define P10_RPING TYPE(RPING) #define P10_RPONG TYPE(RPONG) +#define P10_SASL TYPE(SASL) #define P10_SERVER CMD_SERVER #define P10_SERVLIST TYPE(SERVLIST) #define P10_SERVSET TYPE(SERVSET) @@ -349,8 +352,8 @@ static const char *his_servername; static const char *his_servercomment; static int extended_accounts; -/* These correspond to 1 << X: 012345678901234567 */ -const char irc_user_mode_chars[] = "o iw dkgn I"; +/* These correspond to 1 << X: 01234567890123456789012345 */ +const char irc_user_mode_chars[] = "oOiw dkgh x BnIX azDRWHLq"; static struct userNode *AddUser(struct server* uplink, const char *nick, const char *ident, const char *hostname, const char *modes, const char *numeric, const char *userinfo, time_t timestamp, const char *realip); @@ -496,10 +499,10 @@ irc_server(struct server *srv) inttobase64(extranum, srv->num_mask, (srv->numeric[1] || (srv->num_mask >= 64*64)) ? 3 : 2); if (srv == self) { - putsock(P10_SERVER " %s %d " FMT_TIME_T " " FMT_TIME_T " J10 %s%s +s6 :%s", + putsock(P10_SERVER " %s %d " FMT_TIME_T " " FMT_TIME_T " J10 %s%s +s6o :%s", srv->name, srv->hops+1, srv->boot, srv->link_time, srv->numeric, extranum, srv->description); } else { - putsock("%s " P10_SERVER " %s %d " FMT_TIME_T " " FMT_TIME_T " %c10 %s%s +s6 :%s", + putsock("%s " P10_SERVER " %s %d " FMT_TIME_T " " FMT_TIME_T " %c10 %s%s +s6o :%s", self->numeric, srv->name, srv->hops+1, srv->boot, srv->link_time, (srv->self_burst ? 'J' : 'P'), srv->numeric, extranum, srv->description); } } @@ -834,8 +837,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 @@ -850,13 +853,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 @@ -906,6 +909,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; @@ -931,13 +938,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++] = ' '; } @@ -1094,23 +1106,27 @@ void irc_topic(struct userNode *service, struct userNode *who, struct chanNode *what, const char *topic) { - int type = 4, host_in_topic = 0, hasident = 0; - const char *hstr, *tstr; + int type = 4, host_in_topic = 0, hasident = 0, hhtype = 0; + const char *hstr, *tstr, *hhstr, *htstr; char *host, *hostmask; char shost[MAXLEN]; char sident[MAXLEN]; tstr = conf_get_data("server/type", RECDB_QSTRING); hstr = conf_get_data("server/host_in_topic", RECDB_QSTRING); + hhstr = conf_get_data("server/hidden_host", RECDB_QSTRING); + htstr = conf_get_data("server/hidden_host_type", RECDB_QSTRING); if(tstr) type = atoi(tstr); else type = 4;/* default to 040 style topics */ + if (htstr) + hhtype = atoi(htstr); if (hstr) { - if (IsFakeHost(who)) + if (IsHiddenHost(who) && IsFakeHost(who)) safestrncpy(shost, who->fakehost, sizeof(shost)); - else if (IsSetHost(who)) { + else if (IsHiddenHost(who) && IsSetHost(who)) { hostmask = strdup(who->sethost); if ((host = (strrchr(hostmask, '@')))) { hasident = 1; @@ -1124,6 +1140,10 @@ 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) || (hhtype == 3)) && who->handle_info && hhstr) { + snprintf(shost, sizeof(shost), "%s.%s", who->handle_info->handle, hhstr); + } else if (IsHiddenHost(who) && ((hhtype == 2) || (hhtype == 3)) && who->crypthost[0]) { + safestrncpy(shost, who->crypthost, sizeof(shost)); } else safestrncpy(shost, who->hostname, sizeof(shost)); @@ -1161,6 +1181,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) @@ -1208,6 +1256,12 @@ void irc_sno(unsigned int mask, char const* format, ...) { putsock("%s " CMD_SNO " %d :%s", self->numeric, mask, buffer); } +void +irc_sasl(struct server* dest, const char *identifier, const char *subcmd, const char *data) +{ + putsock("%s " P10_SASL " %s %s %s %s", self->numeric, dest->numeric, identifier, subcmd, data); +} + static void send_burst(void); static void @@ -1426,6 +1480,22 @@ static CMD_FUNC(cmd_rping) return 1; } +static CMD_FUNC(cmd_sasl) +{ + struct server *serv; + + if (argc < 5) + return 0; + + serv = GetServerH(origin); + if (!serv) + return 0; + + call_sasl_input_func(serv, argv[2], argv[3], argv[4], (argc>5 ? argv[5] : NULL)); + + return 1; +} + static CMD_FUNC(cmd_ping) { struct server *srv; @@ -1835,24 +1905,14 @@ static CMD_FUNC(cmd_burst) break; } case '%': { + ctype = 1; for(parm = mysep(&argv[next], " "); /* parm = first param */ parm; /* While param is not null */ parm = mysep(&argv[next], " ") /* parm = next param */ ) { - switch (parm[0]) { - case '%': { - ctype = 1; - break; - } - case '~': { - ctype = 2; - break; - } - default: { - break; - } - } + if (0 == strcmp("~", parm)) + ctype = 2; if (ctype == 1) { if (bcheck == 0) { /* strip % char off start of very first ban */ @@ -1946,25 +2006,47 @@ static CMD_FUNC(cmd_burst) */ 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; } @@ -2241,9 +2323,11 @@ static CMD_FUNC(cmd_kill) * Ghost response to a KILL we sent out earlier. So we only * whine if the target is local. */ - if (!strncmp(argv[1], self->numeric, strlen(self->numeric))) + if (!strncmp(argv[1], self->numeric, strlen(self->numeric))) { log_module(MAIN_LOG, LOG_ERROR, "Unable to find kill victim %s", argv[1]); - return 0; + return 0; + } + return 1; } if (IsLocal(user) && IsService(user)) { @@ -2673,6 +2757,9 @@ init_parse(void) dict_insert(irc_func_dict, CMD_RPONG, cmd_dummy); dict_insert(irc_func_dict, TOK_RPONG, cmd_dummy); + dict_insert(irc_func_dict, CMD_SASL, cmd_sasl); + dict_insert(irc_func_dict, TOK_SASL, cmd_sasl); + /* In P10, DESTRUCT doesn't do anything except be broadcast to servers. * Apparently to obliterate channels from any servers that think they * exist? @@ -2990,7 +3077,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 * @@ -3205,6 +3292,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); @@ -3330,6 +3419,14 @@ void mod_usermode(struct userNode *user, const char *mode_change) { assign_fakehost(user, host, 0); } break; + case 'a': do_user_mode(FLAGS_ADMIN); break; + case 'z': do_user_mode(FLAGS_SSL); break; + case 'D': do_user_mode(FLAGS_PRIVDEAF); break; + case 'R': do_user_mode(FLAGS_ACCOUNTONLY); break; + case 'W': do_user_mode(FLAGS_WHOIS); break; + case 'H': do_user_mode(FLAGS_HIDEOPER); break; + case 'L': do_user_mode(FLAGS_NOLINK); break; + case 'q': do_user_mode(FLAGS_COMMONCHANSONLY); break; } #undef do_user_mode } @@ -3450,7 +3547,8 @@ mod_chanmode_parse(struct chanNode *channel, char **modes, unsigned int argc, un case 'A': if (add) { if ((in_arg >= argc) - || keyncpy(change->new_upass, modes[in_arg++], sizeof(change->new_upass))) + || keyncpy(change->new_apass, modes[in_arg++], sizeof(change->new_apass))) + goto error; change->modes_set |= MODE_APASS; } else { change->modes_clear |= MODE_APASS; @@ -3789,59 +3887,19 @@ mod_chanmode_format(struct mod_chanmode *change, char *outbuff) DO_MODE_CHAR(REGISTERED, 'z'); DO_MODE_CHAR(SSLONLY, 'Z'); DO_MODE_CHAR(HIDEMODE, 'L'); -#undef DO_MODE_CHAR - switch (change->modes_set & (MODE_KEY|MODE_LIMIT|MODE_APASS|MODE_UPASS)) { - /* Doing this implementation has been a pain in the arse, I hope I didn't forget a possible combination */ - case MODE_KEY|MODE_LIMIT|MODE_APASS|MODE_UPASS: - used += sprintf(outbuff+used, "lkAU %d %s %s %s", change->new_limit, change->new_key,change->new_apass, change->new_upass); - break; - case MODE_KEY|MODE_LIMIT|MODE_APASS: - used += sprintf(outbuff+used, "lkA %d %s %s", change->new_limit, change->new_key, change->new_apass); - break; - case MODE_KEY|MODE_LIMIT|MODE_UPASS: - used += sprintf(outbuff+used, "lkU %d %s %s", change->new_limit, change->new_key, change->new_upass); - break; - case MODE_KEY|MODE_APASS|MODE_UPASS: - used += sprintf(outbuff+used, "kAU %s %s %s", change->new_key, change->new_apass, change->new_upass); - break; - - case MODE_KEY|MODE_APASS: - used += sprintf(outbuff+used, "kA %s %s", change->new_key, change->new_apass); - break; - case MODE_KEY|MODE_UPASS: - used += sprintf(outbuff+used, "kU %s %s", change->new_key, change->new_upass); - break; - case MODE_KEY|MODE_LIMIT: - used += sprintf(outbuff+used, "lk %d %s", change->new_limit, change->new_key); - break; - - case MODE_LIMIT|MODE_UPASS: - used += sprintf(outbuff+used, "lU %d %s", change->new_limit, change->new_upass); - break; - case MODE_LIMIT|MODE_APASS: - used += sprintf(outbuff+used, "lA %d %s", change->new_limit, change->new_apass); - break; - case MODE_APASS|MODE_UPASS: - used += sprintf(outbuff+used, "AU %s %s", change->new_apass, change->new_upass); - - case MODE_LIMIT|MODE_APASS|MODE_UPASS: - used += sprintf(outbuff+used, "lAU %d %s %s", change->new_limit, change->new_apass, change->new_upass); - break; + DO_MODE_CHAR(KEY, 'k'); + DO_MODE_CHAR(LIMIT, 'l'); + DO_MODE_CHAR(APASS, 'A'); + DO_MODE_CHAR(UPASS, 'U'); +#undef DO_MODE_CHAR - case MODE_APASS: - used += sprintf(outbuff+used, "A %s", change->new_apass); - break; - case MODE_UPASS: - used += sprintf(outbuff+used, "U %s", change->new_upass); - break; - case MODE_KEY: - used += sprintf(outbuff+used, "k %s", change->new_key); - break; - case MODE_LIMIT: - used += sprintf(outbuff+used, "l %d", change->new_limit); - break; - } +#define DO_MODE_PARM(BIT, PARM) if (change->modes_set & MODE_##BIT) used += sprintf(outbuff+used, " %s", PARM); + DO_MODE_PARM(KEY, change->new_key); + if (change->modes_set & MODE_LIMIT) used += sprintf(outbuff+used, " %d", change->new_limit); + DO_MODE_PARM(APASS, change->new_apass); + DO_MODE_PARM(UPASS, change->new_upass); +#undef DO_MODE_PARM } outbuff[used] = 0; return outbuff;