예제 #1
0
int
configuration(struct app_parent *app_p,
              const char *configfile,
              char **policy_file,
              char **syslog_ident,
              int *syslog_flags,
              int *syslog_facility) {
    unsigned int i, j;
    struct tq_listener_s *p_listener = NULL;
    struct tq_service_s *p_service = NULL;
    char *buf = NULL;
    cfg_t *cfg;
    cfg_t *syslog_sec;
    unsigned n_listener, n_services;
    int ret;
    static cfg_opt_t syslog_opts[] = {
        CFG_STR("ident", NULL, CFGF_NONE),
        CFG_INT_CB("facility", NONE, CFGF_NONE, &cb_syslog_facility),
        CFG_INT_LIST_CB("options", NULL, CFGF_NONE, &cb_syslog_options),
        CFG_END()
    };
    static cfg_opt_t service_opts[] = {
        CFG_INT_CB("type", NONE, CFGF_NONE, &cb_service_type),
        CFG_STR("uri", 0, CFGF_NONE),
        CFG_INT("threads", 4, CFGF_NONE),
        CFG_END()
    };
    static cfg_opt_t listener_opts[] = {
        CFG_STR("bindaddress", 0, CFGF_NONE),
        CFG_INT("port", 9001, CFGF_NONE),
        CFG_INT("backlog", 1024, CFGF_NONE),
        CFG_STR("cert", 0, CFGF_NONE),
        CFG_STR("key", 0, CFGF_NONE),
        CFG_STR("cafile", 0, CFGF_NONE),
        CFG_STR("capath", 0, CFGF_NONE),
        CFG_STR("crlpath", 0, CFGF_NONE),
        CFG_STR("password", 0, CFGF_NONE),
        CFG_STR("cipherlist", 0, CFGF_NONE),
        CFG_INT_CB("clientauth", NONE, CFGF_NONE, &cb_answer),
        CFG_INT_CB("rfc3820", NONE, CFGF_NONE, &cb_answer),
        CFG_STR("whitelist", 0, CFGF_NONE),
        CFG_STR("blacklist", 0, CFGF_NONE),
        CFG_SEC("service", service_opts, CFGF_MULTI),
        CFG_END()
    };
    cfg_opt_t opts[] = {
        CFG_INT_CB("debug", NONE, CFGF_NONE, &cb_answer),
        CFG_STR("policyfile", 0, CFGF_NONE),
        CFG_SEC("syslog", syslog_opts, CFGF_NONE),
        CFG_SEC("listener", listener_opts, CFGF_MULTI),
        CFG_END()
    };

    cfg = cfg_init(opts, CFGF_NOCASE);

    /* set a validating callback function for bookmark sections */
    /* cfg_set_validate_func(cfg, "bookmark", &cb_validate_bookmark); */

    ret = cfg_parse(cfg, configfile);
    if (ret == CFG_FILE_ERROR) {
        fprintf(stderr, "Error: could not open or read the configuration file "
               "\"%s\".\n", configfile);
        return GA_BAD;
    } else if (ret == CFG_PARSE_ERROR) {
        fprintf(stderr, "Error: parse error in the configuration file "
               "\"%s\".\n", configfile);
        return GA_BAD;
    }

    /* Generic */
    app_p->debug = cfg_getint(cfg, "debug");
    if (app_p->debug == MAYBE || app_p->debug == OPTIONAL) {
        printf("Overriding debug setting to 'yes'\n");
        app_p->debug = YES;
    } else if (app_p->debug == YES) {
        printf("= Service running in DEBUG mode =\n");
    }

    /* XACML Rules file */
    *policy_file = strdup(cfg_getstr(cfg, "policyfile"));
    if (*policy_file == NULL) {
        fprintf(stderr, "Error: no \"policyfile\" set in the configuration file\n");
        return GA_BAD;
    } else {
        if (app_p->verbose) {
            printf("Using XACML Policy file: \"%s\"\n", *policy_file);
        }
    }

    /* Syslog */
    syslog_sec = cfg_getsec(cfg, "syslog");
    if (syslog_sec == NULL) {
        fprintf(stderr, "Error: no \"syslog\" section found in the "
                        "configuration file \"%s\"\n", configfile);
    } else {
        *syslog_ident = strdup(cfg_getstr(syslog_sec, "ident"));
        *syslog_facility = cfg_getint(syslog_sec, "facility");

        if (app_p->debug == YES) {
            printf("found syslog\n");
            printf("    ident = %s\n", cfg_getstr(syslog_sec, "ident"));
            printf("    facility = %ld\n", cfg_getint(syslog_sec, "facility"));
            printf("BUG\n");

            for (i = 0; i < cfg_size(syslog_sec, "options"); i++) {
                printf("options[%d] == %ld\n", i, cfg_getnint(syslog_sec, "options", i));
            }
            printf("BUG\n");
        }

        /* Hardwired the settings */
        *syslog_flags = LOG_PID|LOG_NDELAY;

        if (app_p->verbose > 1) {
            *syslog_flags |= LOG_PERROR;
        }
    }

    /* Listeners */
    n_listener = cfg_size(cfg, "listener");
    if (app_p->verbose) {
        printf("%d configured listeners:\n", n_listener);
    }
    for (i = 0; i < n_listener; i++) {
        cfg_t *ls = cfg_getnsec(cfg, "listener", i);
        if (ls == NULL) {
            goto cleanup;
        }

        p_listener = malloc(sizeof(struct tq_listener_s));
        if (p_listener == NULL) {
            fprintf(stderr, "Error: memory allocation problem, couldn't allocate %lu bytes\n",
                    sizeof(struct tq_listener_s));
            goto cleanup;
        }
        memset(p_listener, 0, sizeof(struct tq_listener_s));
        TAILQ_INIT(&(p_listener->services_head));

        /* Settings */
        STRDUP_OR_GOTO_CLEANUP(p_listener->bindip,          cfg_getstr(ls, "bindaddress"));
        p_listener->port                           = (short)cfg_getint(ls, "port");
        p_listener->backlog                        = (short)cfg_getint(ls, "backlog");
        STRDUP_OR_GOTO_CLEANUP(p_listener->cert,            cfg_getstr(ls, "cert"));
        STRDUP_OR_GOTO_CLEANUP(p_listener->key,             cfg_getstr(ls, "key"));
        STRDUP_OR_GOTO_CLEANUP(p_listener->cafile,          cfg_getstr(ls, "cafile"));
        STRDUP_OR_GOTO_CLEANUP(p_listener->capath,          cfg_getstr(ls, "capath"));
        STRDUP_OR_GOTO_CLEANUP(p_listener->crlpath,         cfg_getstr(ls, "crlpath"));
        STRDUP_OR_GOTO_CLEANUP(p_listener->cipherlist,      cfg_getstr(ls, "cipherlist") ?
                                                                cfg_getstr(ls, "cipherlist") :
                                                                "HIGH");
        STRDUP_OR_GOTO_CLEANUP(p_listener->cert_password,   cfg_getstr(ls, "password"));
        STRDUP_OR_GOTO_CLEANUP(p_listener->whitelist_path,  cfg_getstr(ls, "whitelist"));
        STRDUP_OR_GOTO_CLEANUP(p_listener->blacklist_path,  cfg_getstr(ls, "blacklist"));
        p_listener->clientauth                     = (short)cfg_getint(ls, "clientauth");
        p_listener->rfc3820                        = (short)cfg_getint(ls, "rfc3820");

        /* Normalizer */
        if (p_listener->clientauth == MAYBE)
            p_listener->clientauth = OPTIONAL;
        if (p_listener->rfc3820 == MAYBE || p_listener->rfc3820 == OPTIONAL)
            p_listener->rfc3820 = YES;

        /* Create evhtp_ssl_cfg_t */
        if (create_evhtp_ssl_cfg_from_tq_listener(p_listener) == GA_BAD) {
            goto cleanup;
        }


        /* Services per listener */
        n_services = cfg_size(ls, "service");
        if (app_p->verbose) {
            printf("      %d\n", n_services);
        }
        for (j = 0; j < n_services; j++) {
            cfg_t *serv = cfg_getnsec(ls, "service", j);
            if (serv == NULL) {
                goto cleanup;
            }

            p_service = malloc(sizeof(struct tq_service_s));
            if (p_service == NULL) {
                fprintf(stderr, "Error: memory allocation problem, couldn't allocate %lu bytes\n",
                        sizeof(struct tq_service_s));
                goto cleanup;
            }
            memset(p_service, 0, sizeof(struct tq_service_s));

            p_service->parent_listener = p_listener;

            /* Thread count override in Debug mode - max is 1 worker thread */
            if (app_p->debug == YES) {
                p_service->thread_cnt = 1;
            } else {
                p_service->thread_cnt = (short)cfg_getint(serv, "threads");
            }

            p_service->ltype = cfg_getint(serv, "type");
            p_service->uri = cfg_getstr(serv, "uri");
            if (p_service->uri && p_service->uri[0] == '/') {
                p_service->uri = strdup(p_service->uri);
            } else {
                buf = malloc(strlen(p_service->uri) + 2);
                if (buf == NULL) {
                    goto cleanup;
                }
                snprintf(buf, strlen(p_service->uri) + 2, "/%s", p_service->uri);
                p_service->uri = buf;
            }
            if (app_p->verbose) {
                printf("       uri = %s\n", p_service->uri);
                printf("       type = %s\n", p_service->ltype == PDP ? "PDP" : p_service->ltype == PAP ? "PAP" : p_service->ltype == PEP ? "PEP" : "unknown");
            }

            TAILQ_INSERT_TAIL(&(p_listener->services_head), p_service, next);
        }

        TAILQ_INSERT_TAIL(&(app_p->listener_head), p_listener, next);
    }

    cfg_free(cfg);
    return GA_GOOD;
cleanup:
    cfg_free(cfg);
    return GA_BAD;

}
예제 #2
0
int main(int argc, char **argv)
{
    unsigned int i;
    cfg_t *cfg;
    unsigned n;
    int ret;
    cfg_opt_t proxy_opts[] = {
        CFG_INT("type", 0, CFGF_NONE),
        CFG_STR("host", 0, CFGF_NONE),
        CFG_STR_LIST("exclude", "{localhost, .localnet}", CFGF_NONE),
        CFG_INT("port", 21, CFGF_NONE),
        CFG_END()
    };
    cfg_opt_t bookmark_opts[] = {
        CFG_STR("machine", 0, CFGF_NONE),
        CFG_INT("port", 21, CFGF_NONE),
        CFG_STR("login", 0, CFGF_NONE),
        CFG_STR("password", 0, CFGF_NONE),
        CFG_STR("directory", 0, CFGF_NONE),
        CFG_BOOL("passive-mode", cfg_false, CFGF_NONE),
        CFG_SEC("proxy", proxy_opts, CFGF_NONE),
        CFG_END()
    };
    cfg_opt_t opts[] = {
        CFG_INT("backlog", 42, CFGF_NONE),
        CFG_STR("probe-device", "eth2", CFGF_NONE),
        CFG_SEC("bookmark", bookmark_opts, CFGF_MULTI | CFGF_TITLE),
        CFG_FLOAT_LIST("delays", "{3.567e2, 0.2, -47.11}", CFGF_NONE),
        CFG_FUNC("func", &cb_func),
        CFG_INT_CB("ask-quit", 3, CFGF_NONE, &cb_verify_ask),
        CFG_INT_LIST_CB("ask-quit-array", "{maybe, yes, no}",
                        CFGF_NONE, &cb_verify_ask),
        CFG_FUNC("include", &cfg_include),
        CFG_END()
    };

#ifndef _WIN32
    /* for some reason, MS Visual C++ chokes on this (?) */
    printf("Using %s\n\n", confuse_copyright);
#endif

    cfg = cfg_init(opts, CFGF_NOCASE);

    /* set a validating callback function for bookmark sections */
    cfg_set_validate_func(cfg, "bookmark", &cb_validate_bookmark);

    ret = cfg_parse(cfg, argc > 1 ? argv[1] : "test.conf");
    printf("ret == %d\n", ret);
    if(ret == CFG_FILE_ERROR) {
        perror("test.conf");
        return 1;
    } else if(ret == CFG_PARSE_ERROR) {
        fprintf(stderr, "parse error\n");
        return 2;
    }

    printf("backlog == %ld\n", cfg_getint(cfg, "backlog"));

    printf("probe device is %s\n", cfg_getstr(cfg, "probe-device"));
    cfg_setstr(cfg, "probe-device", "lo");
    printf("probe device is %s\n", cfg_getstr(cfg, "probe-device"));

    n = cfg_size(cfg, "bookmark");
    printf("%d configured bookmarks:\n", n);
    for(i = 0; i < n; i++) {
        cfg_t *pxy;
        cfg_t *bm = cfg_getnsec(cfg, "bookmark", i);
        printf("  bookmark #%u (%s):\n", i+1, cfg_title(bm));
        printf("    machine = %s\n", cfg_getstr(bm, "machine"));
        printf("    port = %d\n", (int)cfg_getint(bm, "port"));
        printf("    login = %s\n", cfg_getstr(bm, "login"));
        printf("    passive-mode = %s\n",
               cfg_getbool(bm, "passive-mode") ? "true" : "false");
        printf("    directory = %s\n", cfg_getstr(bm, "directory"));
        printf("    password = %s\n", cfg_getstr(bm, "password"));

        pxy = cfg_getsec(bm, "proxy");
        if(pxy) {
            int j, m;
            if(cfg_getstr(pxy, "host") == 0) {
                printf("      no proxy host is set, setting it to 'localhost'...\n");
                /* For sections without CFGF_MULTI flag set, there is
                 * also an extended syntax to get an option in a
                 * subsection:
                 */
                cfg_setstr(bm, "proxy|host", "localhost");
            }
            printf("      proxy host is %s\n", cfg_getstr(pxy, "host"));
            printf("      proxy type is %ld\n", cfg_getint(pxy, "type"));
            printf("      proxy port is %ld\n", cfg_getint(pxy, "port"));

            m = cfg_size(pxy, "exclude");
            printf("      got %d hosts to exclude from proxying:\n", m);
            for(j = 0; j < m; j++) {
                printf("        exclude %s\n", cfg_getnstr(pxy, "exclude", j));
            }
        } else
            printf("    no proxy settings configured\n");
    }

    printf("delays are (%d):\n", cfg_size(cfg, "delays"));
    for(i = 0; i < cfg_size(cfg, "delays"); i++)
        printf(" %G\n", cfg_getnfloat(cfg, "delays", i));

    printf("ask-quit == %ld\n", cfg_getint(cfg, "ask-quit"));

    /* Using cfg_setint(), the integer value for the option ask-quit
     * is not verified by the value parsing callback.
     *
     *
     cfg_setint(cfg, "ask-quit", 4);
     printf("ask-quit == %ld\n", cfg_getint(cfg, "ask-quit"));
    */

    /* The following commented line will generate a failed assertion
     * and abort, since the option "foo" is not declared
     *
     *
     printf("foo == %ld\n", cfg_getint(cfg, "foo"));
    */

    cfg_addlist(cfg, "ask-quit-array", 2, 1, 2);

    for(i = 0; i < cfg_size(cfg, "ask-quit-array"); i++)
        printf("ask-quit-array[%d] == %ld\n",
               i, cfg_getnint(cfg, "ask-quit-array", i));

    /* print the parsed values to another file */
    {
        FILE *fp = fopen("test.conf.out", "w");
        cfg_set_print_func(cfg, "func", print_func);
        cfg_set_print_func(cfg, "ask-quit", print_ask);
        cfg_set_print_func(cfg, "ask-quit-array", print_ask);
        cfg_print(cfg, fp);
        fclose(fp);
    }

    cfg_free(cfg);
    return 0;
}