xref: /plan9/sys/src/cmd/auth/factotum/confirm.c (revision 2ebbfa15057a80d5ffc355d10c2a61bb0ac12c16)
1 #include "dat.h"
2 
3 Logbuf confbuf;
4 
5 Req *cusewait;		/* requests waiting for confirmation */
6 Req **cuselast = &cusewait;
7 
8 void
confirmread(Req * r)9 confirmread(Req *r)
10 {
11 	logbufread(&confbuf, r);
12 }
13 
14 void
confirmflush(Req * r)15 confirmflush(Req *r)
16 {
17 	Req **l;
18 
19 	for(l=&cusewait; *l; l=&(*l)->aux){
20 		if(*l == r){
21 			*l = r->aux;
22 			if(r->aux == nil)
23 				cuselast = l;
24 			closereq(r);
25 			break;
26 		}
27 	}
28 	logbufflush(&confbuf, r);
29 }
30 
31 static int
hastag(Fsstate * fss,int tag,int * tagoff)32 hastag(Fsstate *fss, int tag, int *tagoff)
33 {
34 	int i;
35 
36 	for(i=0; i<fss->nconf; i++)
37 		if(fss->conf[i].tag == tag){
38 			*tagoff = i;
39 			return 1;
40 		}
41 	return 0;
42 }
43 
44 int
confirmwrite(char * s)45 confirmwrite(char *s)
46 {
47 	char *t, *ans;
48 	int allow, tagoff;
49 	ulong tag;
50 	Attr *a;
51 	Fsstate *fss;
52 	Req *r, **l;
53 
54 	a = _parseattr(s);
55 	if(a == nil){
56 		werrstr("empty write");
57 		return -1;
58 	}
59 	if((t = _strfindattr(a, "tag")) == nil){
60 		werrstr("no tag");
61 		return -1;
62 	}
63 	tag = strtoul(t, 0, 0);
64 	if((ans = _strfindattr(a, "answer")) == nil){
65 		werrstr("no answer");
66 		return -1;
67 	}
68 	if(strcmp(ans, "yes") == 0)
69 		allow = 1;
70 	else if(strcmp(ans, "no") == 0)
71 		allow = 0;
72 	else{
73 		werrstr("bad answer");
74 		return -1;
75 	}
76 	r = nil;
77 	tagoff = -1;
78 	for(l=&cusewait; *l; l=&(*l)->aux){
79 		r = *l;
80 		if(hastag(r->fid->aux, tag, &tagoff)){
81 			*l = r->aux;
82 			if(r->aux == nil)
83 				cuselast = l;
84 			break;
85 		}
86 	}
87 	if(r == nil || tagoff == -1){
88 		werrstr("tag not found");
89 		return -1;
90 	}
91 	fss = r->fid->aux;
92 	fss->conf[tagoff].canuse = allow;
93 	rpcread(r);
94 	return 0;
95 }
96 
97 void
confirmqueue(Req * r,Fsstate * fss)98 confirmqueue(Req *r, Fsstate *fss)
99 {
100 	int i, n;
101 	char msg[1024];
102 
103 	if(*confirminuse == 0){
104 		respond(r, "confirm is closed");
105 		return;
106 	}
107 
108 	n = 0;
109 	for(i=0; i<fss->nconf; i++)
110 		if(fss->conf[i].canuse == -1){
111 			n++;
112 			snprint(msg, sizeof msg, "confirm tag=%lud %A", fss->conf[i].tag, fss->conf[i].key->attr);
113 			logbufappend(&confbuf, msg);
114 		}
115 	if(n == 0){
116 		respond(r, "no confirmations to wait for (bug)");
117 		return;
118 	}
119 	*cuselast = r;
120 	r->aux = nil;
121 	cuselast = &r->aux;
122 }
123 
124 /* Yes, I am unhappy that the code below is a copy of the code above. */
125 
126 Logbuf needkeybuf;
127 Req *needwait;		/* requests that need keys */
128 Req **needlast = &needwait;
129 
130 void
needkeyread(Req * r)131 needkeyread(Req *r)
132 {
133 	logbufread(&needkeybuf, r);
134 }
135 
136 void
needkeyflush(Req * r)137 needkeyflush(Req *r)
138 {
139 	Req **l;
140 
141 	for(l=&needwait; *l; l=&(*l)->aux){
142 		if(*l == r){
143 			*l = r->aux;
144 			if(r->aux == nil)
145 				needlast = l;
146 			closereq(r);
147 			break;
148 		}
149 	}
150 	logbufflush(&needkeybuf, r);
151 }
152 
153 int
needkeywrite(char * s)154 needkeywrite(char *s)
155 {
156 	char *t;
157 	ulong tag;
158 	Attr *a;
159 	Req *r, **l;
160 
161 	a = _parseattr(s);
162 	if(a == nil){
163 		werrstr("empty write");
164 		return -1;
165 	}
166 	if((t = _strfindattr(a, "tag")) == nil){
167 		werrstr("no tag");
168 		return -1;
169 	}
170 	tag = strtoul(t, 0, 0);
171 	r = nil;
172 	for(l=&needwait; *l; l=&(*l)->aux){
173 		r = *l;
174 		if(r->tag == tag){
175 			*l = r->aux;
176 			if(r->aux == nil)
177 				needlast = l;
178 			break;
179 		}
180 	}
181 	if(r == nil){
182 		werrstr("tag not found");
183 		return -1;
184 	}
185 	rpcread(r);
186 	return 0;
187 }
188 
189 int
needkeyqueue(Req * r,Fsstate * fss)190 needkeyqueue(Req *r, Fsstate *fss)
191 {
192 	char msg[1024];
193 
194 	if(*needkeyinuse == 0)
195 		return -1;
196 
197 	snprint(msg, sizeof msg, "needkey tag=%lud %s", r->tag, fss->keyinfo);
198 	logbufappend(&needkeybuf, msg);
199 	*needlast = r;
200 	r->aux = nil;
201 	needlast = &r->aux;
202 	return 0;
203 }
204 
205