Show
Ignore:
Timestamp:
09/16/09 04:19:24 (5 years ago)
Author:
Theo Schlossnagle <jesus@omniti.com>
git-committer:
Theo Schlossnagle <jesus@omniti.com> 1253074764 +0000
git-parent:

[6298e33b2e6517913907fa76bd9af5a1ea28b922]

git-author:
Theo Schlossnagle <jesus@omniti.com> 1253074764 +0000
Message:

robust input validation, refs #171

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • src/noit_check_rest.c

    r914f047 r7010bc5  
    236236 
    237237static int 
    238 validate_check_post(xmlDocPtr doc, xmlNodePtr *a, xmlNodePtr *c) { 
     238validate_check_post(xmlDocPtr doc, xmlNodePtr *a, xmlNodePtr *c, 
     239                    const char **error) { 
    239240  xmlNodePtr root, tl, an; 
    240   int name=0, module=0, target=0, period=0, timeout=0, filterset=0, disable=0
     241  int name=0, module=0, target=0, period=0, timeout=0, filterset=0
    241242  *a = *c = NULL; 
    242243  root = xmlDocGetRootElement(doc); 
     
    246247      *a = tl->children; 
    247248      for(an = tl->children; an; an = an->next) { 
    248 #define CHECK_N_SET(a) if(!strcmp((char *)an->name, #a)) a = 1 
    249         CHECK_N_SET(name); 
    250         else CHECK_N_SET(module); 
    251         else CHECK_N_SET(target); 
    252         else CHECK_N_SET(period); 
    253         else CHECK_N_SET(timeout); 
    254         else CHECK_N_SET(filterset); 
    255         else CHECK_N_SET(disable); 
     249#define CHECK_N_SET(a) if(!strcmp((char *)an->name, #a)) 
     250        CHECK_N_SET(name) { 
     251          xmlChar *tmp; 
     252          pcre *valid_name = noit_conf_get_valid_name_checker(); 
     253          int ovector[30], valid; 
     254          tmp = xmlNodeGetContent(an); 
     255          valid = (pcre_exec(valid_name, NULL, 
     256                             (char *)tmp, strlen((char *)tmp), 0, 0, 
     257                             ovector, sizeof(ovector)/sizeof(*ovector)) > 0); 
     258          xmlFree(tmp); 
     259          if(!valid) { *error = "invalid name"; return 0; } 
     260          name = 1; 
     261        } 
     262        else CHECK_N_SET(module) module = 1; /* This is validated by called */ 
     263        else CHECK_N_SET(target) { 
     264          int valid; 
     265          xmlChar *tmp; 
     266          tmp = xmlNodeGetContent(an); 
     267          valid = noit_check_is_valid_target((char *)tmp); 
     268          xmlFree(tmp); 
     269          if(!valid) { *error = "invalid target"; return 0; } 
     270          target = 1; 
     271        } 
     272        else CHECK_N_SET(period) { 
     273          int pint; 
     274          xmlChar *tmp; 
     275          tmp = xmlNodeGetContent(an); 
     276          pint = noit_conf_string_to_int((char *)tmp); 
     277          xmlFree(tmp); 
     278          if(pint < 5000 || pint > 300000) { 
     279            *error = "invalid period"; 
     280            return 0; 
     281          } 
     282          period = 1; 
     283        } 
     284        else CHECK_N_SET(timeout) { 
     285          int pint; 
     286          xmlChar *tmp; 
     287          tmp = xmlNodeGetContent(an); 
     288          pint = noit_conf_string_to_int((char *)tmp); 
     289          xmlFree(tmp); 
     290          if(pint < 0 || pint > 300000) { 
     291            *error = "invalid timeout"; 
     292            return 0; 
     293          } 
     294          timeout = 1; 
     295        } 
     296        else CHECK_N_SET(filterset) filterset = 1; 
     297        else CHECK_N_SET(disable) { /* not required */ 
     298          int valid; 
     299          xmlChar *tmp; 
     300          tmp = xmlNodeGetContent(an); 
     301          valid = (!strcasecmp((char *)tmp, "true") || 
     302                   !strcasecmp((char *)tmp, "on") || 
     303                   !strcasecmp((char *)tmp, "false") || 
     304                   !strcasecmp((char *)tmp, "off")); 
     305          xmlFree(tmp); 
     306          if(!valid) { *error = "bad disable parameter"; return 0; } 
     307          target = 1; 
     308        } 
    256309        else return 0; 
    257310      } 
     
    264317  } 
    265318  if(name && module && target && period && timeout && filterset) return 1; 
     319  *error = "insufficient information"; 
    266320  return 0; 
    267321} 
     
    372426  indoc = xmlParseMemory(rxc->buffer, rxc->len); 
    373427  if(indoc == NULL) FAIL("xml parse error"); 
    374   if(!validate_check_post(indoc, &attr, &config)) FAIL("xml validate error")
     428  if(!validate_check_post(indoc, &attr, &config, &error)) goto error
    375429 
    376430  if(uuid_parse(pats[1], checkid)) goto error;