History

20080116-1406

Charles.Forsyth committed 18 years ago

Commit de74bb61 parent d0bd08a2 files · +203 −-1Browse files

Unified · Split

2 files
  1. appl/cmd/auth/factotum/proto/authquery.b +204 −0
  2. dis/auth/proto/authquery.dis +0 −0
appl/cmd/auth/factotum/proto/authquery.b+204−0
@@ -0,0 +1,204 @@
1+implement Authproto;
2+include "sys.m";
3+ sys: Sys;
4+ Rread, Rwrite: import Sys;
5+include "draw.m";
6+include "keyring.m";
7+include "bufio.m";
8+include "sexprs.m";
9+ sexprs: Sexprs;
10+ Sexp: import sexprs;
11+include "spki.m";
12+ spki: SPKI;
13+include "../authio.m";
14+ authio: Authio;
15+ Aattr, Aval, Aquery: import Authio;
16+ Attr, IO, Key, Authinfo: import authio;
17+
18+# queries to handle:
19+# are you a member of group X?
20+# are you group leader of group X?
21+
22+Debug: con 0;
23+
24+# init, addkey, closekey, write, read, close, keyprompt
25+
26+Query: adt {
27+ e: ref Sexp;
28+ certs: list of ref Sexp;
29+ gotcerts: list of ref Sexp;
30+
31+ parse: fn(se: ref Sexp): (ref Query, string);
32+ neededcert: fn(q: self ref Query): ref Sexp;
33+ addcert: fn(q: self ref Query, cert: ref Sexp): string;
34+ result: fn(q: self ref Query): ref Sexp;
35+};
36+
37+Read: adt {
38+ buf: array of byte;
39+ ptr: int;
40+ off: int;
41+ io: ref IO;
42+
43+ new: fn(io: ref IO): ref Read;
44+ getb: fn(r: self ref Read): int;
45+ ungetb: fn(r: self ref Read): int;
46+ offset: fn(r: self ref Read): big;
47+};
48+
49+
50+Maxmsg: con 4000;
51+
52+init(f: Authio): string
53+{
54+ authio = f;
55+ sys = load Sys Sys->PATH;
56+ spki = load SPKI SPKI->PATH;
57+ spki->init();
58+ sexprs = load Sexprs Sexprs->PATH;
59+ sexprs->init();
60+ return nil;
61+}
62+
63+interaction(attrs: list of ref Attr, io: ref IO): string
64+{
65+ case authio->lookattrval(attrs, "role") {
66+ "client" =>
67+ return client(attrs, io);
68+ "server" =>
69+ return server(attrs, io);
70+ * =>
71+ return "unknown role";
72+ }
73+}
74+
75+client(attrs: list of ref Attr, io: ref IO): string
76+{
77+ (sexp, nil, err) := Sexp.parse(authio->lookattrval(attrs, "query"));
78+ if(sexp == nil || err != nil)
79+ raise sys->sprint("bad or empty query %q: %s", authio->lookattrval(attrs, "query"), err);
80+ for(;;){
81+ write(io, sexp.pack());
82+ (sexp, err) = Sexp.read(Read.new(io));
83+ if(err != nil)
84+ return "authquery: bad query: "+err;
85+ if(sexp == nil)
86+ return "authquery: no result";
87+ if(sexp.op() != "needcert"){
88+ io.done(ref Authinfo(nil, nil, nil, sexp.pack())); # XXX use something other than secret
89+ return nil;
90+ }
91+ (sexp, err) = needcert(io, sexp);
92+ if(sexp == nil)
93+ return "authquery: no cert: "+err;
94+ }
95+}
96+
97+server(nil: list of ref Attr, io: ref IO): string
98+{
99+ (sexp, err) := Sexp.read(Read.new(io));
100+ if(err != nil)
101+ return "authquery: bad query sexp: "+err;
102+ q: ref Query;
103+ (q, err) = Query.parse(sexp);
104+ if(q == nil)
105+ return "authquery: bad query: "+err;
106+ while((sexp = q.neededcert()) != nil){
107+ write(io, sexp.pack());
108+ (sexp, err) = Sexp.read(Read.new(io));
109+ if(err != nil)
110+ return "authquery: bad cert sexp: "+err;
111+ if((err = q.addcert(sexp)) != nil)
112+ return "authquery: bad certificate received: "+err;
113+ }
114+ write(io, q.result().pack());
115+ io.done(ref Authinfo);
116+ return nil;
117+}
118+
119+mkop(op: string, els: list of ref Sexp): ref Sexp
120+{
121+ return ref Sexp.List(ref Sexp.String(op, nil) :: els);
122+}
123+
124+needcert(nil: ref IO, se: ref Sexp): (ref Sexp, string)
125+{
126+ return (mkop("cert", se :: nil), nil);
127+# (key, err) := io.findkey(
128+}
129+
130+write(io: ref IO, buf: array of byte)
131+{
132+ while(len buf > Maxmsg){
133+ io.write(buf[0:Maxmsg], Maxmsg);
134+ buf = buf[Maxmsg:];
135+ }
136+ io.write(buf, len buf);
137+}
138+
139+Query.parse(sexp: ref Sexp): (ref Query, string)
140+{
141+ if(!sexp.islist())
142+ return (nil, "query must be a list");
143+ return (ref Query(sexp, sexp.els(), nil), nil);
144+}
145+
146+Query.neededcert(q: self ref Query): ref Sexp
147+{
148+ if(q.certs == nil)
149+ return nil;
150+ c := hd q.certs;
151+ q.certs = tl q.certs;
152+ if(c.op() != "cert")
153+ return nil;
154+ for(a := c.args(); a != nil; a = tl a)
155+ if((hd a).op() == "delay" && (hd a).args() != nil)
156+ sys->sleep(int (hd (hd a).args()).astext());
157+ return mkop("needcert", c :: nil);
158+}
159+
160+Query.addcert(q: self ref Query, cert: ref Sexp): string
161+{
162+ q.gotcerts = cert :: q.gotcerts;
163+ return nil;
164+}
165+
166+Query.result(q: self ref Query): ref Sexp
167+{
168+ return mkop("result", q.gotcerts);
169+}
170+
171+Read.new(io: ref IO): ref Read
172+{
173+ return ref Read(nil, 0, 0, io);
174+}
175+
176+Read.getb(r: self ref Read): int
177+{
178+ if(r.ptr >= len r.buf){
179+ while((buf := r.io.read()) == nil || len buf == 0)
180+ r.io.toosmall(Maxmsg);
181+ r.buf = buf;
182+ r.ptr = 0;
183+ }
184+ r.off++;
185+ return int r.buf[r.ptr++];
186+}
187+
188+Read.ungetb(r: self ref Read): int
189+{
190+ if(r.buf == nil || r.ptr == 0)
191+ return -1;
192+ r.off--;
193+ return int r.buf[--r.ptr];
194+}
195+
196+Read.offset(r: self ref Read): big
197+{
198+ return big r.off;
199+}
200+
201+keycheck(nil: ref Authio->Key): string
202+{
203+ return nil;
204+}
dis/auth/proto/authquery.dis+0−0

Binary file not shown.