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 } 117