auth.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "all.h"
  10. #include "io.h"
  11. #include <authsrv.h>
  12. Nvrsafe nvr;
  13. static int gotnvr; /* flag: nvr contains nvram; it could be bad */
  14. char*
  15. nvrgetconfig(void)
  16. {
  17. return conf.confdev;
  18. }
  19. /*
  20. * we shouldn't be writing nvram any more.
  21. * the secstore/config field is now just secstore key.
  22. * we still use authid, authdom and machkey for authentication.
  23. */
  24. int
  25. nvrcheck(void)
  26. {
  27. uint8_t csum;
  28. if (readnvram(&nvr, NVread) < 0) {
  29. print("nvrcheck: can't read nvram\n");
  30. return 1;
  31. } else
  32. gotnvr = 1;
  33. print("nvr read\n");
  34. csum = nvcsum(nvr.machkey, sizeof nvr.machkey);
  35. if(csum != nvr.machsum) {
  36. print("\n\n ** NVR key checksum is incorrect **\n");
  37. print(" ** set password to allow attaches **\n\n");
  38. memset(nvr.machkey, 0, sizeof nvr.machkey);
  39. return 1;
  40. }
  41. return 0;
  42. }
  43. int
  44. nvrsetconfig(char* word)
  45. {
  46. /* config block is on device `word' */
  47. USED(word);
  48. return 0;
  49. }
  50. int
  51. conslock(void)
  52. {
  53. char *ln;
  54. char nkey1[DESKEYLEN];
  55. static char zeroes[DESKEYLEN];
  56. if(memcmp(nvr.machkey, zeroes, DESKEYLEN) == 0) {
  57. print("no password set\n");
  58. return 0;
  59. }
  60. for(;;) {
  61. print("%s password:", service);
  62. /* could turn off echo here */
  63. if ((ln = Brdline(&bin, '\n')) == nil)
  64. return 0;
  65. ln[Blinelen(&bin)-1] = '\0';
  66. /* could turn on echo here */
  67. memset(nkey1, 0, DESKEYLEN);
  68. passtokey(nkey1, ln);
  69. if(memcmp(nkey1, nvr.machkey, DESKEYLEN) == 0) {
  70. prdate();
  71. break;
  72. }
  73. print("Bad password\n");
  74. delay(1000);
  75. }
  76. return 1;
  77. }
  78. /*
  79. * authentication specific to 9P2000
  80. */
  81. /* authentication states */
  82. enum
  83. {
  84. HaveProtos=1,
  85. NeedProto,
  86. HaveOK,
  87. NeedCchal,
  88. HaveSinfo,
  89. NeedTicket,
  90. HaveSauthenticator,
  91. SSuccess,
  92. };
  93. char *phasename[] =
  94. {
  95. [HaveProtos] "HaveProtos",
  96. [NeedProto] "NeedProto",
  97. [HaveOK] "HaveOK",
  98. [NeedCchal] "NeedCchal",
  99. [HaveSinfo] "HaveSinfo",
  100. [NeedTicket] "NeedTicket",
  101. [HaveSauthenticator] "HaveSauthenticator",
  102. [SSuccess] "SSuccess",
  103. };
  104. /* authentication structure */
  105. struct Auth
  106. {
  107. int inuse;
  108. char uname[NAMELEN]; /* requestor's remote user name */
  109. char aname[NAMELEN]; /* requested aname */
  110. Userid uid; /* uid decided on */
  111. int phase;
  112. char cchal[CHALLEN];
  113. char tbuf[TICKETLEN+AUTHENTLEN]; /* server ticket */
  114. Ticket t;
  115. Ticketreq tr;
  116. };
  117. Auth* auths;
  118. Lock authlock;
  119. void
  120. authinit(void)
  121. {
  122. auths = malloc(conf.nauth * sizeof(*auths));
  123. }
  124. static int
  125. failure(Auth *s, char *why)
  126. {
  127. int i;
  128. if(*why)print("authentication failed: %s: %s\n", phasename[s->phase], why);
  129. srand((uintptr)s + time(nil));
  130. for(i = 0; i < CHALLEN; i++)
  131. s->tr.chal[i] = nrand(256);
  132. s->uid = -1;
  133. strncpy(s->tr.authid, nvr.authid, NAMELEN);
  134. strncpy(s->tr.authdom, nvr.authdom, DOMLEN);
  135. memmove(s->cchal, s->tr.chal, sizeof(s->cchal));
  136. s->phase = HaveProtos;
  137. return -1;
  138. }
  139. Auth*
  140. authnew(char *uname, char *aname)
  141. {
  142. static int si = 0;
  143. int i, nwrap;
  144. Auth *s;
  145. i = si;
  146. nwrap = 0;
  147. for(;;){
  148. if(i < 0 || i >= conf.nauth){
  149. if(++nwrap > 1)
  150. return nil;
  151. i = 0;
  152. }
  153. s = &auths[i++];
  154. if(s->inuse)
  155. continue;
  156. lock(&authlock);
  157. if(s->inuse == 0){
  158. s->inuse = 1;
  159. strncpy(s->uname, uname, NAMELEN-1);
  160. strncpy(s->aname, aname, NAMELEN-1);
  161. failure(s, "");
  162. si = i;
  163. unlock(&authlock);
  164. break;
  165. }
  166. unlock(&authlock);
  167. }
  168. return s;
  169. }
  170. void
  171. authfree(Auth *s)
  172. {
  173. if(s != nil)
  174. s->inuse = 0;
  175. }
  176. int
  177. authread(File* file, uint8_t* data, int n)
  178. {
  179. Auth *s;
  180. int m;
  181. s = file->auth;
  182. if(s == nil)
  183. return -1;
  184. switch(s->phase){
  185. default:
  186. return failure(s, "unexpected phase");
  187. case HaveProtos:
  188. m = snprint((char*)data, n, "v.2 p9sk1@%s", nvr.authdom) + 1;
  189. s->phase = NeedProto;
  190. break;
  191. case HaveOK:
  192. m = 3;
  193. if(n < m)
  194. return failure(s, "read too short");
  195. strcpy((char*)data, "OK");
  196. s->phase = NeedCchal;
  197. break;
  198. case HaveSinfo:
  199. m = TICKREQLEN;
  200. if(n < m)
  201. return failure(s, "read too short");
  202. convTR2M(&s->tr, (char*)data);
  203. s->phase = NeedTicket;
  204. break;
  205. case HaveSauthenticator:
  206. m = AUTHENTLEN;
  207. if(n < m)
  208. return failure(s, "read too short");
  209. memmove(data, s->tbuf+TICKETLEN, m);
  210. s->phase = SSuccess;
  211. break;
  212. }
  213. return m;
  214. }
  215. int
  216. authwrite(File* file, uint8_t *data, int n)
  217. {
  218. Auth *s;
  219. int m;
  220. char *p, *d;
  221. Authenticator a;
  222. s = file->auth;
  223. if(s == nil)
  224. return -1;
  225. switch(s->phase){
  226. default:
  227. return failure(s, "unknown phase");
  228. case NeedProto:
  229. p = (char*)data;
  230. if(p[n-1] != 0)
  231. return failure(s, "proto missing terminator");
  232. d = strchr(p, ' ');
  233. if(d == nil)
  234. return failure(s, "proto missing separator");
  235. *d++ = 0;
  236. if(strcmp(p, "p9sk1") != 0)
  237. return failure(s, "unknown proto");
  238. if(strcmp(d, nvr.authdom) != 0)
  239. return failure(s, "unknown domain");
  240. s->phase = HaveOK;
  241. m = n;
  242. break;
  243. case NeedCchal:
  244. m = CHALLEN;
  245. if(n < m)
  246. return failure(s, "client challenge too short");
  247. memmove(s->cchal, data, sizeof(s->cchal));
  248. s->phase = HaveSinfo;
  249. break;
  250. case NeedTicket:
  251. m = TICKETLEN+AUTHENTLEN;
  252. if(n < m)
  253. return failure(s, "ticket+auth too short");
  254. convM2T((char*)data, &s->t, nvr.machkey);
  255. if(s->t.num != AuthTs
  256. || memcmp(s->t.chal, s->tr.chal, sizeof(s->t.chal)) != 0)
  257. return failure(s, "bad ticket");
  258. convM2A((char*)data+TICKETLEN, &a, s->t.key);
  259. if(a.num != AuthAc
  260. || memcmp(a.chal, s->tr.chal, sizeof(a.chal)) != 0
  261. || a.id != 0)
  262. return failure(s, "bad authenticator");
  263. /* at this point, we're convinced */
  264. s->uid = strtouid(s->t.suid);
  265. if(s->uid < 0)
  266. return failure(s, "unknown user");
  267. if(cons.flags & authdebugflag)
  268. print("user %s = %d authenticated\n",
  269. s->t.suid, s->uid);
  270. /* create an authenticator to send back */
  271. a.num = AuthAs;
  272. memmove(a.chal, s->cchal, sizeof(a.chal));
  273. a.id = 0;
  274. convA2M(&a, s->tbuf+TICKETLEN, s->t.key);
  275. s->phase = HaveSauthenticator;
  276. break;
  277. }
  278. return m;
  279. }
  280. int
  281. authuid(Auth* s)
  282. {
  283. return s->uid;
  284. }
  285. char*
  286. authaname(Auth* s)
  287. {
  288. return s->aname;
  289. }
  290. char*
  291. authuname(Auth* s)
  292. {
  293. return s->uname;
  294. }