]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/ip/httpd/authorize.c
add ip/tftpfs
[plan9front.git] / sys / src / cmd / ip / httpd / authorize.c
1 #include <u.h>
2 #include <libc.h>
3 #include <auth.h>
4 #include "httpd.h"
5 #include "httpsrv.h"
6
7 static char*    readfile(char*);
8
9 /*
10  * these should be done better; see the response codes in /lib/rfc/rfc2616 for
11  * more info on what should be included.
12  */
13 #define UNAUTHED        "You are not authorized to see this area.\n"
14
15 /*
16  * check for authorization for some parts of the server tree.
17  * the user name supplied with the authorization request is ignored;
18  * instead, we authenticate as the realm's user.
19  *
20  * authorization should be done before opening any files so that
21  * unauthorized users don't get to validate file names.
22  *
23  * returns 1 if authorized, 0 if unauthorized, -1 for io failure.
24  */
25 int
26 authorize(HConnect *c, char *file)
27 {
28         char *p, *p0;
29         Hio *hout;
30         char *buf;
31         int i, n;
32         char *t[257];
33
34         p0 = halloc(c, strlen(file)+STRLEN("/.httplogin")+1);
35         strcpy(p0, file);
36         for(;;){
37                 p = strrchr(p0, '/');
38                 if(p == nil)
39                         return hfail(c, HInternal);
40                 if(*(p+1) != 0)
41                         break;
42
43                 /* ignore trailing '/'s */
44                 *p = 0;
45         }
46         strcpy(p, "/.httplogin");
47
48         buf = readfile(p0);
49         if(buf == nil){
50                 return 1;
51         }
52         n = tokenize(buf, t, nelem(t));
53         
54         if(c->head.authuser != nil && c->head.authpass != 0){
55                 for(i = 1; i+1 < n; i += 2){
56                         if(strcmp(t[i], c->head.authuser) == 0
57                         && strcmp(t[i+1], c->head.authpass) == 0){
58                                 free(buf);
59                                 return 1;
60                         }
61                 }
62         }
63
64         hout = &c->hout;
65         hprint(hout, "%s 401 Unauthorized\r\n", hversion);
66         hprint(hout, "Server: Plan9\r\n");
67         hprint(hout, "Date: %D\r\n", time(nil));
68         hprint(hout, "WWW-Authenticate: Basic realm=\"%s\"\r\n", t[0]);
69         hprint(hout, "Content-Type: text/html\r\n");
70         hprint(hout, "Content-Length: %d\r\n", STRLEN(UNAUTHED));
71         if(c->head.closeit)
72                 hprint(hout, "Connection: close\r\n");
73         else if(!http11(c))
74                 hprint(hout, "Connection: Keep-Alive\r\n");
75         hprint(hout, "\r\n");
76         if(strcmp(c->req.meth, "HEAD") != 0)
77                 hprint(hout, "%s", UNAUTHED);
78         writelog(c, "Reply: 401 Unauthorized\n");
79         free(buf);
80         return hflush(hout);
81 }
82
83 static char*
84 readfile(char *file)
85 {
86         Dir *d;
87         int fd;
88         char *buf;
89         int n, len;
90
91         fd = open(file, OREAD);
92         if(fd < 0)
93                 return nil;
94         d = dirfstat(fd);
95         if(d == nil){           /* shouldn't happen */
96                 close(fd);
97                 return nil;
98         }
99         len = d->length;
100         free(d);
101
102         buf = malloc(len+1);
103         if(buf == 0){
104                 close(fd);
105                 return nil;
106         }
107
108         n = readn(fd, buf, len);
109         close(fd);
110         if(n <= 0){
111                 free(buf);
112                 return nil;
113         }
114         buf[n] = '\0';
115         return buf;
116 }