Ejemplo n.º 1
0
static int
ip_acl_onload(noit_image_t *self) {
  int i, cnt;
  noit_conf_section_t *acl_c;
  ip_acl_module_id = noit_check_register_module("ip_acl");
  if(ip_acl_module_id < 0) return -1;

  acl_c = noit_conf_get_sections(NULL, "/noit/acls//acl", &cnt);
  if(acl_c) {
    for(i=0; i<cnt; i++) {
      char *name;
      int j, rcnt, arcnt = 0;
      noit_conf_section_t *rule_c;
      if(noit_conf_get_string(acl_c[i], "@name", &name)) {
        rule_c = noit_conf_get_sections(acl_c[i], "rule", &rcnt);
        if(rule_c) {
          btrie *acl = calloc(1, sizeof(*acl));
          for(j=0; j<rcnt; j++) {
            int mask = -1, rv;
            char dirstr[16] = "unspecified";
            char *cp, target[256] = "";
            union {
              struct in_addr addr4;
              struct in6_addr addr6;
            } a;

            noit_conf_get_stringbuf(rule_c[j], "self::node()", target, sizeof(target));
            if(NULL != (cp = strchr(target, '/'))) {
              *cp++ = '\0';
              mask = atoi(cp);
            }
            if(!noit_conf_get_stringbuf(rule_c[j], "@type", dirstr, sizeof(dirstr)) ||
               (strcmp(dirstr, "deny") && strcmp(dirstr, "allow"))) {
              noitL(noit_error, "Unknown acl rule type \"%s\" in acl \"%s\"\n",
                    dirstr, name);
            }
            else if(inet_pton(AF_INET, target, &a) == 1) {
              if(mask == -1) mask = 32;
              noit_add_route_ipv4(acl, &a.addr4, mask, strcmp(dirstr, "allow") ? DENY_PTR : ALLOW_PTR);
              arcnt++;
            }
            else if(inet_pton(AF_INET6, target, &a) == 1) {
              if(mask == -1) mask = 128;
              noit_add_route_ipv6(acl, &a.addr6, mask, strcmp(dirstr, "allow") ? DENY_PTR : ALLOW_PTR);
              arcnt++;
            }
          }
          noitL(noit_error, "ACL %s/%p -> %d/%d rules\n", name, acl, arcnt, rcnt);
          noit_hash_replace(&acls, name, strlen(name), acl, free, free_btrie);
          free(rule_c);
        }
      }
    }
    free(acl_c);
  }
  return 0;
}
Ejemplo n.º 2
0
static int
noit_console_filter_show(noit_console_closure_t ncct,
                         int argc, char **argv,
                         noit_console_state_t *state,
                         void *closure) {
  noit_conf_t_userdata_t *info;
  char xpath[1024];
  xmlNodePtr fsnode;
  noit_conf_section_t *rules;
  int i, rulecnt;

  info = noit_console_userdata_get(ncct, NOIT_CONF_T_USERDATA);
  snprintf(xpath, sizeof(xpath), "/%s",
           info->path);
  fsnode = noit_conf_get_section(NULL, xpath);
  if(!fsnode) {
    nc_printf(ncct, "internal error\n");
    return -1;
  }
  rules = noit_conf_get_sections(fsnode, "rule", &rulecnt);
  for(i=0; i<rulecnt; i++) {
    char val[256];
    val[0] = '\0';
    noit_conf_get_stringbuf(rules[i], "@type", val, sizeof(val));
    nc_printf(ncct, "Rule %d [%s]:\n", i+1, val);
#define DUMP_ATTR(a) do { \
  char *vstr; \
  noit_conf_section_t ht; \
  int cnt; \
  ht = noit_conf_get_sections(rules[i], #a, &cnt); \
  if(ht && cnt) { \
    nc_printf(ncct, "\t%s: hash match of %d items\n", #a, cnt); \
  } \
  else if(noit_conf_get_string(rules[i], "@" #a, &vstr)) { \
    nc_printf(ncct, "\t%s: /%s/\n", #a, val); \
    free(vstr); \
  } \
  free(ht); \
} while(0)
    DUMP_ATTR(target);
    DUMP_ATTR(module);
    DUMP_ATTR(name);
    DUMP_ATTR(metric);
  }
  if(rules) free(rules);
  return 0;
}
Ejemplo n.º 3
0
void
noit_filter_compile_add(noit_conf_section_t setinfo) {
  noit_conf_section_t *rules;
  int j, fcnt;
  char filterset_name[256];
  filterset_t *set;
  if(!noit_conf_get_stringbuf(setinfo, "@name",
                              filterset_name, sizeof(filterset_name))) {
    noitL(noit_error,
          "filterset with no name, skipping as it cannot be referenced.\n");
    return;
  }
  set = calloc(1, sizeof(*set));
  set->ref_cnt = 1;
  set->name = strdup(filterset_name);

  rules = noit_conf_get_sections(setinfo, "rule", &fcnt);
  /* Here we will work through the list backwards pushing the rules on
   * the front of the list.  That way we can simply walk them in order
   * for the application process.
   */
  noitL(noit_debug, "Compiling filterset '%s'\n", set->name);
  for(j=fcnt-1; j>=0; j--) {
    filterrule_t *rule;
    char buffer[256];
    if(!noit_conf_get_stringbuf(rules[j], "@type", buffer, sizeof(buffer)) ||
       (strcmp(buffer, "accept") && strcmp(buffer, "allow") && strcmp(buffer, "deny"))) {
      noitL(noit_error, "rule must have type 'accept' or 'allow' or 'deny'\n");
      continue;
    }
    noitL(noit_debug, "Prepending %s into %s\n", buffer, set->name);
    rule = calloc(1, sizeof(*rule));
    rule->type = (!strcmp(buffer, "accept") || !strcmp(buffer, "allow")) ?
                   NOIT_FILTER_ACCEPT : NOIT_FILTER_DENY;

    /* Compile our rules */
#define RULE_COMPILE(rname) do { \
  char *longre = NULL; \
  if(noit_conf_get_string(rules[j], "@" #rname, &longre)) { \
    const char *error; \
    int erroffset; \
    rule->rname = pcre_compile(longre, 0, &error, &erroffset, NULL); \
    if(!rule->rname) { \
      noitL(noit_error, "set '%s' rule '%s: %s' compile failed: %s\n", \
            set->name, #rname, longre, error ? error : "???"); \
    } \
    else { \
      rule->rname##_e = pcre_study(rule->rname, 0, &error); \
    } \
    free(longre); \
  } \
} while(0)

    RULE_COMPILE(target);
    RULE_COMPILE(module);
    RULE_COMPILE(name);
    RULE_COMPILE(metric);
    rule->next = set->rules;
    set->rules = rule;
  }
  free(rules);
  LOCKFS();
  noit_hash_replace(filtersets, set->name, strlen(set->name), (void *)set,
                    NULL, filterset_free);
  UNLOCKFS();
}
Ejemplo n.º 4
0
int main(int argc, char **argv) {
  int fd, lockfd = -1;
  char lockfile[PATH_MAX];
  char user[32], group[32];
  char *trace_dir = NULL;
  parse_clargs(argc, argv);

  noit_log_init();
  noit_log_stream_add_stream(noit_debug, noit_stderr);
  noit_log_stream_add_stream(noit_error, noit_stderr);

  /* Next load the configs */
  noit_conf_init(APPNAME);
  if(noit_conf_load(config_file) == -1) {
    fprintf(stderr, "Cannot load config: '%s'\n", config_file);
    exit(-1);
  }

  /* Reinitialize the logging system now that we have a config */
  snprintf(user, sizeof(user), "%d", getuid());
  snprintf(group, sizeof(group), "%d", getgid());
  if(noit_security_usergroup(droptouser, droptogroup, noit_true)) {
    noitL(noit_stderr, "Failed to drop privileges, exiting.\n");
    exit(-1);
  }
  noit_conf_log_init(APPNAME);
  cli_log_switches();
  if(noit_security_usergroup(user, group, noit_true)) {
    noitL(noit_stderr, "Failed to regain privileges, exiting.\n");
    exit(-1);
  }
  if(debug)
    noit_debug->enabled = 1;

  if(!glider) noit_conf_get_string(NULL, "/" APPNAME "/watchdog/@glider", &glider);
  noit_watchdog_glider(glider);
  noit_conf_get_string(NULL, "/" APPNAME "/watchdog/@tracedir", &trace_dir);
  if(trace_dir) noit_watchdog_glider_trace_dir(trace_dir);

  if(chdir("/") != 0) {
    fprintf(stderr, "cannot chdir(\"/\"): %s\n", strerror(errno));
    exit(2);
  }

  noit_watchdog_prefork_init();

  /* Acquire the lock so that we can throw an error if it doesn't work.
   * If we've started -D, we'll have the lock.
   * If not we will daemon and must reacquire the lock.
   */
  lockfd = -1;
  lockfile[0] = '\0';
  if(noit_conf_get_stringbuf(NULL, "/" APPNAME "/@lockfile",
                             lockfile, sizeof(lockfile))) {
    if((lockfd = noit_lockfile_acquire(lockfile)) < 0) {
      noitL(noit_stderr, "Failed to acquire lock: %s\n", lockfile);
      exit(-1);
    }
  }

  if(foreground) exit(child_main());

  /* This isn't inherited across forks... */
  if(lockfd >= 0) noit_lockfile_release(lockfd);

  fd = open("/dev/null", O_RDWR);
  dup2(fd, STDIN_FILENO);
  dup2(fd, STDOUT_FILENO);
  dup2(fd, STDERR_FILENO);
  if(fork()) exit(0);
  setsid();
  if(fork()) exit(0);

  /* Reacquire the lock */
  if(*lockfile) {
    if(noit_lockfile_acquire(lockfile) < 0) {
      noitL(noit_stderr, "Failed to acquire lock: %s\n", lockfile);
      exit(-1);
    }
  }

  return noit_watchdog_start_child("stratcond", child_main, 0);
}
Ejemplo n.º 5
0
static int child_main() {
  char conf_str[1024];

  /* Next (re)load the configs */
  if(noit_conf_load(config_file) == -1) {
    fprintf(stderr, "Cannot load config: '%s'\n", config_file);
    exit(2);
  }

  noit_log_reopen_all();

  /* Lastly, run through all other system inits */
  if(!noit_conf_get_stringbuf(NULL, "/" APPNAME "/eventer/@implementation",
                              conf_str, sizeof(conf_str))) {
    noitL(noit_stderr, "Cannot find '%s' in configuration\n",
          "/" APPNAME "/eventer/@implementation");
    exit(2);
  }
  if(eventer_choose(conf_str) == -1) {
    noitL(noit_stderr, "Cannot choose eventer %s\n", conf_str);
    exit(2);
  }
  if(configure_eventer() != 0) {
    noitL(noit_stderr, "Cannot configure eventer\n");
    exit(2);
  }
  if(eventer_init() == -1) {
    noitL(noit_stderr, "Cannot init eventer %s\n", conf_str);
    exit(2);
  }
  /* rotation init requires, eventer_init() */
  noit_conf_log_init_rotate(APPNAME, noit_false);

  noit_watchdog_child_eventer_heartbeat();

  noit_console_init(APPNAME);
  noit_console_conf_init();
  noit_http_rest_init();
  stratcon_realtime_http_init(APPNAME);
  noit_capabilities_listener_init();
  noit_listener_init(APPNAME);

  noit_module_init();
  if(strict_module_load && noit_module_load_failures() > 0) {
    noitL(noit_stderr, "Failed to load some modules and -M given.\n");
    exit(2);
  }

  if(stratcon_datastore_get_enabled())
    stratcon_datastore_init();

  /* Drop privileges */
  if(chrootpath && noit_security_chroot(chrootpath)) {
    noitL(noit_stderr, "Failed to chroot(), exiting.\n");
    exit(-1);
  }
  if(noit_security_usergroup(droptouser, droptogroup, noit_false)) {
    noitL(noit_stderr, "Failed to drop privileges, exiting.\n");
    exit(-1);
  }

  stratcon_jlog_streamer_init(APPNAME);

  if(stratcon_iep_get_enabled())
    stratcon_iep_init();
  if(stratcon_datastore_get_enabled()) {
    /* Write our log out, and setup a watchdog to write it out on change. */
    stratcon_datastore_saveconfig(NULL);
    noit_conf_coalesce_changes(10); /* 10 seconds of no changes before we write */
  }
  else
    noit_conf_coalesce_changes(INT_MAX);

  noit_conf_watch_and_journal_watchdog(stratcon_datastore_saveconfig, NULL);

  eventer_loop();
  return 0;
}
Ejemplo n.º 6
0
void noit_http_rest_load_rules() {
  int ai, cnt = 0;
  noit_conf_section_t *acls;
  char path[256];
  struct noit_rest_acl *newhead = NULL, *oldacls, *remove_acl;
  struct noit_rest_acl_rule *remove_rule;

  snprintf(path, sizeof(path), "//rest//acl");
  acls = noit_conf_get_sections(NULL, path, &cnt);
  noitL(noit_debug, "Found %d acl stanzas\n", cnt);
  for(ai = cnt-1; ai>=0; ai--) {
    char tbuff[32];
    struct noit_rest_acl *newacl;
    int ri, rcnt = 0;
    noit_boolean default_allow = noit_false;
    noit_conf_section_t *rules;

    newacl = calloc(1, sizeof(*newacl));
    newacl->next = newhead;
    newhead = newacl;
    if(noit_conf_get_stringbuf(acls[ai], "@type", tbuff, sizeof(tbuff)) &&
       !strcmp(tbuff, "allow"))
      newacl->allow = noit_true;

#define compile_re(node, cont, name) do { \
  char buff[256]; \
  if(noit_conf_get_stringbuf(node, "@" #name, buff, sizeof(buff))) { \
    const char *error; \
    int erroffset; \
    cont->name = pcre_compile(buff, 0, &error, &erroffset, NULL); \
  } \
} while(0)

    newacl->allow = default_allow;
    compile_re(acls[ai], newacl, cn);
    compile_re(acls[ai], newacl, url);
    rules = noit_conf_get_sections(acls[ai], "rule", &rcnt);
    for(ri = rcnt - 1; ri >= 0; ri--) {
      struct noit_rest_acl_rule *newacl_rule;
      newacl_rule = calloc(1, sizeof(*newacl_rule));
      newacl_rule->next = newacl->rules;
      newacl->rules = newacl_rule;
      if(noit_conf_get_stringbuf(rules[ri], "@type", tbuff, sizeof(tbuff)) &&
         !strcmp(tbuff, "allow"))
        newacl_rule->allow = noit_true;
      compile_re(rules[ri], newacl_rule, cn);
      compile_re(rules[ri], newacl_rule, url);
    }
    free(rules);
  }
  free(acls);

  oldacls = global_rest_acls;
  global_rest_acls = newhead;

  while(oldacls) {
    remove_acl = oldacls->next;
    while(oldacls->rules) {
      remove_rule = oldacls->rules->next;
      if(oldacls->rules->cn) pcre_free(oldacls->rules->cn);
      if(oldacls->rules->url) pcre_free(oldacls->rules->url);
      free(oldacls->rules);
      oldacls->rules = remove_rule;
    }
    if(oldacls->cn) pcre_free(oldacls->cn);
    if(oldacls->url) pcre_free(oldacls->url);
    free(oldacls);
    oldacls = remove_acl;
  }
}
Ejemplo n.º 7
0
void
noit_listener_reconfig(const char *toplevel) {
  int i, cnt = 0;
  noit_conf_section_t *listener_configs;
  char path[256];

  snprintf(path, sizeof(path), "/%s/listeners//listener",
           toplevel ? toplevel : "*");
  listener_configs = noit_conf_get_sections(NULL, path, &cnt);
  noitL(noit_debug, "Found %d %s stanzas\n", cnt, path);
  for(i=0; i<cnt; i++) {
    char address[256];
    char type[256];
    unsigned short port;
    int portint;
    int backlog;
    eventer_func_t f;
    noit_boolean ssl;
    noit_hash_table *sslconfig, *config;

    if(!noit_conf_get_stringbuf(listener_configs[i],
                                "ancestor-or-self::node()/@type",
                                type, sizeof(type))) {
      noitL(noit_error, "No type specified in listener stanza %d\n", i+1);
      continue;
    }
    f = eventer_callback_for_name(type);
    if(!f) {
      noitL(noit_error,
            "Cannot find handler for listener type: '%s'\n", type);
      continue;
    }
    if(!noit_conf_get_stringbuf(listener_configs[i],
                                "ancestor-or-self::node()/@address",
                                address, sizeof(address))) {
      address[0] = '*';
      address[1] = '\0';
    }
    if(!noit_conf_get_int(listener_configs[i],
                          "ancestor-or-self::node()/@port", &portint))
      portint = 0;
    port = (unsigned short) portint;
    if(address[0] != '/' && (portint == 0 || (port != portint))) {
      /* UNIX sockets don't require a port (they'll ignore it if specified */
      noitL(noit_error,
            "Invalid port [%d] specified in stanza %d\n", port, i+1);
      continue;
    }
    if(noit_listener_should_skip(address, port)) {
      if(port)
        noitL(noit_error, "Operator forced skipping listener %s:%d\n", address, port);
      else
        noitL(noit_error, "Operator forced skipping listener %s\n", address);
      continue;
    }
    if(!noit_conf_get_int(listener_configs[i],
                          "ancestor-or-self::node()/@backlog", &backlog))
      backlog = 5;

    if(!noit_conf_get_boolean(listener_configs[i],
                              "ancestor-or-self::node()/@ssl", &ssl))
     ssl = noit_false;

    sslconfig = ssl ?
                  noit_conf_get_hash(listener_configs[i], "sslconfig") :
                  NULL;
    config = noit_conf_get_hash(listener_configs[i], "config");

    if(noit_listener(address, port, SOCK_STREAM, backlog,
                     sslconfig, config, f, NULL) != 0) {
      noit_hash_destroy(config,free,free);
      free(config);
    }
    if(sslconfig) {
      /* A copy of this is made within noit_listener */
      noit_hash_destroy(sslconfig,free,free);
      free(sslconfig);
    }
  }
  free(listener_configs);
}
Ejemplo n.º 8
0
int
noit_main(const char *appname,
          const char *config_filename, int debug, int foreground,
          const char *_glider,
          const char *drop_to_user, const char *drop_to_group,
          int (*passed_child_main)(void)) {
  int fd, lockfd, watchdog_timeout = 0;
  char conf_str[1024];
  char lockfile[PATH_MAX];
  char user[32], group[32];
  char *trace_dir = NULL;
  char appscratch[1024];
  char *glider = (char *)_glider;
  char *watchdog_timeout_str;
   
  /* First initialize logging, so we can log errors */
  noit_log_init();
  noit_log_stream_add_stream(noit_debug, noit_stderr);
  noit_log_stream_add_stream(noit_error, noit_stderr);

  /* Next load the configs */
  noit_conf_init(appname);
  if(noit_conf_load(config_filename) == -1) {
    fprintf(stderr, "Cannot load config: '%s'\n", config_filename);
    exit(-1);
  }

  /* Reinitialize the logging system now that we have a config */
  snprintf(user, sizeof(user), "%d", getuid());
  snprintf(group, sizeof(group), "%d", getgid());
  if(noit_security_usergroup(drop_to_user, drop_to_group, noit_true)) {
    noitL(noit_stderr, "Failed to drop privileges, exiting.\n");
    exit(-1);
  }
  noit_conf_log_init(appname);
  cli_log_switches();
  if(noit_security_usergroup(user, group, noit_true)) {
    noitL(noit_stderr, "Failed to regain privileges, exiting.\n");
    exit(-1);
  }
  if(debug)
    noit_debug->enabled = 1;

  snprintf(appscratch, sizeof(appscratch), "/%s/watchdog/@glider", appname);
  if(!glider) noit_conf_get_string(NULL, appscratch, &glider);
  noit_watchdog_glider(glider);
  snprintf(appscratch, sizeof(appscratch), "/%s/watchdog/@tracedir", appname);
  noit_conf_get_string(NULL, appscratch, &trace_dir);
  if(trace_dir) noit_watchdog_glider_trace_dir(trace_dir);

  /* Lastly, run through all other system inits */
  snprintf(appscratch, sizeof(appscratch), "/%s/eventer/@implementation", appname);
  if(!noit_conf_get_stringbuf(NULL, appscratch, conf_str, sizeof(conf_str))) {
    noitL(noit_stderr, "Cannot find '%s' in configuration\n", appscratch);
    exit(-1);
  }
  if(eventer_choose(conf_str) == -1) {
    noitL(noit_stderr, "Cannot choose eventer %s\n", conf_str);
    exit(-1);
  }
  if(configure_eventer(appname) != 0) {
    noitL(noit_stderr, "Cannot configure eventer\n");
    exit(-1);
  }

  noit_watchdog_prefork_init();

  if(chdir("/") != 0) {
    noitL(noit_stderr, "Failed chdir(\"/\"): %s\n", strerror(errno));
    exit(-1);
  }

  /* Acquire the lock so that we can throw an error if it doesn't work.
   * If we've started -D, we'll have the lock.
   * If not we will daemon and must reacquire the lock.
   */
  lockfd = -1;
  lockfile[0] = '\0';
  snprintf(appscratch, sizeof(appscratch), "/%s/@lockfile", appname);
  if(noit_conf_get_stringbuf(NULL, appscratch,
                             lockfile, sizeof(lockfile))) {
    if((lockfd = noit_lockfile_acquire(lockfile)) < 0) {
      noitL(noit_stderr, "Failed to acquire lock: %s\n", lockfile);
      exit(-1);
    }
  }

  if(foreground) return passed_child_main();

  watchdog_timeout_str = getenv("WATCHDOG_TIMEOUT");
  if(watchdog_timeout_str) {
    watchdog_timeout = atoi(watchdog_timeout_str);
    noitL(noit_error, "Setting watchdog timeout to %d\n",
          watchdog_timeout);
  }

  /* This isn't inherited across forks... */
  if(lockfd >= 0) noit_lockfile_release(lockfd);

  fd = open("/dev/null", O_RDWR);
  dup2(fd, STDIN_FILENO);
  dup2(fd, STDOUT_FILENO);
  dup2(fd, STDERR_FILENO);
  if(fork()) exit(0);
  setsid();
  if(fork()) exit(0);

  /* Reacquire the lock */
  if(*lockfile) {
    if(noit_lockfile_acquire(lockfile) < 0) {
      noitL(noit_stderr, "Failed to acquire lock: %s\n", lockfile);
      exit(-1);
    }
  }

  signal(SIGHUP, SIG_IGN);
  return noit_watchdog_start_child("noitd", passed_child_main, watchdog_timeout);
}