xref: /plan9/sys/src/cmd/auth/factotum/confirm.c (revision 2ebbfa15057a80d5ffc355d10c2a61bb0ac12c16)
19a747e4fSDavid du Colombier #include "dat.h"
29a747e4fSDavid du Colombier 
39a747e4fSDavid du Colombier Logbuf confbuf;
49a747e4fSDavid du Colombier 
59a747e4fSDavid du Colombier Req *cusewait;		/* requests waiting for confirmation */
69a747e4fSDavid du Colombier Req **cuselast = &cusewait;
79a747e4fSDavid du Colombier 
89a747e4fSDavid du Colombier void
confirmread(Req * r)99a747e4fSDavid du Colombier confirmread(Req *r)
109a747e4fSDavid du Colombier {
119a747e4fSDavid du Colombier 	logbufread(&confbuf, r);
129a747e4fSDavid du Colombier }
139a747e4fSDavid du Colombier 
149a747e4fSDavid du Colombier void
confirmflush(Req * r)159a747e4fSDavid du Colombier confirmflush(Req *r)
169a747e4fSDavid du Colombier {
179a747e4fSDavid du Colombier 	Req **l;
189a747e4fSDavid du Colombier 
199a747e4fSDavid du Colombier 	for(l=&cusewait; *l; l=&(*l)->aux){
209a747e4fSDavid du Colombier 		if(*l == r){
219a747e4fSDavid du Colombier 			*l = r->aux;
229a747e4fSDavid du Colombier 			if(r->aux == nil)
239a747e4fSDavid du Colombier 				cuselast = l;
249a747e4fSDavid du Colombier 			closereq(r);
259a747e4fSDavid du Colombier 			break;
269a747e4fSDavid du Colombier 		}
279a747e4fSDavid du Colombier 	}
289a747e4fSDavid du Colombier 	logbufflush(&confbuf, r);
299a747e4fSDavid du Colombier }
309a747e4fSDavid du Colombier 
319a747e4fSDavid du Colombier static int
hastag(Fsstate * fss,int tag,int * tagoff)329a747e4fSDavid du Colombier hastag(Fsstate *fss, int tag, int *tagoff)
339a747e4fSDavid du Colombier {
349a747e4fSDavid du Colombier 	int i;
359a747e4fSDavid du Colombier 
369a747e4fSDavid du Colombier 	for(i=0; i<fss->nconf; i++)
379a747e4fSDavid du Colombier 		if(fss->conf[i].tag == tag){
389a747e4fSDavid du Colombier 			*tagoff = i;
399a747e4fSDavid du Colombier 			return 1;
409a747e4fSDavid du Colombier 		}
419a747e4fSDavid du Colombier 	return 0;
429a747e4fSDavid du Colombier }
439a747e4fSDavid du Colombier 
449a747e4fSDavid du Colombier int
confirmwrite(char * s)459a747e4fSDavid du Colombier confirmwrite(char *s)
469a747e4fSDavid du Colombier {
479a747e4fSDavid du Colombier 	char *t, *ans;
489a747e4fSDavid du Colombier 	int allow, tagoff;
499a747e4fSDavid du Colombier 	ulong tag;
509a747e4fSDavid du Colombier 	Attr *a;
519a747e4fSDavid du Colombier 	Fsstate *fss;
529a747e4fSDavid du Colombier 	Req *r, **l;
539a747e4fSDavid du Colombier 
549a747e4fSDavid du Colombier 	a = _parseattr(s);
559a747e4fSDavid du Colombier 	if(a == nil){
569a747e4fSDavid du Colombier 		werrstr("empty write");
579a747e4fSDavid du Colombier 		return -1;
589a747e4fSDavid du Colombier 	}
59*2ebbfa15SDavid du Colombier 	if((t = _strfindattr(a, "tag")) == nil){
609a747e4fSDavid du Colombier 		werrstr("no tag");
619a747e4fSDavid du Colombier 		return -1;
629a747e4fSDavid du Colombier 	}
639a747e4fSDavid du Colombier 	tag = strtoul(t, 0, 0);
64*2ebbfa15SDavid du Colombier 	if((ans = _strfindattr(a, "answer")) == nil){
659a747e4fSDavid du Colombier 		werrstr("no answer");
669a747e4fSDavid du Colombier 		return -1;
679a747e4fSDavid du Colombier 	}
689a747e4fSDavid du Colombier 	if(strcmp(ans, "yes") == 0)
699a747e4fSDavid du Colombier 		allow = 1;
709a747e4fSDavid du Colombier 	else if(strcmp(ans, "no") == 0)
719a747e4fSDavid du Colombier 		allow = 0;
729a747e4fSDavid du Colombier 	else{
739a747e4fSDavid du Colombier 		werrstr("bad answer");
749a747e4fSDavid du Colombier 		return -1;
759a747e4fSDavid du Colombier 	}
769a747e4fSDavid du Colombier 	r = nil;
779a747e4fSDavid du Colombier 	tagoff = -1;
789a747e4fSDavid du Colombier 	for(l=&cusewait; *l; l=&(*l)->aux){
799a747e4fSDavid du Colombier 		r = *l;
809a747e4fSDavid du Colombier 		if(hastag(r->fid->aux, tag, &tagoff)){
819a747e4fSDavid du Colombier 			*l = r->aux;
829a747e4fSDavid du Colombier 			if(r->aux == nil)
839a747e4fSDavid du Colombier 				cuselast = l;
849a747e4fSDavid du Colombier 			break;
859a747e4fSDavid du Colombier 		}
869a747e4fSDavid du Colombier 	}
879a747e4fSDavid du Colombier 	if(r == nil || tagoff == -1){
889a747e4fSDavid du Colombier 		werrstr("tag not found");
899a747e4fSDavid du Colombier 		return -1;
909a747e4fSDavid du Colombier 	}
919a747e4fSDavid du Colombier 	fss = r->fid->aux;
929a747e4fSDavid du Colombier 	fss->conf[tagoff].canuse = allow;
939a747e4fSDavid du Colombier 	rpcread(r);
949a747e4fSDavid du Colombier 	return 0;
959a747e4fSDavid du Colombier }
969a747e4fSDavid du Colombier 
979a747e4fSDavid du Colombier void
confirmqueue(Req * r,Fsstate * fss)989a747e4fSDavid du Colombier confirmqueue(Req *r, Fsstate *fss)
999a747e4fSDavid du Colombier {
1009a747e4fSDavid du Colombier 	int i, n;
1019a747e4fSDavid du Colombier 	char msg[1024];
1029a747e4fSDavid du Colombier 
1039a747e4fSDavid du Colombier 	if(*confirminuse == 0){
1049a747e4fSDavid du Colombier 		respond(r, "confirm is closed");
1059a747e4fSDavid du Colombier 		return;
1069a747e4fSDavid du Colombier 	}
1079a747e4fSDavid du Colombier 
1089a747e4fSDavid du Colombier 	n = 0;
1099a747e4fSDavid du Colombier 	for(i=0; i<fss->nconf; i++)
1109a747e4fSDavid du Colombier 		if(fss->conf[i].canuse == -1){
1119a747e4fSDavid du Colombier 			n++;
1129a747e4fSDavid du Colombier 			snprint(msg, sizeof msg, "confirm tag=%lud %A", fss->conf[i].tag, fss->conf[i].key->attr);
1139a747e4fSDavid du Colombier 			logbufappend(&confbuf, msg);
1149a747e4fSDavid du Colombier 		}
1159a747e4fSDavid du Colombier 	if(n == 0){
1169a747e4fSDavid du Colombier 		respond(r, "no confirmations to wait for (bug)");
1179a747e4fSDavid du Colombier 		return;
1189a747e4fSDavid du Colombier 	}
1199a747e4fSDavid du Colombier 	*cuselast = r;
1209a747e4fSDavid du Colombier 	r->aux = nil;
1219a747e4fSDavid du Colombier 	cuselast = &r->aux;
1229a747e4fSDavid du Colombier }
1239a747e4fSDavid du Colombier 
1249a747e4fSDavid du Colombier /* Yes, I am unhappy that the code below is a copy of the code above. */
1259a747e4fSDavid du Colombier 
1269a747e4fSDavid du Colombier Logbuf needkeybuf;
1279a747e4fSDavid du Colombier Req *needwait;		/* requests that need keys */
1289a747e4fSDavid du Colombier Req **needlast = &needwait;
1299a747e4fSDavid du Colombier 
1309a747e4fSDavid du Colombier void
needkeyread(Req * r)1319a747e4fSDavid du Colombier needkeyread(Req *r)
1329a747e4fSDavid du Colombier {
1339a747e4fSDavid du Colombier 	logbufread(&needkeybuf, r);
1349a747e4fSDavid du Colombier }
1359a747e4fSDavid du Colombier 
1369a747e4fSDavid du Colombier void
needkeyflush(Req * r)1379a747e4fSDavid du Colombier needkeyflush(Req *r)
1389a747e4fSDavid du Colombier {
1399a747e4fSDavid du Colombier 	Req **l;
1409a747e4fSDavid du Colombier 
1419a747e4fSDavid du Colombier 	for(l=&needwait; *l; l=&(*l)->aux){
1429a747e4fSDavid du Colombier 		if(*l == r){
1439a747e4fSDavid du Colombier 			*l = r->aux;
1449a747e4fSDavid du Colombier 			if(r->aux == nil)
1459a747e4fSDavid du Colombier 				needlast = l;
1469a747e4fSDavid du Colombier 			closereq(r);
1479a747e4fSDavid du Colombier 			break;
1489a747e4fSDavid du Colombier 		}
1499a747e4fSDavid du Colombier 	}
1509a747e4fSDavid du Colombier 	logbufflush(&needkeybuf, r);
1519a747e4fSDavid du Colombier }
1529a747e4fSDavid du Colombier 
1539a747e4fSDavid du Colombier int
needkeywrite(char * s)1549a747e4fSDavid du Colombier needkeywrite(char *s)
1559a747e4fSDavid du Colombier {
1569a747e4fSDavid du Colombier 	char *t;
1579a747e4fSDavid du Colombier 	ulong tag;
1589a747e4fSDavid du Colombier 	Attr *a;
1599a747e4fSDavid du Colombier 	Req *r, **l;
1609a747e4fSDavid du Colombier 
1619a747e4fSDavid du Colombier 	a = _parseattr(s);
1629a747e4fSDavid du Colombier 	if(a == nil){
1639a747e4fSDavid du Colombier 		werrstr("empty write");
1649a747e4fSDavid du Colombier 		return -1;
1659a747e4fSDavid du Colombier 	}
166*2ebbfa15SDavid du Colombier 	if((t = _strfindattr(a, "tag")) == nil){
1679a747e4fSDavid du Colombier 		werrstr("no tag");
1689a747e4fSDavid du Colombier 		return -1;
1699a747e4fSDavid du Colombier 	}
1709a747e4fSDavid du Colombier 	tag = strtoul(t, 0, 0);
1719a747e4fSDavid du Colombier 	r = nil;
1729a747e4fSDavid du Colombier 	for(l=&needwait; *l; l=&(*l)->aux){
1739a747e4fSDavid du Colombier 		r = *l;
1749a747e4fSDavid du Colombier 		if(r->tag == tag){
1759a747e4fSDavid du Colombier 			*l = r->aux;
1769a747e4fSDavid du Colombier 			if(r->aux == nil)
1779a747e4fSDavid du Colombier 				needlast = l;
1789a747e4fSDavid du Colombier 			break;
1799a747e4fSDavid du Colombier 		}
1809a747e4fSDavid du Colombier 	}
1819a747e4fSDavid du Colombier 	if(r == nil){
1829a747e4fSDavid du Colombier 		werrstr("tag not found");
1839a747e4fSDavid du Colombier 		return -1;
1849a747e4fSDavid du Colombier 	}
1859a747e4fSDavid du Colombier 	rpcread(r);
1869a747e4fSDavid du Colombier 	return 0;
1879a747e4fSDavid du Colombier }
1889a747e4fSDavid du Colombier 
1899a747e4fSDavid du Colombier int
needkeyqueue(Req * r,Fsstate * fss)1909a747e4fSDavid du Colombier needkeyqueue(Req *r, Fsstate *fss)
1919a747e4fSDavid du Colombier {
1929a747e4fSDavid du Colombier 	char msg[1024];
1939a747e4fSDavid du Colombier 
1949a747e4fSDavid du Colombier 	if(*needkeyinuse == 0)
1959a747e4fSDavid du Colombier 		return -1;
1969a747e4fSDavid du Colombier 
1979a747e4fSDavid du Colombier 	snprint(msg, sizeof msg, "needkey tag=%lud %s", r->tag, fss->keyinfo);
1989a747e4fSDavid du Colombier 	logbufappend(&needkeybuf, msg);
1999a747e4fSDavid du Colombier 	*needlast = r;
2009a747e4fSDavid du Colombier 	r->aux = nil;
2019a747e4fSDavid du Colombier 	needlast = &r->aux;
2029a747e4fSDavid du Colombier 	return 0;
2039a747e4fSDavid du Colombier }
2049a747e4fSDavid du Colombier 
205