password.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /* password.c */
  2. #include <u.h>
  3. #include <libc.h>
  4. #include <bio.h>
  5. #include <mp.h>
  6. #include <libsec.h>
  7. #include "SConn.h"
  8. #include "secstore.h"
  9. static Biobuf*
  10. openPW(char *id, int mode)
  11. {
  12. Biobuf *b;
  13. int nfn = strlen(SECSTORE_DIR)+strlen(id)+20;
  14. char *fn = emalloc(nfn);
  15. snprint(fn, nfn, "%s/who/%s", SECSTORE_DIR, id);
  16. b = Bopen(fn, mode);
  17. free(fn);
  18. return b;
  19. }
  20. static ulong
  21. mtimePW(char *id)
  22. {
  23. Dir *d;
  24. int nfn = strlen(SECSTORE_DIR)+strlen(id)+20;
  25. char *fn = emalloc(nfn);
  26. ulong mt;
  27. snprint(fn, nfn, "%s/who/%s", SECSTORE_DIR, id);
  28. d = dirstat(fn);
  29. free(fn);
  30. mt = d->mtime;
  31. free(d);
  32. return mt;
  33. }
  34. PW *
  35. getPW(char *id, int dead_or_alive)
  36. {
  37. uint now = time(0);
  38. Biobuf *bin;
  39. PW *pw;
  40. char *f1, *f2; // fields 1, 2 = attribute, value
  41. if((bin = openPW(id, OREAD)) == 0){
  42. id = "FICTITIOUS";
  43. if((bin = openPW(id, OREAD)) == 0){
  44. werrstr("account does not exist");
  45. return nil;
  46. }
  47. }
  48. pw = emalloc(sizeof(*pw));
  49. pw->id = estrdup(id);
  50. pw->status |= Enabled;
  51. while( (f1 = Brdline(bin, '\n')) != 0){
  52. f1[Blinelen(bin)-1] = 0;
  53. for(f2 = f1; *f2 && (*f2!=' ') && (*f2!='\t'); f2++){}
  54. if(*f2)
  55. for(*f2++ = 0; *f2 && (*f2==' ' || *f2=='\t'); f2++){}
  56. if(strcmp(f1, "exp") == 0){
  57. pw->expire = strtoul(f2, 0, 10);
  58. }else if(strcmp(f1, "DISABLED") == 0){
  59. pw->status &= ~Enabled;
  60. }else if(strcmp(f1, "STA") == 0){
  61. pw->status |= STA;
  62. }else if(strcmp(f1, "failed") == 0){
  63. pw->failed = strtoul(f2, 0, 10);
  64. }else if(strcmp(f1, "other") == 0){
  65. pw->other = estrdup(f2);
  66. }else if(strcmp(f1, "PAK-Hi") == 0){
  67. pw->Hi = strtomp(f2, nil, 64, nil);
  68. }
  69. }
  70. Bterm(bin);
  71. if(dead_or_alive)
  72. return pw; // return PW entry for editing, whether currently valid or not
  73. if(pw->expire <= now){
  74. werrstr("account expired");
  75. freePW(pw);
  76. return nil;
  77. }
  78. if((pw->status & Enabled) == 0){
  79. werrstr("account disabled");
  80. freePW(pw);
  81. return nil;
  82. }
  83. if(pw->failed < 10)
  84. return pw; // success
  85. if(now < mtimePW(id)+300){
  86. werrstr("too many failures; try again in five minutes");
  87. freePW(pw);
  88. return nil;
  89. }
  90. pw->failed = 0;
  91. putPW(pw); // reset failed-login-counter after five minutes
  92. return pw;
  93. }
  94. int
  95. putPW(PW *pw)
  96. {
  97. Biobuf *bout;
  98. char *hexHi;
  99. if((bout = openPW(pw->id, OWRITE|OTRUNC)) ==0){
  100. werrstr("can't open PW file");
  101. return -1;
  102. }
  103. Bprint(bout, "exp %lud\n", pw->expire);
  104. if(!(pw->status & Enabled))
  105. Bprint(bout, "DISABLED\n");
  106. if(pw->status & STA)
  107. Bprint(bout, "STA\n");
  108. if(pw->failed)
  109. Bprint(bout, "failed\t%d\n", pw->failed);
  110. if(pw->other)
  111. Bprint(bout,"other\t%s\n", pw->other);
  112. hexHi = mptoa(pw->Hi, 64, nil, 0);
  113. Bprint(bout, "PAK-Hi\t%s\n", hexHi);
  114. free(hexHi);
  115. return 0;
  116. }
  117. void
  118. freePW(PW *pw)
  119. {
  120. if(pw == nil)
  121. return;
  122. free(pw->id);
  123. free(pw->other);
  124. mpfree(pw->Hi);
  125. free(pw);
  126. }