static int read_2ip(const char *buf, const char *delim, struct sockaddr_storage *addr, struct sockaddr_storage *addr2) { char tmpbuf[BUFLEN]; char *deli; deli = strstr(buf, delim); if (!deli) { return -1; } strncpy(tmpbuf, buf, deli-buf); tmpbuf[deli-buf] = '\0'; if (get_ipaddress(tmpbuf, addr)) { return -1; } if (get_ipaddress(deli+1, addr2)) { return -1; } return 0; }
static int search_handler(request_rec *r, softbot_handler_rec *s) { int rv = 0; int i = 0, j = 0, cmt_idx = 0, deleted_cnt = 0; struct timeval tv; uint32_t start_time = 0, end_time = 0; char content_type[SHORT_STRING_SIZE+1]; init_server(r, s); if ( print_elapsed_time ) { gettimeofday(&tv, NULL); start_time = tv.tv_sec*1000 + tv.tv_usec/1000; } msg_record_init(&s->msg); set_con_config(r->server); rv = sb_run_qp_init(); if(rv != SUCCESS && rv != DECLINE) { MSG_RECORD(&s->msg, error, "qp init failed"); return FAIL; } if(apr_table_get(s->parameters_in, "q") == NULL || strlen(apr_table_get(s->parameters_in, "q")) == 0) { MSG_RECORD(&s->msg, error, "Parameter 'q' is null or has zero length. query is null." " You have to input a valid query or use GET method instead of POST."); return FAIL; } ap_unescape_url((char *)apr_table_get(s->parameters_in, "q")); rv = sb_run_qp_init_request(&qp_request, (char *)apr_table_get(s->parameters_in, "q")); if(rv != SUCCESS) { error("can not init request"); s->msg = qp_request.msg; return FAIL; } rv = sb_run_qp_init_response(&qp_response); if(rv != SUCCESS) { error("can not init request"); return FAIL; } //2. get result timelog("full_search_start"); rv = sb_run_qp_full_search(&qp_request, &qp_response); timelog("full_search_finish"); if (rv != SUCCESS) { error("sb_run_qp_full_search failed: query[%s]", qp_request.query); s->msg = qp_request.msg; return FAIL; } if ( qp_request.is_delete ) { int i = 0; int j = 0; int is_recovery = 0; if( qp_request.select_list.cnt > 0 && qp_request.select_list.field[0].name[0] == '0' ) { info("recovery deleted document"); is_recovery = 1; } for(i = 0; i < qp_response.vdl->cnt; i++) { for(j = 0; j < qp_response.vdl->data[i].dochit_cnt; j++) { int rv = 0; uint32_t docid = qp_response.vdl->data[i].dochits[j].id; docattr_t* docattr = NULL; debug("delete docid[%u]", docid); rv = sb_run_docattr_ptr_get(docid, &docattr); if ( rv < 0 ) { error("cannot get docattr of docid[%u]", docid); continue; } if( is_recovery ) { rv = sb_run_docattr_set_docattr_function(docattr, "Delete", "0"); } else { rv = sb_run_docattr_set_docattr_function(docattr, "Delete", "1"); } if ( rv < 0 ) { error("cannot delete docid[%u]", docid); continue; } deleted_cnt++; } } } if ( print_elapsed_time ) { gettimeofday(&tv, NULL); end_time = tv.tv_sec*1000 + tv.tv_usec/1000; } timelog("send_result_start"); snprintf( content_type, SHORT_STRING_SIZE, "text/xml; charset=%s", default_charset); ap_set_content_type(r, content_type); ap_rprintf(r, "<?xml version=\"1.0\" encoding=\"%s\"?>\n", default_charset); ap_rprintf(r, "<xml>\n" "<status>1</status>\n" "<query><![CDATA[%s]]></query>\n" "<parsed_query><![CDATA[%s]]></parsed_query>\n" "<result_count>%d</result_count>\n", qp_request.query, qp_response.parsed_query, qp_response.search_result); if ( qp_request.is_delete ) { ap_rprintf(r, "<deleted_count>%d</deleted_count>\n", deleted_cnt); } if(server_id[0] == '\0') { ap_rprintf(r, "<server_id><![CDATA[%s]]></server_id>\n", get_ipaddress(r->pool)); } else { ap_rprintf(r, "<server_id><![CDATA[%s]]></server_id>\n", server_id); } /* elapsed time */ if ( print_elapsed_time ) { ap_rprintf(r, "<elapsed_time>%u</elapsed_time>\n", end_time - start_time); } /* group result */ ap_rprintf(r, "<groups count=\"%d\">\n", qp_response.groupby_result_vid.rules.cnt); print_group(r, &qp_response.groupby_result_vid); ap_rprintf(r, "</groups>\n"); /* ap_rprintf(r, "<groups type=\"did\">\n"); print_group(r, &qp_response.groupby_result_did); ap_rprintf(r, "</groups>\n"); */ if( qp_request.is_delete ) { } else { /* each result */ ap_rprintf(r, "<vdocs count=\"%d\">\n", qp_response.vdl->cnt); for(i = 0; i < qp_response.vdl->cnt; i++) { virtual_document_t* vd = (virtual_document_t*)&qp_response.vdl->data[i]; ap_rprintf(r, "<vdoc vid=\"%d\" node_id=\"%0X\" relevance=\"%d\">\n", vd->id, vd->node_id, vd->relevance); ap_rprintf(r, "<docs count=\"%d\">\n", vd->comment_cnt); for(j = 0; j < vd->comment_cnt; j++) { comment_t* cmt = &qp_response.comments[cmt_idx++]; ap_rprintf(r, "<doc doc_id=\"%d\">\n", cmt->did); if(qp_request.output_style == STYLE_XML) { ap_rprintf(r, "%s\n", cmt->s); } else { ap_rprintf(r, "<![CDATA[%s]]>\n", cmt->s); } ap_rprintf(r, "</doc>\n"); } ap_rprintf(r, "</docs>\n"); ap_rprintf(r, "</vdoc>\n"); } ap_rprintf(r, "</vdocs>\n"); } ap_rprintf(r, "</xml>\n"); timelog("send_result_finish"); s->msg = qp_request.msg; sb_run_qp_finalize_search(&qp_request, &qp_response); timelog("qp_finalize"); return SUCCESS; }
int test(void) { int i = 0; int expected; struct sockaddr_storage saddr; struct acl_match_entry *match_entry; /* * default tests */ while (tests[i] != NULL) { /* * First char is A (accept) or R (Reject) */ switch(tests[i][0] & 0x5F) { case 'A': expected = 1; break; case 'R': expected = 0; break; default: fprintf(stderr, "Unknown record type on line %d: %s\n", i, tests[i]); return FAIL; break; } if (get_ipaddress(tests[i]+1, &saddr)) { fprintf(stderr, "Cannot parse address %s\n", tests[i]+1); return FAIL; } if (saddr.ss_family == AF_INET) { match_entry = match_entry_v4; } else { match_entry = match_entry_v6; } if (ipcheck_validate(&match_entry, &saddr) != expected) { fprintf(stderr, "Failed to check access list for ip: %s\n", tests[i]); return FAIL; } i++; } /* * insert tests */ if (get_ipaddress("192.168.2.1", &saddr)) { fprintf(stderr, "Cannot parse address 192.168.2.1\n"); return FAIL; } if (ipcheck_addip(&match_entry_v4, 3, &saddr, &saddr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) { fprintf(stderr, "Unable to insert address in position 3 192.168.2.1\n"); return FAIL; } if (get_ipaddress("3ffe:1::1", &saddr)) { fprintf(stderr, "Cannot parse address 3ffe:1::1\n"); return FAIL; } if (ipcheck_addip(&match_entry_v6, 3, &saddr, &saddr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) { fprintf(stderr, "Unable to insert address in position 3 3ffe:1::1\n"); return FAIL; } while (after_insert_tests[i] != NULL) { /* * First char is A (accept) or R (Reject) */ switch(after_insert_tests[i][0] & 0x5F) { case 'A': expected = 1; break; case 'R': expected = 0; break; default: fprintf(stderr, "Unknown record type on line %d: %s\n", i, after_insert_tests[i]); return FAIL; break; } if (get_ipaddress(after_insert_tests[i]+1, &saddr)) { fprintf(stderr, "Cannot parse address %s\n", after_insert_tests[i]+1); return FAIL; } if (saddr.ss_family == AF_INET) { match_entry = match_entry_v4; } else { match_entry = match_entry_v6; } if (ipcheck_validate(&match_entry, &saddr) != expected) { fprintf(stderr, "Failed to check access list for ip: %s\n", after_insert_tests[i]); return FAIL; } i++; } return PASS; }
int main(int argc, char *argv[]) { struct sockaddr_storage saddr; struct acl_match_entry *match_entry; int ret = PASS; int i; if (default_rules(1) < 0) { return -1; } if (argc > 1) { /* * run manual check against default access lists */ for (i=1; i<argc; i++) { if (get_ipaddress(argv[i], &saddr)) { fprintf(stderr, "Cannot parse address %s\n", argv[i]); ret = FAIL; goto out; } else { if (saddr.ss_family == AF_INET) { match_entry = match_entry_v4; } else { match_entry = match_entry_v6; } if (ipcheck_validate(&match_entry, &saddr)) { printf("%s is VALID\n", argv[i]); ret = PASS; } else { printf("%s is not allowed\n", argv[i]); ret = FAIL; } } } } else { /* * run automatic tests */ ret = test(); } /* * test memory leaks with ipcheck_rmip */ if (default_rules(0) < 0) { return FAIL; } /* * test memory leaks with ipcheck_rmall */ if (default_rules(1) < 0) { return FAIL; } out: ipcheck_rmall(&match_entry_v4); ipcheck_rmall(&match_entry_v6); return ret; }
static int default_rules(int load) { int ret; check_type_t type; check_acceptreject_t acceptreject; struct sockaddr_storage addr1; struct sockaddr_storage addr2; int i = 0; int (*loadfn)(void *fd_tracker_match_entry_head, struct sockaddr_storage *ss1, struct sockaddr_storage *ss2, check_type_t type, check_acceptreject_t acceptreject); if (load) { loadfn = _ipcheck_addip; } else { loadfn = ipcheck_rmip; } while (rules[i] != NULL) { printf("Parsing rule: %s\n", rules[i]); memset(&addr1, 0, sizeof(struct sockaddr_storage)); memset(&addr2, 0, sizeof(struct sockaddr_storage)); /* * First char is A (accept) or R (Reject) */ switch(rules[i][0] & 0x5F) { case 'A': acceptreject = CHECK_ACCEPT; break; case 'R': acceptreject = CHECK_REJECT; break; default: fprintf(stderr, "Unknown record type on line %d: %s\n", i, rules[i]); goto next_record; } /* * Second char is the filter type: * A Address * M Mask * R Range */ switch(rules[i][1] & 0x5F) { case 'A': type = CHECK_TYPE_ADDRESS; ret = get_ipaddress(rules[i]+2, &addr1); break; case 'M': type = CHECK_TYPE_MASK; ret = read_2ip(rules[i]+2, "/", &addr1, &addr2); break; case 'R': type = CHECK_TYPE_RANGE; ret = read_2ip(rules[i]+2, "-", &addr1, &addr2); break; default: fprintf(stderr, "Unknown filter type on line %d: %s\n", i, rules[i]); goto next_record; break; } if (ret) { fprintf(stderr, "Failed to parse address on line %d: %s\n", i, rules[i]); return -1; } else { if (addr1.ss_family == AF_INET) { if (loadfn(&match_entry_v4, &addr1, &addr2, type, acceptreject) < 0) { fprintf(stderr, "Failed to add/rm address on line %d: %s (errno: %s)\n", i, rules[i], strerror(errno)); return -1; } } else { if (loadfn(&match_entry_v6, &addr1, &addr2, type, acceptreject) < 0) { fprintf(stderr, "Failed to add/rm address on line %d: %s (errno: %s)\n", i, rules[i], strerror(errno)); return -1; } } } next_record: i++; } return 0; }