예제 #1
0
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;
}
예제 #2
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
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;
}