1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include <ucx/string.h>
30
31 #include "pathcheck.h"
32
33 #include "../util/pblock.h"
34 #include "../daemon/config.h"
35 #include "../daemon/acl.h"
36 #include "../daemon/acldata.h"
37 #include "../daemon/session.h"
38 #include "../daemon/vserver.h"
39
40 #include "../daemon/vfs.h"
41
42 #include "../config/acl.h"
43
44 int require_auth(pblock *pb, Session *sn, Request *rq) {
45 char *user = pblock_findkeyval(pb_key_auth_user, rq->vars);
46
47 if(user ==
NULL) {
48 pblock_nvinsert(
49 "www-authenticate",
50 "Basic realm=\"Webserver\"",
51 rq->srvhdrs);
52
53 protocol_status(sn, rq,
PROTOCOL_UNAUTHORIZED,
NULL);
54 return REQ_ABORTED;
55 }
56
57 return REQ_PROCEED;
58 }
59
60 int require_access(pblock *pb, Session *sn, Request *rq) {
61 char *mask_str = pblock_findval(
"mask", pb);
62 if(!mask_str) {
63 log_ereport(
LOG_MISCONFIG,
"require-access: missing mask parameter");
64 protocol_status(sn, rq,
500,
NULL);
65 return REQ_ABORTED;
66 }
67
68 char *method = pblock_findval(
"method", pb);
69 if(method) {
70 char *m = pblock_findkeyval(pb_key_method, rq->reqpb);
71 if(strcmp(method, m)) {
72 return REQ_NOACTION;
73 }
74 }
75
76 uint32_t access_mask =
0;
77 ssize_t n =
0;
78 sstr_t *rights = sstrsplit(sstr(mask_str), sstrn(
",",
1), &n);
79 for(
int i=
0;i<n;i++) {
80 sstr_t right = rights[i];
81 access_mask = access_mask | accstr2int(right);
82 free(right.ptr);
83 }
84 free(rights);
85
86 rq->aclreqaccess = access_mask;
87
88 return REQ_PROCEED;
89 }
90
91 int append_acl(pblock *pb, Session *sn, Request *rq) {
92 const VirtualServer *vs = request_get_vs(rq);
93
94 WS_ASSERT(vs);
95
96 char *aclname = pblock_findval(
"acl", pb);
97 if(aclname) {
98 ACLList *acl = acl_get(vs->acls, aclname);
99 if(!acl) {
100 log_ereport(
101 LOG_MISCONFIG,
102 "append-acl: acl %s not found", aclname);
103 protocol_status(sn, rq,
500,
NULL);
104 return REQ_ABORTED;
105 }
106
107 acllist_append(sn, rq, acl);
108 }
109
110 return REQ_PROCEED;
111 }
112
113
114 int check_acl(pblock *pb, Session *sn, Request *rq) {
115 int access_mask =
ACL_READ_DATA | rq->aclreqaccess;
116
117 int ret = acl_evaluate(sn, rq, access_mask);
118 if(ret ==
REQ_ABORTED) {
119
120 return REQ_ABORTED;
121 }
122
123 return REQ_PROCEED;
124 }
125
126 int find_index(pblock *pb, Session *sn, Request *rq) {
127 char *inames = pblock_findval(
"index-names", pb);
128 if(!inames) {
129 log_ereport(
130 LOG_MISCONFIG,
131 "find-index: index-names parameter missing");
132 return REQ_ABORTED;
133 }
134
135 ssize_t ni =
0;
136 sstr_t *names = sstrsplit(sstr(inames),
S(
","), &ni);
137 if(ni <=
0) {
138 log_ereport(
139 LOG_MISCONFIG,
140 "find-index: no files specified in index-names parameter");
141 return REQ_ABORTED;
142 }
143
144 int ret =
REQ_NOACTION;
145
146 char *path = pblock_findkeyval(pb_key_path, rq->vars);
147 size_t pathlen = strlen(path);
148 sstr_t p = sstrn(path, pathlen);
149 if(path[pathlen-
1] ==
'/') {
150 for(
int i=
0;i<ni;i++) {
151 sstr_t newpath = sstrcat(
2, p, sstrtrim(names[i]));
152 struct stat s;
153 if(!stat(newpath.ptr, &s)) {
154 pblock_kvinsert(
155 pb_key_path,
156 newpath.ptr,
157 newpath.length,
158 rq->vars);
159 free(newpath.ptr);
160 ret =
REQ_PROCEED;
161 }
else {
162 free(newpath.ptr);
163 }
164 }
165 }
166
167 for(
int i=
0;i<ni;i++) {
168 free(names[i].ptr);
169 }
170 free(names);
171
172 return ret;
173 }
174
175 int dir_redirect(pblock *pb, Session *sn, Request *rq) {
176 char *path = pblock_findkeyval(pb_key_path, rq->vars);
177
178
179
180 struct stat s;
181 if(stat(path, &s) !=
0) {
182 return REQ_NOACTION;
183 }
184
185
186 if(
S_ISDIR(s.st_mode) && path[strlen(path)-
1] !=
'/') {
187 pblock_nvinsert(
"content-length",
"0", rq->srvhdrs);
188 pblock_removekey(pb_key_content_type, rq->srvhdrs);
189 char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
190 size_t urilen = strlen(uri);
191 char *location = pool_malloc(sn->pool, urilen +
2);
192 memcpy(location, uri, urilen);
193 location[urilen] =
'/';
194 location[urilen+
1] =
'\0';
195 pblock_kvinsert(pb_key_location, location, urilen +
1, rq->srvhdrs);
196 protocol_status(sn, rq,
302,
NULL);
197 http_start_response(sn, rq);
198 return REQ_ABORTED;
199 }
200
201 return REQ_PROCEED;
202 }
203