int Mod_fw_open(FW_handle_T handle) { struct fw_handle *fwh = NULL; char *npfdev_path; int npfdev; npfdev_path = Config_get_str(handle->config, "npfdev_path", "firewall", NPFDEV_PATH); if((fwh = malloc(sizeof(*fwh))) == NULL) return -1; npfdev = open(npfdev_path, O_RDONLY); if(npfdev < 1) { i_warning("could not open %s: %s", npfdev_path, strerror(errno)); return -1; } fwh->npfdev = npfdev; fwh->pcap_handle = NULL; handle->fwh = fwh; return 0; }
int Mod_fw_open(FW_handle_T handle) { struct fw_handle *fwh = NULL; char *pfdev_path; int pfdev; pfdev_path = Config_get_str(handle->config, "pfdev_path", "firewall", PFDEV_PATH); if((fwh = malloc(sizeof(*fwh))) == NULL) return -1; pfdev = open(pfdev_path, O_RDWR); if(pfdev < 1 || pfdev > MAX_PFDEV) { i_warning("could not open %s: %s", pfdev_path, strerror(errno)); return -1; } fwh->pfdev = pfdev; fwh->pcap_handle = NULL; handle->fwh = fwh; return 0; }
void Mod_fw_start_log_capture(FW_handle_T handle) { struct fw_handle *fwh = handle->fwh; struct bpf_program bpfp; char *pflog_if, *net_if; char errbuf[PCAP_ERRBUF_SIZE]; char filter[PCAPFSIZ] = "ip and port 25 and action pass " "and tcp[13]&0x12=0x2"; pflog_if = Config_get_str(handle->config, "pflog_if", "firewall", PFLOG_IF); net_if = Config_get_str(handle->config, "net_if", "firewall", NULL); if((fwh->pcap_handle = pcap_open_live(pflog_if, PCAPSNAP, 1, PCAPTIMO, errbuf)) == NULL) { i_critical("failed to initialize: %s", errbuf); } if(pcap_datalink(fwh->pcap_handle) != DLT_PFLOG) { pcap_close(fwh->pcap_handle); fwh->pcap_handle = NULL; i_critical("invalid datalink type"); } if(net_if != NULL) { sstrncat(filter, " and on ", PCAPFSIZ); sstrncat(filter, net_if, PCAPFSIZ); } if((pcap_compile(fwh->pcap_handle, &bpfp, filter, PCAPOPTZ, 0) == -1) || (pcap_setfilter(fwh->pcap_handle, &bpfp) == -1)) { i_critical("%s", pcap_geterr(fwh->pcap_handle)); } pcap_freecode(&bpfp); #ifdef BIOCLOCK if(ioctl(pcap_fileno(fwh->pcap_handle), BIOCLOCK) < 0) { i_critical("BIOCLOCK: %s", strerror(errno)); } #endif fwh->entries = List_create(destroy_log_entry); }
int Config_get_int(const char *par_name) { unsigned int intval; char *strval = Config_get_str(par_name); if(!sscanf(strval, "0x%04x", &intval) && !sscanf(strval, "%d", &intval)) { return 0; } return(intval); }
int Mod_fw_replace(FW_handle_T handle, const char *set_name, List_T cidrs, short af) { struct fw_handle *fwh = handle->fwh; int fd, nadded = 0, child = -1, status; char *cidr, *fd_path = NULL, *pfctl_path = PFCTL_PATH; char *table = (char *) set_name; static FILE *pf = NULL; struct List_entry *entry; struct sigaction act, oldact; char *argv[11] = { "pfctl", "-p", PFDEV_PATH, "-q", "-t", table, "-T", "replace", "-f", "-", NULL }; if(List_size(cidrs) == 0) return 0; pfctl_path = Config_get_str(handle->config, "pfctl_path", "firewall", PFCTL_PATH); if(asprintf(&fd_path, "/dev/fd/%d", fwh->pfdev) == -1) return -1; argv[2] = fd_path; memset(&act, 0, sizeof(act)); act.sa_handler = SIG_DFL; sigaction(SIGCHLD, &act, &oldact); if((pf = setup_cntl_pipe(pfctl_path, argv, &child)) == NULL) { free(fd_path); fd_path = NULL; goto err; } free(fd_path); fd_path = NULL; LIST_EACH(cidrs, entry) { if((cidr = List_entry_value(entry)) != NULL) { fprintf(pf, "%s\n", cidr); nadded++; } } fclose(pf); waitpid(child, &status, 0); if(WIFEXITED(status) && WEXITSTATUS(status) != 0) { i_warning("%s returned status %d", pfctl_path, WEXITSTATUS(status)); goto err; } else if(WIFSIGNALED(status)) { i_warning("%s died on signal %d", pfctl_path, WTERMSIG(status)); goto err; } signal(SIGCHLD, &oldact, NULL); return nadded; err: return -1; }
int main(void) { Config_T c, m; Config_section_T s1, s2, s; Config_value_T v; List_T list; int *count; TEST_START(34); c = Config_create(); TEST_OK((c != NULL), "Config created successfully"); s1 = Config_section_create(SEC1); Config_section_set_str(s1, VAR1, VAL1); Config_section_set_int(s1, VAR2, VAL2); Config_add_section(c, s1); s = Config_get_section(c, SEC1); TEST_OK((s != NULL), "Non-null section fetched as expected"); TEST_OK((strcmp(s->name, SEC1) == 0), "Fetched section matches expected name"); s = Config_get_section(c, "this section doesn't exist"); TEST_OK((s == NULL), "Non-existant section fetched as expected"); Config_destroy(&c); /* * Test the recursive config loading & parsing from a blank config. */ c = Config_create(); Config_load_file(c, "data/config_test1.conf"); s1 = Config_get_section(c, "storage"); TEST_OK((s1 != NULL), "Storage section parsed correctly"); v = Config_section_get(s1, "storage_driver"); TEST_OK((v && (strcmp(v->v.s, "MySQL") == 0)), "Section variable overridden correctly"); v = Config_section_get(s1, "db_host"); TEST_OK((v && (strcmp(v->v.s, "localhost") == 0)), "Section variable overridden correctly"); v = Config_section_get(s1, "db_port"); TEST_OK((v && (v->v.i == 3306)), "Section variable overridden correctly"); v = Config_section_get(s1, "db_name"); TEST_OK((v && (strcmp(v->v.s, "greyd") == 0)), "Section variable overridden correctly"); s2 = Config_get_section(c, CONFIG_DEFAULT_SECTION); TEST_OK((s2 != NULL), "Storage section parsed correctly"); v = Config_section_get(s2, "ip_address"); TEST_OK((v && (strcmp(v->v.s, "1.2.3.4") == 0)), "Default section variable left alone correctly"); v = Config_section_get(s2, "another_global"); TEST_OK((v && (strcmp(v->v.s, "this is overwritten") == 0)), "Default section variable overridden correctly"); v = Config_section_get(s2, "limit"); TEST_OK((v && (v->v.i == 25)), "Default section variable overridden correctly"); s1 = Config_get_section(c, "cache"); TEST_OK((s1 != NULL), "Storage section in included config parsed correctly"); v = Config_section_get(s1, "cache_driver"); TEST_OK((v && (strcmp(v->v.s, "memcached") == 0)), "Section variable overridden correctly"); v = Config_section_get(s1, "port"); TEST_OK((v && (v->v.i == 11211)), "Section variable overridden correctly"); v = Config_section_get(s1, "host"); TEST_OK((v && (strcmp(v->v.s, "localhost") == 0)), "Section variable overridden correctly"); /* Check the hashed included file counts. */ count = (int *) Hash_get(c->processed_includes, "data/config_test1.conf"); TEST_OK((count && (*count == 1)), "First config include file count as expected"); count = (int *) Hash_get(c->processed_includes, "data/config_test2.conf"); TEST_OK((count && (*count == 1)), "Second config include file count as expected"); count = (int *) Hash_get(c->processed_includes, "data/config_test3.conf"); TEST_OK((count && (*count == 1)), "Third config include file count as expected"); TEST_OK((Queue_size(c->includes) == 0), "Include file to process queue is empty as expected"); Config_set_str(c, "mystr1", NULL, "mystr value"); Config_set_str(c, "mystr1", "mysection1", "mystr1 value"); Config_set_int(c, "myint1", NULL, 4321); Config_set_int(c, "myint1", "mysection2", 1234); TEST_OK(!strcmp(Config_get_str(c, "mystr1", NULL, NULL), "mystr value"), "str set/get ok"); TEST_OK(!strcmp(Config_get_str(c, "mystr1", "mysection1", NULL), "mystr1 value"), "str set/get ok"); TEST_OK(Config_get_int(c, "myint1", NULL, 0) == 4321, "int set/get ok"); TEST_OK(Config_get_int(c, "myint1", "mysection2", 0) == 1234, "int set/get ok"); m = Config_create(); Config_set_str(m, "mystr1", NULL, "overwritten"); Config_set_str(m, "mystr1", "mysection6", "preserved"); Config_set_int(m, "myint1", "mysection2", 4); Config_set_int(m, "myint86", NULL, 4); Config_merge(m, c); TEST_OK(!strcmp(Config_get_str(m, "mystr1", NULL, NULL), "mystr value"), "str overwritten ok"); TEST_OK(!strcmp(Config_get_str(m, "mystr1", "mysection1", NULL), "mystr1 value"), "new str/section ok"); Config_delete(m, "mystr1", "mysection1"); TEST_OK(Config_get_str(m, "mystr1", "mysection1", NULL) == NULL, "str deleted ok"); TEST_OK(Config_get_int(m, "myint86", NULL, 0) == 4, "new int ok"); TEST_OK(Config_get_int(m, "myint1", "mysection2", 0) == 1234, "int overwrite"); Config_delete(m, "myint1", "mysection2"); TEST_OK(Config_get_int(m, "myint1", "mysection2", -1000) == -1000, "int deleted ok"); Config_append_list_str(m, "newlist", "newsection", "my str var"); Config_append_list_str(m, "newlist", "newsection", "another var"); list = Config_get_list(m, "newlist", "newsection"); TEST_OK((list != NULL), "list created successfully"); TEST_OK((List_size(list) == 2), "list entries ok"); Config_delete(m, "newlist", "newsection"); list = Config_get_list(m, "newlist", "newsection"); TEST_OK((list == NULL), "list deleted successfully"); /* Test deleting a non-existant value. */ Config_delete(m, "i dont exist", "no section"); Config_destroy(&c); Config_destroy(&m); TEST_COMPLETE; }