3 * This file is part of httpd.
5 * 02/17/1996 Michael Temari <Michael@TemWare.Com>
6 * 07/07/1996 Initial Release Michael Temari <Michael@TemWare.Com>
7 * 12/29/2002 Michael Temari <Michael@TemWare.Com>
10 #include <sys/types.h>
30 _PROTOTYPE(static int authaccess
, (struct http_request
*rq
, struct http_reply
*rp
));
31 _PROTOTYPE(static void purl
, (struct http_request
*rq
, struct http_reply
*rp
));
32 _PROTOTYPE(static char *virt
, (char *to
, char *host
));
34 static int authaccess(rq
, rp
)
35 struct http_request
*rq
;
36 struct http_reply
*rp
;
41 /* set authorization to be checked against */
42 if(rq
->type
== HTTP_REQUEST_TYPE_PROXY
)
47 /* no authorization so no access to anyone */
49 rp
->status
= HTTP_STATUS_FORBIDDEN
;
50 strcpy(rp
->statusmsg
, "No Authoriation");
54 /* access must be R for PROXY */
55 if(rq
->type
== HTTP_REQUEST_TYPE_PROXY
)
56 if(!(auth
->urlaccess
& URLA_READ
)) {
57 rp
->status
= HTTP_STATUS_FORBIDDEN
;
58 strcpy(rp
->statusmsg
, "Proxy not authorized");
62 /* no password file so it is a free for all */
63 if(auth
->passwdfile
== NULL
)
66 /* they did not give us an authorized user */
67 if(rq
->authuser
[0] == '\0') {
68 if(rq
->type
== HTTP_REQUEST_TYPE_PROXY
)
69 rp
->status
= HTTP_STATUS_PROXY_AUTH_REQRD
;
71 rp
->status
= HTTP_STATUS_UNAUTHORIZED
;
72 strcpy(rp
->statusmsg
, "No Authorized User Given");
76 /* check if user okay */
79 ; /* no user list we allow anyone in file */
82 if(!strcmp(pu
->user
, rq
->authuser
))
86 /* user is not in list so no access */
88 if(rq
->type
== HTTP_REQUEST_TYPE_PROXY
)
89 rp
->status
= HTTP_STATUS_PROXY_AUTH_REQRD
;
91 rp
->status
= HTTP_STATUS_UNAUTHORIZED
;
92 strcpy(rp
->statusmsg
, "Forbidden User not authorized");
97 /* check if password file exists, if not no access */
98 if(passfile(auth
->passwdfile
)) {
99 rp
->status
= HTTP_STATUS_FORBIDDEN
;
100 strcpy(rp
->statusmsg
, "Invalid passwd file");
104 /* check if user in password file, if not no access */
105 if(passuser(auth
->passwdfile
, rq
->authuser
)) {
106 if(rq
->type
== HTTP_REQUEST_TYPE_PROXY
)
107 rp
->status
= HTTP_STATUS_PROXY_AUTH_REQRD
;
109 rp
->status
= HTTP_STATUS_UNAUTHORIZED
;
110 strcpy(rp
->statusmsg
, "Forbidden Bad User");
114 /* check if a password exists, if not no access */
115 if(passnone(auth
->passwdfile
, rq
->authuser
)) {
116 if(rq
->type
== HTTP_REQUEST_TYPE_PROXY
)
117 rp
->status
= HTTP_STATUS_PROXY_AUTH_REQRD
;
119 rp
->status
= HTTP_STATUS_UNAUTHORIZED
;
120 strcpy(rp
->statusmsg
, "Forbidden no password");
124 /* check if password matches, if not no access */
125 if(passpass(auth
->passwdfile
, rq
->authuser
, rq
->authpass
)) {
126 if(rq
->type
== HTTP_REQUEST_TYPE_PROXY
)
127 rp
->status
= HTTP_STATUS_PROXY_AUTH_REQRD
;
129 rp
->status
= HTTP_STATUS_UNAUTHORIZED
;
130 strcpy(rp
->statusmsg
, "Forbidden bad password");
134 /* whew, all the checks passed so I guess we let them have it */
139 struct http_request
*rq
;
140 struct http_reply
*rp
;
148 rp
->mtype
= "text/html";
151 fprintf(stderr
, "httpd: Trying %s\n", rp
->realurl
);
154 /* now check authorizations */
155 if(authaccess(rq
, rp
)) {
156 /* Don't give them any details why authorization failed */
157 strcpy(rp
->statusmsg
, "No Access Granted");
161 /* a proxy request only needs an authorization check */
162 if(rq
->type
== HTTP_REQUEST_TYPE_PROXY
)
165 /* check access to real url */
166 if(stat(rp
->realurl
, &st
)) {
168 rp
->status
= HTTP_STATUS_FORBIDDEN
;
170 rp
->status
= HTTP_STATUS_NOT_FOUND
;
171 strcpy(rp
->statusmsg
, strerror(errno
));
172 /* a PUT and NOT FOUND is okay since we are creating */
173 if(rq
->method
!= HTTP_METHOD_PUT
|| rp
->status
!= HTTP_STATUS_NOT_FOUND
)
177 /* If it is a directory do the appropriate thang! */
178 if(rq
->method
== HTTP_METHOD_GET
|| rq
->method
== HTTP_METHOD_HEAD
)
179 if((st
.st_mode
& S_IFMT
) == S_IFDIR
) {
180 if(rq
->url
[strlen(rq
->url
) - 1] != '/') {
181 strncat(rq
->url
, "/", sizeof(rq
->url
) - strlen(rq
->url
));
182 rp
->status
= HTTP_STATUS_MOVED_TEMP
;
183 sprintf(rp
->statusmsg
, "Moved to %s", rq
->url
);
186 size
= strlen(rq
->url
);
189 strncpy(rq
->url
+size
, ds
->file
, sizeof(rq
->url
)-size
);
191 if(stat(rp
->realurl
, &st
)) {
193 rp
->status
= HTTP_STATUS_FORBIDDEN
;
196 rp
->status
= HTTP_STATUS_NOT_FOUND
;
199 if(rp
->status
!= HTTP_STATUS_OK
) {
200 strcpy(rp
->statusmsg
, strerror(errno
));
206 rq
->url
[size
] = '\0';
208 if(stat(rp
->realurl
, &st
)) {
210 rp
->status
= HTTP_STATUS_FORBIDDEN
;
212 rp
->status
= HTTP_STATUS_NOT_FOUND
;
213 strcpy(rp
->statusmsg
, strerror(errno
));
219 if(rq
->method
== HTTP_METHOD_PUT
&& !(rp
->urlaccess
& URLA_WRITE
)) {
220 rp
->status
= HTTP_STATUS_METHOD_NOT_ALLOWED
;
221 strcpy(rp
->statusmsg
, "Method not allowed");
225 if(rp
->status
== HTTP_STATUS_OK
) {
226 /* Here is where we check if it is a program or script to run */
230 if((st
.st_mode
& S_IFMT
) == S_IFDIR
) {
231 rp
->status
= HTTP_STATUS_NOT_FOUND
;
232 strcpy(rp
->statusmsg
, "Directory listing not available");
236 if((st
.st_mode
& S_IFMT
) != S_IFREG
) {
237 rp
->status
= HTTP_STATUS_NOT_FOUND
;
238 strcpy(rp
->statusmsg
, "Not a regular file");
243 /* open the URL for updating */
244 if(rq
->method
== HTTP_METHOD_PUT
) {
245 rp
->status
= HTTP_STATUS_OK
;
246 strcpy(rp
->statusmsg
, "OK");
247 rp
->ofd
= open(rp
->realurl
, O_WRONLY
| O_CREAT
| O_TRUNC
);
250 rp
->status
= HTTP_STATUS_FORBIDDEN
;
252 rp
->status
= HTTP_STATUS_NOT_FOUND
;
253 strcpy(rp
->statusmsg
, strerror(errno
));
259 if(!(rp
->urlaccess
& URLA_READ
)) {
260 rp
->status
= HTTP_STATUS_FORBIDDEN
;
261 strcpy(rp
->statusmsg
, "No way...");
265 rp
->mtype
= mimetype(rp
->realurl
);
267 rp
->size
= st
.st_size
;
268 rp
->modtime
= st
.st_mtime
;
270 /* open the url if it is a file */
271 rp
->fd
= open(rp
->realurl
, O_RDONLY
);
274 rp
->status
= HTTP_STATUS_FORBIDDEN
;
276 rp
->status
= HTTP_STATUS_NOT_FOUND
;
277 strcpy(rp
->statusmsg
, strerror(errno
));
284 static void purl(rq
, rp
)
285 struct http_request
*rq
;
286 struct http_reply
*rp
;
289 int gotreal
, gotperm
;
294 gotreal
= 0; gotperm
= 0;
297 fprintf(stderr
, "httpd: Processing url = \"%s\"\n", rq
->url
);
300 /* remove any .. references */
303 while(*p
&& *p
!= '/') p
++;
304 if(*p
!= '/') continue;
306 if(*p
!= '.') continue;
308 if(*p
!= '.') continue;
314 for(pv
= vpath
; pv
!= NULL
; pv
= pv
->next
) {
315 len
= strlen(pv
->from
) - 1;
316 if(pv
->from
[len
] == '*' || pv
->from
[len
] == '$')
320 match
= strncmp(rq
->url
, pv
->from
, len
) ? MATCH_NONE
: MATCH_WILD
;
322 if(!strcmp(rq
->url
, pv
->from
))
327 fprintf(stderr
, "httpd: Trying \"%s\" %d %d %d %s\n",
328 pv
->from
, match
, gotreal
, gotperm
, pv
->auth
->name
);
330 if(match
!= MATCH_NONE
) {
333 if(pv
->urlaccess
== -1 && rp
->auth
!= NULL
)
334 rp
->urlaccess
= rp
->auth
->urlaccess
;
336 rp
->urlaccess
= pv
->urlaccess
;
337 if(strcmp(pv
->to
, ".")) {
339 strncpy(rp
->realurl
, virt(pv
->to
, rq
->host
), sizeof(rp
->realurl
));
340 rp
->realurl
[sizeof(rp
->realurl
)-1] = '\0';
341 if(match
== MATCH_WILD
&& pv
->from
[len
] != '$') {
342 strncat(rp
->realurl
, rq
->url
+len
, sizeof(rp
->realurl
) - strlen(rp
->realurl
));
343 rp
->realurl
[sizeof(rp
->realurl
)-1] = '\0';
347 if(match
== MATCH_FULL
) break;
350 if(rp
->urlaccess
== -1) rp
->urlaccess
= mkurlaccess("");
353 strncpy(rp
->realurl
, rq
->url
, sizeof(rp
->realurl
));
354 rp
->realurl
[sizeof(rp
->realurl
)-1] = '\0';
361 fprintf(stderr
, "DEBUG: url = \"%s\" realurl = \"%s\" auth = \"%s\"\n",
362 rq
->url
, rp
->realurl
, ((rp
->auth
== NULL
) ? "No Access" : rp
->auth
->name
));
363 fprintf(stderr
, "DEBUG: query = %s\n", rq
->query
);
369 static char *virt(to
, host
)
373 static char vroot
[256];
377 fprintf(stderr
, "virt: %s %s\n", to
, host
);
380 if(vhost
== NULL
) return(to
);
382 if(to
[0] != '/') return(to
);
383 if(to
[1] != '/') return(to
);
384 if(to
[2] != '/') return(to
);
388 for(ph
= vhost
; ph
!= NULL
; ph
= ph
->next
) {
390 fprintf(stderr
, "ph: %s %s %s\n", ph
->hname
, ph
->root
, vroot
);
392 if(!strcmp(ph
->hname
, "*") && vroot
[0] == '\0')
393 strncpy(vroot
, ph
->root
, sizeof(vroot
));
394 if(!strcasecmp(ph
->hname
, host
)) {
395 strncpy(vroot
, ph
->root
, sizeof(vroot
));
400 strncat(vroot
, to
+3, sizeof(vroot
));
403 fprintf(stderr
, "vroot: %s\n", vroot
);