Changeset 3739c78a534317b34706e055d7a120bdd59ab883

Show
Ignore:
Timestamp:
01/26/10 02:02:09 (4 years ago)
Author:
Theo Schlossnagle <jesus@omniti.com>
git-committer:
Theo Schlossnagle <jesus@omniti.com> 1264471329 +0000
git-parent:

[1cbadd5988d74e8a64480afe248a082ef6ea1ebe]

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

fixes #245

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • src/noit.conf.in

    r48647bb r3739c78  
    9595    </listener> 
    9696  </listeners> 
     97  <rest> 
     98    <acl> 
     99      <rule type="allow" /> 
     100    </acl> 
     101  </rest> 
    97102  <checks max_initial_stutter="30000" filterset="default"> 
    98103    <check uuid="f7cea020-f19d-11dd-85a6-cb6d3a2207dc" module="selfcheck" target="10.80.117.90" period="5000" timeout="4000"/> 
  • src/noit_rest.c

    rce0c8f2 r3739c78  
    3535#include "noit_http.h" 
    3636#include "noit_rest.h" 
     37#include "noit_conf.h" 
    3738 
    3839#include <pcre.h> 
     
    6667}; 
    6768noit_hash_table dispatch_points = NOIT_HASH_EMPTY; 
     69 
     70struct noit_rest_acl_rule { 
     71  noit_boolean allow; 
     72  pcre *url; 
     73  pcre *cn; 
     74  struct noit_rest_acl_rule *next; 
     75}; 
     76struct noit_rest_acl { 
     77  noit_boolean allow; 
     78  pcre *url; 
     79  pcre *cn; 
     80  struct noit_rest_acl_rule *rules; 
     81  struct noit_rest_acl *next; 
     82}; 
     83 
     84static struct noit_rest_acl *global_rest_acls = NULL; 
    6885 
    6986static int 
     
    128145noit_http_rest_client_cert_auth(noit_http_rest_closure_t *restc, 
    129146                                int npats, char **pats) { 
     147  struct noit_rest_acl *acl; 
     148  struct noit_rest_acl_rule *rule; 
     149  int ovector[30]; 
     150 
    130151  if(!restc->remote_cn || !strlen(restc->remote_cn)) return noit_false; 
    131   return noit_true; 
     152  for(acl = global_rest_acls; acl; acl = acl->next) { 
     153    if(acl->cn && pcre_exec(acl->cn, NULL, restc->remote_cn, 
     154                            strlen(restc->remote_cn), 0, 0, 
     155                            ovector, sizeof(ovector)/sizeof(*ovector)) <= 0) 
     156      continue; 
     157    if(acl->url && pcre_exec(acl->url, NULL, restc->http_ctx->req.uri_str, 
     158                             strlen(restc->http_ctx->req.uri_str), 0, 0, 
     159                             ovector, sizeof(ovector)/sizeof(*ovector)) <= 0) 
     160      continue; 
     161    for(rule = acl->rules; rule; rule = rule->next) { 
     162      if(rule->cn && pcre_exec(rule->cn, NULL, restc->remote_cn, 
     163                               strlen(restc->remote_cn), 0, 0, 
     164                               ovector, sizeof(ovector)/sizeof(*ovector)) <= 0) 
     165        continue; 
     166      if(rule->url && pcre_exec(rule->url, NULL, restc->http_ctx->req.uri_str, 
     167                                strlen(restc->http_ctx->req.uri_str), 0, 0, 
     168                                ovector, sizeof(ovector)/sizeof(*ovector)) <= 0) 
     169        continue; 
     170      return rule->allow; 
     171    } 
     172    return acl->allow; 
     173  } 
     174  return noit_false; 
    132175} 
    133176int 
     
    411454} 
    412455 
     456void noit_http_rest_load_rules() { 
     457  int ai, cnt = 0; 
     458  noit_conf_section_t *acls; 
     459  char path[256]; 
     460  struct noit_rest_acl *newhead = NULL, *oldacls, *remove_acl; 
     461  struct noit_rest_acl_rule *remove_rule; 
     462 
     463  snprintf(path, sizeof(path), "//rest/acl"); 
     464  acls = noit_conf_get_sections(NULL, path, &cnt); 
     465  noitL(noit_stderr, "Found %d acl stanzas\n", cnt); 
     466  for(ai = cnt-1; ai>=0; ai--) { 
     467    char tbuff[32]; 
     468    struct noit_rest_acl *newacl; 
     469    int ri, rcnt = 0; 
     470    noit_boolean default_allow = false; 
     471    noit_conf_section_t *rules; 
     472 
     473    newacl = calloc(1, sizeof(*newacl)); 
     474    newacl->next = newhead; 
     475    newhead = newacl; 
     476    if(noit_conf_get_stringbuf(acls[ai], "@type", tbuff, sizeof(tbuff)) && 
     477       !strcmp(tbuff, "allow")) 
     478      newacl->allow = noit_true; 
     479 
     480#define compile_re(node, cont, name) do { \ 
     481  char buff[256]; \ 
     482  if(noit_conf_get_stringbuf(node, "@" #name, buff, sizeof(buff))) { \ 
     483    const char *error; \ 
     484    int erroffset; \ 
     485    cont->name = pcre_compile(buff, 0, &error, &erroffset, NULL); \ 
     486  } \ 
     487} while(0) 
     488 
     489    newacl->allow = default_allow; 
     490    compile_re(acls[ai], newacl, cn); 
     491    compile_re(acls[ai], newacl, url); 
     492    rules = noit_conf_get_sections(acls[ai], "rule", &rcnt); 
     493    for(ri = rcnt - 1; ri >= 0; ri--) { 
     494      struct noit_rest_acl_rule *newacl_rule; 
     495      newacl_rule = calloc(1, sizeof(*newacl_rule)); 
     496      newacl_rule->next = newacl->rules; 
     497      newacl->rules = newacl_rule; 
     498      if(noit_conf_get_stringbuf(rules[ri], "@type", tbuff, sizeof(tbuff)) && 
     499         !strcmp(tbuff, "allow")) 
     500        newacl_rule->allow = noit_true; 
     501      compile_re(rules[ri], newacl_rule, cn); 
     502      compile_re(rules[ri], newacl_rule, url); 
     503    } 
     504    free(rules); 
     505  } 
     506  free(acls); 
     507 
     508  oldacls = global_rest_acls; 
     509  global_rest_acls = newhead; 
     510 
     511  while(oldacls) { 
     512    remove_acl = oldacls->next; 
     513    while(oldacls->rules) { 
     514      remove_rule = oldacls->rules->next; 
     515      if(oldacls->rules->cn) pcre_free(oldacls->rules->cn); 
     516      if(oldacls->rules->url) pcre_free(oldacls->rules->url); 
     517      free(oldacls->rules); 
     518      oldacls->rules = remove_rule; 
     519    } 
     520    if(oldacls->cn) pcre_free(oldacls->cn); 
     521    if(oldacls->url) pcre_free(oldacls->url); 
     522    free(oldacls); 
     523    oldacls = remove_acl; 
     524  } 
     525} 
    413526void noit_http_rest_init() { 
    414527  eventer_name_callback("noit_wire_rest_api/1.0", noit_http_rest_handler); 
    415528  eventer_name_callback("http_rest_api", noit_http_rest_raw_handler); 
     529 
     530  noit_http_rest_load_rules(); 
     531 
    416532  noit_control_dispatch_delegate(noit_control_dispatch, 
    417533                                 NOIT_CONTROL_DELETE, 
  • src/stratcon.conf.in

    raaa42af r3739c78  
    181181  </listeners> 
    182182 
     183  <rest> 
     184    <acl> 
     185      <rule type="allow" /> 
     186    </acl> 
     187    <!-- 
     188    <acl cn="^clientfoo$" url=".*" type="deny"> 
     189      <rule type="deny" url="^/check/set/"/> 
     190      <rule type="allow" url=".*"/> 
     191    </acl> 
     192    --> 
     193  </rest> 
     194 
    183195</stratcon> 
  • test/t/testconfig.pm

    rc35ae3a r3739c78  
    6565  </eventer> 
    6666}; 
     67} 
     68sub make_rest_acls { 
     69  my ($o, $opts) = @_; 
     70  my $acls = $opts->{rest_acls}; 
     71  print $o qq{  <rest>\n}; 
     72  foreach my $acl (@$acls) { 
     73    print $o qq^    <acl^; 
     74    print $o qq^ type="$acl->{type}"^ if exists($acl->{type}); 
     75    print $o qq^ cn="$acl->{cn}"^ if exists($acl->{cn}); 
     76    print $o qq^ url="$acl->{url}"^ if exists($acl->{url}); 
     77    print $o qq^>\n^; 
     78    my $rules = $acl->{rules}; 
     79    foreach my $rule (@$rules) { 
     80      print $o qq^      <rule^; 
     81      print $o qq^ type="$rule->{type}"^ if exists($rule->{type}); 
     82      print $o qq^ cn="$rule->{cn}"^ if exists($rule->{cn}); 
     83      print $o qq^ url="$rule->{url}"^ if exists($rule->{url}); 
     84      print $o qq^/>\n^; 
     85    } 
     86    print $o qq^    </acl>\n^; 
     87  } 
     88  print $o qq{  </rest>\n}; 
    6789} 
    6890sub make_log_section { 
     
    227249  $options->{cwd} ||= cwd(); 
    228250  $options->{modules} = $all_noit_modules unless exists($options->{modules}); 
     251  $options->{rest_acls} ||= [ { type => 'deny', rules => [ { type => 'allow' } ] } ]; 
    229252  my $cwd = $options->{cwd}; 
    230253  my $file = "$cwd/logs/${name}_noit.conf"; 
     
    233256  print $o qq{<noit>}; 
    234257  make_eventer_config($o, $options); 
     258  make_rest_acls($o, $options); 
    235259  make_logs_config($o, $options); 
    236260  make_modules_config($o, $options); 
     
    416440  $options->{cwd} ||= cwd(); 
    417441  $options->{generics} ||= { 'stomp_driver' => { image => 'stomp_driver' } }; 
     442  $options->{rest_acls} ||= [ { type => 'deny', rules => [ { type => 'allow' } ] } ]; 
    418443  $options->{iep}->{mq} ||= { 'stomp' => {} }; 
    419444  my $cwd = $options->{cwd}; 
     
    423448  print $o qq{<stratcon>}; 
    424449  make_eventer_config($o, $options); 
     450  make_rest_acls($o, $options); 
    425451  make_stratcon_noits_config($o, $options); 
    426452  make_logs_config($o, $options);