Changeset 1062
- Timestamp:
- 08/05/07 02:52:17 (1 year ago)
- Files:
-
- 1.8.3/branches/devel/CHANGES.183 (modified) (1 diff)
- 1.8.3/branches/devel/hdrs/access.h (modified) (3 diffs)
- 1.8.3/branches/devel/hdrs/externs.h (modified) (1 diff)
- 1.8.3/branches/devel/src/access.c (modified) (19 diffs)
- 1.8.3/branches/devel/src/wild.c (modified) (1 diff)
- 1.8.3/branches/devel/src/wiz.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
1.8.3/branches/devel/CHANGES.183
r1054 r1062 26 26 algorithm, with constant-time lookups even in the worst case. 27 27 (And appears to have generally faster lookup even in normal usage.) 28 28 * Regular expression @sitelocks save the compiled regexp instead of 29 recompiling every time the rule is tested. 30 29 31 Fixes: 30 32 * decode64() does better validation of its input. 31 33 * Various compile fixes reported by Interevis and Kimiko. 32 34 Win32 patched by Intrevis. 35 * @sitelock does better error reporting. 33 36 34 37 Version 1.8.3 patchlevel 4 July 9, 2007 1.8.3/branches/devel/hdrs/access.h
r905 r1062 10 10 char comment[BUFFER_LEN]; /**< A comment about the rule */ 11 11 dbref who; /**< Who created this rule if sitelock used */ 12 int can; /**< Bitflags of what the host can do */ 13 int cant; /**< Bitflags of what the host can't do */ 12 uint32_t can; /**< Bitflags of what the host can do */ 13 uint32_t cant; /**< Bitflags of what the host can't do */ 14 pcre *re; /**< Compiled regexp */ 14 15 struct access *next; /**< Pointer to next rule in the list */ 15 16 }; … … 17 18 18 19 /* These flags are can/can't - a site may or may not be allowed to do them */ 19 #define ACS_CONNECT 0x1 /* Connect to non-guests */20 #define ACS_CREATE 0x2 /* Create new players */21 #define ACS_GUEST 0x4 /* Connect to guests */22 #define ACS_REGISTER 0x8 /* Site can use the 'register' command */20 #define ACS_CONNECT 0x1U /* Connect to non-guests */ 21 #define ACS_CREATE 0x2U /* Create new players */ 22 #define ACS_GUEST 0x4U /* Connect to guests */ 23 #define ACS_REGISTER 0x8U /* Site can use the 'register' command */ 23 24 /* These flags are set in the 'can' bit, but they mark special processing */ 24 #define ACS_SITELOCK 0x10 /* Marker for where to insert @sitelock */25 #define ACS_SUSPECT 0x20 /* All players from this site get SUSPECT */26 #define ACS_DENY_SILENT 0x40 /* Don't log failed attempts */27 #define ACS_REGEXP 0x80 /* Treat the host pattern as a regexp */25 #define ACS_SITELOCK 0x10U /* Marker for where to insert @sitelock */ 26 #define ACS_SUSPECT 0x20U /* All players from this site get SUSPECT */ 27 #define ACS_DENY_SILENT 0x40U /* Don't log failed attempts */ 28 #define ACS_REGEXP 0x80U /* Treat the host pattern as a regexp */ 28 29 29 #define ACS_GOD 0x100 /* God can connect from this site */30 #define ACS_WIZARD 0x200 /* Wizards can connect from this site */31 #define ACS_ADMIN 0x400 /* Admins can connect from this site */30 #define ACS_GOD 0x100U /* God can connect from this site */ 31 #define ACS_WIZARD 0x200U /* Wizards can connect from this site */ 32 #define ACS_ADMIN 0x400U /* Admins can connect from this site */ 32 33 33 34 /* This is the usual default access */ … … 45 46 46 47 /* Public functions */ 47 intread_access_file(void);48 bool read_access_file(void); 48 49 void write_access_file(void); 49 int site_can_access(const char *hname, int flag, dbref who);50 bool site_can_access(const char *hname, uint32_t flag, dbref who); 50 51 struct access *site_check_access(const char *hname, dbref who, int *rulenum); 51 intformat_access(struct access *ap, int rulenum,52 void format_access(struct access *ap, int rulenum, 52 53 dbref who 53 54 __attribute__ ((__unused__)), char *buff, char **bp); 54 int add_access_sitelock(dbref player, const char *host, dbref who, int can,55 int cant);55 bool add_access_sitelock(dbref player, const char *host, dbref who, 56 uint32_t can, uint32_t cant); 56 57 int remove_access_sitelock(const char *pattern); 57 58 void do_list_access(dbref player); 58 59 int parse_access_options 59 (const char *opts, dbref *who, int *can, int *cant, dbref player);60 (const char *opts, dbref *who, uint32_t *can, uint32_t *cant, dbref player); 60 61 61 62 #endif /* __ACCESS_H */ 1.8.3/branches/devel/hdrs/externs.h
r1017 r1062 591 591 bool quick_regexp_match(const char *restrict s, 592 592 const char *restrict d, bool cs); 593 bool qcomp_regexp_match(const pcre *re, const char *s); 593 594 bool wild_match_case_r(const char *restrict s, 594 595 const char *restrict d, bool cs, 1.8.3/branches/devel/src/access.c
r945 r1062 78 78 #include "conf.h" 79 79 #include "externs.h" 80 #include "pcre.h" 80 81 #include "access.h" 81 82 #include "mymalloc.h" … … 95 96 struct a_acsflag { 96 97 const char *name; /**< Name of the access flag */ 97 inttoggle; /**< Is this a negatable flag? */98 int flag; /**< Bitmask of the flag */98 bool toggle; /**< Is this a negatable flag? */ 99 uint32_t flag; /**< Bitmask of the flag */ 99 100 }; 100 101 static acsflag acslist[] = { … … 114 115 115 116 static struct access *access_top; 116 static int add_access_node117 (const char *host, const dbref who, const int can, const int cant,118 const char *comment);119 117 static void free_access_list(void); 120 118 121 static int 122 add_access_node(const char *host, const dbref who, const int can, 123 const int cant, const char *comment) 124 { 125 struct access *end; 119 extern const unsigned char *tables; 120 121 static struct access* sitelock_alloc(const char *host, dbref who, 122 uint32_t can, uint32_t cant, 123 const char *comment, const char **errptr) 124 __attribute_malloc__; 125 126 static struct access* 127 sitelock_alloc(const char *host, dbref who, uint32_t can, uint32_t cant, 128 const char *comment, const char **errptr) 129 { 126 130 struct access *tmp; 127 128 tmp = (struct access *) mush_malloc(sizeof(struct access), "struct_access"); 129 if (!tmp) 130 return 0; 131 tmp = mush_malloc(sizeof(struct access), "sitelock.rule"); 132 if (!tmp) { 133 static const char *memerr = "unable to allocate memory"; 134 if (errptr) 135 *errptr = memerr; 136 return NULL; 137 } 131 138 tmp->who = who; 132 139 tmp->can = can; 133 140 tmp->cant = cant; 134 strcpy(tmp->host, host);141 mush_strncpy(tmp->host, host, BUFFER_LEN); 135 142 if (comment) 136 strcpy(tmp->comment, comment);143 mush_strncpy(tmp->comment, comment, BUFFER_LEN); 137 144 else 138 145 tmp->comment[0] = '\0'; 139 146 tmp->next = NULL; 147 148 if (can & ACS_REGEXP) { 149 int erroffset = 0; 150 tmp->re = pcre_compile(host, 0, errptr, &erroffset, tables); 151 if (!tmp->re) { 152 mush_free(tmp, "sitelock.rule"); 153 return NULL; 154 } 155 } else 156 tmp->re = NULL; 157 158 return tmp; 159 } 160 161 static bool 162 add_access_node(const char *host, dbref who, uint32_t can, 163 uint32_t cant, const char *comment, const char **errptr) 164 { 165 struct access *end, *tmp; 166 167 tmp = sitelock_alloc(host, who, can, cant, comment, errptr); 168 if (!tmp) 169 return false; 140 170 141 171 if (!access_top) { … … 148 178 end->next = tmp; 149 179 } 150 151 return 1; 180 return true; 152 181 } 153 182 … … 155 184 /** Read the access.cnf file. 156 185 * Initialize the access rules linked list and read in the access.cnf file. 157 * Return 1 if successful, 0if not158 */ 159 int 186 * \return true if successful, false if not 187 */ 188 bool 160 189 read_access_file(void) 161 190 { … … 163 192 char buf[BUFFER_LEN]; 164 193 char *p; 165 int can, cant;194 uint32_t can, cant; 166 195 int retval; 167 196 dbref who; 168 197 char *comment; 198 const char *errptr = NULL; 169 199 170 200 if (access_top) { … … 198 228 /* Is this the @sitelock entry? */ 199 229 if (!strncasecmp(p, "@sitelock", 9)) { 200 if (!add_access_node("@sitelock", AMBIGUOUS, ACS_SITELOCK, 0, "")) 201 do_log(LT_ERR, GOD, GOD, T("Failed to add sitelock node!")); 230 if (!add_access_node("@sitelock", AMBIGUOUS, ACS_SITELOCK, 0, "", 231 &errptr)) 232 do_log(LT_ERR, GOD, GOD, T("Failed to add sitelock node: %s"), 233 errptr); 202 234 } else { 203 235 if ((comment = strchr(p, '#'))) { … … 214 246 /* Nothing listed, so assume we can't do anything! */ 215 247 cant = ACS_DEFAULT; 216 if (!add_access_node(buf, who, can, cant, comment)) 217 do_log(LT_ERR, GOD, GOD, T("Failed to add access node!")); 248 if (!add_access_node(buf, who, can, cant, comment, &errptr)) 249 do_log(LT_ERR, GOD, GOD, T("Failed to add access node: %s"), 250 errptr); 218 251 } 219 252 } … … 317 350 * \endverbatim 318 351 */ 319 int 320 site_can_access(const char *hname, int flag, dbref who)352 bool 353 site_can_access(const char *hname, uint32_t flag, dbref who) 321 354 { 322 355 struct access *ap; … … 333 366 if (!(ap->can & ACS_SITELOCK) 334 367 && ((ap->can & ACS_REGEXP) 335 ? (q uick_regexp_match(ap->host, hname, 0)336 || (p && q uick_regexp_match(ap->host, p, 0))368 ? (qcomp_regexp_match(ap->re, hname) 369 || (p && qcomp_regexp_match(ap->re, p)) 337 370 #ifdef FORCE_IPV4 338 || q uick_regexp_match(ip4_to_ip6(ap->host), hname, 0)339 || (p && q uick_regexp_match(ip4_to_ip6(ap->host), p, 0))371 || qcomp_regexp_match(ip4_to_ip6(ap->re), hname) 372 || (p && qcomp_regexp_match(ip4_to_ip6(ap->re), p)) 340 373 #endif 341 374 ) … … 403 436 if (!(ap->can & ACS_SITELOCK) 404 437 && ((ap->can & ACS_REGEXP) 405 ? (q uick_regexp_match(ap->host, hname, 0)406 || (p && q uick_regexp_match(ap->host, p, 0))438 ? (qcomp_regexp_match(ap->re, hname) 439 || (p && qcomp_regexp_match(ap->re, p)) 407 440 #ifdef FORCE_IPV4 408 || q uick_regexp_match(ip4_to_ip6(ap->host), hname, 0)409 || (p && q uick_regexp_match(ip4_to_ip6(ap->host), p, 0))441 || qcomp_regexp_match(ip4_to_ip6(ap->host), hname) 442 || (p && qcomp_regexp_match(ip4_to_ip6(ap->host), p)) 410 443 #endif 411 444 ) … … 434 467 * in the list. 435 468 */ 436 int 469 void 437 470 format_access(struct access *ap, int rulenum, 438 471 dbref who __attribute__ ((__unused__)), char *buff, char **bp) … … 475 508 safe_str(T("No matching access rule"), buff, bp); 476 509 } 477 return 0;478 510 } 479 511 … … 494 526 * \endverbatim 495 527 */ 496 int 497 add_access_sitelock(dbref player, const char *host, dbref who, int can,498 int cant)528 bool 529 add_access_sitelock(dbref player, const char *host, dbref who, uint32_t can, 530 uint32_t cant) 499 531 { 500 532 struct access *end; 501 533 struct access *tmp; 502 503 tmp = (struct access *) mush_malloc(sizeof(struct access), "struct_access"); 504 if (!tmp) 505 return 0; 506 507 tmp->who = who; 508 tmp->can = can; 509 tmp->cant = cant; 510 strcpy(tmp->host, host); 511 snprintf(tmp->comment, sizeof tmp->comment, 512 "By %s(#%d) on %s", Name(player), player, show_time(mudtime, 0)); 513 tmp->next = NULL; 534 const char *errptr = NULL; 535 536 537 tmp = sitelock_alloc(host, who, can, cant, "", &errptr); 538 539 if (!tmp) { 540 notify_format(player, T("Unable to add sitelock entry: %s"), errptr); 541 return false; 542 } 514 543 515 544 if (!access_top) { 516 545 /* Add to the beginning, but first add a sitelock marker */ 517 if (!add_access_node("@sitelock", AMBIGUOUS, ACS_SITELOCK, 0, "")) 546 if (!add_access_node("@sitelock", AMBIGUOUS, ACS_SITELOCK, 0, "", 547 &errptr)) { 548 notify_format(player, T("Unable to add @sitelock separator: %s"), errptr); 518 549 return 0; 550 } 519 551 access_top->next = tmp; 520 552 } else { … … 525 557 if (end->can != ACS_SITELOCK) { 526 558 /* We're at the end and there's no sitelock marker. Add one */ 527 if (!add_access_node("@sitelock", AMBIGUOUS, ACS_SITELOCK, 0, "")) 559 if (!add_access_node("@sitelock", AMBIGUOUS, ACS_SITELOCK, 0, "", 560 &errptr)) { 561 notify_format(player, T("Unable to add @sitelock separator: %s"), 562 errptr); 528 563 return 0; 564 } 529 565 end = end->next; 530 566 } else { … … 540 576 * \param pattern access rule host pattern to match. 541 577 * \return number of rule removed. 542 * \verbatim543 578 * This function removes an access rule from the list. 544 579 * Only rules that appear after the "@sitelock" rule can be 545 580 * removed with this function. 546 * \endverbatim547 581 */ 548 582 int … … 564 598 if (strcasecmp(pattern, ap->host) == 0) { 565 599 n++; 566 mush_free(ap, "struct_access"); 600 if (ap->re) 601 free(ap->re); 602 mush_free(ap, "sitelock.rule"); 567 603 if (prev) 568 604 prev->next = next; … … 586 622 while (ap) { 587 623 next = ap->next; 588 mush_free((Malloc_t) ap, "struct_access"); 624 if (ap->re) 625 free(ap->re); 626 mush_free(ap, "sitelock.rule"); 589 627 ap = next; 590 628 } … … 649 687 */ 650 688 int 651 parse_access_options(const char *opts, dbref *who, int *can, int *cant,652 dbref player)689 parse_access_options(const char *opts, dbref *who, uint32_t *can, 690 uint32_t *cant, dbref player) 653 691 { 654 692 char myopts[BUFFER_LEN]; 1.8.3/branches/devel/src/wild.c
r931 r1062 625 625 626 626 return r >= 0; 627 } 628 629 /** Regexp match of a pre-compiled regexp, with no memory. 630 * \param re the regular expression 631 * \param subj the string to match against. 632 * \return true or false 633 */ 634 bool 635 qcomp_regexp_match(const pcre *re, const char *subj) 636 { 637 int len; 638 int offsets[99]; 639 640 if (!re || !subj) 641 return false; 642 643 len = strlen(subj); 644 645 return pcre_exec(re, NULL, subj, len, 0, 0, offsets, 99) >= 0; 646 627 647 } 628 648 1.8.3/branches/devel/src/wiz.c
r1048 r1062 1446 1446 } 1447 1447 if (opts && *opts) { 1448 int can, cant;1448 uint32_t can, cant; 1449 1449 dbref whod = AMBIGUOUS; 1450 1450 /* Options form of the command. */ … … 1466 1466 } 1467 1467 1468 add_access_sitelock(player, site, whod, can, cant); 1469 write_access_file(); 1470 if (whod != AMBIGUOUS) { 1471 notify_format(player, 1472 T("Site %s access options for %s(%s) set to %s"), 1473 site, Name(whod), unparse_dbref(whod), opts); 1474 do_log(LT_WIZ, player, NOTHING, 1475 T("*** SITELOCK *** %s for %s(%s) --> %s"), site, 1476 Name(whod), unparse_dbref(whod), opts); 1477 } else { 1478 notify_format(player, T("Site %s access options set to %s"), site, opts); 1479 do_log(LT_WIZ, player, NOTHING, "*** SITELOCK *** %s --> %s", site, opts); 1480 } 1481 return; 1468 if (add_access_sitelock(player, site, whod, can, cant)) { 1469 write_access_file(); 1470 if (whod != AMBIGUOUS) { 1471 notify_format(player, 1472 T("Site %s access options for %s(%s) set to %s"), 1473 site, Name(whod), unparse_dbref(whod), opts); 1474 do_log(LT_WIZ, player, NOTHING, 1475 T("*** SITELOCK *** %s for %s(%s) --> %s"), site, 1476 Name(whod), unparse_dbref(whod), opts); 1477 } else { 1478 notify_format(player, T("Site %s access options set to %s"), site, opts); 1479 do_log(LT_WIZ, player, NOTHING, "*** SITELOCK *** %s --> %s", site, opts); 1480 } 1481 return; 1482 } 1482 1483 } else { 1483 1484 /* Backward-compatible non-options form of the command, … … 1490 1491 return; 1491 1492 case SITELOCK_ADD: 1492 add_access_sitelock(player, site, AMBIGUOUS, 0, ACS_CREATE); 1493 write_access_file(); 1494 notify_format(player, T("Site %s locked"), site); 1495 do_log(LT_WIZ, player, NOTHING, "*** SITELOCK *** %s", site); 1493 if (add_access_sitelock(player, site, AMBIGUOUS, 0, ACS_CREATE)) { 1494 write_access_file(); 1495 notify_format(player, T("Site %s locked"), site); 1496 do_log(LT_WIZ, player, NOTHING, "*** SITELOCK *** %s", site); 1497 } 1496 1498 break; 1497 1499 case SITELOCK_BAN: 1498 add_access_sitelock(player, site, AMBIGUOUS, 0, ACS_DEFAULT); 1499 write_access_file(); 1500 notify_format(player, T("Site %s banned"), site); 1501 do_log(LT_WIZ, player, NOTHING, "*** SITELOCK *** %s", site); 1500 if (add_access_sitelock(player, site, AMBIGUOUS, 0, ACS_DEFAULT)) { 1501 write_access_file(); 1502 notify_format(player, T("Site %s banned"), site); 1503 do_log(LT_WIZ, player, NOTHING, "*** SITELOCK *** %s", site); 1504 } 1502 1505 break; 1503 1506 case SITELOCK_CHECK:{
