Beispiel #1
0
int main(int argc, char **argv)
{
    char *conffile;
    const char *p, *val;
    int i, len;
    FAILIF(argc < 2, "Usage: %s <conffile> [<variable> [<value>]]\n", argv[0]);

    conffile = codaconf_file(argv[1]);

    if (argc < 3) {
        if (!conffile) {
            fprintf(stdout, "/dev/null\n");
            exit(EXIT_FAILURE);
        }
        fprintf(stdout, "%s\n", conffile);
        exit(EXIT_SUCCESS);
    }

    /* Hmm, should we really copy the template file on lookups as well. On one
     * hand it makes a 'readonly' operation 'write' data. On the other hand
     * there would otherwise be no other way to use the default template
     * without modifications */
    if (!conffile) {
        copy_template(argv[1]);
        conffile = codaconf_file(argv[1]);
        FAILIF(!conffile, "Failed to copy template file to '%s'\n", argv[1]);
    }

    codaconf_init_one(conffile);
    val = codaconf_lookup(argv[2], NULL);

    if (argc < 4) {
        FAILIF(!val, "Variable '%s' not found in '%s'\n", argv[2], conffile);

        fprintf(stdout, "%s\n", val);
        exit(EXIT_SUCCESS);
    }

    /* argc >= 4 */
    /* check if this value was already set */
    if (val) {
        p = val;
        for (i = 3; i <= argc; i++) {
            len = strlen(argv[i]);
            if (strncmp(argv[i], p, len) != 0)
                break;
            p = p + len;
            if (*p != ' ')
                break;
            p++;
        }
        if (i == argc - 1 && *p == '\0')
            exit(EXIT_SUCCESS);
    }

    do_rewrite(conffile, argc, argv);

    exit(EXIT_SUCCESS);
}
Beispiel #2
0
int use_toolkit(char *url, char *toolkit_id, t_toolkit_options *options) {
	t_url_toolkit *toolkit;
	t_toolkit_rule *rule;
	bool condition_met, url_replaced = false;
	int result, skip = 0;
	char *file, *qmark, *header;
	regmatch_t pmatch[REGEXEC_NMATCH];
	struct stat fileinfo;
	t_http_header *headers;

	if (options == NULL) {
		return UT_ERROR;
	}

	options->new_url = NULL;

	if ((toolkit = select_toolkit(toolkit_id, options->url_toolkit)) == NULL) {
		return UT_ERROR;
	}

	rule = toolkit->toolkit_rule;
	while (rule != NULL) {
		condition_met = false;

		/* Skip lines
		 */
		if (skip > 0) {
			skip--;
			rule = rule->next;
			continue;
		}

		/* Condition
		 */
		switch (rule->condition) {
			case tc_none:
				/* None
				 */
				condition_met = true;
				break;
			case tc_match:
				/* Match
				 */
				if (regexec(&(rule->pattern), url, REGEXEC_NMATCH, pmatch, 0) == 0) {
					condition_met = true;
				}
				if (rule->neg_match) {
					condition_met = (condition_met == false);
				}
				break;
			case tc_header:
				/* Header
				 */
				if (rule->header == NULL) {
					headers = options->http_headers;
					while (headers != NULL) {
						if (regexec(&(rule->pattern), headers->data + headers->value_offset, REGEXEC_NMATCH, pmatch, 0) == 0) {
							condition_met = true;
						}
						if (rule->neg_match) {
							condition_met = (condition_met == false);
						}

						if (condition_met) {
							break;
						}

						headers = headers->next;
					}
				} else {
					if ((header = get_http_header(rule->header, options->http_headers)) == NULL) {
						break;
					}
					if (regexec(&(rule->pattern), header, REGEXEC_NMATCH, pmatch, 0) == 0) {
						condition_met = true;
					}
					if (rule->neg_match) {
						condition_met = (condition_met == false);
					}
				}
				break;
			case tc_method:
				/* Request method
				 */
				if (strcmp(options->method, rule->parameter) == 0) {
					condition_met = true;
				}
				if (rule->neg_match) {
					condition_met = (condition_met == false);
				}
				break;
			case tc_request_uri:
				/* Request URI
				 */
				if (valid_uri(url, false) == false) {
					break;
				}
				if ((file = make_path(options->website_root, url)) == NULL) {
					return UT_ERROR;
				}

				if ((qmark = strchr(file, '?')) != NULL) {
					*qmark = '\0';
				}
				url_decode(file);

				if (stat(file, &fileinfo) != -1) {
					switch (rule->value) {
						case IU_EXISTS:
							if (S_ISDIR(fileinfo.st_mode) || S_ISREG(fileinfo.st_mode)) {
								condition_met = true;
							}
							break;
						case IU_ISFILE:
							if (S_ISREG(fileinfo.st_mode)) {
								condition_met = true;
							}
							break;
						case IU_ISDIR:
							if (S_ISDIR(fileinfo.st_mode)) {
								condition_met = true;
							}
							break;
					}
				}

				free(file);
				break;
			case tc_total_connections:
				/* Total connections reached?
				 */
				condition_met = options->total_connections >= rule->value;
				break;
#ifdef ENABLE_TLS
			case tc_use_tls:
				/* Client connections uses TLS?
				 */
				condition_met = options->use_tls;
				break;
#endif
		}

		/* Condition not met
		 */
		if (condition_met == false) {
			rule = rule->next;
			continue;
		}

		/* Operation
		 */
		switch (rule->operation) {
			case to_none:
				/* None
				 */
				break;
			case to_ban:
				/* Ban client
				 */
				options->ban = rule->value;
				break;
			case to_deny_access:
				/* Deny access
				 */
				return UT_DENY_ACCESS;
			case to_omit_request_log:
				/* Omit requeest log
				 */
				options->log_request = false;
				break;
			case to_expire:
				/* Send Expire HTTP header
				 */
				options->expire = rule->value;
				options->caco_private = rule->caco_private;
				break;
			case to_fastcgi:
				/* Use FastCGI server
				 */
				options->fastcgi_server = rule->parameter;
				break;
			case to_redirect:
				/* Redirect client
				 */
				if (rule->neg_match) {
					if ((options->new_url = strdup(rule->parameter)) == NULL) {
						return UT_ERROR;
					}
				} else if (do_rewrite(url, &(rule->pattern), pmatch, rule->parameter, &(options->new_url), rule->match_loop) == -1) {
					if (options->new_url != NULL) {
						free(options->new_url);
						options->new_url = NULL;
					}
					return UT_ERROR;
				}
				if (options->new_url != NULL) {
					if (url_replaced) {
						free(url);
					}
					return UT_REDIRECT;
				} else if (url_replaced) {
					options->new_url = url;
				}
				break;
			case to_rewrite:
				/* Rewrite
				 */
				if (rule->neg_match) {
					if ((options->new_url = strdup(rule->parameter)) == NULL) {
						return UT_ERROR;
					}
				} else if (do_rewrite(url, &(rule->pattern), pmatch, rule->parameter, &(options->new_url), rule->match_loop) == -1) {
					if (options->new_url != NULL) {
						free(options->new_url);
						options->new_url = NULL;
					}
					return UT_ERROR;
				}
				if (options->new_url != NULL) {
					if (url_replaced) {
						free(url);
					}
					url = options->new_url;
					url_replaced = true;
				} else if (url_replaced) {
					options->new_url = url;
				}
				break;
			case to_skip:
				/* Skip
				 */
				skip = rule->value;
				break;
			case to_sub:
				/* Subroutine
				 */
				if (++(options->sub_depth) > MAX_SUB_DEPTH) {
					return UT_ERROR;
				}

				if ((result = use_toolkit(url, rule->parameter, options)) == UT_ERROR) {
					if (options->new_url != NULL) {
						free(options->new_url);
						options->new_url = NULL;
					}
					return UT_ERROR;
				}
				options->sub_depth--;

				if (options->new_url != NULL) {
					if (url_replaced) {
						free(url);
					}
					url = options->new_url;
					url_replaced = true;
				} else if (url_replaced) {
					options->new_url = url;
				}

				if (result != UT_RETURN) {
					return result;
				}
				break;
			case to_use:
				/* Replace URL
				 */
				if (url_replaced) {
					free(url);
				}
				if ((options->new_url = strdup(rule->parameter)) == NULL) {
					return UT_ERROR;
				}
				break;
		}

		/* Flow
		 */
		switch (rule->flow) {
			case tf_continue:
				/* Continue
				 */
				break;
			case tf_exit:
				/* Exit
				 */
				return UT_EXIT;
			case tf_return:
				/* Return
				 */
				return UT_RETURN;
		}

		rule = rule->next;
	}

	return UT_RETURN;
}