コード例 #1
0
ファイル: main.c プロジェクト: tperalta82/apache2nginx
int main(int argc, const char * const argv[])
{
    char c;
    const char *ap_confname = "httpd.conf";
    const char *ngx_confname = "nginx.conf";
    const char *def_server_root = NULL;
    const char *temp_error_log = NULL;
    const char *error;
    process_rec *process;
    server_rec *server_conf;
    apr_pool_t *pglobal;
    apr_pool_t *pconf;
    apr_pool_t *plog; /* Pool of log streams, reset _after_ each read of conf */
    apr_pool_t *ptemp; /* Pool for temporary config stuff, reset often */
    apr_pool_t *pcommands; /* Pool for -D, -C and -c switches */
    apr_getopt_t *opt;
    apr_status_t rv;
    const char *optarg;

    AP_MONCONTROL(0); /* turn off profiling of startup */

    process = init_process(&argc, &argv);
    pglobal = process->pool;
    pconf = process->pconf;
    ap_server_argv0 = process->short_name;

#if APR_CHARSET_EBCDIC
    if (ap_init_ebcdic(pglobal) != APR_SUCCESS) {
        destroy_and_exit_process(process, 1);
    }
#endif

    apr_pool_create(&pcommands, pglobal);
    apr_pool_tag(pcommands, "pcommands");
    ap_server_pre_read_config  = apr_array_make(pcommands, 1, sizeof(char *));
    ap_server_post_read_config = apr_array_make(pcommands, 1, sizeof(char *));
    ap_server_config_defines   = apr_array_make(pcommands, 1, sizeof(char *));

    error = ap_setup_prelinked_modules(process);
    if (error) {
        ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_EMERG, 0, NULL, "%s: %s",
                     ap_server_argv0, error);
        destroy_and_exit_process(process, 1);
    }

    ap_run_rewrite_args(process);

    /* Maintain AP_SERVER_BASEARGS list in http_main.h to allow the MPM
     * to safely pass on our args from its rewrite_args() handler.
     */
    apr_getopt_init(&opt, pcommands, process->argc, process->argv);
    
    while ((rv = apr_getopt(opt, APN_SERVER_BASEARGS, &c, &optarg))
            == APR_SUCCESS) {
        switch (c) {

        case 'f':
            ap_confname = optarg;
            break;

        case 'o':
            ngx_confname = optarg;
            break;

        case 'd':
            def_server_root = optarg;
            break;

        case 'l':
            ap_show_modules();
            destroy_and_exit_process(process, 0);

        case 'L':
            ap_show_directives();
            destroy_and_exit_process(process, 0);

        case 'h':
        case '?':
            usage(process);
            destroy_and_exit_process(process, 0);
            
        case 'H':
            setconf = 1;
            confname = optarg;
            break;
                
        case 'i':
            defindex = 1;
            break;
  
        case 'G':
            defgzip = 1;
            break;
            
        case 'D':
            cleancfg = 1;
            break;
            
        case 'R':
            forcerm = 1;
            break;
        }    
    }

    if (rv != APR_EOF || argc < 3) {
        if (c != 'h' && c != '?') {
            usage(process);
        }
        destroy_and_exit_process(process, 1);
    }

    apr_pool_create(&plog, pglobal);
    apr_pool_tag(plog, "plog");
    apr_pool_create(&ptemp, pconf);
    apr_pool_tag(ptemp, "ptemp");

	/** we need the real path */
	char* fullpath = NULL;
	rv = apr_get_realpath(&fullpath, ap_confname, plog);
	if (rv != APR_SUCCESS){
		apn_error("Apache conf file is not found " 
				"or the given path is invalid! Exit.\n");
		destroy_and_exit_process(process, 1);
	}
	ap_confname = apr_pstrdup(plog, fullpath);

    /* Note that we preflight the config file once
     * before reading it _again_ in the main loop.
     * This allows things, log files configuration
     * for example, to settle down.
     */
    ap_server_root = def_server_root;
    if (!ap_server_root){ // no specify serverroot by -d in commandline.

        if (!ap_confname) {
            apn_error("Apache conf file name is null!\n");
            destroy_and_exit_process(process, 1);
        }

        /**
         * if ap_confname is absolute path, get the prefix as serverroot.
         * if it is not, set the current path as serverroot.
         */
        char* basedir;
        rv = apr_get_basedir(&basedir, ap_confname, process->pool);
        if(rv!=APR_SUCCESS){
            apn_error("Apache conf file is not found " 
                    "or the given path is invalid! Exit.\n");
            destroy_and_exit_process(process, 1);
        }

        ap_server_root = def_server_root = basedir;

		/**
		 * Sometimes, ap_server_root should be set more intelligence.
		 * Because of apache conf depend on the ServerRoot.
		 * when not in localhost, maybe ServerRoot is not valid,
		 * and here need to guess the ap_server_root.
		 */
		apn_fixed_server_root(plog);
    }
    if (temp_error_log) {
        ap_replace_stderr_log(process->pool, temp_error_log);
    }
 
    char *ngx_fullpath = NULL;
    rv = apr_get_realpath(&ngx_fullpath, ngx_confname, plog);
    
    if (rv == APR_SUCCESS && forcerm != 1) {
             apn_error("Config file exists: %s. Exit.\n", ngx_fullpath);
             destroy_and_exit_process(process, 1);
    } else {
        /* Create a empty nginx.conf, because mod_mime needs this file. */
        apr_file_t *f;
        rv = apr_file_open(&f, ngx_confname, 
                (forcerm == 1 ? APR_TRUNCATE : APR_CREATE ) |APR_APPEND|APR_WRITE,
                APR_OS_DEFAULT, plog);
        if (rv != APR_SUCCESS) {
            apn_error("Create file error: %s\n", ngx_fullpath);
            destroy_and_exit_process(process, 1);
        }
        apr_file_close(f);
    }

    /*
     * here just create the main server, and the vhost is not created.
     */
    server_conf = ap_read_config(process, ptemp, ap_confname, &ap_conftree);
    if (!server_conf) {
        destroy_and_exit_process(process, 1);
    }
    /* sort hooks here to make sure pre_config hooks are sorted properly */
    apr_hook_sort_all();

    if (ap_run_pre_config(pconf, plog, ptemp) != OK) {
        ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR, 0,
                     NULL, "Pre-configuration failed");
        destroy_and_exit_process(process, 1);
    }

    /* Lijinhu added : check the configuration validation */
    if (ap_conftree == NULL) {
        apn_error("The apache conf file is invalid! Please check it. Exit.\n");
        destroy_and_exit_process(process, 1);
    }

    rv = ap_process_config_tree(server_conf, ap_conftree,
                                process->pconf, ptemp);
    if (rv == OK) {
        /*
         * 1. merge server configs.
         * 2. merge per dir configs for each server.
         * 3. re-order the directorise.
         */
        ap_fixup_virtual_hosts(pconf, server_conf);

        /* compile the tables and such we need to do the run-time vhost lookups */
        ap_fini_vhost_config(pconf, server_conf);

        /*
         * Sort hooks again because ap_process_config_tree may have added
         * modules and hence hooks. This happens with mod_perl and modules
         * written in perl.
         */
        apr_hook_sort_all();

        ap_run_test_config(pconf, server_conf);
        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "Syntax OK");

        if ( ap_run_post_config(pconf, plog, ptemp, server_conf) != OK) {
            ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR, 0,
                    NULL, "Failed when merge some configurations");
            destroy_and_exit_process(process, 1);
        }


        /*
         * migrate the config to nginx conf format.
         * generate the conf file of nginx.
         */
        rv = apn_migrate_to_nginx(plog, server_conf, ngx_confname);
        if (rv != OK) {
            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "Migrate Error!");
        }
        destroy_and_exit_process(process, 0);
    }

   return 0; /* Termination 'ok' */
}
コード例 #2
0
ファイル: engine_config.c プロジェクト: David-Hiker/waf-pe
/* 处理每个服务器策略下的指令 */
static int process_server_policy(server_policy_t *sp,
                                 server_rec *server_conf, apr_pool_t *ptemp)
{
    apr_status_t rv;
    ap_directive_t *newdir;
    ap_directive_t *current;
    ap_directive_t *conftree;
    virt_host_t *vhost;
    int sname_set;
    char strbuf[STR_LEN_MAX];

    /* 每个服务器策略建立一颗临时的配置树 */
    conftree = NULL;
    current = NULL;

    /* 限制了当启用KeepAlive时,每个连接允许的请求数量。*/
    newdir = (ap_directive_t *)apr_pcalloc(ptemp, sizeof(ap_directive_t));
    newdir->filename = sp->name; /* 使用服务器策略名字作为指令文件名 */
    newdir->line_num = (current == NULL) ? 1 : (current->line_num + 1);
    newdir->directive = apr_pstrdup(ptemp, "MaxKeepAliveRequests");
    newdir->args = apr_pstrdup(ptemp, "500");
    current = ap_add_node(&conftree, current, newdir, 0);
    conftree = current;

    if (sp->work_mode == WORK_REVERSE) {
        /* 处理反向代理配置 */
        if (sp->orig_host->proto == PROTO_HTTPS) {
            sprintf(strbuf, "/ https://%d.%d.%d.%d:%d/",
                    NIPQUAD(sp->orig_host->ipaddr.s_addr), sp->orig_host->port);
        } else {
            sprintf(strbuf, "/ http://%d.%d.%d.%d:%d/",
                    NIPQUAD(sp->orig_host->ipaddr.s_addr), sp->orig_host->port);
        }
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_main_server,
                     "backend host: %s", strbuf);

        newdir = (ap_directive_t *)apr_pcalloc(ptemp, sizeof(ap_directive_t));
        newdir->filename = sp->name; 
        newdir->line_num = (current == NULL) ? 1 : (current->line_num + 1);
        newdir->directive = apr_pstrdup(ptemp, "ProxyPass");
        newdir->args = apr_pstrdup(ptemp, strbuf);
        current = ap_add_node(&conftree, current, newdir, 0);

        newdir = (ap_directive_t *)apr_pcalloc(ptemp, sizeof(ap_directive_t));
        newdir->filename = sp->name;
        newdir->line_num = (current == NULL) ? 1 : (current->line_num + 1);
        newdir->directive = apr_pstrdup(ptemp, "ProxyPassReverse");
        newdir->args = apr_pstrdup(ptemp, strbuf);
        current = ap_add_node(&conftree, current, newdir, 0);
    } else if ((sp->work_mode == WORK_BRIDGE) || (sp->work_mode == WORK_ROUTE)) {
        /* 处理透明代理配置 */
        newdir = (ap_directive_t *)apr_pcalloc(ptemp, sizeof(ap_directive_t));
        newdir->filename = sp->name; 
        newdir->line_num = (current == NULL) ? 1 : (current->line_num + 1);
        newdir->directive = apr_pstrdup(ptemp, "ProxyTransparent");
        newdir->args = apr_pstrdup(ptemp, "On");
        current = ap_add_node(&conftree, current, newdir, 0);

        if (!sp->is_default) {
            for (sname_set = 0, vhost = sp->virt_host->next; vhost; vhost = vhost->next) {
                if (strlen(vhost->server_name) > 0) {
                    newdir = (ap_directive_t *)apr_pcalloc(ptemp, sizeof(ap_directive_t));
                    newdir->filename = sp->name; 
                    newdir->line_num = (current == NULL) ? 1 : (current->line_num + 1);
                    if (!sname_set) {
                        newdir->directive = apr_pstrdup(ptemp, "ServerName");
                        sname_set = 1;
                    } else {
                        newdir->directive = apr_pstrdup(ptemp, "ServerAlias");
                    }
                    newdir->args = apr_pstrdup(ptemp, vhost->server_name);
                    current = ap_add_node(&conftree, current, newdir, 0);
                }
            }
        }

        newdir = (ap_directive_t *)apr_pcalloc(ptemp, sizeof(ap_directive_t));
        newdir->filename = sp->name; 
        newdir->line_num = (current == NULL) ? 1 : (current->line_num + 1);
        newdir->directive = apr_pstrdup(ptemp, "ProxyPreserveHost");
        newdir->args = apr_pstrdup(ptemp, "On");
        current = ap_add_node(&conftree, current, newdir, 0);
    } else if (sp->work_mode == WORK_OFFLINE) {
        /* 处理离线模式配置 */
        if (!sp->is_default) {
            for (sname_set = 0, vhost = sp->virt_host->next; vhost; vhost = vhost->next) {
                if (strlen(vhost->server_name) > 0) {
                    newdir = (ap_directive_t *)apr_pcalloc(ptemp, sizeof(ap_directive_t));
                    newdir->filename = sp->name; 
                    newdir->line_num = (current == NULL) ? 1 : (current->line_num + 1);
                    if (!sname_set) {
                        newdir->directive = apr_pstrdup(ptemp, "ServerName");
                        sname_set = 1;
                    } else {
                        newdir->directive = apr_pstrdup(ptemp, "ServerAlias");
                    }
                    newdir->args = apr_pstrdup(ptemp, vhost->server_name);
                    current = ap_add_node(&conftree, current, newdir, 0);
                }
            }
        }
    } else {
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_main_server,
                     "work mode error");
        return DECLINED;
    }

    /* 配置防护引擎 */
    if (BitGet(sp->opt_flags, ENGINE_FLAG)) {
        switch (sp->engine) {
        case BLOCK_OFF:
            sprintf(strbuf, "Off");
            break;
        case BLOCK_DET:
            sprintf(strbuf, "DetectionOnly");
            break;
        case BLOCK_ON:
            sprintf(strbuf, "On");
            break;
        default:
            sprintf(strbuf, "On");
            break;
        }
        newdir = (ap_directive_t *)apr_pcalloc(ptemp, sizeof(ap_directive_t));
        newdir->filename = sp->name;   
        newdir->line_num = (current == NULL) ? 1 : (current->line_num + 1);
        newdir->directive = apr_pstrdup(ptemp, "SecRuleEngine");
        newdir->args = apr_pstrdup(ptemp, strbuf);
        current = ap_add_node(&conftree, current, newdir, 0);
    }

    /* 配置审核日志 */
    if (BitGet(sp->audit_set, ACCESS_LOG)) {
        if (BitGet(sp->audit_log, ACCESS_LOG)) {
            newdir = (ap_directive_t *)apr_pcalloc(ptemp, sizeof(ap_directive_t));
            newdir->filename = sp->name; 
            newdir->line_num = (current == NULL) ? 1 : (current->line_num + 1);
            newdir->directive = apr_pstrdup(ptemp, "SecAccessLog");
            newdir->args = apr_pstrdup(ptemp, "On");
            current = ap_add_node(&conftree, current, newdir, 0);
        } else {
            newdir = (ap_directive_t *)apr_pcalloc(ptemp, sizeof(ap_directive_t));
            newdir->filename = sp->name; 
            newdir->line_num = (current == NULL) ? 1 : (current->line_num + 1);
            newdir->directive = apr_pstrdup(ptemp, "SecAccessLog");
            newdir->args = apr_pstrdup(ptemp, "Off");
            current = ap_add_node(&conftree, current, newdir, 0);
        }
    }
    if (BitGet(sp->audit_set, ATTACK_LOG)) {
        if (BitGet(sp->audit_log, ATTACK_LOG)) {
            newdir = (ap_directive_t *)apr_pcalloc(ptemp, sizeof(ap_directive_t));
            newdir->filename = sp->name; 
            newdir->line_num = (current == NULL) ? 1 : (current->line_num + 1);
            newdir->directive = apr_pstrdup(ptemp, "SecAttackLog");
            newdir->args = apr_pstrdup(ptemp, "On");
            current = ap_add_node(&conftree, current, newdir, 0);
            if (sp->atlog_lev) {
                sprintf(strbuf, "%d", sp->atlog_lev);
                newdir = (ap_directive_t *)apr_pcalloc(ptemp, sizeof(ap_directive_t));
                newdir->filename = sp->name; /* 使用服务器策略名字作为指令文件名 */
                newdir->line_num = (current == NULL) ? 1 : (current->line_num + 1);
                newdir->directive = apr_pstrdup(ptemp, "SecAttackLogLevel");
                newdir->args = apr_pstrdup(ptemp, strbuf);
                current = ap_add_node(&conftree, current, newdir, 0);
            }
        } else {
            newdir = (ap_directive_t *)apr_pcalloc(ptemp, sizeof(ap_directive_t));
            newdir->filename = sp->name; /* 使用服务器策略名字作为指令文件名 */
            newdir->line_num = (current == NULL) ? 1 : (current->line_num + 1);
            newdir->directive = apr_pstrdup(ptemp, "SecAttackLog");
            newdir->args = apr_pstrdup(ptemp, "Off");
            current = ap_add_node(&conftree, current, newdir, 0);
        }
    }
    
    /* 离线模式不配置缓存模块 */
    if (sp->cache_root && sp->work_mode != WORK_OFFLINE) {
        newdir = (ap_directive_t *)apr_pcalloc(ptemp, sizeof(ap_directive_t));
        newdir->filename = sp->name; /* 使用服务器策略名字作为指令文件名 */
        newdir->line_num = (current == NULL) ? 1 : (current->line_num + 1);
        newdir->directive = apr_pstrdup(ptemp, "CacheEnable");
        newdir->args = apr_pstrdup(ptemp, "disk /");
        current = ap_add_node(&conftree, current, newdir, 0);
        
        newdir = (ap_directive_t *)apr_pcalloc(ptemp, sizeof(ap_directive_t));
        newdir->filename = sp->name; 
        newdir->line_num = (current == NULL) ? 1 : (current->line_num + 1);
        newdir->directive = apr_pstrdup(ptemp, "CacheRoot");
        newdir->args = apr_pstrdup(ptemp, sp->cache_root);
        current = ap_add_node(&conftree, current, newdir, 0);
    } else if (sp->cache_root && sp->work_mode == WORK_OFFLINE) {
        newdir = (ap_directive_t *)apr_pcalloc(ptemp, sizeof(ap_directive_t));
        newdir->filename = sp->name; 
        newdir->line_num = (current == NULL) ? 1 : (current->line_num + 1);
        newdir->directive = apr_pstrdup(ptemp, "CacheDisable");
        newdir->args = apr_pstrdup(ptemp, "/");
        current = ap_add_node(&conftree, current, newdir, 0);
    }

    /* 配置安全策略和规则集 */
    rv = process_security_rule(sp, current, conftree, ptemp);
    if (rv != OK) {
        return DECLINED;
    }

    #if SHOW_SECURITY_RULE
    /* 指令下发调试 */
    conftree_traverse(conftree);
    #endif

    if (conftree) {
        rv = ap_process_config_tree(server_conf, conftree,
                                    sp->pvhost, ptemp);
    }

    return rv;
}
コード例 #3
0
ファイル: engine_config.c プロジェクト: David-Hiker/waf-pe
/**
 * 离线模式配置初始化
 */
AP_DECLARE(int) ap_offline_configure(void)
{
    int i;
    apr_status_t rv;
    ap_directive_t *newdir;
    ap_directive_t *current;
    ap_directive_t *conftree;
    apr_pool_t *ptemp; /* Pool for temporary config stuff, reset often */
    char strbuf[STR_LEN_MAX];

    if (ap_off_iface == 0) {
        return DONE;
    }
    
    /* 配置处理过程中的临时数据放在临时内存池里面 */
    apr_pool_create(&ptemp, pconf);
    apr_pool_tag(ptemp, "ptemp");
 
    rv = OK;
    
    /* 建立一颗临时的配置树 */
    conftree = NULL;
    current = conftree;

    newdir = (ap_directive_t *)apr_pcalloc(ptemp, sizeof(ap_directive_t));
    newdir->filename = "offline mode";
    newdir->line_num = (current == NULL) ? 1 : (current->line_num + 1);
    newdir->directive = apr_pstrdup(ptemp, "OfflineEngine");
    newdir->args = apr_pstrdup(ptemp, "On");
    current = ap_add_node(&conftree, current, newdir, 0);
    conftree = current;

    /* 设定监听端口 */
    for (i = 0; i < OFFLINE_INTF_NUM; i++) {
        if (BitGet(ap_off_iface, i + 1)) {
            sprintf(strbuf, "eth%d", i);
            newdir = (ap_directive_t *)apr_pcalloc(ptemp, sizeof(ap_directive_t));
            newdir->filename = "offline mode";
            newdir->line_num = (current == NULL) ? 1 : (current->line_num + 1);
            newdir->directive = apr_pstrdup(ptemp, "OfflineEthName");
            newdir->args = apr_pstrdup(ptemp, strbuf);
            current = ap_add_node(&conftree, current, newdir, 0);
        }
    }

    newdir = (ap_directive_t *)apr_pcalloc(ptemp, sizeof(ap_directive_t));
    newdir->filename = "offline mode";
    newdir->line_num = (current == NULL) ? 1 : (current->line_num + 1);
    newdir->directive = apr_pstrdup(ptemp, "OfflineLogLevel");
    newdir->args = apr_pstrdup(ptemp, "fatal");
    current = ap_add_node(&conftree, current, newdir, 0);

    /* 指令下发调试 */
    for (current = conftree; current != NULL; current = current->next) {
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_main_server,
                     "%s: line[%d] directive[%s] args[%s]",
                     current->filename, current->line_num,
                     current->directive, current->args);
    }

    if (conftree) {
        rv = ap_process_config_tree(ap_main_server, conftree,
                                    pconf, ptemp);
    }

    apr_pool_destroy(ptemp);

    return rv;
}
コード例 #4
0
ファイル: engine_config.c プロジェクト: David-Hiker/waf-pe
/**********************************************************
 * 黑白名单相关的处理函数
 **********************************************************/
AP_DECLARE(int) ap_access_list_handle(int lst)
{
    apr_status_t rv;
    ap_directive_t *newdir;
    ap_directive_t *current;
    ap_directive_t *conftree;
    apr_array_header_t *acl_config;
    apr_pool_t *ptemp;
    char *cmd_name;
    const char **cmd_args;

    if ((lst < IP_BLACK) || (lst > ALL_LIST)) {
        return DECLINED;
    }

    /* 配置处理过程中的临时数据放在临时内存池里面 */
    apr_pool_create(&ptemp, pconf);
    apr_pool_tag(ptemp, "ptemp");

    /* 读取黑白名单的指令 */
    acl_config  = apr_array_make(ptemp, 1, sizeof(char *));
    rv = convert_access_list_query(lst, &acl_config);
    if (rv != OK) {
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
                     "query access list %d error", lst);
        return DECLINED;
    }

    /* 建立一颗临时的配置树 */
    conftree = NULL;
    current = conftree;

    while (1) {
        cmd_args = (const char **)apr_array_pop(acl_config);
        if (!cmd_args) {
            break;
        }
        cmd_name = ap_getword_conf(ptemp, cmd_args);
        newdir = (ap_directive_t *)apr_pcalloc(ptemp, sizeof(ap_directive_t));
        newdir->filename = "access list";
        newdir->line_num = (current == NULL) ? 1 : (current->line_num + 1);
        newdir->directive = apr_pstrdup(ptemp, cmd_name);
        newdir->args = apr_pstrdup(ptemp, *cmd_args);
        current = ap_add_node(&conftree, current, newdir, 0);
        if (conftree == NULL && current != NULL) {
            conftree = current;
        }
    }

    /* 指令下发调试 */
    for (current = conftree; current != NULL; current = current->next) {
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_main_server,
                     "%s: line[%d] directive[%s] args[%s]",
                     current->filename, current->line_num,
                     current->directive, current->args);
    }

    /* 处理黑白名单的指令 */
    if (conftree) {
        rv = ap_process_config_tree(ap_main_server, conftree,
                                    pconf, ptemp);
    }

    apr_pool_destroy(ptemp);

    return rv;
}