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 @@
1implement Authproto;
2include "sys.m";
3 sys: Sys;
4 Rread, Rwrite: import Sys;
5include "draw.m";
6include "keyring.m";
7include "bufio.m";
8include "sexprs.m";
9 sexprs: Sexprs;
10 Sexp: import sexprs;
11include "spki.m";
12 spki: SPKI;
13include "../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
22Debug: con 0;
23
24# init, addkey, closekey, write, read, close, keyprompt
25
26Query: 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
37Read: 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
50Maxmsg: con 4000;
51
52init(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
63interaction(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
75client(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
97server(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
119mkop(op: string, els: list of ref Sexp): ref Sexp
120{
121 return ref Sexp.List(ref Sexp.String(op, nil) :: els);
122}
123
124needcert(nil: ref IO, se: ref Sexp): (ref Sexp, string)
125{
126 return (mkop("cert", se :: nil), nil);
127# (key, err) := io.findkey(
128}
129
130write(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
139Query.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
146Query.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
160Query.addcert(q: self ref Query, cert: ref Sexp): string
161{
162 q.gotcerts = cert :: q.gotcerts;
163 return nil;
164}
165
166Query.result(q: self ref Query): ref Sexp
167{
168 return mkop("result", q.gotcerts);
169}
170
171Read.new(io: ref IO): ref Read
172{
173 return ref Read(nil, 0, 0, io);
174}
175
176Read.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
188Read.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
196Read.offset(r: self ref Read): big
197{
198 return big r.off;
199}
200
201keycheck(nil: ref Authio->Key): string
202{
203 return nil;
204}
dis/auth/proto/authquery.dis+0−0

Binary file not shown.