Changeset 786
- Timestamp:
- 10/14/06 10:02:21 (6 years ago)
- Location:
- branches/ithildin-scons/modules
- Files:
-
- 55 edited
-
ircd/addons/acl.c (modified) (24 diffs)
-
ircd/addons/acl.h (modified) (3 diffs)
-
ircd/addons/cmode_filter.c (modified) (1 diff)
-
ircd/addons/cmode_strip.c (modified) (3 diffs)
-
ircd/addons/core.c (modified) (1 diff)
-
ircd/addons/hostcrypt.c (modified) (1 diff)
-
ircd/addons/hostmask.c (modified) (4 diffs)
-
ircd/addons/quarantine.c (modified) (1 diff)
-
ircd/addons/throttle.c (modified) (1 diff)
-
ircd/client.c (modified) (5 diffs)
-
ircd/client.h (modified) (5 diffs)
-
ircd/command.c (modified) (4 diffs)
-
ircd/command.h (modified) (1 diff)
-
ircd/commands/acl.c (modified) (2 diffs)
-
ircd/commands/akill.c (modified) (5 diffs)
-
ircd/commands/die.c (modified) (2 diffs)
-
ircd/commands/error.c (modified) (1 diff)
-
ircd/commands/info.c (modified) (2 diffs)
-
ircd/commands/join.c (modified) (2 diffs)
-
ircd/commands/kill.c (modified) (1 diff)
-
ircd/commands/mode.c (modified) (7 diffs)
-
ircd/commands/motd.c (modified) (1 diff)
-
ircd/commands/nick.c (modified) (3 diffs)
-
ircd/commands/oper.c (modified) (1 diff)
-
ircd/commands/pass.c (modified) (1 diff)
-
ircd/commands/quit.c (modified) (2 diffs)
-
ircd/commands/rehash.c (modified) (1 diff)
-
ircd/commands/server.c (modified) (9 diffs)
-
ircd/commands/sjoin.c (modified) (10 diffs)
-
ircd/commands/squit.c (modified) (4 diffs)
-
ircd/commands/svinfo.c (modified) (2 diffs)
-
ircd/commands/svsmode.c (modified) (2 diffs)
-
ircd/commands/topic.c (modified) (1 diff)
-
ircd/commands/version.c (modified) (1 diff)
-
ircd/commands/watch.c (modified) (1 diff)
-
ircd/commands/whois.c (modified) (3 diffs)
-
ircd/commands/whowas.c (modified) (1 diff)
-
ircd/commands/xinfo.c (modified) (5 diffs)
-
ircd/conf.c (modified) (2 diffs)
-
ircd/connection.c (modified) (5 diffs)
-
ircd/connection.h (modified) (3 diffs)
-
ircd/doc/conf.txt (modified) (2 diffs)
-
ircd/ircd.c (modified) (2 diffs)
-
ircd/protocol.c (modified) (11 diffs)
-
ircd/protocol.h (modified) (2 diffs)
-
ircd/protocols/dreamforge.c (modified) (1 diff)
-
ircd/protocols/ithildin1.c (modified) (2 diffs)
-
ircd/protocols/shared/rfc1459_io.c (modified) (3 diffs)
-
ircd/send.c (modified) (3 diffs)
-
ircd/send.h (modified) (1 diff)
-
ircd/server.c (modified) (5 diffs)
-
ircd/server.h (modified) (1 diff)
-
ircd/support.c (modified) (6 diffs)
-
ircd/support.h (modified) (3 diffs)
-
log/log.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/ithildin-scons/modules/ircd/addons/acl.c
r665 r786 26 26 * CIDR mask, or something else) */ 27 27 #define ACL_DEFAULT_HASH 0 28 /* the default rule at which inserts happen */29 #define ACL_DEFAULT_RULE 100030 #define ACL_DEFAULT_CONF_RULE 200031 28 32 29 /* function prototypes */ … … 36 33 XINFO_FUNC(xinfo_acl_handler); 37 34 38 /* create an acl structure with the given definition (or find one if it exists 39 * already) and add it in to the system. ACLs are equivalent for our purposes 40 * if they are in the same stage and have the same host-pattern. It doesn't 41 * make sense to have an accept for a host and a deny for host (with the 42 * exception that hosts which have a password are considered different enough 43 * to be left alone. */ 44 acl_t *create_acl(int stage, int acc, char *host, const char *type) { 35 /* Create an ACL with the given data. We will override ACLs that are 36 * similar enough to ourself (same stage/host/access/rule#) unless they have 37 * special parameter data (such as passwords or 'info line' bans) */ 38 acl_t *create_acl(int stage, int acc, char *host, const char *type, int rule) { 45 39 acl_t *ap, *ap2; 46 40 char *at, hostcopy[USERLEN + HOSTLEN + 2]; 47 struct acl_ tq*list;41 struct acl_list *list; 48 42 49 if ((ap = find_acl(stage, host, type, NULL, NULL)) != NULL) { 50 if ((ap->pass != NULL && (ap->access != acc)) || ap->info != NULL) 51 ap = NULL; /* if it has a password, don't trample it unless we are 52 adding another rule with a password and the same 53 access. if it has an info field, don't trample it at 54 all. */ 43 /* look for an ACL in this stage from the same hostname and with the 44 * same access and rule number. If we find one we will delete it unless 45 * it has an info-line, in which case we will leave it alone. (This is 46 * sort of a broken concession to not having a create command which 47 * takes that information...) */ 48 if ((ap = find_acl(stage, acc, host, type, rule, NULL, NULL)) != NULL) { 49 if (ap->info != NULL) 50 ap = NULL; 55 51 } 56 52 … … 78 74 79 75 /* add them into the big list... */ 80 ap->rule = acl.default_rule; 76 if (rule == ACL_DEFAULT_RULE) 77 ap->rule = acl.default_rule; 78 else 79 ap->rule = (short)rule; 81 80 ap->hash = get_acl_hash(ap->host); 82 81 … … 90 89 list = acl.stage3_list; 91 90 92 if ( TAILQ_EMPTY(list))93 TAILQ_INSERT_HEAD(list, ap, intlp);91 if (LIST_EMPTY(list)) 92 LIST_INSERT_HEAD(list, ap, intlp); 94 93 else { 95 TAILQ_FOREACH(ap2, list, intlp) {94 LIST_FOREACH(ap2, list, intlp) { 96 95 if (ap2->rule > ap->rule) { 97 TAILQ_INSERT_BEFORE(ap2, ap, intlp);96 LIST_INSERT_BEFORE(ap2, ap, intlp); 98 97 break; 99 } 100 } 101 if (ap2 == NULL) 102 TAILQ_INSERT_TAIL(list, ap, intlp); 98 } else if (LIST_NEXT(ap2, intlp) == NULL) { 99 LIST_INSERT_AFTER(ap2, ap, intlp); 100 break; 101 } 102 } 103 103 } 104 104 … … 153 153 /* this function finds an ACL based on stage/host/type, and possibly based on 154 154 * the pass/info parameters. */ 155 acl_t *find_acl(int stage, char *hostmask, const char *type, char *pass,156 char *info) {157 struct acl_ tq*list;155 acl_t *find_acl(int stage, int acc, char *hostmask, const char *type, 156 int rule, char *pass, char *info) { 157 struct acl_list *list; 158 158 char *at, hostcopy[USERLEN + HOSTLEN + 2], user[USERLEN + 1]; 159 159 char host[HOSTLEN + 1]; 160 160 acl_t *ap; 161 161 162 162 163 /* extract user@host data */ 163 164 strlcpy(hostcopy, hostmask, USERLEN + HOSTLEN + 2); … … 172 173 } 173 174 175 if (rule == ACL_DEFAULT_RULE) 176 rule = acl.default_rule; 177 174 178 if (stage == ACL_STAGE_CONNECT) 175 179 list = acl.stage1_list; … … 180 184 181 185 /* now try and find them in the bucket. */ 182 TAILQ_FOREACH(ap, list, intlp) { 186 LIST_FOREACH(ap, list, intlp) { 187 if (acc != ACL_ACCESS_ANY && ap->access != acc) 188 continue; 189 if (rule != ACL_ANY_RULE && ap->rule != rule) 190 continue; 191 183 192 if (!strcasecmp(ap->user, user) && !strcasecmp(ap->host, host) && 184 193 !strcasecmp(ap->type, type) && … … 202 211 /* and remove it from whatever list it's in */ 203 212 if (ap->stage == ACL_STAGE_CONNECT) 204 TAILQ_REMOVE(acl.stage1_list,ap, intlp);213 LIST_REMOVE(ap, intlp); 205 214 else if (ap->stage == ACL_STAGE_PREREG) 206 TAILQ_REMOVE(acl.stage2_list,ap, intlp);215 LIST_REMOVE(ap, intlp); 207 216 else 208 TAILQ_REMOVE(acl.stage3_list,ap, intlp);217 LIST_REMOVE(ap, intlp); 209 218 210 219 /* now free the memory */ … … 217 226 if (ap->info != NULL) 218 227 free(ap->info); 228 if (ap->redirect != NULL) 229 free(ap->redirect); 219 230 if (ap->timer != TIMER_INVALID) 220 231 destroy_timer(ap->timer); … … 308 319 /* now match. skip over any entries that aren't the default hash or our 309 320 * hash. */ 310 TAILQ_FOREACH(ap, acl.stage1_list, intlp) {321 LIST_FOREACH(ap, acl.stage1_list, intlp) { 311 322 if (ap->hash != hash && ap->hash != ACL_DEFAULT_HASH) 312 323 continue; … … 347 358 * and the ip (using hostmatch and ipmatch). All together that is four 348 359 * calls. Also, our hash space is expanded. */ 349 TAILQ_FOREACH(ap, acl.stage2_list, intlp) {360 LIST_FOREACH(ap, acl.stage2_list, intlp) { 350 361 if (ap->hash != hash && ap->hash != iphash && 351 362 ap->hash != ACL_DEFAULT_HASH) … … 393 404 * aren't allowed because of a class being full we actually have to keep on 394 405 * looking to see if they fit in somewhere else. blechhh. */ 395 TAILQ_FOREACH(ap, acl.stage3_list, intlp) {406 LIST_FOREACH(ap, acl.stage3_list, intlp) { 396 407 if (ap->hash != hash && ap->hash != iphash && 397 408 ap->hash != ACL_DEFAULT_HASH) … … 400 411 /* check password/info first, since they're cheaper than all the 401 412 * match calls (I guess */ 402 if (ap->pass != NULL && strcmp(ap->pass, cp->pass))413 if (ap->pass != NULL && cp->pass != NULL && strcmp(ap->pass, cp->pass)) 403 414 continue; /* password incorrect */ 404 415 if (ap->info != NULL && !match(ap->info, cp->cli->info)) … … 409 420 /* okay, it actually matches. */ 410 421 if (ap->access == ACL_DENY) { 422 /* Is this a redirect? Maybe so, let's send them the 423 * redirect message if it is. */ 424 if (ap->redirect != NULL) 425 sendto_one(cp->cli, RPL_FMT(cp->cli, RPL_REDIR), 426 ap->redirect, ap->redirect_port); 427 411 428 /* if there's a reason for the ban and they weren't already 412 * denied set ret, otherwise just leave it alone */ 429 * denied set ret, otherwise just leave it alone. Why? 430 * this is possible if there is no more room in their 431 * connection class. We want them to know that they 432 * would be authorized if the class wasn't full, instead 433 * of telling them they are not at all authorized. */ 413 434 ret = (ret != NULL ? ret : ap->reason); 414 435 break; /* we'll return below. */ … … 430 451 } 431 452 432 if (ret == NULL && ! TAILQ_EMPTY(acl.stage3_list))453 if (ret == NULL && !LIST_EMPTY(acl.stage3_list)) 433 454 return "You are not authorised to use this server."; 434 455 return ret; … … 444 465 } 445 466 467 /* These two are the defaults for runtime and configured rule numbers, 468 * respectively. */ 469 #define ACLCONF_DEFAULT_RULE 1000 470 #define ACLCONF_DEFAULT_CONF_RULE 2000 446 471 HOOK_FUNCTION(acl_conf_hook) { 447 472 conf_entry_t *cep; 448 473 conf_list_t *clp; 449 474 acl_t *ap, *ap2; 450 int stg, acc; 451 char *s, *class, *pass, *info, *reason; 475 int stg, acc, redirect_port = 0; 476 char *s, *class, *pass, *info, *reason, *redir; 477 char redirect[SERVLEN + 1]; 452 478 class_t *cls; 453 int odr, rn, dcr; /* Old Default Rule, Rule Number, Default Conf Rule */ 479 int rule; 480 int default_rule; /* default rule for config entries */ 454 481 455 482 /* remove anything that points to a conf. usually this will only be … … 466 493 /* see about setting the default rule number.. */ 467 494 if ((s = conf_find_entry("default-acl-rule", *ircd.confhead, 1)) != NULL) 468 acl.default_rule = str_conv_int(s, ACL _DEFAULT_RULE);495 acl.default_rule = str_conv_int(s, ACLCONF_DEFAULT_RULE); 469 496 else 470 acl.default_rule = ACL _DEFAULT_RULE;497 acl.default_rule = ACLCONF_DEFAULT_RULE; 471 498 if ((s = conf_find_entry("default-acl-conf-rule", *ircd.confhead, 1)) != 472 499 NULL) 473 d cr = str_conv_int(s, ACL_DEFAULT_CONF_RULE);500 default_rule = str_conv_int(s, ACLCONF_DEFAULT_CONF_RULE); 474 501 else 475 d cr = ACL_DEFAULT_CONF_RULE;502 default_rule = ACLCONF_DEFAULT_CONF_RULE; 476 503 477 504 /* now read through the conf looking for ACLs, as we find them parse and … … 482 509 while ((cep = conf_find_next("acl", NULL, CONF_TYPE_LIST, cep, 483 510 *ircd.confhead, 1)) != NULL) { 484 r n = dcr;511 rule = default_rule; 485 512 if (cep->string != NULL) 486 r n= str_conv_int(cep->string, -1);487 if (r n < 0 || rn> USHRT_MAX) {488 log_warn("got acl with bogus rule number (%d)", r n);489 r n = dcr;513 rule = str_conv_int(cep->string, -1); 514 if (rule < 0 || rule > USHRT_MAX) { 515 log_warn("got acl with bogus rule number (%d)", rule); 516 rule = default_rule; 490 517 } 491 518 … … 522 549 pass = conf_find_entry("pass", clp, 1); 523 550 info = conf_find_entry("info", clp, 1); 524 if (acc ess== ACL_DENY) {551 if (acc == ACL_DENY) { 525 552 if ((reason = conf_find_entry("reason", clp, 1)) == NULL) 526 553 reason = "You are not authorised to use this server."; 527 554 } 555 556 if ((redir = conf_find_entry("redirect", clp, 1)) != NULL) { 557 /* try finding the port .. */ 558 if ((s = strchr(redir, ':')) != NULL) { 559 strlcpy(redirect, redir, (s - redir <= SERVLEN ? 560 (s - redir) + 1 : SERVLEN + 1)); 561 if ((redirect_port = str_conv_int(s + 1, 0)) == 0) 562 log_warn("Could not parse server:port combo for redirect " 563 "%s", redir); 564 } else { 565 strlcpy(redirect, redir, SERVLEN + 1); 566 redirect_port = 6667; 567 } 568 569 if (acc != ACL_DENY) { 570 log_warn("Redirection forces a DENY ACL type."); 571 acc = ACL_DENY; 572 } 573 } else 574 *redirect = '\0'; 575 576 528 577 529 578 /* now iterate through all the host lists and all the regular hosts and 530 579 * add the acl. yikes! Use this macro to make life a bit easier. */ 531 580 #define ACL_PARSE_ADD(_host) do { \ 532 odr = acl.default_rule; \ 533 acl.default_rule = rn; \ 534 ap = create_acl(stg, acc, _host, "acl"); \ 535 acl.default_rule = odr; \ 581 ap = create_acl(stg, acc, _host, "acl", rule); \ 536 582 ap->conf = clp; \ 537 583 ap->cls = cls; \ … … 546 592 if (str_conv_bool(conf_find_entry("skip-ident", clp, 1), 0)) \ 547 593 ap->flags |= ACL_FL_SKIP_IDENT; \ 594 if (*redirect != '\0' && redirect_port != 0) { \ 595 ap->redirect = strdup(redirect); \ 596 ap->redirect_port = redirect_port; \ 597 } \ 548 598 } while (0) 549 599 … … 572 622 * for ACLs based on four parameters: mask, stage, access, and type. */ 573 623 acl_t *ap; 574 struct acl_ tq*list;624 struct acl_list *list; 575 625 char rpl[XINFO_LEN]; 576 626 char *mask = NULL, *type = NULL; … … 645 695 } 646 696 while (list != NULL) { 647 TAILQ_FOREACH(ap, list, intlp) {697 LIST_FOREACH(ap, list, intlp) { 648 698 if (acc != -1 && ap->access != acc) 649 699 continue; … … 694 744 695 745 LIST_ALLOC(acl.list); 696 TAILQ_ALLOC(acl.stage1_list);697 TAILQ_ALLOC(acl.stage2_list);698 TAILQ_ALLOC(acl.stage3_list);699 700 add_xinfo_handler(xinfo_acl_handler, "ACL", XINFO_HANDLER_OPER, NULL,746 LIST_ALLOC(acl.stage1_list); 747 LIST_ALLOC(acl.stage2_list); 748 LIST_ALLOC(acl.stage3_list); 749 750 add_xinfo_handler(xinfo_acl_handler, "ACL", XINFO_HANDLER_OPER, 701 751 "Provides information about the server Access Control List"); 702 752 … … 716 766 destroy_acl(LIST_FIRST(acl.list)); 717 767 LIST_FREE(acl.list); 718 TAILQ_FREE(acl.stage1_list);719 TAILQ_FREE(acl.stage2_list);720 TAILQ_FREE(acl.stage3_list);768 LIST_FREE(acl.stage1_list); 769 LIST_FREE(acl.stage2_list); 770 LIST_FREE(acl.stage3_list); 721 771 722 772 remove_xinfo_handler(xinfo_acl_handler); -
branches/ithildin-scons/modules/ircd/addons/acl.h
r665 r786 16 16 #define ACL_STAGE_REGISTER 3 17 17 int stage; /* one of 1, 2, or 3 */ 18 #define ACL_ACCESS_ANY -1 18 19 #define ACL_DENY 0 19 20 #define ACL_ALLOW 1 … … 31 32 only) */ 32 33 char *pass; /* password */ 34 char *redirect; /* redirect server (or NULL if none) */ 35 int redirect_port; /* redirect port */ 36 33 37 time_t added; /* when it was added */ 34 38 time_t expire; /* when this will expire */ … … 44 48 NULL otherwise. */ 45 49 46 TAILQ_ENTRY(acl) intlp; /* list pointers. intlp is for internal */ 47 LIST_ENTRY(acl) lp; /* use. lp is part of 'the big list'. */ 50 LIST_ENTRY(acl) intlp; /* list pointers. intlp is for internal 51 (stage-segregated) lists */ 52 LIST_ENTRY(acl) lp; /* lp is for the 'big list'. */ 48 53 } acl_t; 49 54 50 TAILQ_HEAD(acl_tq, acl);55 LIST_HEAD(acl_list, acl); 51 56 52 57 extern struct acl_module_data { 53 struct acl_ tq*stage1_list;54 struct acl_ tq*stage2_list;55 struct acl_ tq*stage3_list;56 LIST_HEAD(, acl)*list;58 struct acl_list *stage1_list; 59 struct acl_list *stage2_list; 60 struct acl_list *stage3_list; 61 struct acl_list *list; 57 62 58 63 unsigned short default_rule; 59 64 } acl; 60 65 61 acl_t *create_acl(int, int, char *, const char *); 62 acl_t *find_acl(int, char *, const char *, char *, char *); 66 #define ACL_ANY_RULE -1 67 #define ACL_DEFAULT_RULE -2 68 acl_t *create_acl(int, int, char *, const char *, int); 69 acl_t *find_acl(int, int, char *, const char *, int, char *, char *); 63 70 void destroy_acl(acl_t *); 64 71 void acl_add_timer(acl_t *, time_t); -
branches/ithildin-scons/modules/ircd/addons/cmode_filter.c
r613 r786 35 35 "chanmode_flag", "chanmode_flag_query", 0, NULL); 36 36 37 add_hook (ircd.events.can_send_channel, can_send_filter);37 add_hook_before(ircd.events.can_send_channel, can_send_filter, NULL); 38 38 add_hook(me.events.read_conf, filter_conf_hook); 39 39 -
branches/ithildin-scons/modules/ircd/addons/cmode_strip.c
r613 r786 42 42 "chanmode_flag", "chanmode_flag_query", 0, NULL); 43 43 44 add_hook (ircd.events.can_send_channel, can_send_strip);44 add_hook_before(ircd.events.can_send_channel, can_send_strip, NULL); 45 45 add_hook(me.events.read_conf, strip_conf_hook); 46 46 … … 58 58 59 59 remove_hook(ircd.events.can_send_channel, can_send_strip); 60 remove_hook(me.events.read_conf, strip_conf_hook); 60 61 } 61 62 62 #define ANSI_CHAR '\033'63 #define BLINK_CHAR '\006'64 #define BOLD_CHAR '\002'65 #define COLOR_CHAR '\003'66 #define INVERSE_CHAR '\026'67 #define UNDERLINE_CHAR '\037'63 #define ANSI_CHAR '\033' 64 #define BLINK_CHAR '\006' 65 #define BOLD_CHAR '\002' 66 #define COLOR_CHAR '\003' 67 #define INVERSE_CHAR '\026' 68 #define UNDERLINE_CHAR '\037' 68 69 69 70 HOOK_FUNCTION(strip_conf_hook) { … … 117 118 118 119 if (chanmode_isset(ccap->chan, chanmode_strip)) { 119 char *from, *to;120 from = to = ccap->extra;120 unsigned char *from, *to; 121 from = to = (unsigned char *)ccap->extra; 121 122 122 123 while (*from != '\0') { 123 if (strip_chars[(unsigned char)*from]) { 124 if (strip_chars[*from]) { 125 /* We will always skip the character here, it just may not 126 * match COLOR_CHAR in which case we simply continue on */ 124 127 if (*from++ == COLOR_CHAR) { 125 128 if (isdigit(*from)) { 126 if (isdigit(*++from)) { 127 if (*++from == ',') { 128 if (isdigit(*++from)) { 129 if (isdigit(*from)) 130 from++; 131 } 132 } 129 if (isdigit(*++from)) 130 from++; /* skip second digit which is optional */ 131 132 if (*from == ',' && isdigit(*(from + 1))) { 133 /* background color specified ... */ 134 from += 2; 135 if (isdigit(*from)) 136 from++; 133 137 } 134 138 } 135 139 } 136 continue; 137 } 138 *to++ = *from++; 140 } else 141 *to++ = *from++; 139 142 } 143 *to = '\0'; 140 144 } 141 145 -
branches/ithildin-scons/modules/ircd/addons/core.c
r689 r786 303 303 match(cbp->host, host)) 304 304 return CHANMODE_FAIL; /* already set. */ 305 #else 306 if (!strcasecmp(cbp->nick, nick) && 307 !strcasecmp(cbp->user, user) && 308 !strcasecmp(cbp->host, host)) 309 return CHANMODE_FAIL; 305 310 #endif 306 311 } -
branches/ithildin-scons/modules/ircd/addons/hostcrypt.c
r759 r786 243 243 if (set) 244 244 hostcrypt_encrypt(cli); 245 else 246 hostcrypt_decrypt(cli); 245 else { 246 /* Do not decrypt their hostname if they've been added to the 247 * history section. This is indicative of an automated unsetting, 248 * not a manual one. */ 249 if (!(cli->flags & IRCD_CLIENT_HISTORY)) 250 hostcrypt_decrypt(cli); 251 } 247 252 248 253 return 1; -
branches/ithildin-scons/modules/ircd/addons/hostmask.c
r579 r786 20 20 */ 21 21 22 #define CGI_IRC_SPECIAL_MASK "cgi:irc" 23 22 24 static struct mdext_item *class_hostmask_mdi; 23 25 24 26 HOOK_FUNCTION(hostmask_conf_hook); 25 27 HOOK_FUNCTION(hostmask_cc_hook); 28 static int validate_cgiirc_host(const char *, char **, char **); 26 29 27 30 MODULE_LOADER(hostmask) { … … 53 56 /* verify the mask. make sure it consists ONLY of valid 54 57 * characters, and that it has multiple parts. */ 55 if (!istr_okay(ircd.maps.host, s) || strchr(s, '.') == NULL) 56 log_error("hostmask %s is invalid.", s); 57 else 58 if (strcasecmp(s, CGI_IRC_SPECIAL_MASK) && 59 (!istr_okay(ircd.maps.host, s) || 60 strchr(s, '.') == NULL)) 61 log_error("hostmask for class %s is invalid", cls->name); 62 else { 58 63 strlcpy(mdext(cls, class_hostmask_mdi), s, HOSTLEN + 1); 64 log_debug("setting hostmask for class %s to %s", cls->name, 65 mdext(cls, class_hostmask_mdi)); 66 } 59 67 } 60 68 } … … 65 73 HOOK_FUNCTION(hostmask_cc_hook) { 66 74 client_t *cli = (client_t *)data; 67 char *mask = NULL;75 char *mask, *ip; 68 76 69 if (cli->conn != NULL)70 mask = mdext(cli->conn->cls, class_hostmask_mdi);77 if (cli->conn == NULL) 78 return NULL; /* nothing to do */ 71 79 80 mask = ip = NULL; 81 82 mask = mdext(cli->conn->cls, class_hostmask_mdi); 72 83 if (mask != NULL && *mask != '\0') { 84 if (!strcasecmp(mask, CGI_IRC_SPECIAL_MASK)) { 85 /* Special CGI:IRC hack. We take the password, if supplied, an 86 * use it as a hostname (as long as it's valid). Good stuff. */ 87 if (cli->conn->pass != NULL && *cli->conn->pass != '\0' && 88 validate_cgiirc_host(cli->conn->pass, &ip, &mask)) { 89 log_debug("cgi:irc connection masked as %s / %s", ip, mask); 90 strcpy(cli->ip, ip); /* set the IP as well */ 91 } else { 92 log_warn("cgi:irc hostmasked connection provided invalid " 93 "host (%s) (%s!%s@%s)", 94 (cli->conn->pass == NULL ? "" : cli->conn->pass), 95 cli->nick, cli->user, cli->host); 96 return NULL; 97 } 98 /* fallthrough to normal mask case. */ 99 } 73 100 sendto_flag(SFLAG("SPY"), "Changing hostname for %s!%s@%s to %s", 74 101 cli->nick, cli->user, cli->host, mask); … … 79 106 } 80 107 108 /* CGIIRC(6)+__(2)+\0(1)+ip+host */ 109 #define CGIIRC_HOST_SIZE 9 + IPADDR_MAXLEN + HOSTLEN 110 111 /* validate the string from a CGI:IRC connection. The string is of the form 112 * CGIIRC_<ip>_<host>. We ensure that both the IP and hostname are valid. */ 113 static int validate_cgiirc_host(const char *in, char **ip, char **host) { 114 static char str[CGIIRC_HOST_SIZE]; 115 char *s_ip, *s_host; 116 117 *ip = *host = NULL; 118 strlcpy(str, in, CGIIRC_HOST_SIZE); 119 120 if (strncmp(str, "CGIIRC_", 7)) 121 return 0; 122 123 s_ip = str + 7; 124 if ((s_host = strchr(s_ip, '_')) == NULL) 125 return 0; /* no hostname */ 126 *s_host++ = '\0'; 127 128 /* now we have ip/host, let's validate */ 129 if (*s_ip == '\0' || *s_host == '\0') 130 return 0; 131 132 if (get_address_type(s_ip) == PF_UNSPEC) 133 return 0; /* bad IP */ 134 135 if (strchr(s_host, '.') == NULL || !istr_okay(ircd.maps.host, s_host)) 136 return 0; /* bogus host */ 137 138 *ip = s_ip; 139 *host = s_host; 140 return 1; 141 } 142 81 143 /* vi:set ts=8 sts=4 sw=4 tw=76 et: */ -
branches/ithildin-scons/modules/ircd/addons/quarantine.c
r579 r786 237 237 } 238 238 239 add_xinfo_handler(xinfo_quarantine_handler, "QUARANTINE", 0, NULL,239 add_xinfo_handler(xinfo_quarantine_handler, "QUARANTINE", 0, 240 240 "Provides a list of nickname and channel quarantines"); 241 241 -
branches/ithildin-scons/modules/ircd/addons/throttle.c
r665 r786 164 164 165 165 if (tp->banned + len >= me.now) { 166 if ((ap = find_acl(ACL_STAGE_CONNECT, cp->host, throttle_acl_type,167 NULL, NULL)) == NULL) {166 if ((ap = find_acl(ACL_STAGE_CONNECT, ACL_DENY, cp->host, 167 throttle_acl_type, ACL_DEFAULT_RULE, NULL, NULL)) == NULL) { 168 168 ap = create_acl(ACL_STAGE_CONNECT, ACL_DENY, cp->host, 169 throttle_acl_type );169 throttle_acl_type, ACL_DEFAULT_RULE); 170 170 ap->reason = strdup(THROTTLE_ERRMSG); 171 171 } -
branches/ithildin-scons/modules/ircd/client.c
r744 r786 68 68 sendto_serv_butone(cli->server, cli, NULL, NULL, "QUIT", ":%s", 69 69 msg); 70 /* uh, also, if they're leaving from a squit we need to send a QUIT to71 * servers without NOQUIT support. */72 if (cli->flags & IRCD_CLIENT_SQUIT)73 sendto_serv_pflag_butone(PROTOCOL_SFL_NOQUIT, false, cli->server,74 cli, NULL, NULL, "QUIT", ":%s", msg);75 70 76 71 clp = LIST_FIRST(&cli->chans); … … 119 114 ircd.stats.serv.unkclients--; 120 115 cli->conn->cli = NULL; 121 destroy_connection(cli->conn, msg); 116 117 /* If sendq_flush does not close the connection for us (it will 118 * return 0 if it does) then close the connection. This ensures 119 * that we do best-effort work on dumping the last dribbly bits of 120 * the sendq out to the client if we can. We do not try hard to 121 * make this work, though! */ 122 if (sendq_flush(cli->conn)) 123 destroy_connection(cli->conn, msg); 122 124 } 123 125 … … 137 139 * however, as that is left up to the caller. */ 138 140 void client_change_nick(client_t *cli, char *to) { 139 int casechng ;141 int casechng = !istrcmp(ircd.maps.nick, cli->nick, to); 140 142 141 143 /* check to see if this is just a case change. if it is, istrcmp will 142 144 * return 0. if it's a case change, we don't do anything except set the 143 145 * new nickname in the client structure. */ 144 casechng = !istrcmp(ircd.maps.nick, cli->nick, to); 145 if (!casechng) { 146 if (*cli->nick != '\0' && !casechng) { 146 147 hash_delete(ircd.hashes.client, cli); 147 client_add_history(cli); 148 } 148 149 /* History entries for unregistered clients are extremely useless, 150 * and detrimental sometimes. */ 151 if (CLIENT_REGISTERED(cli)) 152 client_add_history(cli); 153 } 154 149 155 strncpy(cli->nick, to, NICKLEN); 156 150 157 if (!casechng) { 151 158 hash_insert(ircd.hashes.client, cli); 152 hook_event(ircd.events.client_nick, cli); 159 160 /* We only hook client_nick for registered clients, there is little 161 * value in hooking it for nonregistered folks. */ 162 if (CLIENT_REGISTERED(cli)) 163 hook_event(ircd.events.client_nick, cli); 153 164 } 154 165 } … … 180 191 if (returns[x] != NULL) {/* denied, with a reason */ 181 192 destroy_client(cli, (char *)returns[x]); 182 return IRCD_C LOSEDCONN; /* not successful */193 return IRCD_CONNECTION_CLOSED; /* not successful */ 183 194 } 184 195 x++; … … 189 200 LIST_INSERT_HEAD(ircd.connections.clients, cp, lp); 190 201 ircd.stats.serv.unkclients--; 202 191 203 } 192 204 193 205 cli->signon = cli->ts = me.now; 194 206 cli->hops = 0; /* our client, they're 0 hops from us <G> */ 195 } 196 197 /* do other work now.. */ 198 if (MYCLIENT(cli)) { 207 199 208 /* only hook for local registration */ 200 209 hook_event(ircd.events.client_connect, cli); 210 211 /* clear the password after client_connect, assume that nothing else 212 * will need to hook it and use it anymore. */ 213 if (cp != NULL) { 214 /* clean out their password */ 215 if (cp->pass != NULL) { 216 free(cp->pass); 217 cp->pass = NULL; 218 } 219 } 201 220 202 221 /* accounting stuff */ -
branches/ithildin-scons/modules/ircd/client.h
r593 r786 12 12 13 13 struct client { 14 char nick[NICKLEN + 1]; /* nickname */15 char user[USERLEN + 1]; /* username on IRC (different from username16 in conn */17 char host[HOSTLEN + 1]; /* hostname on IRC */18 char *orighost; /* concession for host-changing modules. this19 will normally point to the 'host' field of20 the client, but may be pointed elsewhere if21 need be. */22 char ip[IPADDR_MAXLEN + 1]; /* IP address (NICKIP) */23 char info[GCOSLEN + 1]; /* gecos/gcos info (ircname) */14 char nick[NICKLEN + 1]; /* nickname */ 15 char user[USERLEN + 1]; /* username on IRC (different from username 16 in conn */ 17 char host[HOSTLEN + 1]; /* hostname on IRC */ 18 char *orighost; /* concession for host-changing modules. this 19 will normally point to the 'host' field of 20 the client, but may be pointed elsewhere if 21 need be. */ 22 char ip[IPADDR_MAXLEN + 1]; /* IP address (NICKIP) */ 23 char info[GCOSLEN + 1]; /* gecos/gcos info (ircname) */ 24 24 25 25 #define IRCD_CLIENT_REGISTERED 0x0001 … … 28 28 #define IRCD_CLIENT_KILLED 0x0002 29 29 #define IRCD_CLIENT_HISTORY 0x0004 30 #define IRCD_CLIENT_SQUIT 0x0008 31 int flags; 30 int flags; 32 31 33 32 /* check to see if this is our client. we know it's ours if their server … … 36 35 #define MYCLIENT(cli) (cli->server == ircd.me) 37 36 struct connection *conn; /* the connection for this client, NULL if 38 remote or pseudo-client. */37 remote or pseudo-client. */ 39 38 40 time_t signon; /* signon time */41 time_t ts; /* timestamp of the nickname */42 time_t last; /* used for idle time (different from43 conn->last) */44 int hops;/* how many hops away are they? */45 uint64_t modes; /* the user's modes, see below */39 time_t signon; /* signon time */ 40 time_t ts; /* timestamp of the nickname */ 41 time_t last; /* used for idle time (different from 42 conn->last) */ 43 int hops; /* how many hops away are they? */ 44 uint64_t modes; /* the user's modes, see below */ 46 45 47 struct userchans chans; /* our channels */46 struct userchans chans; /* our channels */ 48 47 49 struct privilege_set *pset; /* privileges (usually derived from class) */50 struct server *server; /* server which owns this client */48 struct privilege_set *pset; /* privileges (usually derived from class) */ 49 struct server *server; /* server which owns this client */ 51 50 52 51 struct client_history *hist; 53 52 54 char *mdext; /* mdext data */53 char *mdext; /* mdext data */ 55 54 56 55 LIST_ENTRY(client) lp; … … 139 138 140 139 struct usermode { 141 unsigned char mode; /* the actual mode */142 char avail; /* 1 if available, 0 otherwise */143 #define USERMODE_FL_GLOBAL 0x1 /* the usermode is spread across the140 unsigned char mode; /* the actual mode */ 141 char avail; /* 1 if available, 0 otherwise */ 142 #define USERMODE_FL_GLOBAL 0x1 /* the usermode is spread across the 144 143 network */ 145 #define USERMODE_FL_OPER 0x2 /* the usermode is operator only */144 #define USERMODE_FL_OPER 0x2 /* the usermode is operator only */ 146 145 #define USERMODE_FL_PRESERVE 0x4 /* preserve the mode once set unless 147 146 explicitly unset by the user */ 148 int flags;/* flags for the usermode */149 uint64_t mask; /* the bitmask for the mode */150 msymbol_t *changer; /* the changer function for the mode */151 int sflag;/* send flag (if any) for this mode. */147 int flags; /* flags for the usermode */ 148 uint64_t mask; /* the bitmask for the mode */ 149 msymbol_t *changer; /* the changer function for the mode */ 150 int sflag; /* send flag (if any) for this mode. */ 152 151 }; 153 152 154 153 TAILQ_HEAD(client_history_list, client_history); 155 154 struct client_history { 156 char nick[NICKLEN + 1]; /* these are all the same as in the */155 char nick[NICKLEN + 1]; /* these are all the same as in the */ 157 156 char serv[SERVLEN + 1]; 158 157 159 client_t *cli; /* points to the client we created this158 client_t *cli; /* points to the client we created this 160 159 from. for currently online clients the 161 160 nick will be different. */ 162 time_t signoff; /* when the client signed off */161 time_t signoff; /* when the client signed off */ 163 162 164 163 TAILQ_ENTRY(client_history) lp; … … 176 175 * functions when checking for access */ 177 176 struct client_check_args { 178 client_t *from; /* the client performing the action */179 client_t *to; /* the client being acted on */180 char *extra; /* any extra data */177 client_t *from; /* the client performing the action */ 178 client_t *to; /* the client being acted on */ 179 char *extra; /* any extra data */ 181 180 }; 182 181 183 #define CLIENT_CHECK_OVERRIDE HOOK_COND_SPASS184 #define CLIENT_CHECK_OK HOOK_COND_PASS185 #define CLIENT_CHECK_NO HOOK_COND_FAIL182 #define CLIENT_CHECK_OVERRIDE HOOK_COND_SPASS 183 #define CLIENT_CHECK_OK HOOK_COND_PASS 184 #define CLIENT_CHECK_NO HOOK_COND_FAIL 186 185 int client_check_access(client_t *, client_t *, char *, event_t *); 187 186 #define can_can_send_client(from, to, arg) \ -
branches/ithildin-scons/modules/ircd/command.c
r744 r786 401 401 } 402 402 } 403 /* check operator and command use privileges */ 403 /* check operator and command use privileges. Why do this only for 404 * local clients? Because we need to assume that even if we are not 405 * configured to accept commands from a client, every other server 406 * is. Without a distributed privilege understanding we have to 407 * assume positive intent. */ 404 408 if ((cmd->client.flags & COMMAND_FL_OPERATOR && !OPER(cli)) || 405 409 !BPRIV(cli, cmd->priv)) { … … 426 430 * touch it in this state. */ 427 431 switch ((ret = cmd->client.cmd(cmd, argc, argv, cli))) { 428 case IRCD_C LOSEDCONN:429 case IRCD_P ARSESTOP:432 case IRCD_CONNECTION_CLOSED: 433 case IRCD_PROTOCOL_CHANGED: 430 434 return ret; 431 435 } … … 433 437 /* same as above, if it's not ours we need to get out of here now. 434 438 * commands that destroy non-local clients are not under obligation to 435 * return IRCD_CLOSEDCONN for those clients, so we don't know that the 436 * client structure is dead. Avoid the race here. */ 439 * return IRCD_CONNECTION_CLOSED for those clients, so we don't know 440 * that the client structure is dead, and we're done handling it at any 441 * rate. */ 437 442 if (ours == false || cli->conn == NULL || cli->conn->cls->flood <= 0) 438 443 return ret; … … 476 481 if (cli->conn->flood >= flimit) { 477 482 destroy_client(cli, "Excess Flood"); 478 return IRCD_C LOSEDCONN;483 return IRCD_CONNECTION_CLOSED; 479 484 } 480 485 } -
branches/ithildin-scons/modules/ircd/command.h
r672 r786 20 20 /* error numbers which can be returned by the command executer and commands 21 21 * themselves */ 22 #define IRCD_CLOSEDCONN -1 /* connection closed, stop any parsing */ 23 #define IRCD_PARSESTOP -2 /* finish current work on buffer and then stop 24 parsing (this differs from CLOSEDCONN in that 25 the buf field of the connection can continue to 26 be modified, this is basically an allowance for 27 the rfc1459 hackery) */ 22 23 /* Connection has been closed. Stop any parsing or handling of the 24 * associated pointers *IMMEDIATELY* */ 25 #define IRCD_CONNECTION_CLOSED -1 26 /* Notification that the protocol has been changed. This should cause 27 * parsing to stop AFTER the finalized cleanup on the existing buffer. 28 * Input functions are only gauranteed that the connection structure is 29 * still valid for the buffer variables, parsing routines should never be 30 * called after this is returned.*/ 31 #define IRCD_PROTOCOL_CHANGED -2 32 28 33 29 34 extern union cptr_u { -
branches/ithildin-scons/modules/ircd/commands/acl.c
r586 r786 228 228 229 229 /* see if it exists */ 230 ap = find_acl(stage, mask, type, NULL, NULL);230 ap = find_acl(stage, acc, mask, type, ACL_DEFAULT_RULE, NULL, NULL); 231 231 232 232 /* are we adding..? */ … … 238 238 } 239 239 240 ap = create_acl(stage, acc, mask, type );240 ap = create_acl(stage, acc, mask, type, ACL_DEFAULT_RULE); 241 241 ap->reason = strdup(reason); 242 242 /* if the expire time is non-zero, set a conf to 0x1 so it will get -
branches/ithildin-scons/modules/ircd/commands/akill.c
r586 r786 55 55 char *info = NULL; 56 56 57 if (!SERVER_MASTER(srv)) { 57 /* XXX: This is a hack to allow sglinebursts to be sent from non-master 58 * servers. I guess we should detect the bursting condition and only 59 * accept these at that time, but that's not we do it. :) */ 60 if (!SERVER_MASTER(srv) && strcasecmp(argv[0], "SGLINE") && 61 strcasecmp(argv[0], "UNSGLINE")) { 58 62 sendto_serv_butone(NULL, NULL, ircd.me, NULL, "GLOBOPS", 59 63 ":Non-master server %s trying to %s", srv->name, argv[0]); … … 64 68 65 69 if (!strcasecmp(argv[0], "AKILL")) { 70 char *user, *host, *set_by; 71 time_t set_at; 66 72 /* arguments: host user length set-by set-at reason */ 67 73 if ((!SERVER_SUPPORTS(sptr, PROTOCOL_SFL_SHORTAKILL) && argc != 7) || … … 72 78 } 73 79 74 snprintf(mask, USERLEN + HOSTLEN + 2, "%s@%s", argv[2], argv[1]); 75 if (SERVER_SUPPORTS(sptr, PROTOCOL_SFL_SHORTAKILL)) 76 reason = (argc > 3 ? argv[3] : ""); 77 else { 80 host = argv[1]; 81 user = argv[2]; 82 if (SERVER_SUPPORTS(sptr, PROTOCOL_SFL_SHORTAKILL)) { 83 reason = (argc > 3 ? argv[3] : "<no reason>"); 84 85 /* others we don't get ... */ 86 set_by = "<unknown>"; 87 set_at = me.now; 88 expire = 0; 89 } else { 78 90 expire = str_conv_time(argv[3], 0); 91 set_by = argv[4]; 92 set_at = str_conv_time(argv[5], me.now); 79 93 reason = argv[6]; 80 94 } 95 snprintf(mask, USERLEN + HOSTLEN + 2, "%s@%s", user, host); 96 97 /* propogate out. If we're getting data from a 'SHORTAKILL' server 98 * we'll end up sending out some fallacious/made up stuff. Oh well! */ 81 99 sendto_serv_pflag_butone(PROTOCOL_SFL_SHORTAKILL, true, sptr, NULL, 82 srv, NULL, "AKILL", "%s %s :%s", argv[1], argv[2], reason);100 srv, NULL, "AKILL", "%s %s :%s", host, user, reason); 83 101 sendto_serv_pflag_butone(PROTOCOL_SFL_SHORTAKILL, false, sptr, NULL, 84 srv, NULL, "AKILL", "%s %s % s %s %s :%s", argv[1], argv[2],85 argv[3], argv[4], argv[5], argv[6]);102 srv, NULL, "AKILL", "%s %s %d %s %d :%s", host, user, 103 expire, set_by, set_at, reason); 86 104 } else if (!strcasecmp(argv[0], "RAKILL")) { 87 105 /* arguments: host user */ … … 173 191 174 192 if (op == ACL_ADD) { 175 ap = create_acl(stage, ACL_DENY, mask, type );193 ap = create_acl(stage, ACL_DENY, mask, type, ACL_DEFAULT_RULE); 176 194 ap->conf = ACL_CONF_TEMP; 177 195 if (expire) … … 184 202 acl_force_check(ap->stage, ap, srv->name, false); 185 203 } else if (op == ACL_DEL) { 186 if ((ap = find_acl(stage, mask, type, NULL, info)))204 if ((ap = find_acl(stage, ACL_DENY, mask, type, ACL_DEFAULT_RULE, NULL, info))) 187 205 destroy_acl(ap); 188 206 } -
branches/ithildin-scons/modules/ircd/commands/die.c
r598 r786 56 56 } 57 57 while ((cp = LIST_FIRST(ircd.connections.servers)) != NULL) 58 destroy_server(cp->srv, smsg , NULL);58 destroy_server(cp->srv, smsg); 59 59 60 60 /* mark the process for shutdown. this won't actually kill the process, … … 62 62 exit_process(NULL, NULL); 63 63 64 return IRCD_C LOSEDCONN; /* and nothing else matters! */64 return IRCD_CONNECTION_CLOSED; /* and nothing else matters! */ 65 65 } 66 66 -
branches/ithildin-scons/modules/ircd/commands/error.c
r601 r786 24 24 sendto_flag(ircd.sflag.ops, "ERROR :from %s -- %s", srv->name, argv[1]); 25 25 /* ERROR means destroy the connection. :) */ 26 destroy_server(srv, argv[1] , srv);27 return IRCD_C LOSEDCONN;26 destroy_server(srv, argv[1]); 27 return IRCD_CONNECTION_CLOSED; 28 28 } 29 29 /* vi:set ts=8 sts=4 sw=4 tw=76 et: */ -
branches/ithildin-scons/modules/ircd/commands/info.c
r579 r786 34 34 CMSG("371", ":%s"); 35 35 #define RPL_INFOSTART 373 36 CMSG("373", ": Server INFO");36 CMSG("373", ":%s Server INFO"); 37 37 #define RPL_ENDOFINFO 374 38 38 CMSG("374", ":End of /INFO list."); … … 59 59 int i, lines = 2; 60 60 61 sendto_one(cli, RPL_FMT(cli, RPL_INFOSTART) );61 sendto_one(cli, RPL_FMT(cli, RPL_INFOSTART), ircd.me->name); 62 62 if (info_text_copying != NULL) { 63 63 for (i = 0;info_text_copying[i] != NULL;i++) -
branches/ithildin-scons/modules/ircd/commands/join.c
r679 r786 106 106 fargv[1] = clp->chan->name; 107 107 switch ((i = command_exec_client(2, fargv, cli))) { 108 case IRCD_P ARSESTOP:109 case IRCD_C LOSEDCONN:108 case IRCD_PROTOCOL_CHANGED: 109 case IRCD_CONNECTION_CLOSED: 110 110 return i; 111 111 } … … 144 144 sendto_channel_local(chan, cli, NULL, "JOIN", NULL); 145 145 if (new) 146 sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, true, sptr, cli,NULL,147 NULL, "SJOIN", "%d %s + :%s%s", chan->created, chan->name,148 chan mode_getprefixes(chan, cli), cli->nick);146 sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, true, sptr, NULL, 147 cli->server, NULL, "SJOIN", "%d %s + :%s%s", chan->created, 148 chan->name, chanmode_getprefixes(chan, cli), cli->nick); 149 149 else 150 150 sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, true, sptr, cli, -
branches/ithildin-scons/modules/ircd/commands/kill.c
r579 r786 135 135 destroy_client(cp, msg); 136 136 if (cp == cli) 137 return IRCD_C LOSEDCONN; /* suicide kills end here. */137 return IRCD_CONNECTION_CLOSED; /* suicide kills end here. */ 138 138 139 139 if (++count == KILL_MAX) { -
branches/ithildin-scons/modules/ircd/commands/mode.c
r613 r786 89 89 &argv[2], 1); 90 90 } else { 91 return channel_mode(cli, NULL, chan, 0, argc - 2, &argv[2], 1); 91 return channel_mode(cli, NULL, chan, chan->created, argc - 2, 92 &argv[2], 1); 92 93 } 93 94 } else if ((cp = find_client(argv[1])) != NULL) { … … 244 245 (cli != NULL ? cli_server_uplink(cli) : srv), "MODE", \ 245 246 "%s %s", result, rbuf); \ 247 sendto_serv_pflag_butone(PROTOCOL_SFL_TSMODE, false, sptr, cli, \ 248 srv, chan->name, "MODE", "%s%s %d", result, rbuf, \ 249 chan->created); \ 246 250 r = result + 1; \ 247 251 rblen = 0; \ … … 251 255 } 252 256 /* this is a lot like my mode changer from bahamut 1.x. hopefully it'll be a 253 * bit cleaner/more readable, though l. Oh, and we now do the logic of ts257 * bit cleaner/more readable, though. Oh, and we now do the logic of ts 254 258 * changes completely in this function. lovely. argc is the count only of the 255 259 * mode changes and any arguments, and argv[0] is the mode changes if argc is … … 271 275 char rbuf[RBUF_SIZE], *rb = rbuf; 272 276 int rblen = 0; 273 int changeok = 1; 274 int keepours = 1; 277 bool changeok = true, keepours = true; 275 278 276 279 if (cli != NULL && MYCLIENT(cli) && argc == 0) { … … 298 301 this. */ 299 302 300 /* check timestamp. we only accept modes if ts is <= to ours. if ts is 301 * less than ours, blast away our modes (all of them!). if ts is greater, 302 * dump any mode changes. this should really only apply at synchronization 303 * time, so we don't bother sending back an 'unset' if we dump their 304 * changes, as we assume they'll get the new ts soon anyhow. */ 305 if ((cli && !MYCLIENT(cli)) || srv) { 306 if (ts > chan->created) 307 changeok = 0; /* no changes! */ 308 else if (ts < chan->created) 309 keepours = 0; 303 /* 304 * Check timestamp. From servers which do not have the TS flag in their 305 * protocol we ACCEPT the changes and set the channel's TS to 0 (this is 306 * a bad hack to support older servers, not reasonable behavior). 307 * In the case where TS is properly supported from the sending server we 308 * only accept modes if ts is <= to our own. 309 * 310 * If the sender's TS for the channel is LESS than ours we remove every 311 * mode we have set on the channel, treating them all as invalid. This 312 * case should only *ever* occur during synchronization. We do not send 313 * the mode changes down in the opposite direction because we will send 314 * this command, with the correct TS, down the wire and all other TS 315 * servers will do the same thing. 316 * 317 * Similarly if we ignore their changes (ts > ours) we simply return, 318 * believing that a TS server will properly remove its modes. 319 * 320 * This is perhaps an overly trusting maneuever and, should this become 321 * an issue, the code #if 0'd out below should suffice to reverse any 322 * changes we got. :) 323 */ 324 325 if ((cli != NULL && !MYCLIENT(cli)) || (srv != NULL && srv != ircd.me)) { 326 /* We need the uplink for either the server or client in order to 327 * verify flags. */ 328 server_t *sp = (srv != NULL ? srv_server_uplink(srv) : cli_server_uplink(cli)); 329 330 if (!SERVER_SUPPORTS(sp, PROTOCOL_SFL_TS)) { 331 /* server does not have TS support, set ts to 0, but we do not 332 * remove our own modes (because we believe the server will 333 * accept our modes as stupidly as we accepted theirs... */ 334 if (srv != NULL && !SERVER_MASTER(srv)) { 335 log_debug("server %s has no TS support, setting TS for %s to 0!", 336 sp->name, chan->name); 337 ts = 0; 338 chan->created = 0; /* normally set when we reject our modes, but 339 we don't reject our modes in this case.. */ 340 } else 341 /* For master servers without TS protocol support just 342 * default to giving them what we think is the right TS. 343 * Why do this? Because it fits in with the whole 'master' 344 * concept. We're going to take these modes no matter what. 345 * Why break TS over it? */ 346 ts = chan->created; 347 } else { 348 if (ts > chan->created) 349 changeok = false; /* no changes! */ 350 else if (ts < chan->created) 351 keepours = false; 352 } 310 353 } 311 354 312 355 if (!changeok) { 356 log_debug("rejecting changes to channel %s (ours=%d, theirs=%d", 357 chan->name, chan->created, ts); 313 358 #if 0 314 359 /* invert their modes and send them right back. */ … … 344 389 /* this is a rather complex case, we basically have to wade through 345 390 * our modes and remove them as we go. First we remove channel 346 * modes, then user prefixes. blech, */ 391 * modes, then user prefixes. 392 * 393 * NB: We send reverted modes to local clients and non-ts servers 394 * only. Servers which are TS will get the updated TS and revert 395 * their modes accordingly on their own. This helps to reduce spam 396 * from changes of this nature. */ 347 397 unsigned char *s; 348 398 int cnt = 0; … … 351 401 r = result + 1; 352 402 rblen = 0; 403 404 log_debug("reverting our modes for channel %s (ours=%d, theirs=%d", 405 chan->name, chan->created, ts); 406 chan->created = ts; 353 407 354 408 s = ircd.cmodes.avail; -
branches/ithildin-scons/modules/ircd/commands/motd.c
r579 r786 37 37 /* numerics .. */ 38 38 #define RPL_MOTD 372 39 CMSG("372", ": %s");39 CMSG("372", ":- %s"); 40 40 #define RPL_MOTDSTART 375 41 41 CMSG("375", ":- %s Message of the Day - "); -
branches/ithildin-scons/modules/ircd/commands/nick.c
r593 r786 106 106 sendto_one(cli, RPL_FMT(cli, changeok), argv[1]); 107 107 else if (changeok < 0) { 108 strcpy(cli->nick, argv[1]); 109 /* add the client to the hash immediately to prevent collisions. */ 110 hash_insert(ircd.hashes.client, cli); 108 client_change_nick(cli, argv[1]); 111 109 /* if the username has been filled in then assume the USER command 112 110 * was called as well. */ … … 158 156 * a channel, sendto_common_channels ensures they'll get the message */ 159 157 sendto_common_channels(cli, NULL, "NICK", ":%s", argv[1]); 160 sendto_serv_butone(sptr, cli, NULL, NULL, "NICK", "%s :%d", argv[1],161 cli->ts);158 sendto_serv_butone(sptr, cli, NULL, NULL, "NICK", "%s :%d", 159 argv[1], cli->ts); 162 160 client_change_nick(cli, argv[1]); 163 161 … … 289 287 check_collision(client_t *known, client_t *unknown, bool new) { 290 288 289 /* This condition is extremely incorrect for what should be obvious 290 * reasons. */ 291 assert(known != unknown); 292 291 293 /* known is the only one which might be a local connection. if it is on 292 294 * our server and is unregistered then drop it no matter what. */ -
branches/ithildin-scons/modules/ircd/commands/oper.c
r579 r786 23 23 MODULE_LOADER(oper) { 24 24 25 add_xinfo_handler(xinfo_oper_func, "OPERATORS", 0, NULL,25 add_xinfo_handler(xinfo_oper_func, "OPERATORS", 0, 26 26 "Provides information about server operators"); 27 27 -
branches/ithildin-scons/modules/ircd/commands/pass.c
r577 r786 17 17 */ 18 18 19 static void copy_in_pass(connection_t *, char *); 20 19 21 CLIENT_COMMAND(pass, 1, 1, COMMAND_FL_UNREGISTERED) { 22 20 23 /* just copy the pass in */ 21 strncpy(cli->conn->pass, argv[1], PASSWDLEN); 22 24 copy_in_pass(cli->conn, argv[1]); 23 25 return COMMAND_WEIGHT_NONE; 24 26 } 25 27 26 28 SERVER_COMMAND(pass, 1, 1, COMMAND_FL_UNREGISTERED) { 29 27 30 /* just copy the pass in */ 28 strncpy(srv->conn->pass, argv[1], PASSWDLEN); 29 31 copy_in_pass(srv->conn, argv[1]); 30 32 return 0; 31 33 } 34 35 static void copy_in_pass(connection_t *conn, char *pass) { 36 37 /* Hack to support CGI IRC, which sends the 'real hostname' as the client 38 * password. What? Let's use HOSTLEN I guess! */ 39 if (conn->pass != NULL) 40 free(conn->pass); /* dump whatever was there before.. */ 41 conn->pass = strdup(pass); 42 } 43 32 44 /* vi:set ts=8 sts=4 sw=4 tw=76 et: */ -
branches/ithildin-scons/modules/ircd/commands/quit.c
r579 r786 37 37 38 38 if (MYCLIENT(cli)) { 39 snprintf(fmsg, TOPICLEN, MSG_FMT(cli, quit_format), msg); 40 fmsg[TOPICLEN] = '\0'; 41 39 42 /* We check to see if their message would be moderated in any channels 40 43 * they are in. If this is the case they are parted from the channels 41 44 * before the quit is sent. */ 42 if (!CLIENT_MASTER(cli) && msg != NULL) {45 if (!CLIENT_MASTER(cli) && *fmsg != '\0') { 43 46 clp = LIST_FIRST(&cli->chans); 44 47 while (clp != NULL) { 45 48 clp2 = LIST_NEXT(clp, lpcli); 46 49 47 if (can_can_send_channel(cli, clp->chan, msg) >= 0) {50 if (can_can_send_channel(cli, clp->chan, fmsg) >= 0) { 48 51 sendto_channel_local(clp->chan, cli, NULL, "PART", NULL); 49 52 sendto_serv_butone(sptr, cli, NULL, clp->chan->name, … … 55 58 } 56 59 57 /* if it's our client, the connection will be closed. we check here 58 * because we can't after a destroy_client() */ 59 snprintf(fmsg, TOPICLEN, MSG_FMT(cli, quit_format), msg); 60 fmsg[TOPICLEN] = '\0'; 60 /* Be sure to return appropriately for our local clients */ 61 61 destroy_client(cli, fmsg); 62 return IRCD_CLOSEDCONN; 62 return IRCD_CONNECTION_CLOSED; 63 } else { 64 destroy_client(cli, msg); 65 return COMMAND_WEIGHT_NONE; 63 66 } 64 destroy_client(cli, msg);65 return COMMAND_WEIGHT_NONE;66 67 } 67 68 -
branches/ithildin-scons/modules/ircd/commands/rehash.c
r579 r786 60 60 /* it's for us. */ 61 61 sendto_one(cli, RPL_FMT(cli, RPL_REHASHING), me.conf_file); 62 sendto_flag(ircd.sflag.ops, "%s is rehashing the server .", cli->nick);62 sendto_flag(ircd.sflag.ops, "%s is rehashing the server configuration.", cli->nick); 63 63 log_notice("%s!%s@%s rehashed the server", cli->nick, cli->user, 64 64 cli->host); -
branches/ithildin-scons/modules/ircd/commands/server.c
r624 r786 53 53 if (clp == NULL) { 54 54 /* no access for this server */ 55 destroy_server(srv, "no access" , NULL);56 return IRCD_C LOSEDCONN;55 destroy_server(srv, "no access"); 56 return IRCD_CONNECTION_CLOSED; 57 57 } 58 58 … … 66 66 ":Link %s cancelled, server %s already exists", 67 67 srv->conn->host, argv[1]); 68 destroy_server(srv, "Server Exists" , NULL);69 return IRCD_C LOSEDCONN;68 destroy_server(srv, "Server Exists"); 69 return IRCD_CONNECTION_CLOSED; 70 70 } 71 71 … … 77 77 } 78 78 if (servers > 1 && !SERVER_HUB((ircd.me))) { 79 destroy_server(srv, "I'm a leaf, not a hub!" , NULL);80 return IRCD_C LOSEDCONN;79 destroy_server(srv, "I'm a leaf, not a hub!"); 80 return IRCD_CONNECTION_CLOSED; 81 81 } 82 82 … … 96 96 if (SOCKET_SSL(srv->conn->sock)) { 97 97 if (!server_ssl_verify(srv)) { 98 destroy_server(srv, "no access" , NULL);99 return IRCD_C LOSEDCONN;98 destroy_server(srv, "no access"); 99 return IRCD_CONNECTION_CLOSED; 100 100 } 101 101 } else … … 107 107 s = conf_find_entry("address", clp, 1); 108 108 if (s == NULL || strcmp(s, ip)) { 109 destroy_server(srv, "no access" , NULL);110 return IRCD_C LOSEDCONN;109 destroy_server(srv, "no access"); 110 return IRCD_CONNECTION_CLOSED; 111 111 } 112 112 113 113 /* now check passwords. */ 114 114 if ((pass = conf_find_entry("theirpass", clp, 1)) == NULL) { 115 destroy_server(srv, "no access" , NULL);116 return IRCD_C LOSEDCONN; /* passwordless servers are a bad115 destroy_server(srv, "no access"); 116 return IRCD_CONNECTION_CLOSED; /* passwordless servers are a bad 117 117 idea! */ 118 118 } 119 119 120 if (s trcmp(pass, srv->conn->pass)) {120 if (srv->conn->pass == NULL || strcmp(pass, srv->conn->pass)) { 121 121 destroy_connection(srv->conn, "password mismatch"); 122 return IRCD_C LOSEDCONN; /* password mismatch */122 return IRCD_CONNECTION_CLOSED; /* password mismatch */ 123 123 } 124 124 } … … 152 152 sendto_serv_butone(srv, NULL, ircd.me, NULL, "GNOTICE", 153 153 ":Non-Hub link %s introduced %s.", srv->name, argv[1]); 154 destroy_server(srv, "Too many servers." , NULL);155 return IRCD_C LOSEDCONN;154 destroy_server(srv, "Too many servers."); 155 return IRCD_CONNECTION_CLOSED; 156 156 } 157 157 } … … 193 193 else { 194 194 destroy_client(cli, "no access"); 195 return IRCD_C LOSEDCONN;195 return IRCD_CONNECTION_CLOSED; 196 196 } 197 197 … … 200 200 (pp = find_protocol(s)) == NULL) { 201 201 destroy_client(cli, "no access"); 202 return IRCD_C LOSEDCONN;202 return IRCD_CONNECTION_CLOSED; 203 203 } 204 204 … … 216 216 cp->proto->setup(cp); 217 217 if ((ret = s_server_cmd(NULL, argc, argv, cp->srv)) != 0) 218 return ret; /* Give them whatever s_server_cmd gave, it 219 will always return 0 on success, anything220 else is an error. */ 221 222 return IRCD_P ARSESTOP; /* make sure they halt immediately. */218 return ret; /* Give them whatever s_server_cmd gave, it will always 219 return 0 on success, anything else is an error. */ 220 221 /* Inform them that the protocol has been changed. */ 222 return IRCD_PROTOCOL_CHANGED; 223 223 } 224 224 -
branches/ithildin-scons/modules/ircd/commands/sjoin.c
r586 r786 39 39 add_to_channel(cli, chan, true); 40 40 sendto_channel_local(chan, cli, NULL, "JOIN", NULL); 41 sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, true, sptr, cli, NULL, NULL,42 "SJOIN", "%d %s", chan->created, chan->name);43 sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, false, sptr, cli, NULL, NULL,44 "JOIN", "%s", chan->name);41 sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, true, cli->server, cli, NULL, 42 NULL, "SJOIN", "%d %s", chan->created, chan->name); 43 sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, false, cli->server, cli, NULL, 44 NULL, "JOIN", "%s", chan->name); 45 45 46 46 return COMMAND_WEIGHT_NONE; … … 55 55 SERVER_COMMAND(sjoin, 4, 5, 0) { 56 56 channel_t *chan; 57 char * joiners = argv[argc - 1], *prefix;58 char * s;57 char *client, *prefix; 58 char *buf = argv[argc - 1]; 59 59 char realjoiners[512]; 60 60 client_t *cp; 61 61 time_t ts = str_conv_int(argv[1], 0); 62 int changeok = 1;62 bool changeok = true; 63 63 int i; 64 64 int mset = 0; … … 68 68 69 69 mlen = 0; 70 /* make sure to set this incase we never actually touch the modes below, 71 * this prevents us from sending out goofy SJOIn data */ 72 *modes = *modebuf = '\0'; 70 73 chan = find_channel(argv[2]); 71 74 … … 75 78 chan->created = ts; 76 79 } 80 81 /* Check TS before running channel_mode (which will reset TS in a 82 * variety of conditions). All we need to know is whether or not to 83 * accept ops down below, channel_mode does the rest of the logic... */ 84 if (ts > chan->created) 85 changeok = false; 86 77 87 /* handle mode changes. we basically dump off the stuff to the mode 78 88 * command handler. We subtract four from argc (argv[0] is cmd, … … 81 91 channel_mode(NULL, srv, chan, ts, (argc - 4), argv + 3, 0); 82 92 83 /* check for ts changes. */84 /* we actually accept the older ts here. if their ts is newer than85 * ours we will quite likely have to undo changes and stuff.86 * basically, we shouldn't trust any changes made to a channel whose ts87 * isn't the same or lower than ours. */88 if (ts > chan->created)89 changeok = 0;90 else if (ts < chan->created)91 chan->created = ts;92 /* otherwise everything is the same and copacetic */93 94 93 /* now parse the list of joiners, and propogate our SJOIN out to others */ 95 94 *realjoiners = '\0'; 96 while (*joiners) { 97 s = strchr(joiners, ' '); 98 if (s != NULL) 99 *s = '\0'; 95 while ((client = strsep(&buf, " ")) != NULL) { 96 if (*client == '\0') 97 continue; 100 98 101 99 /* handle prefix stuff. first find out where the prefixes end and the 102 100 * nick begins, prefixes can't be normal nick characters for obvious 103 101 * reasons, so use this fact.. */ 104 prefix = joiners;105 while (* joiners && !istr_okay(ircd.maps.nick, joiners))106 joiners++;102 prefix = client; 103 while (*client && !istr_okay(ircd.maps.nick, client)) 104 client++; 107 105 /* now we know what our prefixes are.. */ 108 106 109 cp = find_client( joiners);107 cp = find_client(client); 110 108 if (cp != NULL) { 111 109 add_to_channel(cp, chan, true); … … 114 112 strcat(realjoiners, prefix); 115 113 else /* otherwise, just the nick! */ 116 strcat(realjoiners, joiners);114 strcat(realjoiners, client); 117 115 strcat(realjoiners, " "); 118 116 … … 120 118 * channel. */ 121 119 sendto_channel_local(chan, cp, NULL, "JOIN", NULL); 122 sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, false, s ptr, cp,120 sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, false, srv, cp, 123 121 NULL, chan->name, "JOIN", NULL); 124 122 if (changeok) { 125 while (prefix != joiners) { 126 chanmode_setprefix(*prefix, chan, joiners, &i); 123 while (prefix != client) { 124 chanmode_setprefix(*prefix, chan, client, &i); 125 /* XXX: hardcoded prefixes :( */ 127 126 if (*prefix == '@') 128 127 modes[mset++] = 'o'; … … 132 131 continue; 133 132 modes[mset] = '\0'; 134 mlen += sprintf(&modebuf[mlen], " %s", joiners);133 mlen += sprintf(&modebuf[mlen], " %s", client); 135 134 prefix++; 136 135 } 137 if (mset == 6) { /* if we've got sixmodes to set */136 if (mset >= 6) { /* if we've got six (or more) modes to set */ 138 137 /* okay... assume that non SJOIN servers also don't use 139 138 * TSMODE.. */ 140 sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, false, s ptr,141 NULL, srv, chan->name, "MODE", " %s%s %d", modes,139 sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, false, srv, 140 NULL, srv, chan->name, "MODE", "+%s%s %d", modes, 142 141 modebuf, chan->created); 143 142 sendto_channel_local(chan, NULL, srv, "MODE", "+%s%s", … … 148 147 } 149 148 } else 150 log_warn("got SJOIN for unknown nick %s", joiners); 151 152 if (s != NULL) 153 joiners = s + 1; 154 else /* if there's nothing left, break */ 155 break; 149 log_warn("got SJOIN for unknown nick %s on %s", client, 150 chan->name); 156 151 } 157 152 158 153 /* if we have leftover modes, send them first */ 159 154 if (changeok && mset) { 160 sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, false, s ptr,161 NULL, srv, chan->name, "MODE", " %s%s %d", modes,155 sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, false, srv, 156 NULL, srv, chan->name, "MODE", "+%s%s %d", modes, 162 157 modebuf, chan->created); 163 158 sendto_channel_local(chan, NULL, srv, "MODE", "+%s%s", … … 173 168 mlen += sprintf(&modebuf[mlen], " %s", argv[i++]); 174 169 175 sendto_serv_butone(srv, NULL, srv, NULL, "SJOIN", "%d %s %s%s :%s", 176 chan->created, chan->name, argv[3], modebuf, realjoiners); 170 sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, true, srv, NULL, srv, NULL, 171 "SJOIN", "%d %s %s%s :%s", chan->created, chan->name, argv[3], 172 modebuf, realjoiners); 177 173 178 174 return 1; -
branches/ithildin-scons/modules/ircd/commands/squit.c
r744 r786 55 55 /* preserve this old behavior. ;) I find it amusing. */ 56 56 destroy_client(cli, argv[2]); 57 return IRCD_C LOSEDCONN;57 return IRCD_CONNECTION_CLOSED; 58 58 } 59 59 … … 67 67 if (MYSERVER(sp)) { 68 68 if (!MYCLIENT(cli)) { 69 sendto_flag(SFLAG("GNOTICE"), "Remote SQUIT %s from %s (%s)",70 sp->name, cli->nick, msg);71 69 sendto_serv_butone(NULL, NULL, ircd.me, NULL, "GNOTICE", 72 70 ":Remote SQUIT %s from %s (%s)", sp->name, cli->nick, 73 71 msg); 72 sendto_flag(SFLAG("GNOTICE"), "Remote SQUIT %s from %s (%s)", 73 sp->name, cli->nick, msg); 74 74 } 75 destroy_server(sp, msg, NULL); 76 } else { 77 /* Otherwise this is not a verification of a server quit, just a 78 * request to do so. In this case we pass the request towards the 79 * server and wait for confirmation. */ 80 sendto_serv_from(sp, cli, NULL, sp->name, "SQUIT", msg); 81 } 75 } else 76 /* We are an interrim along the road, ensure the final 77 * destination gets the message. */ 78 sendto_serv_from(sp, cli, NULL, sp->name, "SQUIT", ":%s", msg); 79 80 destroy_server(sp, msg); 82 81 } else 83 82 sendto_one(cli, RPL_FMT(cli, ERR_NOSUCHSERVER), argv[1]); … … 93 92 * parameters we lovingly drop the sender on his head. */ 94 93 if (argc < 2) { 95 destroy_server(srv, msg , NULL);96 return IRCD_C LOSEDCONN;94 destroy_server(srv, msg); 95 return IRCD_CONNECTION_CLOSED; 97 96 } 98 97 99 98 if ((sp = find_server(argv[1])) == NULL) { 100 log_ warn("received SQUIT for unknown server %s from %s", argv[1],99 log_debug("received SQUIT for unknown server %s from %s", argv[1], 101 100 srv->name); 102 101 return 0; … … 115 114 sendto_serv_butone(NULL, NULL, ircd.me, NULL, "GNOTICE", 116 115 ":Remote SQUIT %s from %s (%s)", sp->name, srv->name, msg); 117 destroy_server(sp, msg, NULL); 118 if (sp == srv) 119 /* be sure to let them know that the connection will be closed */ 120 return IRCD_CLOSEDCONN; 121 } else { 122 /* Otherwise we need to see if this is coming from the direction of the 123 * server, or from somewhere else. If it's coming from somewhere else, 124 * it's a request to SQUIT the server, if it's coming from the 125 * direction of the server it means the server *did* quit */ 126 if (srv_server_uplink(srv) != srv_server_uplink(sp)) 127 /* a request to SQUIT ... */ 128 sendto_serv_from(sp, NULL, srv, sp->name, "SQUIT", msg); 129 else 130 destroy_server(sp, msg, srv); 131 } 116 } else 117 /* Otherwise we must continue to pass the SQUIT towards its final 118 * destination, as well as destroying the server. See the 119 * commentary in destroy_server for an explanation of what messages 120 * this sends. */ 121 sendto_serv_from(sp, NULL, srv, sp->name, "SQUIT", ":%s", msg); 132 122 133 return 0; 123 destroy_server(sp, msg); 124 125 if (sp == srv) 126 /* If the command came from the server we're killing, be sure to 127 * send back a 'CLOSEDCONN' so we stop parsing the buffer. */ 128 return IRCD_CONNECTION_CLOSED; 129 else 130 return 0; 134 131 } 135 132 -
branches/ithildin-scons/modules/ircd/commands/svinfo.c
r598 r786 41 41 "Link %s dropped, wrong TS protocol version (%s,%s)", 42 42 sptr->conn->host, argv[1], argv[2]); 43 destroy_server(sptr, "Incompatible TS version" , NULL);44 return IRCD_C LOSEDCONN;43 destroy_server(sptr, "Incompatible TS version"); 44 return IRCD_CONNECTION_CLOSED; 45 45 } 46 46 … … 57 57 ":Link %s dropped, excessive TS delta (delta=%d)", 58 58 sptr->conn->host, delta); 59 destroy_server(sptr, "Excessive TS delta" , NULL);60 return IRCD_C LOSEDCONN;59 destroy_server(sptr, "Excessive TS delta"); 60 return IRCD_CONNECTION_CLOSED; 61 61 } 62 62 -
branches/ithildin-scons/modules/ircd/commands/svsmode.c
r586 r786 49 49 channel_t *chan; 50 50 client_t *cp; 51 time_t ts; 52 char *s; 53 int oarg = 2; 54 int plus = 1; 55 uint64_t oldmode; 56 char result[64]; 51 char **myargv; 52 int myargc; 57 53 58 54 if (check_channame(argv[1]) && (chan = find_channel(argv[1])) != NULL) { … … 60 56 channel_mode(cli, srv, chan, chan->created, argc - 2, argv + 2, 1); 61 57 } else if ((cp = find_client(argv[1])) != NULL) { 62 /* this is less simple. svsmode sends +d <x> to set 'services id' on 63 * people, and we'll handle that here. XXX: this is a hack, and we 64 * should call user_mode() but we don't. :( */ 65 if (isdigit(*argv[oarg])) 66 ts = str_conv_int(argv[oarg++], 0); 67 else 68 ts = 0; 58 /* Services setting "client modes." There's also this sort of like, 59 * stupid hack where they send "+d <ts>" which is a 'servicesid' 60 * used to track clients on the network. We one-off support this 61 * and treat everything else as a real client mode. */ 69 62 70 if (ts && cp->ts != ts) 71 return; /* not the same client */ 72 73 oldmode = cp->modes; 74 s = argv[oarg++]; 75 while (*s) { 76 switch (*s) { 77 case '+': 78 plus = 1; 79 break; 80 case '-': 81 plus = 0; 82 break; 83 case 'd': 84 /* special case to set 'services id' */ 85 if (oarg < argc) 86 SVSID(cp) = str_conv_int(argv[oarg++], 0); 87 break; 88 default: 89 if (plus) 90 usermode_set(*s, NULL, cp, NULL, NULL); 91 else 92 usermode_unset(*s, NULL, cp, NULL, NULL); 93 break; 94 } 95 s++; 63 /* They may send a ts along first. We must skip this. */ 64 if (isdigit(*argv[2])) { 65 myargv = argv + 3; /* skip to argv[3] */ 66 myargc = argc - 3; 67 } else { 68 myargv = argv + 2; 69 myargc = argc - 2; 96 70 } 97 71 98 if (MYCLIENT(cp)) { 99 usermode_diff(oldmode, cp->modes, result, 0); 100 if (*result != '\0') { 101 if (cli != NULL) 102 sendto_one_from(cp, cli, NULL, "MODE", ":%s", result); 103 else 104 sendto_one_from(cp, cp, NULL, "MODE", ":%s", result); 105 } 72 if (myargc == 2 && (!strcmp(myargv[0], "+d") || 73 !strcmp(myargv[0], "+T"))) { 74 if (!strcmp(argv[0], "+d")) 75 /* this is so dumb */ 76 SVSID(cp) = str_conv_int(myargv[1], 0); 77 78 sendto_serv_butone(sptr, cli, srv, cp->nick, "SVSMODE", 79 "%s %s", myargv[0], myargv[1]); 80 return; 106 81 } 107 if (argc > 3) 108 sendto_serv_butone(sptr, cli, srv, cp->nick, "SVSMODE", 109 "%d %s %s", ts, argv[2], argv[3]); 110 else 111 sendto_serv_butone(sptr, cli, srv, cp->nick, "SVSMODE", 112 "%d %s", ts, argv[2]); 82 if (MYCLIENT(cp)) 83 /* Is this our client? If so do the usermode thing. Otherwise 84 * just pass along the command, we expect a MODE back when it is 85 * processed by the user's server. */ 86 user_mode(NULL, cp, myargc, myargv, true); 87 88 sendto_serv_butone(sptr, cli, srv, cp->nick, "SVSMODE", "%s", 89 myargv[0]); 113 90 } 114 91 } -
branches/ithildin-scons/modules/ircd/commands/topic.c
r613 r786 37 37 add_isupport("TOPICLEN", ISUPPORT_FL_INT, (char *)&i64); 38 38 39 add_hook(ircd.events.channel_add, topic_channel_add_hook); 39 /* stuff this hook in nice and early so we are always in front of NAMES. 40 * THis should be harmless, at least for now. Some clients seem to 41 * depend on speculative wording in RFC1459 that says RPL_TOPIC and 42 * RPL_NAMREPLY are sent. They believe this implies that RPL_TOPIC must 43 * be first. Most clients do not break when this isn't the case, but a 44 * few poorly written ones do. */ 45 add_hook_before(ircd.events.channel_add, topic_channel_add_hook, NULL); 46 40 47 add_hook(ircd.events.server_establish, topic_server_establish_hook); 41 48 -
branches/ithildin-scons/modules/ircd/commands/version.c
r579 r786 40 40 ircd.vercomment); 41 41 send_isupport(cli); 42 if (me.debug) 43 sendto_one(cli, "NOTICE", ":This server is running in debug mode. " 44 "Some traffic may be logged."); 42 45 43 46 return COMMAND_WEIGHT_MEDIUM; -
branches/ithildin-scons/modules/ircd/commands/watch.c
r579 r786 200 200 int sblen = 0; 201 201 202 /* XXX: static sized buffer-fuck. this must be cleaned up */ 202 203 wp = find_watch(cli->nick); 203 204 sendto_one(cli, RPL_FMT(cli, RPL_WATCHSTAT), cwp->count, 204 205 (wp != NULL ? wp->count : 0)); 205 206 LIST_FOREACH(wlp, &cwp->list, lpwtch) { 206 if (3 20 - sblen <= strlen(wlp->watch->nick)) {207 if (310 - sblen <= strlen(wlp->watch->nick)) { 207 208 /* send the list if it's getting full */ 208 209 sendto_one(cli, RPL_FMT(cli, RPL_WATCHLIST), sbuf); 209 210 sblen = 0; 210 211 } 211 sblen += snprintf(sbuf + sblen, 3 20 - sblen, "%s ",212 sblen += snprintf(sbuf + sblen, 310 - sblen, "%s ", 212 213 wlp->watch->nick); 213 214 } -
branches/ithildin-scons/modules/ircd/commands/whois.c
r579 r786 57 57 CLIENT_COMMAND(whois, 1, 2, 0) { 58 58 client_t *target; 59 char *nick = (argc > 2 ? argv[2] : argv[1]); 59 60 struct chanlink *clp; 60 61 #define WHOISBUFLEN 320 … … 67 68 return COMMAND_WEIGHT_HIGH; 68 69 69 if (argc > 2) 70 target = find_client(argv[2]); 71 else 72 target = find_client(argv[1]); 73 70 target = find_client(nick); 74 71 if (target == NULL) { 75 sendto_one(cli, RPL_FMT(cli, ERR_NOSUCHNICK), 76 (argc > 2 ? argv[2] : argv[1]));77 return COMMAND_WEIGHT_ NONE;72 sendto_one(cli, RPL_FMT(cli, ERR_NOSUCHNICK), nick); 73 sendto_one(cli, RPL_FMT(cli, RPL_ENDOFWHOIS), nick); 74 return COMMAND_WEIGHT_LOW; 78 75 } 79 76 … … 83 80 /* show them the real host if they can see it and this is either a local 84 81 * real client (conn != NULL) or orighost points somewhere different */ 85 if (CAN_SEE_REAL_HOST(cli, target)) { 86 if (target->conn != NULL) { 87 /* in this case show them the values we got from identd/dns */ 88 if (*target->conn->user == '\0' || *target->conn->user == '~') 89 sendto_one(cli, RPL_FMT(cli, RPL_WHOISACTUALLY), target->nick, 90 target->user, target->conn->host, target->ip); 91 else 92 sendto_one(cli, RPL_FMT(cli, RPL_WHOISACTUALLY), target->nick, 93 target->conn->user, target->conn->host, target->ip); 94 } else if (target->orighost != target->host) 95 sendto_one(cli, RPL_FMT(cli, RPL_WHOISACTUALLY), target->nick, 96 target->user, target->orighost, target->ip); 97 } 82 if (CAN_SEE_REAL_HOST(cli, target) && target->orighost != target->host) 83 sendto_one(cli, RPL_FMT(cli, RPL_WHOISACTUALLY), target->nick, 84 target->user, target->orighost, target->ip); 98 85 if (!CLIENT_MASTER(target) || MYCLIENT(target)) { 99 86 /* don't show channels that master clients are in unless this is a -
branches/ithildin-scons/modules/ircd/commands/whowas.c
r579 r786 54 54 if (target == NULL) { 55 55 sendto_one(cli, RPL_FMT(cli, ERR_WASNOSUCHNICK), argv[1]); 56 return COMMAND_WEIGHT_NONE; 56 sendto_one(cli, RPL_FMT(cli, RPL_ENDOFWHOWAS), argv[1]); 57 return COMMAND_WEIGHT_LOW; 57 58 } 58 59 -
branches/ithildin-scons/modules/ircd/commands/xinfo.c
r744 r786 30 30 MODULE_LOADER(xinfo) { 31 31 32 add_xinfo_handler(xinfo_class_handler, "CLASS", 0, NULL,32 add_xinfo_handler(xinfo_class_handler, "CLASS", 0, 33 33 "Provides information about server connection classes"); 34 add_xinfo_handler(xinfo_client_handler, "CLIENT", XINFO_HANDLER_OPER, NULL,34 add_xinfo_handler(xinfo_client_handler, "CLIENT", XINFO_HANDLER_OPER, 35 35 "Provices information about clients on this server"); 36 36 add_xinfo_handler(xinfo_connects_handler, "CONNECTS", XINFO_HANDLER_OPER, 37 NULL,"Shows information about server uplinks");38 add_xinfo_handler(xinfo_hash_handler, "HASH", XINFO_HANDLER_OPER, NULL,37 "Shows information about server uplinks"); 38 add_xinfo_handler(xinfo_hash_handler, "HASH", XINFO_HANDLER_OPER, 39 39 "Shows hash table statistics."); 40 add_xinfo_handler(xinfo_me_handler, "ME", XINFO_HANDLER_LOCAL, NULL,40 add_xinfo_handler(xinfo_me_handler, "ME", XINFO_HANDLER_LOCAL, 41 41 "Provides information about your connection statistics"); 42 42 add_xinfo_handler(xinfo_privilege_handler, "PRIVILEGE", 43 XINFO_HANDLER_LOCAL | XINFO_HANDLER_OPER, NULL,43 XINFO_HANDLER_LOCAL | XINFO_HANDLER_OPER, 44 44 "Provides information about available privileges"); 45 add_xinfo_handler(xinfo_server_handler, "SERVER", 0, NULL,45 add_xinfo_handler(xinfo_server_handler, "SERVER", 0, 46 46 "Provides information about this (or other) servers"); 47 add_xinfo_handler(xinfo_xinfo_handler, "XINFO", 0, NULL,47 add_xinfo_handler(xinfo_xinfo_handler, "XINFO", 0, 48 48 "Provides a list of available XINFO query-handlers"); 49 49 … … 136 136 return COMMAND_WEIGHT_LOW; /* silently ignore these */ 137 137 if ((xhp->flags & XINFO_HANDLER_OPER && !OPER(cli)) || 138 (xhp->flags & XINFO_HANDLER_PRIV && !BPRIV(cli, xhp->priv))) {138 !BPRIV(cli, xhp->priv)) { 139 139 sendto_one(cli, RPL_FMT(cli, ERR_NOPRIVILEGES)); 140 140 return COMMAND_WEIGHT_LOW; … … 182 182 client_t *cp; 183 183 char rpl[XINFO_LEN]; 184 char *user; 185 char ip[IPADDR_MAXLEN + 1]; 184 186 185 187 if (argc < 2) { … … 197 199 } 198 200 199 snprintf(rpl, XINFO_LEN, "%s!%s@%s[%s]", cp->nick, cp->user, cp->host, 200 cp->ip); 201 if (cp->conn != NULL) { 202 /* give them the connection info if we can... */ 203 if (*cp->conn->user == '\0' || *cp->conn->user == '~') 204 user = cp->user; /* this information is not valuable here */ 205 else 206 user = cp->conn->user; 207 if (cp->conn->sock != NULL) /* should never be NULL but.. */ 208 get_socket_address(isock_raddr(cp->conn->sock), ip, 209 IPADDR_MAXLEN + 1, NULL); 210 else 211 strcpy(ip, cp->ip); 212 snprintf(rpl, XINFO_LEN, "%s!%s@%s[%s]", cp->nick, user, 213 cp->conn->host, ip); 214 } else 215 snprintf(rpl, XINFO_LEN, "%s!%s@%s[%s]", cp->nick, cp->user, 216 cp->host, cp->ip); 201 217 sendto_one(cli, RPL_FMT(cli, RPL_XINFO), "ADDRESS", rpl); 202 218 snprintf(rpl, XINFO_LEN, "TS %d SIGNON %d IDLE %d", cp->ts, … … 425 441 continue; /* non-local */ 426 442 if ((xhp->flags & XINFO_HANDLER_OPER && !OPER(cli)) || 427 (xhp->flags & XINFO_HANDLER_PRIV && !BPRIV(cli, xhp->priv)))443 !BPRIV(cli, xhp->priv)) 428 444 continue; /* not privileged */ 429 445 -
branches/ithildin-scons/modules/ircd/conf.c
r744 r786 335 335 log_warn("could not enable SSL on %s/%d", addr, port); 336 336 destroy_socket(isp); 337 return; 337 338 } 338 339 #endif … … 505 506 /* update their flags, too. */ 506 507 server_set_flags(srv); 507 } 508 } 509 510 /* now check for autoconnects */ 508 } else 509 srv->conf = NULL; /* important to re-set this if we need to */ 510 } 511 512 /* Wipe out any existing auto-connect info.. */ 513 while (!LIST_EMPTY(ircd.lists.server_connects)) 514 destroy_server_connect(LIST_FIRST(ircd.lists.server_connects)); 515 516 /* And add new ones */ 511 517 cep = NULL; 512 518 while ((cep = conf_find_next("server", NULL, CONF_TYPE_LIST, cep, conf, 1)) -
branches/ithildin-scons/modules/ircd/connection.c
r744 r786 41 41 return; 42 42 } else if (c->srv != NULL) { 43 destroy_server(c->srv, reason , NULL);43 destroy_server(c->srv, reason); 44 44 return; 45 45 } 46 46 47 /* empty their sendq */ 48 while (STAILQ_FIRST(&c->sendq) != NULL) 49 sendq_pop(c); 50 /* if there is a reason, send them a message */ 51 if (reason != NULL && *reason != '\0') { 47 /* Try to send them an error message if we can. We assume someone has 48 * tried to flush their sendq or doesn't think we should, so if it's 49 * empty we send an error, otherwise we clean it off and don't bother 50 * trying to send since other sends have already failed (and we infer 51 * that this means the socket is not writeable) */ 52 if (STAILQ_EMPTY(&c->sendq) && reason != NULL && *reason != '\0') { 52 53 snprintf(msg, 512, "\r\nERROR :Closing Link: %s (%s)\r\n", 53 54 c->host, reason); 54 55 socket_write(c->sock, msg, strlen(msg)); 55 } 56 } else { 57 while (STAILQ_FIRST(&c->sendq) != NULL) 58 sendq_pop(c); 59 } 60 61 if (c->pass != NULL) 62 free(c->pass); 63 56 64 if (c->buf != NULL) 57 65 free(c->buf); … … 182 190 183 191 /* this is used to initialize the stage2 lookups. it is kept separate so that 184 * SSL acc pets can be done prior to the data sending. */192 * SSL accepts can be done prior to the data sending. */ 185 193 static void connection_init_lookups(connection_t *c) { 186 194 char msg[256]; … … 363 371 connection_t *c = (connection_t *)s->udata; 364 372 char msg[512]; 373 int ret; 365 374 366 375 #ifdef HAVE_OPENSSL … … 379 388 #endif 380 389 381 /* We have to assume that once c->proto->input() is called, 'c' is 382 * potentially no longer valid. We're the high end of the chain: 383 * socket read ready -> read data -> parse data -> execute command, the 384 * command execution could invalidate the client (and thus connection) so 385 * we take the easy road and read last because that way we don't touch 'c' 386 * anymore and so if it is invalidated by destruction, it's still safe. */ 390 /* 391 * Read first, then write, then check errors. If the read succeeds 392 * (does not return IRCD_CONNECTION_CLOSED) we should be ensured that 393 * the connection is still valid. 394 */ 395 396 if (SOCKET_READ(s)) { 397 ret = (int)c->proto->input(ep, data); 398 /* We do this in a while loop because we may end up doing more than 399 * one proto change (unlikely but the support for this is nearly 400 * free so...) */ 401 while (ret == IRCD_PROTOCOL_CHANGED) { 402 /* A protocol change implies two things to us: 403 * 1) We may need to resize the buffer for this protocol. We 404 * can only resize up, not down! In the down case we do the 405 * wrong thing and close the connection instead of looping a 406 * parser to clear the buffer. (XXX: worth fixing?) 407 * 2) If there is any data in the buffer we should call the new 408 * protocol's input function, protocol changes may leave 409 * lingering data which would otherwise generate socket events 410 * if we acted on it, so.. act on it here. */ 411 412 if (c->bufsize < c->proto->bufsize) { 413 /* We must resize the buffer... we can happily just use 414 * realloc here, since nothing should depend on the address 415 * of c->buf between input calls */ 416 c->buf = realloc(c->buf, c->proto->bufsize); 417 c->bufsize = c->proto->bufsize; 418 } 419 if (c->buflen > 0) 420 /* We pass NULL as the event parameter for the input 421 * function as a way of saying "this was forcefully called 422 * outisde the normal event mechanism". This is to tell the 423 * protocol handler that it should try to flush its current 424 * buffer even if there is no data from the socket. 425 * XXX: this is kind of a hack... */ 426 ret = (int)c->proto->input(NULL, data); 427 else 428 ret = 0; /* kill the loop :) */ 429 } 430 431 if (ret == IRCD_CONNECTION_CLOSED) 432 return NULL; /* nothing to do... */ 433 } 434 435 if (SOCKET_WRITE(s)) 436 /* Only flag that we are writeable. The writer hook takes care of 437 * doing buffered writes for us outside the construct of this loop. 438 * I thiml, potentially falsely, that it may be beneficial to batch 439 * writes and reads in this manner. */ 440 c->flags |= IRCD_CONNFL_WRITEABLE; 441 387 442 if (SOCKET_ERROR(s)) { 388 443 if (c->srv != NULL) { … … 400 455 return NULL; 401 456 } 402 if (SOCKET_WRITE(s))403 c->flags |= IRCD_CONNFL_WRITEABLE;404 if (SOCKET_READ(s))405 c->proto->input(ep, data);406 457 407 458 return NULL; -
branches/ithildin-scons/modules/ircd/connection.h
r579 r786 2 2 * connection.h: support structures/prototypes for connection.c 3 3 * 4 * Copyright 2002 the Ithildin Project.4 * Copyright 2002-2006 the Ithildin Project. 5 5 * See the COPYING file for more information on licensing and use. 6 6 * … … 8 8 */ 9 9 10 #ifndef IRCD_ SOCKET_H11 #define IRCD_ SOCKET_H10 #ifndef IRCD_CONNECTION_H 11 #define IRCD_CONNECTION_H 12 12 13 13 struct connection { 14 isocket_t *sock; /* our socket */15 client_t *cli; /* either a client or a server, should */16 server_t *srv; /* never be both! */17 char host[HOSTLEN + 1]; /* user and host data (as given by14 isocket_t *sock; /* our socket */ 15 client_t *cli; /* either a client or a server, should */ 16 server_t *srv; /* never be both! */ 17 char host[HOSTLEN + 1]; /* user and host data (as given by 18 18 identd/dns) */ 19 19 char user[USERLEN + 1]; 20 char pass[PASSWDLEN + 1]; /* password, after registration feel 21 free to use this as empty bufferspace */ 20 char *pass; /* password, if not NULL it must be 21 malloc'd memory. It will be 22 destroyed after client registration. */ 22 23 23 char *buf; /* temporary buffer pointer, possibly24 char *buf; /* temporary buffer pointer, possibly 24 25 used in many places */ 25 26 size_t buflen; /* length of data in the buffer */ 26 size_t bufsize; /* size of the temporary buffer. */ 27 size_t bufsize; /* size of the temporary buffer. */ 28 size_t bufresize; /* When non-0 a resize request for the 29 buffer. We do this in the socket 30 event hook, after reading has 31 completed. */ 27 32 28 class_t *cls; /* our connection class */29 protocol_t *proto; /* our current protocol */33 class_t *cls; /* our connection class */ 34 protocol_t *proto; /* our current protocol */ 30 35 message_set_t *mset; /* our message set, NULL for servers */ 31 36 32 time_t signon; /* time of connection (not registration) */33 time_t last; /* last update to this item */34 int flood;/* flood level (clients only) */37 time_t signon; /* time of connection (not registration) */ 38 time_t last; /* last update to this item */ 39 int flood; /* flood level (clients only) */ 35 40 36 41 struct { 37 int64_t sent; /* bytes sent */38 int64_t psent; /* "packets" sent */39 int64_t recv; /* bytes received */40 int64_t precv; /* "packets" received */42 int64_t sent; /* bytes sent */ 43 int64_t psent; /* "packets" sent */ 44 int64_t recv; /* bytes received */ 45 int64_t precv; /* "packets" received */ 41 46 } stats; 42 47 43 #define IRCD_CONNFL_DNS_PTR 0x144 #define IRCD_CONNFL_DNS_ADDR 0x248 #define IRCD_CONNFL_DNS_PTR 0x1 49 #define IRCD_CONNFL_DNS_ADDR 0x2 45 50 #define IRCD_CONNFL_DNS (IRCD_CONNFL_DNS_PTR | IRCD_CONNFL_DNS_ADDR) 46 #define IRCD_CONNFL_IDENT 0x447 #define IRCD_CONNFL_STAGE2 0x848 #define IRCD_CONN_DONE(x) \49 (((x)->flags & (IRCD_CONNFL_DNS | IRCD_CONNFL_IDENT)) == \51 #define IRCD_CONNFL_IDENT 0x4 52 #define IRCD_CONNFL_STAGE2 0x8 53 #define IRCD_CONN_DONE(x) \ 54 (((x)->flags & (IRCD_CONNFL_DNS | IRCD_CONNFL_IDENT)) == \ 50 55 (IRCD_CONNFL_DNS | IRCD_CONNFL_IDENT)) 51 #define IRCD_CONN_NEED_STAGE2(x) (!((x)->flags & IRCD_CONNFL_STAGE2))56 #define IRCD_CONN_NEED_STAGE2(x) (!((x)->flags & IRCD_CONNFL_STAGE2)) 52 57 53 58 #define IRCD_CONNFL_WRITEABLE 0x100 /* set if the socket is writeable */ … … 68 73 #endif 69 74 70 int flags;/* connection flags (DO NOT PUT75 int flags; /* connection flags (DO NOT PUT 71 76 CLIENT/SERVER FLAGS HERE) */ 72 77 73 int sendq_items; /* items on the send queue */74 STAILQ_HEAD(, sendq_item) sendq; /* and te queue itself */78 int sendq_items; /* items on the send queue */ 79 STAILQ_HEAD(, sendq_item) sendq;/* and te queue itself */ 75 80 LIST_ENTRY(connection) lp; 76 81 }; -
branches/ithildin-scons/modules/ircd/doc/conf.txt
r579 r786 66 66 reason "You are not authorized to use this server."; 67 67 68 // redirect: (optional) 69 // This specifies that a connection should be redirected to the 70 // specified server/port (server:port form). If the port is left off 71 // it is assumed to be the default port (typically 6667). This applies 72 // only to entries in stage 3. 73 // NB: redirect ACLs are always deny type. That is, the redirect message 74 // is provided and then the connection is closed. 75 redirect <some-irc-server:some-port>; 76 68 77 // skip-dns: (optional) 69 78 // This option can be used to skip doing a dns lookup on a connection. … … 111 120 // hostmask: addons/hostmask (optional) 112 121 // This masks all users in this connection class to the given hostname. 122 // The special mask "cgi:irc" enables support for the CGI:IRC web gateway 123 // to pass in the user's real hostname via the PASS command. If you set 124 // the hostmask to "cgi:irc" and a connection in the class either does not 125 // give a password or gives an invalid host the connection will be 126 // unmasked. 113 127 hostmask <some.host.name>; 114 128 -
branches/ithildin-scons/modules/ircd/ircd.c
r744 r786 18 18 IDSTRING(rcsid, "$Id$"); 19 19 20 MODULE_REGISTER( PACKAGE_VERSION);20 MODULE_REGISTER("1.0rc1"); 21 21 /* 22 22 @DEPENDENCIES@: dns ident … … 443 443 CMSG("004", "%s %s %s %s"); /* rpl_myinfo */ 444 444 CMSG("005", "%s :are available on this server."); /* rpl_isupport */ 445 CMSG("010", "%s %d :Please redirect your client to this server and " 446 "port."); /* rpl_redir */ 445 447 CMSG("263", ":Server load is temporarily too heavy, please wait a " 446 448 "while and try again."); /* rpl_loadtoohigh */ -
branches/ithildin-scons/modules/ircd/protocol.c
r744 r786 21 21 static int protocol_packet_parse(connection_t *cp, char *end); 22 22 23 /* Return codes from protocol_packet_parse */ 24 #define PROTOCOL_PARSE_PROTOSET 1 25 #define PROTOCOL_PARSE_1459STOP 2 26 23 27 #define DEFAULT_BUFFER_SIZE 512 24 28 HOOK_FUNCTION(protocol_default_input) { … … 40 44 cp->bufsize - cp->buflen); 41 45 if (ret < 0) 42 return NULL; /* the error should be picked up by the handler. */46 return (void *)0; /* the error should be picked up by the handler. */ 43 47 else if (ret == 0) 44 return NULL; /* nothing to do */48 return (void *)0; /* nothing to do */ 45 49 46 50 cp->buflen += ret; … … 63 67 s = strchr(cp->buf, '\n'); 64 68 if (s == NULL) 65 return NULL; /* no command terminator found and we're out of66 data */69 return (void *)0; /* no command terminator found and we're out 70 of data */ 67 71 } 68 72 /* make a local copy of the packet, then pass it off to the parser. … … 74 78 else 75 79 *s = '\0'; 76 if ((ret = protocol_packet_parse(cp, s)) == IRCD_PARSESTOP) 77 return NULL; /* stop parsing.. */ 78 else if (ret == IRCD_CLOSEDCONN) 79 return NULL; 80 81 /* Parse the packet, we must stop parsing immediately if the 82 * connection is closed. Additionally, we stop parsing immediately 83 * if we get the 1459 return because the code that returns it 84 * modifies our buffer for us. In that case we return proto changed 85 * and let input be call for us above. */ 86 if ((ret = protocol_packet_parse(cp, s)) == IRCD_CONNECTION_CLOSED) 87 return (void *)ret; /* stop parsing.. */ 88 else if (ret == PROTOCOL_PARSE_1459STOP) 89 return (void *)IRCD_PROTOCOL_CHANGED; 80 90 s++; /* increment s, now we see if our packet contains more data */ 81 91 if ((size_t)(s - cp->buf) < cp->buflen) { … … 86 96 *cp->buf = '\0'; /* no leftovers! */ 87 97 } 88 if (ret) { 89 /* if the parser was otherwise successful, see if we have left over 90 * data and call the input function for the protocol if we do, then 91 * return. */ 92 if (cp->buflen != 0) 93 cp->proto->input(NULL, (void *)cp->sock); 94 return NULL; /* now stop. */ 95 } 96 } 97 98 return NULL; 98 if (ret == PROTOCOL_PARSE_PROTOSET) 99 return (void *)IRCD_PROTOCOL_CHANGED; 100 } 101 102 return (void *)0; 99 103 } 100 104 … … 110 114 if (!strncasecmp(cp->buf, "QUIT", 4)) { 111 115 destroy_connection(cp, ""); 112 return IRCD_C LOSEDCONN;116 return IRCD_CONNECTION_CLOSED; 113 117 } else if (!strncasecmp(cp->buf, "PROTOCOL", 8)) { 114 118 /* we received a 'protocol' command. cool. this makes our life easy, … … 119 123 if (*s == '\0') { 120 124 destroy_connection(cp, "bogus protocol command"); 121 return IRCD_C LOSEDCONN;125 return IRCD_CONNECTION_CLOSED; 122 126 } 123 127 … … 139 143 sprintf(emsg, "protocol %s is not supported", s); 140 144 destroy_connection(cp, emsg); 141 return IRCD_C LOSEDCONN;145 return IRCD_CONNECTION_CLOSED; 142 146 } 143 147 … … 147 151 148 152 if (rfc1459) { 149 /* an ugly hack. re-add the [\r]\n, then call the input function. */ 153 /* Re-adjust the buffer and return the special token to immediately 154 * and successfully halt parsing (see above). We do this because 155 * the protocol itself needs to receive the message we hooked onto 156 * for 1459 verification. */ 150 157 if (*(end - 1) == '\0') 151 158 *(end - 1) = '\r'; 152 159 *end = '\n'; 153 /* we had re-set cp->buflen here, but I don't see why we're doing that? 154 * PARSESTOP prevents the buffer adjustments above, so let's not jack 155 * with cp->buflen. Yikes. */ 156 #if 0 157 cp->buflen = strlen(cp->buf); /* ... */ 158 #endif 159 cp->proto->input(NULL, (void *)cp->sock); 160 return IRCD_PARSESTOP; 161 } 162 return 1; /* success */ 160 161 return PROTOCOL_PARSE_1459STOP; 162 } 163 164 return PROTOCOL_PARSE_PROTOSET; 163 165 } 164 166 … … 231 233 if ((i64p = (uint64_t *)module_symbol(pp->dll, "protocol_flags")) != NULL) 232 234 pp->flags = *i64p; 235 236 if ((i64p = (uint64_t *)module_symbol(pp->dll, "protocol_buffer_size")) != NULL) 237 pp->bufsize = *i64p; 238 else 239 pp->bufsize = DEFAULT_BUFFER_SIZE; 233 240 } 234 241 … … 271 278 cp2 = LIST_NEXT(cp, lp); 272 279 if (cp->proto == pp) 273 destroy_server(cp->srv, "protocol removed" , NULL);280 destroy_server(cp->srv, "protocol removed"); 274 281 cp = cp2; 275 282 } -
branches/ithildin-scons/modules/ircd/protocol.h
r579 r786 20 20 struct protocol { 21 21 char *name; /* name of protocol */ 22 hook_function_t input; /* function hooked when data is available */ 22 23 /* The input function is hooked when data is available. The return code 24 * (if not 0) from the command parser should be honored and also 25 * returned up the chain (it is used by the socket hook function) */ 26 hook_function_t input; 23 27 24 28 /* function called to create a new message. the arguments are: sender … … 43 47 * these are somewhat hackish. client and server protocols may have 44 48 * different flags with the same value, so beware! */ 45 #define PROTOCOL_SFL_SJOIN 0x000146 #define PROTOCOL_SFL_NOQUIT 0x000247 #define PROTOCOL_SFL_TSMODE 0x000448 #define PROTOCOL_SFL_ATTR 0x000849 #define PROTOCOL_SFL_TS 0x001050 #define PROTOCOL_SFL_SHORTAKILL 0x002049 #define PROTOCOL_SFL_SJOIN 0x0001 50 #define PROTOCOL_SFL_NOQUIT 0x0002 51 #define PROTOCOL_SFL_TSMODE 0x0004 52 #define PROTOCOL_SFL_ATTR 0x0008 53 #define PROTOCOL_SFL_TS 0x0010 54 #define PROTOCOL_SFL_SHORTAKILL 0x0020 51 55 52 #define PROTOCOL_MFL_NOCACHE (0x01ULL << 56) 56 /* Top eight bits (currently) reserved for "module" flags. Right now 57 * just one, nocache, exists. This instructs the send* functions to not 58 * cache messages when they otherwise would. This is a hack to allow 59 * sending slightly different messages to different individual members 60 * in a protocol (see the hostcrypt addon for a real-world example of 61 * the usefulness/uselessness of this. :) */ 62 #define PROTOCOL_MFL_NOCACHE (0x01ULL << 56) 53 63 uint64_t flags; 64 65 /* the buffer size we should allocate for clients in this protocol */ 66 uint64_t bufsize; 54 67 55 68 /* the module this protocol is represented by */ -
branches/ithildin-scons/modules/ircd/protocols/dreamforge.c
r616 r786 2 2 * dreamforge.c: the dreamforge server<->server protocol 3 3 * 4 * Copyright 2003 , 2004the Ithildin Project.4 * Copyright 2003-2006 the Ithildin Project. 5 5 * See the COPYING file for more information on licensing and use. 6 6 */ -
branches/ithildin-scons/modules/ircd/protocols/ithildin1.c
r579 r786 28 28 void sync_channel(connection_t *, channel_t *); 29 29 30 /* With \n included. We allow longer server messages as a convenience here. */ 31 #define MAX_PACKET_LEN 1024 30 /* With \n included. We allow longer server messages as a convenience here 31 * (reduces net traffic on very big commands like SJOINs) */ 32 #define MAX_PACKET_LEN 512 32 33 /* Use the rfc1459-type input routine, since we do effectively the same thing 33 34 * here. Note also that MAX_COMMAND_ARGS remains unchanged. */ … … 123 124 "%s %d %d %s %s %s :%s", cli->nick, cli->hops + 1, cli->ts, 124 125 cli->user, cli->orighost, cli->server->name, cli->info); 126 sendto_serv_from(conn->srv, cli, NULL, cli->nick, "MODE", "%s", 127 usermode_getstr(cli->modes, 1)); 125 128 } 126 129 127 #define BUF_SIZE 768130 #define BUF_SIZE 320 128 131 #include "shared/sjoin_sync_channel.c" 129 132 -
branches/ithildin-scons/modules/ircd/protocols/shared/rfc1459_io.c
r765 r786 10 10 #endif 11 11 12 const uint64_t protocol_buffer_size = MAX_PACKET_LEN; 13 12 14 HOOK_FUNCTION(input); 13 15 struct send_msg *output(struct protocol_sender *, char *, char *, char *, 14 16 va_list); 17 15 18 /* input as much data as we can from the user. */ 16 19 HOOK_FUNCTION(input) { … … 63 66 (cp->cli != NULL ? cp->cli->nick : 64 67 (cp->srv != NULL ? cp->srv->name : "")), cp->buf); 65 if ((ret = packet_parse(cp)) == IRCD_C LOSEDCONN)66 return NULL; /* connection closed, stop immediately */68 if ((ret = packet_parse(cp)) == IRCD_CONNECTION_CLOSED) 69 return (void *)ret; /* connection closed, stop immediately */ 67 70 s++; /* increment s, now we see if our packet contains more data */ 68 71 if (s - cp->buf < cp->buflen) { … … 75 78 } 76 79 77 if (ret == IRCD_P ARSESTOP)78 return NULL;80 if (ret == IRCD_PROTOCOL_CHANGED) 81 return (void *)ret; 79 82 } 80 83 } 81 84 82 85 /* if there are any errors they will be picked up elsewhere */ 83 return NULL;86 return (void *)0; 84 87 } 85 88 -
branches/ithildin-scons/modules/ircd/send.c
r744 r786 608 608 } 609 609 free(ircd.sflag.flags[flg].name); 610 611 memset(&ircd.sflag.flags[flg], 0, sizeof(struct send_flag)); 610 612 ircd.sflag.flags[flg].num = -1; 611 613 } … … 631 633 632 634 /* otherwise, put them in. */ 633 clp = malloc(sizeof(struct chanlink));635 clp = calloc(1, sizeof(struct chanlink)); 634 636 clp->cli = cli; 635 637 clp->chan = NULL; … … 672 674 char lmsg[512]; 673 675 va_list vl; 674 676 675 677 if (flg < 0 || flg >= ircd.sflag.size || ircd.sflag.flags[flg].num < 0) 676 678 return; /* nothing to do here. */ -
branches/ithildin-scons/modules/ircd/send.h
r593 r786 166 166 ircd.messages.msgs[index].default_fmt)) 167 167 168 /* below here are defines for the numerics added by default */ 169 #define RPL_WELCOME 001 170 #define RPL_YOURHOST 002 171 #define RPL_CREATED 003 172 #define RPL_MYINFO 004 173 #define RPL_ISUPPORT 005 168 /* below here are defines for the numerics added by default. Worth noting 169 * that it is unwise to prefix numerics with leading 0s because then they 170 * will be interpreted as octal numbers (not that uh.. I did that...) */ 171 #define RPL_WELCOME 1 172 #define RPL_YOURHOST 2 173 #define RPL_CREATED 3 174 #define RPL_MYINFO 4 175 #define RPL_ISUPPORT 5 176 #define RPL_REDIR 10 174 177 #define RPL_LOADTOOHIGH 263 175 178 -
branches/ithildin-scons/modules/ircd/server.c
r744 r786 42 42 * quits for its clients out to users, and sending the split message. it calls 43 43 * itself recursively to remove other servers connected to the server it is 44 * called for, as well. The source argument is used as the 'but one' 45 * argument when sending SQUITs via sendto_serv_butone. */ 44 * called for, as well. We do not take care of sending a SQUIT message to 45 * srv! This is important, because some callers (specifically the SQUIT 46 * command code) may very well need to pass on a SQUIT if this isn't a 47 * locally connected server. In this case they are expected to do so, we 48 * don't do it here because we don't have the information required. */ 46 49 static int destroy_server_count = 0; 47 50 static char destroy_server_splitmsg[512]; 48 void destroy_server(server_t *srv, char *msg , server_t *source) {51 void destroy_server(server_t *srv, char *msg) { 49 52 client_t *cp, *cp2; 50 53 server_t *sp, *sp2; … … 56 59 sprintf(destroy_server_splitmsg, "%s %s", srv->parent->name, srv->name); 57 60 58 /* now remove each client on the server, and remove all servers on the 59 * server. this is recursive. neat */ 60 cp = LIST_FIRST(ircd.lists.clients); 61 while (cp != NULL) { 62 cp2 = LIST_NEXT(cp, lp); 63 if (cp->server == srv) { 64 cp->flags |= IRCD_CLIENT_KILLED | IRCD_CLIENT_SQUIT; 65 destroy_client(cp, destroy_server_splitmsg); 61 if (SERVER_REGISTERED(srv)) { 62 /* First remove all its attached servers, this runs recursively and 63 * will send out SQUITs and QUITs and all that gack for servers that 64 * are NOQUIT-dumb */ 65 sp = LIST_FIRST(ircd.lists.servers); 66 while (sp != NULL) { 67 sp2 = LIST_NEXT(sp, lp); 68 if (sp->parent == srv) 69 destroy_server(sp, msg); 70 sp = sp2; 66 71 } 67 cp = cp2; 68 } 69 sp = LIST_FIRST(ircd.lists.servers); 70 while (sp != NULL) { 71 sp2 = LIST_NEXT(sp, lp); 72 if (sp->parent == srv) 73 destroy_server(sp, msg, source); 74 sp = sp2; 75 } 76 77 if (SERVER_REGISTERED(srv)) { 72 73 /* Now remove all the clients from this server */ 74 cp = LIST_FIRST(ircd.lists.clients); 75 while (cp != NULL) { 76 cp2 = LIST_NEXT(cp, lp); 77 if (cp->server == srv) { 78 cp->flags |= IRCD_CLIENT_KILLED; 79 /* Send out QUITs for servers that are not 'NOQUIT' enabled. 80 * In doing so we send QUITs to *everything* that doesn't do 81 * NOQUIT, including the source of the SQUIT! The only place 82 * we don't send towards is srv, since we believe this will 83 * be handled properly downstream. That is, NOQUIT makes 84 * the strange assumption that every server in the path of a 85 * SQUIT knows all about the server being squit, but other 86 * servers not in the path might not. Why/how this makes 87 * sense is a mystery to me, and this is *really* spammy. */ 88 sendto_serv_pflag_butone(PROTOCOL_SFL_NOQUIT, false, srv, 89 cp, NULL, NULL, "QUIT", ":%s", 90 destroy_server_splitmsg); 91 destroy_client(cp, destroy_server_splitmsg); 92 } 93 cp = cp2; 94 } 95 78 96 ircd.stats.servers--; 79 97 if (srv->conn != NULL) 80 98 ircd.stats.serv.servers--; 81 LIST_REMOVE(srv, lp); 82 } 83 84 /* Send the SQUIT for this server, last but not least. */ 85 if (SERVER_REGISTERED(srv)) { 99 100 /* Send the SQUIT for this server, last but not least. */ 86 101 /* Some servers are really dumb. For servers which properly support 87 102 * NOQUIT we can simply send a single SQUIT for the first-tier 88 103 * server. For other servers (dreamforge is stupid like this) we 89 * have to send a SQUIT for *every single server* that goes away. */ 104 * have to send a SQUIT for *every single server* that goes away, 105 * and we do it in the same fashion as when sending out QUITs, that 106 * is, everything but srv will get a SQUIT, even if it might not 107 * need it (see above commentary) */ 90 108 if (destroy_server_count == 1) 91 sendto_serv_butone(source, NULL, NULL, srv->name, "SQUIT", msg); 109 sendto_serv_butone(srv, NULL, NULL, srv->name, "SQUIT", 110 ":%s", ircd.me->name); 92 111 else 93 sendto_serv_pflag_butone(PROTOCOL_SFL_NOQUIT, false, source, 94 NULL, NULL, srv->name, "SQUIT", msg); 95 } 96 97 /* if this server is ours, we have to close the connection. also, we 98 * should try as best we can to flush the buffer. this probably won't work 99 * very well, but we take a stab at it. */ 112 sendto_serv_pflag_butone(PROTOCOL_SFL_NOQUIT, false, srv, 113 NULL, NULL, srv->name, "SQUIT", ":%s", ircd.me->name); 114 115 /* Lastly, remove 'srv' from the list of servers */ 116 LIST_REMOVE(srv, lp); 117 } 118 119 /* If this server is ours we have to close the connection. We try first 120 * to flush the sendq. If sendq_flush returns 0 it has closed the 121 * connection for us (socket error), otherwise we close it ourself. */ 100 122 if (MYSERVER(srv)) { 101 if (sendq_flush(srv->conn)) {102 srv->conn->srv = NULL;123 srv->conn->srv = NULL; 124 if (sendq_flush(srv->conn)) 103 125 destroy_connection(srv->conn, msg); 104 }105 126 } 106 127 … … 172 193 /* XXX: we should perform more stringement protocol checks. */ 173 194 sendto_serv_from(srv, NULL, NULL, NULL, "PROTOCOL", "%s", 174 s == NULL ? " bahamut14" : s);195 s == NULL ? "ithildin1" : s); 175 196 176 197 /* send them our password unless we're using SSL for the server, in which … … 272 293 LIST_REMOVE(sp->conn, lp); 273 294 LIST_INSERT_HEAD(ircd.connections.servers, sp->conn, lp); 295 296 /* clean out the password area */ 297 if (sp->conn->pass != NULL) { 298 free(sp->conn->pass); 299 sp->conn->pass = NULL; 300 } 274 301 } 275 302 … … 494 521 "connection to server %s failed (%s)", sp->name, 495 522 socket_strerror(sock)); 496 destroy_server(sp, "" , NULL);523 destroy_server(sp, ""); 497 524 scp->srv = NULL; /* don't forget to unset this */ 498 525 -
branches/ithildin-scons/modules/ircd/server.h
r598 r786 88 88 89 89 server_t *create_server(connection_t *); 90 void destroy_server(server_t *, char * , server_t *);90 void destroy_server(server_t *, char *); 91 91 server_t *find_server(char *); 92 92 -
branches/ithildin-scons/modules/ircd/support.c
r744 r786 35 35 ip = malloc(sizeof(struct isupport)); 36 36 memset(ip, 0, sizeof(struct isupport)); 37 ip->name = strdup(name);37 strlcpy(ip->name, name, ISUPPORTNAME_MAXLEN + 1); 38 38 /* now insert into a list. we alphabetically sort our list, just 39 39 * because I like to. :) */ … … 84 84 if (ip != NULL) { 85 85 LIST_REMOVE(ip, lp); 86 free(ip->name);87 86 if (!(ip->flags & ISUPPORT_FL_PRIV) && ip->value.str != NULL) 88 87 free(ip->value.str); … … 127 126 slen = tc = 0; 128 127 } 129 slen += sprintf(str + slen, " %s", token); 128 129 /* tricky code here to prevent sending an additional space at the 130 * beginning of the line when one is not needed. */ 131 slen += sprintf(str + slen, (slen ? " %s" : "%s"), token); 130 132 } 131 133 /* send remnants */ … … 144 146 * fifth is a description of the handler (usually short). The function returns 145 147 * non-zero upon successful installation. */ 146 int add_xinfo_handler(xinfo_func func, char *name, int flags, 147 void *udata, char *desc) { 148 int add_xinfo_handler(xinfo_func func, char *name, int flags, char *desc) { 148 149 struct xinfo_handler *xhp = find_xinfo_handler(name); 150 uint64_t i64 = 1; 151 char privname[XINFONAME_MAXLEN + 1 + 6]; /* add 6 for "xinfo-" tag */ 149 152 150 153 if (xhp != NULL) … … 153 156 xhp = malloc(sizeof(struct xinfo_handler)); 154 157 xhp->func = func; 155 xhp->name = strdup(name);158 strlcpy(xhp->name, name, XINFONAME_MAXLEN + 1); 156 159 xhp->flags = flags; 157 if (xhp->flags & XINFO_HANDLER_PRIV) 158 xhp->priv = *(int *)udata; 159 else 160 xhp->priv = -1; 160 161 /* Create a privilege for them. Always bool, this is simply a "yes/no" 162 * flag to whether or not this information is available. Always default 163 * to 1 */ 164 sprintf(privname, "xinfo-%s", xhp->name); 165 xhp->priv = create_privilege(privname, PRIVILEGE_FL_BOOL, &i64, NULL); 166 161 167 xhp->desc = strdup((desc != NULL ? desc : "no description")); 162 168 … … 206 212 if (xhp->func == func) { 207 213 LIST_REMOVE(xhp, lp); 208 free(xhp->name);209 214 free(xhp->desc); 210 215 free(xhp); -
branches/ithildin-scons/modules/ircd/support.h
r593 r786 11 11 #define IRCD_SUPPORT_H 12 12 13 #define ISUPPORTNAME_MAXLEN 31 /* XXX: what does the spec say, if anything, 14 about this...? */ 15 13 16 /* a feature may have a straightforward string value, or it may have a value 14 17 * which is connect-time dependent. features which are connect-time dependent 15 18 * are assumed to be privileges, but see below. */ 16 19 struct isupport { 17 char *name; /* name of the feature supported. */20 char name[ISUPPORTNAME_MAXLEN + 1]; 18 21 union { 19 22 char *str; /* string value */ … … 47 50 char **argv __UNUSED) 48 51 52 #define XINFONAME_MAXLEN ISUPPORTNAME_MAXLEN 53 49 54 /* The xinfo_handler structure contains a each xinfo handler's necessary 50 55 * details. */ 51 56 struct xinfo_handler { 52 char *name;57 char name[XINFONAME_MAXLEN + 1]; 53 58 char *desc; 54 59 #define XINFO_HANDLER_LOCAL 0x1 55 60 #define XINFO_HANDLER_OPER 0x2 56 #define XINFO_HANDLER_PRIV 0x457 61 int flags; 58 int priv; /* privilege , if any*/62 int priv; /* privilege */ 59 63 xinfo_func func; 60 64 … … 64 68 #define XINFO_LEN 512 65 69 66 int add_xinfo_handler(xinfo_func, char *, int, void *,char *);70 int add_xinfo_handler(xinfo_func, char *, int, char *); 67 71 struct xinfo_handler *find_xinfo_handler(char *); 68 72 void remove_xinfo_handler(xinfo_func); -
branches/ithildin-scons/modules/log/log.c
r677 r786 126 126 127 127 if ((lhp->file = fopen(fname, "a")) == NULL) { 128 /* Be sure to set DEFUNCT *first* to avoid nasty log 129 * recursion! This way when we come back around to 130 * this rule we will not hit it again. */ 131 lhp->flags |= LOG_FL_DEFUNCT; 128 132 log_error("cannot open logfile %s: %s", 129 133 lhp->filename, strerror(errno)); 130 lhp->flags |= LOG_FL_DEFUNCT;131 134 } 132 135 }
Note: See TracChangeset
for help on using the changeset viewer.
