Esempio n. 1
0
File: cgi.c Progetto: 2asoft/freebsd
/*
 * Scan for indexable paths.
 */
static void
pathgen(struct req *req)
{
	FILE	*fp;
	char	*dp;
	size_t	 dpsz;
	ssize_t	 len;

	if (NULL == (fp = fopen("manpath.conf", "r"))) {
		fprintf(stderr, "%s/manpath.conf: %s\n",
			MAN_DIR, strerror(errno));
		pg_error_internal();
		exit(EXIT_FAILURE);
	}

	dp = NULL;
	dpsz = 0;

	while ((len = getline(&dp, &dpsz, fp)) != -1) {
		if (dp[len - 1] == '\n')
			dp[--len] = '\0';
		req->p = mandoc_realloc(req->p,
		    (req->psz + 1) * sizeof(char *));
		if ( ! validate_urifrag(dp)) {
			fprintf(stderr, "%s/manpath.conf contains "
			    "unsafe path \"%s\"\n", MAN_DIR, dp);
			pg_error_internal();
			exit(EXIT_FAILURE);
		}
		if (NULL != strchr(dp, '/')) {
			fprintf(stderr, "%s/manpath.conf contains "
			    "path with slash \"%s\"\n", MAN_DIR, dp);
			pg_error_internal();
			exit(EXIT_FAILURE);
		}
		req->p[req->psz++] = dp;
		dp = NULL;
		dpsz = 0;
	}
	free(dp);

	if ( req->p == NULL ) {
		fprintf(stderr, "%s/manpath.conf is empty\n", MAN_DIR);
		pg_error_internal();
		exit(EXIT_FAILURE);
	}
}
Esempio n. 2
0
/*
 * Scan for indexable paths.
 */
static void
pathgen(struct req *req)
{
	FILE	*fp;
	char	*dp;
	size_t	 dpsz;

	if (NULL == (fp = fopen("manpath.conf", "r"))) {
		fprintf(stderr, "%s/manpath.conf: %s\n",
			MAN_DIR, strerror(errno));
		pg_error_internal();
		exit(EXIT_FAILURE);
	}

	while (NULL != (dp = fgetln(fp, &dpsz))) {
		if ('\n' == dp[dpsz - 1])
			dpsz--;
		req->p = mandoc_realloc(req->p,
		    (req->psz + 1) * sizeof(char *));
		dp = mandoc_strndup(dp, dpsz);
		if ( ! validate_urifrag(dp)) {
			fprintf(stderr, "%s/manpath.conf contains "
			    "unsafe path \"%s\"\n", MAN_DIR, dp);
			pg_error_internal();
			exit(EXIT_FAILURE);
		}
		if (NULL != strchr(dp, '/')) {
			fprintf(stderr, "%s/manpath.conf contains "
			    "path with slash \"%s\"\n", MAN_DIR, dp);
			pg_error_internal();
			exit(EXIT_FAILURE);
		}
		req->p[req->psz++] = dp;
	}

	if ( req->p == NULL ) {
		fprintf(stderr, "%s/manpath.conf is empty\n", MAN_DIR);
		pg_error_internal();
		exit(EXIT_FAILURE);
	}
}
Esempio n. 3
0
int
main(void)
{
	struct req	 req;
	struct itimerval itimer;
	const char	*path;
	const char	*querystring;
	int		 i;

	/* Poor man's ReDoS mitigation. */

	itimer.it_value.tv_sec = 2;
	itimer.it_value.tv_usec = 0;
	itimer.it_interval.tv_sec = 2;
	itimer.it_interval.tv_usec = 0;
	if (setitimer(ITIMER_VIRTUAL, &itimer, NULL) == -1) {
		fprintf(stderr, "setitimer: %s\n", strerror(errno));
		pg_error_internal();
		return(EXIT_FAILURE);
	}

	/* Scan our run-time environment. */

	if (NULL == (scriptname = getenv("SCRIPT_NAME")))
		scriptname = "";

	if ( ! validate_urifrag(scriptname)) {
		fprintf(stderr, "unsafe SCRIPT_NAME \"%s\"\n",
		    scriptname);
		pg_error_internal();
		return(EXIT_FAILURE);
	}

	/*
	 * First we change directory into the MAN_DIR so that
	 * subsequent scanning for manpath directories is rooted
	 * relative to the same position.
	 */

	if (-1 == chdir(MAN_DIR)) {
		fprintf(stderr, "MAN_DIR: %s: %s\n",
		    MAN_DIR, strerror(errno));
		pg_error_internal();
		return(EXIT_FAILURE);
	} 

	memset(&req, 0, sizeof(struct req));
	pathgen(&req);

	/* Next parse out the query string. */

	if (NULL != (querystring = getenv("QUERY_STRING")))
		http_parse(&req, querystring);

	if (req.q.manpath == NULL)
		req.q.manpath = mandoc_strdup(req.p[0]);
	else if ( ! validate_manpath(&req, req.q.manpath)) {
		pg_error_badrequest(
		    "You specified an invalid manpath.");
		return(EXIT_FAILURE);
	}

	if ( ! (NULL == req.q.arch || validate_urifrag(req.q.arch))) {
		pg_error_badrequest(
		    "You specified an invalid architecture.");
		return(EXIT_FAILURE);
	}

	/* Dispatch to the three different pages. */

	path = getenv("PATH_INFO");
	if (NULL == path)
		path = "";
	else if ('/' == *path)
		path++;

	if ('\0' != *path)
		pg_show(&req, path);
	else if (NULL != req.q.query)
		pg_search(&req);
	else
		pg_index(&req);

	free(req.q.manpath);
	free(req.q.arch);
	free(req.q.sec);
	free(req.q.query);
	for (i = 0; i < (int)req.psz; i++)
		free(req.p[i]);
	free(req.p);
	return(EXIT_SUCCESS);
}
Esempio n. 4
0
int
main(void)
{
	struct req	 req;
	struct itimerval itimer;
	const char	*path;
	const char	*querystring;
	int		 i;

	/* Poor man's ReDoS mitigation. */

	itimer.it_value.tv_sec = 2;
	itimer.it_value.tv_usec = 0;
	itimer.it_interval.tv_sec = 2;
	itimer.it_interval.tv_usec = 0;
	if (setitimer(ITIMER_VIRTUAL, &itimer, NULL) == -1) {
		warn("setitimer");
		pg_error_internal();
		return EXIT_FAILURE;
	}

	/*
	 * First we change directory into the MAN_DIR so that
	 * subsequent scanning for manpath directories is rooted
	 * relative to the same position.
	 */

	if (chdir(MAN_DIR) == -1) {
		warn("MAN_DIR: %s", MAN_DIR);
		pg_error_internal();
		return EXIT_FAILURE;
	}

	memset(&req, 0, sizeof(struct req));
	req.q.equal = 1;
	parse_manpath_conf(&req);

	/* Parse the path info and the query string. */

	if ((path = getenv("PATH_INFO")) == NULL)
		path = "";
	else if (*path == '/')
		path++;

	if (*path != '\0') {
		parse_path_info(&req, path);
		if (req.q.manpath == NULL || access(path, F_OK) == -1)
			path = "";
	} else if ((querystring = getenv("QUERY_STRING")) != NULL)
		parse_query_string(&req, querystring);

	/* Validate parsed data and add defaults. */

	if (req.q.manpath == NULL)
		req.q.manpath = mandoc_strdup(req.p[0]);
	else if ( ! validate_manpath(&req, req.q.manpath)) {
		pg_error_badrequest(
		    "You specified an invalid manpath.");
		return EXIT_FAILURE;
	}

	if ( ! (NULL == req.q.arch || validate_urifrag(req.q.arch))) {
		pg_error_badrequest(
		    "You specified an invalid architecture.");
		return EXIT_FAILURE;
	}

	/* Dispatch to the three different pages. */

	if ('\0' != *path)
		pg_show(&req, path);
	else if (NULL != req.q.query)
		pg_search(&req);
	else
		pg_index(&req);

	free(req.q.manpath);
	free(req.q.arch);
	free(req.q.sec);
	free(req.q.query);
	for (i = 0; i < (int)req.psz; i++)
		free(req.p[i]);
	free(req.p);
	return EXIT_SUCCESS;
}