#include <ucx/string.h>
#include "pathcheck.h"
#include "../util/pblock.h"
#include "../daemon/config.h"
#include "../daemon/acl.h"
#include "../daemon/acldata.h"
#include "../daemon/session.h"
#include "../daemon/vserver.h"
#include "../daemon/vfs.h"
#include "../config/acl.h"
int require_auth(pblock *pb, Session *sn, Request *rq) {
char *user = pblock_findkeyval(pb_key_auth_user, rq->vars);
if(user ==
NULL) {
pblock_nvinsert(
"www-authenticate",
"Basic realm=\"Webserver\"",
rq->srvhdrs);
protocol_status(sn, rq,
PROTOCOL_UNAUTHORIZED,
NULL);
return REQ_ABORTED;
}
return REQ_PROCEED;
}
int require_access(pblock *pb, Session *sn, Request *rq) {
char *mask_str = pblock_findval(
"mask", pb);
if(!mask_str) {
log_ereport(
LOG_MISCONFIG,
"require-access: missing mask parameter");
protocol_status(sn, rq,
500,
NULL);
return REQ_ABORTED;
}
char *method = pblock_findval(
"method", pb);
if(method) {
char *m = pblock_findkeyval(pb_key_method, rq->reqpb);
if(strcmp(method, m)) {
return REQ_NOACTION;
}
}
uint32_t access_mask =
0;
ssize_t n =
0;
sstr_t *rights = sstrsplit(sstr(mask_str), sstrn(
",",
1), &n);
for(
int i=
0;i<n;i++) {
sstr_t right = rights[i];
access_mask = access_mask | accstr2int(right);
free(right.ptr);
}
free(rights);
rq->aclreqaccess = access_mask;
return REQ_PROCEED;
}
int append_acl(pblock *pb, Session *sn, Request *rq) {
const VirtualServer *vs = request_get_vs(rq);
WS_ASSERT(vs);
char *aclname = pblock_findval(
"acl", pb);
if(aclname) {
ACLList *acl = acl_get(vs->acls, aclname);
if(!acl) {
log_ereport(
LOG_MISCONFIG,
"append-acl: acl %s not found", aclname);
protocol_status(sn, rq,
500,
NULL);
return REQ_ABORTED;
}
acllist_append(sn, rq, acl);
}
return REQ_PROCEED;
}
int check_acl(pblock *pb, Session *sn, Request *rq) {
int access_mask =
ACL_READ_DATA | rq->aclreqaccess;
int ret = acl_evaluate(sn, rq, access_mask);
if(ret ==
REQ_ABORTED) {
return REQ_ABORTED;
}
return REQ_PROCEED;
}
int find_index(pblock *pb, Session *sn, Request *rq) {
char *inames = pblock_findval(
"index-names", pb);
if(!inames) {
log_ereport(
LOG_MISCONFIG,
"find-index: index-names parameter missing");
return REQ_ABORTED;
}
ssize_t ni =
0;
sstr_t *names = sstrsplit(sstr(inames),
S(
","), &ni);
if(ni <=
0) {
log_ereport(
LOG_MISCONFIG,
"find-index: no files specified in index-names parameter");
return REQ_ABORTED;
}
int ret =
REQ_NOACTION;
char *path = pblock_findkeyval(pb_key_path, rq->vars);
size_t pathlen = strlen(path);
sstr_t p = sstrn(path, pathlen);
if(path[pathlen-
1] ==
'/') {
for(
int i=
0;i<ni;i++) {
sstr_t newpath = sstrcat(
2, p, sstrtrim(names[i]));
struct stat s;
if(!stat(newpath.ptr, &s)) {
pblock_kvinsert(
pb_key_path,
newpath.ptr,
newpath.length,
rq->vars);
free(newpath.ptr);
ret =
REQ_PROCEED;
}
else {
free(newpath.ptr);
}
}
}
for(
int i=
0;i<ni;i++) {
free(names[i].ptr);
}
free(names);
return ret;
}
int dir_redirect(pblock *pb, Session *sn, Request *rq) {
char *path = pblock_findkeyval(pb_key_path, rq->vars);
struct stat s;
if(stat(path, &s) !=
0) {
return REQ_NOACTION;
}
if(
S_ISDIR(s.st_mode) && path[strlen(path)-
1] !=
'/') {
pblock_nvinsert(
"content-length",
"0", rq->srvhdrs);
pblock_removekey(pb_key_content_type, rq->srvhdrs);
char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
size_t urilen = strlen(uri);
char *location = pool_malloc(sn->pool, urilen +
2);
memcpy(location, uri, urilen);
location[urilen] =
'/';
location[urilen+
1] =
'\0';
pblock_kvinsert(pb_key_location, location, urilen +
1, rq->srvhdrs);
protocol_status(sn, rq,
302,
NULL);
http_start_response(sn, rq);
return REQ_ABORTED;
}
return REQ_PROCEED;
}