authorize.c 2.3 KB

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