/* 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; }
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; }
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, <ime_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; }
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; }