Example #1
0
/* Methods implementation
 */
static ret_t
load_theme_load_file (cherokee_buffer_t *theme_path, const char *file, cherokee_buffer_t *output)
{
    cherokee_buffer_t path = CHEROKEE_BUF_INIT;

    cherokee_buffer_add_buffer (&path, theme_path);
    cherokee_buffer_add (&path, file, strlen(file));

    cherokee_buffer_clean (output);
    cherokee_buffer_read_file (output, path.buf);

    cherokee_buffer_mrproper (&path);
    return ret_ok;
}
ret_t
cherokee_validator_htdigest_check (cherokee_validator_htdigest_t *htdigest,
				   cherokee_connection_t         *conn)
{
	ret_t              ret;
	cherokee_buffer_t *fpass;
	cherokee_buffer_t  file = CHEROKEE_BUF_INIT;

	/* Ensure that we have all what we need
	 */
	if ((conn->validator == NULL) ||
	    cherokee_buffer_is_empty (&conn->validator->user))
		return ret_error;

	/* Get the full path to the file
	 */
	ret = cherokee_validator_file_get_full_path (VFILE(htdigest), conn, &fpass,
						     &CONN_THREAD(conn)->tmp_buf1);
	if (ret != ret_ok) {
		ret = ret_error;
		goto out;
	}

	/* Read the whole file
	 */
	ret = cherokee_buffer_read_file (&file, fpass->buf);
	if (ret != ret_ok) {
		ret = ret_error;
		goto out;
	}

	/* Authenticate
	 */
	if (conn->req_auth_type & http_auth_basic) {
		ret = validate_basic (htdigest, conn, &file);

	} else if (conn->req_auth_type & http_auth_digest) {
		ret = validate_digest (htdigest, conn, &file);

	} else {
		SHOULDNT_HAPPEN;
	}

out:
	cherokee_buffer_mrproper (&file);
	return ret;
}
Example #3
0
static ret_t
init (cherokee_handler_ssi_t *hdl,
          cherokee_buffer_t      *local_path)
{
	int                    re;
	ret_t                  ret;
	cherokee_connection_t *conn = HANDLER_CONN(hdl);

	/* Stat the file
	 */
	re = cherokee_stat (local_path->buf, &hdl->cache_info);
	if (re < 0) {
		switch (errno) {
		case ENOENT:
			conn->error_code = http_not_found;
			break;
		case EACCES:
			conn->error_code = http_access_denied;
			break;
		default:
			conn->error_code = http_internal_error;
		}
		return ret_error;
	}

	/* Read the file
	 */
	ret = cherokee_buffer_read_file (&hdl->source, local_path->buf);
	if (ret != ret_ok)
		return ret_error;

	/* Render
	 */
	ret = parse (hdl, &hdl->source, &hdl->render);
	if (ret != ret_ok)
		return ret;

	return ret_ok;
}
Example #4
0
static ret_t
parse (cherokee_handler_ssi_t *hdl,
       cherokee_buffer_t      *in,
       cherokee_buffer_t      *out)
{
	ret_t              ret;
	char              *p, *q;
	char              *begin;
	int                re;
	cuint_t            len;
	operations_t       op;
	path_type_t        path;
	struct stat        info;
	cherokee_boolean_t ignore;
	cherokee_buffer_t  key     = CHEROKEE_BUF_INIT;
	cherokee_buffer_t  val     = CHEROKEE_BUF_INIT;
	cherokee_buffer_t  pair    = CHEROKEE_BUF_INIT;
	cherokee_buffer_t  fpath   = CHEROKEE_BUF_INIT;

	q = in->buf;

	while (true) {
		begin = q;

		/* Check the end
		 */
		if (q >= in->buf + in->len)
			break;

		/* Find next SSI tag
		 */
		p = strstr (q, "<!--#");
		if (p == NULL) {
			cherokee_buffer_add (out, begin, (in->buf + in->len) - begin);
			ret = ret_ok;
			goto out;
		}

		q = strstr (p + 5, "-->");
		if (q == NULL) {
			ret = ret_error;
			goto out;
		}

		len = q - p;
		len -= 5;

		cherokee_buffer_clean (&key);
		cherokee_buffer_add (&key, p+5, len);
		cherokee_buffer_trim (&key);

		q += 3;
		TRACE(ENTRIES, "Found key '%s'\n", key.buf);

		/* Add the previous chunk
		 */
		cherokee_buffer_add (out, begin, p - begin);

		/* Check element
		 */
		op     = op_none;
		ignore = false;

		if (strncmp (key.buf, "include", 7) == 0) {
			op  = op_include;
			len = 7;
		} else if (strncmp (key.buf, "fsize", 5) == 0) {
			op  = op_size;
			len = 5;
		} else if (strncmp (key.buf, "flastmod", 8) == 0) {
			op  = op_lastmod;
			len = 8;
		} else {
			LOG_ERROR (CHEROKEE_ERROR_HANDLER_SSI_PROPERTY, key.buf);
		}

		/* Deeper parsing
		 */
		path = path_none;

		switch (op) {
		case op_size:
		case op_include:
		case op_lastmod:
			/* Read a property key
			 */
			cherokee_buffer_move_to_begin (&key, len);
			cherokee_buffer_trim (&key);

			cherokee_buffer_clean (&pair);
			get_pair (&key, &pair);

			cherokee_buffer_drop_ending (&key, pair.len);
			cherokee_buffer_trim (&key);

			/* Parse the property
			 */
			if (strncmp (pair.buf, "file=", 5) == 0) {
				path = path_file;
				len  = 5;
			} else if (strncmp (pair.buf, "virtual=", 8) == 0) {
				path = path_virtual;
				len  = 8;
			}

			cherokee_buffer_clean (&val);
			get_val (pair.buf + len, &val);

			cherokee_buffer_clean (&fpath);

			switch (path) {
			case path_file:
				cherokee_buffer_add_buffer (&fpath, &hdl->dir);
				cherokee_buffer_add_char   (&fpath, '/');
				cherokee_buffer_add_buffer (&fpath, &val);

				TRACE(ENTRIES, "Path: file '%s'\n", fpath.buf);
				break;
			case path_virtual:
				cherokee_buffer_add_buffer (&fpath, &HANDLER_VSRV(hdl)->root);
				cherokee_buffer_add_char   (&fpath, '/');
				cherokee_buffer_add_buffer (&fpath, &val);

				TRACE(ENTRIES, "Path: virtual '%s'\n", fpath.buf);
				break;
			default:
				ignore = true;
				SHOULDNT_HAPPEN;
			}

			/* Path security check: ensure that the file
			 * to include is inside the document root.
			 */
			if (! cherokee_buffer_is_empty (&fpath)) {
				cherokee_path_short (&fpath);

				if (fpath.len < HANDLER_VSRV(hdl)->root.len) {
					ignore = true;

				}  else {
					re = strncmp (fpath.buf,
					              HANDLER_VSRV(hdl)->root.buf,
					              HANDLER_VSRV(hdl)->root.len);
					if (re != 0) {
						ignore = true;
					}
				}
			}

			/* Perform the operation
			 */
			if (! ignore) {
				switch (op) {
				case op_include: {
					cherokee_buffer_t file_content = CHEROKEE_BUF_INIT;

					ret = cherokee_buffer_read_file (&file_content, fpath.buf);
					if (unlikely (ret != ret_ok)) {
						cherokee_buffer_mrproper (&file_content);
						ret = ret_error;
						goto out;
					}

					TRACE(ENTRIES, "Including file '%s'\n", fpath.buf);

					ret = parse (hdl, &file_content, out);
					if (unlikely (ret != ret_ok)) {
						cherokee_buffer_mrproper (&file_content);
						ret = ret_error;
						goto out;
					}

					cherokee_buffer_mrproper (&file_content);
					break;
				}

				case op_size:
					TRACE(ENTRIES, "Including file size '%s'\n", fpath.buf);
					re = cherokee_stat (fpath.buf, &info);
					if (re >=0) {
						cherokee_buffer_add_ullong10 (out, info.st_size);
					}
					break;

				case op_lastmod:
					TRACE(ENTRIES, "Including file modification date '%s'\n", fpath.buf);
					re = cherokee_stat (fpath.buf, &info);
					if (re >= 0) {
						struct tm *ltime;
						struct tm  ltime_buf;
						char       tmp[50];

						ltime = cherokee_localtime (&info.st_mtime, &ltime_buf);
						if (ltime != NULL) {
							strftime (tmp, sizeof(tmp), "%d-%b-%Y %H:%M", ltime);
							cherokee_buffer_add (out, tmp, strlen(tmp));
						}
					}
					break;
				default:
					SHOULDNT_HAPPEN;
				}
			} /* !ignore */

			break;
		default:
			SHOULDNT_HAPPEN;
		} /* switch(op) */
	} /* while */

	ret = ret_ok;

out:
	cherokee_buffer_mrproper (&key);
	cherokee_buffer_mrproper (&val);
	cherokee_buffer_mrproper (&pair);
	cherokee_buffer_mrproper (&fpath);

	return ret;
}
Example #5
0
ret_t
cherokee_validator_plain_check (cherokee_validator_plain_t *plain,
				cherokee_connection_t      *conn)
{
	int                re;
	ret_t              ret;
	const char        *p;
	const char        *end;
	cherokee_buffer_t *fpass;
	cherokee_buffer_t  file  = CHEROKEE_BUF_INIT;
	cherokee_buffer_t  buser = CHEROKEE_BUF_INIT;
	cherokee_buffer_t  bpass = CHEROKEE_BUF_INIT;

	/* Sanity check */
	if (unlikely ((conn->validator == NULL) ||
	    cherokee_buffer_is_empty(&conn->validator->user))) {
		return ret_error;
	}

	/* Get the full path to the file */
	ret = cherokee_validator_file_get_full_path (VFILE(plain), conn, &fpass,
						     &CONN_THREAD(conn)->tmp_buf1);
	if (ret != ret_ok) {
		ret = ret_error;
		goto out;
	}

	/* Read its contents */
	ret = cherokee_buffer_read_file (&file, fpass->buf);
	if (ret != ret_ok) {
		ret = ret_error;
		goto out;
	}

	if (! cherokee_buffer_is_ending(&file, '\n'))
		cherokee_buffer_add_str (&file, "\n");

	p   = file.buf;
	end = file.buf + file.len;

	while (p < end) {
		char *eol;
		char *colon;

		/* Look for the EOL
		 */
		eol = strchr (p, '\n');
		if (eol == NULL) {
			ret = ret_ok;
			goto out;
		}
		*eol = '\0';

		/* Skip comments
		 */
		if (p[0] == '#')
			goto next;

		colon = strchr (p, ':');
		if (colon == NULL) {
			goto next;
		}

		/* Is it the right user?
		 */
		cherokee_buffer_clean (&buser);
		cherokee_buffer_add (&buser, p, colon - p);

		re = cherokee_buffer_cmp_buf (&buser, &conn->validator->user);
		if (re != 0)
			goto next;

		/* Check the password
		 */
		cherokee_buffer_clean (&bpass);
		cherokee_buffer_add (&bpass, colon+1, eol - (colon+1));

		switch (conn->req_auth_type) {
		case http_auth_basic:
			/* Empty password
			 */
			if (cherokee_buffer_is_empty (&bpass) &&
			    cherokee_buffer_is_empty (&conn->validator->passwd)) {
				ret = ret_ok;
				goto out;
			}

			/* Check the passwd
			 */
			re = cherokee_buffer_cmp_buf (&bpass, &conn->validator->passwd);
			if (re != 0)
				ret = ret_deny;
			goto out;

		case http_auth_digest:
			ret = cherokee_validator_digest_check (VALIDATOR(plain), &bpass, conn);
			goto out;

		default:
			SHOULDNT_HAPPEN;
		}

		/* A user entry has been tested and failed
		 */
		ret = ret_deny;
		goto out;

	next:
		p = eol + 1;

		/* Reached the end without success
		 */
		if (p >= end) {
			ret = ret_deny;
			goto out;
		}
	}

out:
 	cherokee_buffer_mrproper (&file);
 	cherokee_buffer_mrproper (&buser);
 	cherokee_buffer_mrproper (&bpass);
	return ret;
}