Esempio n. 1
0
File: main.c Progetto: kkaneda/vm
int
main ( int argc, char *argv[], char *envp[] )
{
	struct mon_t *mon;
	struct config_t *config;

	config = Config_create ( argc, argv );
	mon = Monitor_create ( config );
	Monitor_run ( mon );

	return 0;
}
Esempio n. 2
0
int
main(void)
{
    Lexer_source_T ls;
    Lexer_T l;
    Config_parser_T cp;
    Config_T c;
    struct Greyd_state gs;
    struct Con con;
    Blacklist_T bl1, bl2, bl3;
    struct sockaddr_storage src;
    int ret;
    char *conf =
        "hostname = \"greyd.org\"\n"
        "banner   = \"greyd IP-based SPAM blocker\"\n"
        "section grey {\n"
        "  enable           = 1,\n"
        "  traplist_name    = \"test traplist\",\n"
        "  traplist_message = \"you have been trapped\",\n"
        "  grey_expiry      = 3600,\n"
        "  stutter          = 15\n"
        "}\n"
        "section firewall {\n"
        "  driver = \"../drivers/fw_dummy.so\"\n"
        "}\n"
        "section database {\n"
        "  driver = \"../drivers/bdb.so\",\n"
        "  path   = \"/tmp/greyd_test_grey.db\"\n"
        "}";

    /* Empty existing database file. */
    ret = unlink("/tmp/greyd_test_grey.db");
    if(ret < 0 && errno != ENOENT) {
        printf("Error unlinking test Berkeley DB: %s\n", strerror(errno));
    }

    TEST_START(49);

    c = Config_create();
    ls = Lexer_source_create_from_str(conf, strlen(conf));
    l = Config_lexer_create(ls);
    cp = Config_parser_create(l);
    Config_parser_start(cp, c);

    /*
     * Set up the greyd state and blacklists.
     */
    memset(&gs, 0, sizeof(gs));
    gs.config = c;
    gs.max_cons = 4;
    gs.max_black = 4;
    gs.blacklists = Hash_create(5, NULL);

    bl1 = Blacklist_create("blacklist_1", "You (%A) are on blacklist 1", BL_STORAGE_TRIE);
    bl2 = Blacklist_create("blacklist_2", "You (%A) are on blacklist 2", BL_STORAGE_TRIE);
    bl3 = Blacklist_create("blacklist_3_with_an_enormously_big_long_long_epic_epicly_long_large_name",
                           "Your address %A\\nis on blacklist 3", BL_STORAGE_TRIE);

    Hash_insert(gs.blacklists, bl1->name, bl1);
    Hash_insert(gs.blacklists, bl2->name, bl2);
    Hash_insert(gs.blacklists, bl3->name, bl3);

    Blacklist_add(bl1, "10.10.10.1/32");
    Blacklist_add(bl1, "10.10.10.2/32");

    Blacklist_add(bl2, "10.10.10.1/32");
    Blacklist_add(bl2, "10.10.10.2/32");
    Blacklist_add(bl2, "2001::fad3:1/128");

    Blacklist_add(bl3, "10.10.10.2/32");
    Blacklist_add(bl3, "10.10.10.3/32");
    Blacklist_add(bl3, "2001::fad3:1/128");

    /*
     * Start testing the connection management.
     */
    memset(&src, 0, sizeof(src));
    ((struct sockaddr_in *) &src)->sin_family = AF_INET;
    inet_pton(AF_INET, "10.10.10.1", &((struct sockaddr_in *) &src)->sin_addr);

    memset(&con, 0, sizeof(con));
    Con_init(&con, 0, &src, &gs);

    TEST_OK(con.state == 0, "init state ok");
    TEST_OK(con.last_state == 0, "last state ok");
    TEST_OK(List_size(con.blacklists) == 2, "blacklist matches ok");
    TEST_OK(!strcmp(con.src_addr, "10.10.10.1"), "src addr ok");
    TEST_OK(con.out_buf != NULL, "out buf ok");
    TEST_OK(con.out_p == con.out_buf, "out buf pointer ok");
    TEST_OK(con.out_size == CON_OUT_BUF_SIZE, "out buf size ok");
    TEST_OK(!strcmp(con.lists, "blacklist_1 blacklist_2"),
            "list summary ok");

    /* The size of the banner. */
    TEST_OK(con.out_remaining == 75, "out buf remaining ok");

    TEST_OK(gs.clients == 1, "clients ok");
    TEST_OK(gs.black_clients == 1, "blacklisted clients ok");

    /*
     * Test the closing of a connection.
     */
    Con_close(&con, &gs);
    TEST_OK(List_size(con.blacklists) == 0, "blacklist empty ok");
    TEST_OK(con.out_buf == NULL, "out buf ok");
    TEST_OK(con.out_p == NULL, "out buf pointer ok");
    TEST_OK(con.out_size == 0, "out buf size ok");
    TEST_OK(con.lists == NULL, "lists ok");

    TEST_OK(gs.clients == 0, "clients ok");
    TEST_OK(gs.black_clients == 0, "blacklisted clients ok");

    /* Test recycling a connection. */
    memset(&src, 0, sizeof(src));
    ((struct sockaddr_in6 *) &src)->sin6_family = AF_INET6;
    inet_pton(AF_INET6, "2001::fad3:1", &((struct sockaddr_in6 *) &src)->sin6_addr);

    Con_init(&con, 0, &src, &gs);

    TEST_OK(con.state == 0, "init state ok");
    TEST_OK(con.last_state == 0, "last state ok");
    TEST_OK(List_size(con.blacklists) == 2, "blacklist matches ok");
    TEST_OK(!strcmp(con.src_addr, "2001::fad3:1"), "src addr ok");
    TEST_OK(con.out_buf != NULL, "out buf ok");
    TEST_OK(con.out_p == con.out_buf, "out buf pointer ok");
    TEST_OK(con.out_size == CON_OUT_BUF_SIZE, "out buf size ok");

    /*
     * As the 3rd blacklist's name is really long, the summarize lists
     * function should truncate with a "...".
     */
    TEST_OK(!strcmp(con.lists, "blacklist_2 ..."),
            "list summary ok");

    /* The size of the banner. */
    TEST_OK(con.out_remaining == 75, "out buf remaining ok");

    TEST_OK(gs.clients == 1, "clients ok");
    TEST_OK(gs.black_clients == 1, "blacklisted clients ok");

    /*
     * Test the rejection message building.
     */
    Con_build_reply(&con, "451");
    TEST_OK(!strcmp(con.out_p,
                    "451-You (2001::fad3:1) are on blacklist 2\n"
                    "451-Your address 2001::fad3:1\n"
                    "451 is on blacklist 3\n"),
            "Blacklisted error response ok");
    TEST_OK(con.out_remaining == 94, "out buf remaining ok");

    /*
     * Test the writing of the buffer without stuttering.
     */
    time_t now = time(NULL);
    int con_pipe[2], to_write, nread;
    char in[CON_OUT_BUF_SIZE];

    pipe(con_pipe);
    con.fd = con_pipe[1];
    con.w = now;
    to_write = con.out_remaining;
    Con_handle_write(&con, &now, &gs);
    nread = read(con_pipe[0], in, to_write);
    in[nread] = '\0';

    TEST_OK(!strcmp(in,
                    "451-You (2001::fad3:1) are on blacklist 2\n"
                    "451-Your address 2001::fad3:1\n"
                    "451 is on blacklist 3\n"),
            "Con write without stuttering ok");

    /*
     * Test the writing with stuttering. Note the reply is longer due
     * to the stutering adding in \r before each \n if there isn't one
     * already.
     */
    Con_build_reply(&con, "451");
    gs.max_cons = 100;
    gs.max_black = 100;
    con.w = now;
    while(con.out_remaining > 0) {
        Con_handle_write(&con, &now, &gs);
        now += con.stutter + 1;
    }

    memset(in, 0, sizeof(in));
    nread = read(con_pipe[0], in, to_write + 3);
    in[nread] = '\0';

    TEST_OK(!strcmp(in,
                    "451-You (2001::fad3:1) are on blacklist 2\r\n"
                    "451-Your address 2001::fad3:1\r\n"
                    "451 is on blacklist 3\r\n"),
            "Con write with stuttering ok");

    /* Test recycling a connection, which is not on a blacklist. */
    Con_close(&con, &gs);
    memset(&src, 0, sizeof(src));
    ((struct sockaddr_in6 *) &src)->sin6_family = AF_INET6;
    inet_pton(AF_INET6, "fa40::fad3:1", &((struct sockaddr_in6 *) &src)->sin6_addr);

    Con_init(&con, 0, &src, &gs);
    TEST_OK(List_size(con.blacklists) == 0, "not on blacklist ok");

    /*
     * Note custom error codes only apply for blacklist connections, so expect
     * a 451 for this greylisted connections.
     */
    Con_build_reply(&con, "551");
    TEST_OK(!strcmp(con.out_p,
                    "451 Temporary failure, please try again later.\r\n"),
            "greylisted error response ok");
    Con_close(&con, &gs);
    List_destroy(&con.blacklists);

    /*
     * Test the connection reading function.
     */
    memset(&src, 0, sizeof(src));
    ((struct sockaddr_in *) &src)->sin_family = AF_INET;
    inet_pton(AF_INET, "10.10.10.1", &((struct sockaddr_in *) &src)->sin_addr);

    pipe(con_pipe);
    memset(&con, 0, sizeof(con));
    Con_init(&con, con_pipe[0], &src, &gs);

    char *out = "EHLO greyd.org\r\n";
    write(con_pipe[1], out, strlen(out));

    Con_handle_read(&con, &now, &gs); /* This should change the state. */
    TEST_OK(con.state == CON_STATE_HELO_IN, "Initial state set ok");
    Con_handle_read(&con, &now, &gs);
    TEST_OK(!strcmp(con.in_buf, "EHLO greyd.org"), "con read ok");
    TEST_OK(!strcmp(con.helo, "greyd.org"), "helo parsed ok");
    TEST_OK(con.state = CON_STATE_HELO_OUT, "state helo out ok");

    char *mail_from = "MAIL FROM: <*****@*****.**>\r\n";
    write(con_pipe[1], mail_from, strlen(mail_from));

    Con_next_state(&con, &now, &gs);
    TEST_OK(con.state = CON_STATE_MAIL_IN, "state mail in ok");
    Con_handle_read(&con, &now, &gs);
    TEST_OK(!strcmp(con.mail, "*****@*****.**"), "MAIL FROM parsed ok");
    TEST_OK(con.state = CON_STATE_MAIL_OUT, "state mail out ok");

    char *rcpt = "RCPT TO: [email protected]\r\n";
    write(con_pipe[1], rcpt, strlen(rcpt));

    Con_next_state(&con, &now, &gs);
    TEST_OK(con.state = CON_STATE_RCPT_IN, "state rcpt in ok");
    Con_handle_read(&con, &now, &gs);
    TEST_OK(!strcmp(con.rcpt, "*****@*****.**"), "RCPT parsed ok");
    TEST_OK(con.state = CON_STATE_RCPT_OUT, "state rcpt out ok");

    char *data = "DATA\r\n";
    write(con_pipe[1], data, strlen(data));

    Con_next_state(&con, &now, &gs);
    TEST_OK(con.state = CON_STATE_RCPT_IN, "state rcpt in ok"); /* this will goto spam. */
    Con_handle_read(&con, &now, &gs);
    TEST_OK(con.state = CON_STATE_DATA_OUT, "state data out ok");

    char *msg = "This is a spam message\r\ndeliver me!\r\n.\r\n";
    write(con_pipe[1], msg, strlen(msg));

    Con_next_state(&con, &now, &gs);
    TEST_OK(con.state = CON_STATE_MESSAGE, "state message ok");
    Con_handle_read(&con, &now, &gs);
    TEST_OK(con.state = CON_STATE_CLOSE, "state close ok");

    /* This should close the connection. */
    Con_next_state(&con, &now, &gs);

    /* Cleanup. */
    List_destroy(&con.blacklists);
    Hash_destroy(&gs.blacklists);
    Blacklist_destroy(&bl1);
    Blacklist_destroy(&bl2);
    Blacklist_destroy(&bl3);
    Config_destroy(&c);
    Config_parser_destroy(&cp);

    TEST_COMPLETE;
}
Esempio n. 3
0
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;
}