Changes in v9fs broke pipesrv. Fix it.
[npfs.git] / libnpauth / p9sk1.c
blob72e5df28342d5d0c4333a00355799eb2449f9171
2 #include <stdio.h>
3 #include <string.h>
4 #ifdef _WIN32
5 #include <ws2tcpip.h>
6 #else
7 #include <unistd.h>
8 #include <sys/types.h>
9 #include <sys/socket.h>
10 #include <netinet/in.h>
11 #include <netdb.h>
12 #endif
13 #include <errno.h>
14 #include "npfs.h"
15 #include "npclient.h"
16 #include "npauth.h"
18 #include "npaimpl.h"
20 static int
21 con(struct addrinfo *srv)
23 int s;
25 s = socket(srv->ai_family, srv->ai_socktype, 0);
26 if(s == -1)
27 return -1;
28 if (connect(s, srv->ai_addr, sizeof(*srv->ai_addr)) < 0) {
29 close(s);
30 return -1;
32 return s;
35 static int
36 getTicket(Npcauth *auth, struct ticketreq *treq, char ctick[72], char stick[72])
38 char treqbuf[141];
39 int fd;
40 char type;
42 fd = con(auth->srv);
43 if(fd == -1)
44 return err("cant reach auth", EPERM);
46 // XXX do we need to handle other type replies?
47 if(encTicketReq(treqbuf, treq) == -1
48 || send(fd, treqbuf, sizeof treqbuf, 0) != sizeof treqbuf
49 || recv(fd, &type, 1, 0) != 1
50 || type != AuthOK
51 || recv(fd, ctick, 72, 0) != 72
52 || recv(fd, stick, 72, 0) != 72) {
53 close(fd);
54 return err("botch", EINVAL);
56 close(fd);
57 return 0;
60 int
61 srvp9sk1(struct npsrvauth *a, char *msg, int len, char *resp, int resplen)
63 struct ticketreq treq;
64 struct auth auth;
65 struct ticket tick;
67 switch(a->state) {
68 case 0:
69 // state 0 is reserved for cases where server speaks first
70 if(len != 0)
71 return err("botch", EINVAL);
72 a->state++;
73 return 0;
75 case 1:
76 if(len != 8)
77 return err("botch", EINVAL);
78 memcpy(a->chc, msg, 8);
79 getRand(a->chs, 8);
81 treq.type = AuthTreq;
82 treq.ids = a->ids;
83 treq.dom = a->dom;
84 treq.ch = a->chs;
85 treq.idc = "";
86 treq.idr = "";
87 if(resplen < 141
88 || encTicketReq(resp, &treq) == -1)
89 return err("internal error", EINVAL);
90 a->state++;
91 return 141;
93 case 2:
94 if(len != 85)
95 return err("botch", EINVAL);
96 if(decTicket(msg, &tick, a->key) == -1
97 || tick.type != AuthTs
98 || memcmp(tick.ch, a->chs, 8) != 0
99 || decAuth(msg+72, &auth, tick.key) == -1
100 || auth.type != AuthAc
101 || memcmp(auth.ch, a->chs, 8) != 0
102 || auth.gen != a->gen)
103 return err("bad auth", EPERM);
105 a->idc = strdup(tick.idc);
106 a->idr = strdup(tick.idr);
107 auth.type = AuthAs;
108 memcpy(auth.ch, a->chc, 8);
109 auth.gen = a->gen;
110 if(resplen < 13
111 || encAuth(resp, &auth, tick.key) == -1)
112 return err("internal error", EINVAL);
113 a->state++;
114 a->done = 1;
115 return 13;
117 default:
118 return err("botch", EINVAL);
123 authp9sk1(Npcfid *afid, Npuser *user, void *aux)
125 char treqbuf[141], ctickbuf[72], stickbuf[72];
126 char authbuf[85], chc[8];
127 struct ticketreq treq;
128 struct ticket ctick;
129 struct auth auth;
130 struct npcauth *a = (struct npcauth *)aux;
132 // C->S CHc
133 getRand(chc, 8);
134 if(put(afid, chc, 8) <= 0)
135 return err("botch", EINVAL);
137 // S->C AuthTreq, IDs, DN, DHs, -, -
138 if(get(afid, treqbuf, 141) <= 0
139 || decTicketReq(treqbuf, &treq) == -1)
140 return err("botch", EINVAL);
141 if(treq.type != AuthTreq)
142 return err("botch", EINVAL);
144 // forward ticket request to authserver to get tickets.
145 treq.idc = user->uname;
146 treq.idr = user->uname;
147 if(getTicket(a, &treq, ctickbuf, stickbuf) == -1)
148 return -1;
149 if(decTicket(ctickbuf, &ctick, a->key) == -1)
150 return err("botch", EINVAL);
151 if(memcmp(treq.ch, ctick.ch, 8) != 0)
152 return err("bad auth", EPERM);
154 // C->S Ks{AuthTs, CHs, IDc, IDr, Kn}, Kn{AuthAc, CHs}
155 auth.type = AuthAc;
156 auth.ch = treq.ch;
157 auth.gen = a->gen;
158 memcpy(authbuf, stickbuf, 72);
159 if(encAuth(authbuf+72, &auth, ctick.key) == -1
160 || put(afid, authbuf, sizeof authbuf) == -1)
161 return err("botch", EINVAL);
163 // S->C Kn{AuthAs, Chc}
164 if(get(afid, authbuf, 13) == -1
165 || decAuth(authbuf, &auth, ctick.key))
166 return err("botch", EINVAL);
167 if(auth.type != AuthAs
168 || memcmp(auth.ch, chc, 8) != 0
169 || auth.gen != a->gen)
170 return err("bad server", EPERM);
172 a->gen++;
173 return 0;