plan9port

[fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port # fast
git clone https://src.adamsgaard.dk/plan9port.git # slow
Log | Files | Refs | README | LICENSE Back to index

auth_proxy.c (5193B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <fcall.h>
      4 #include <auth.h>
      5 #include <9pclient.h>
      6 #include "authlocal.h"
      7 
      8 enum {
      9 	ARgiveup = 100
     10 };
     11 
     12 static uchar*
     13 gstring(uchar *p, uchar *ep, char **s)
     14 {
     15 	uint n;
     16 
     17 	if(p == nil)
     18 		return nil;
     19 	if(p+BIT16SZ > ep)
     20 		return nil;
     21 	n = GBIT16(p);
     22 	p += BIT16SZ;
     23 	if(p+n > ep)
     24 		return nil;
     25 	*s = malloc(n+1);
     26 	memmove((*s), p, n);
     27 	(*s)[n] = '\0';
     28 	p += n;
     29 	return p;
     30 }
     31 
     32 static uchar*
     33 gcarray(uchar *p, uchar *ep, uchar **s, int *np)
     34 {
     35 	uint n;
     36 
     37 	if(p == nil)
     38 		return nil;
     39 	if(p+BIT16SZ > ep)
     40 		return nil;
     41 	n = GBIT16(p);
     42 	p += BIT16SZ;
     43 	if(p+n > ep)
     44 		return nil;
     45 	*s = malloc(n);
     46 	if(*s == nil)
     47 		return nil;
     48 	memmove((*s), p, n);
     49 	*np = n;
     50 	p += n;
     51 	return p;
     52 }
     53 
     54 void
     55 auth_freeAI(AuthInfo *ai)
     56 {
     57 	if(ai == nil)
     58 		return;
     59 	free(ai->cuid);
     60 	free(ai->suid);
     61 	free(ai->cap);
     62 	free(ai->secret);
     63 	free(ai);
     64 }
     65 
     66 static uchar*
     67 convM2AI(uchar *p, int n, AuthInfo **aip)
     68 {
     69 	uchar *e = p+n;
     70 	AuthInfo *ai;
     71 
     72 	ai = mallocz(sizeof(*ai), 1);
     73 	if(ai == nil)
     74 		return nil;
     75 
     76 	p = gstring(p, e, &ai->cuid);
     77 	p = gstring(p, e, &ai->suid);
     78 	p = gstring(p, e, &ai->cap);
     79 	p = gcarray(p, e, &ai->secret, &ai->nsecret);
     80 	if(p == nil)
     81 		auth_freeAI(ai);
     82 	else
     83 		*aip = ai;
     84 	return p;
     85 }
     86 
     87 AuthInfo*
     88 auth_getinfo(AuthRpc *rpc)
     89 {
     90 	AuthInfo *a;
     91 
     92 	if(auth_rpc(rpc, "authinfo", nil, 0) != ARok)
     93 		return nil;
     94 	a = nil;
     95 	if(convM2AI((uchar*)rpc->arg, rpc->narg, &a) == nil){
     96 		werrstr("bad auth info from factotum");
     97 		return nil;
     98 	}
     99 	return a;
    100 }
    101 
    102 static int
    103 dorpc(AuthRpc *rpc, char *verb, char *val, int len, AuthGetkey *getkey)
    104 {
    105 	int ret;
    106 
    107 	for(;;){
    108 		if((ret = auth_rpc(rpc, verb, val, len)) != ARneedkey && ret != ARbadkey)
    109 			return ret;
    110 		if(getkey == nil)
    111 			return ARgiveup;	/* don't know how */
    112 		if((*getkey)(rpc->arg) < 0)
    113 			return ARgiveup;	/* user punted */
    114 	}
    115 }
    116 
    117 /*
    118  *  this just proxies what the factotum tells it to.
    119  */
    120 AuthInfo*
    121 fauth_proxy(int fd, AuthRpc *rpc, AuthGetkey *getkey, char *params)
    122 {
    123 	char *buf;
    124 	int m, n, ret;
    125 	AuthInfo *a;
    126 	char oerr[ERRMAX];
    127 
    128 	rerrstr(oerr, sizeof oerr);
    129 	werrstr("UNKNOWN AUTH ERROR");
    130 
    131 	if(dorpc(rpc, "start", params, strlen(params), getkey) != ARok){
    132 		werrstr("fauth_proxy start: %r");
    133 		return nil;
    134 	}
    135 
    136 	buf = malloc(AuthRpcMax);
    137 	if(buf == nil)
    138 		return nil;
    139 	for(;;){
    140 		switch(dorpc(rpc, "read", nil, 0, getkey)){
    141 		case ARdone:
    142 			free(buf);
    143 			a = auth_getinfo(rpc);
    144 			errstr(oerr, sizeof oerr);	/* no error, restore whatever was there */
    145 			return a;
    146 		case ARok:
    147 			if(write(fd, rpc->arg, rpc->narg) != rpc->narg){
    148 				werrstr("auth_proxy write fd: %r");
    149 				goto Error;
    150 			}
    151 			break;
    152 		case ARphase:
    153 			n = 0;
    154 			memset(buf, 0, AuthRpcMax);
    155 			while((ret = dorpc(rpc, "write", buf, n, getkey)) == ARtoosmall){
    156 				if(atoi(rpc->arg) > AuthRpcMax)
    157 					break;
    158 				m = read(fd, buf+n, atoi(rpc->arg)-n);
    159 				if(m <= 0){
    160 					if(m == 0)
    161 						werrstr("auth_proxy short read: %s", buf);
    162 					goto Error;
    163 				}
    164 				n += m;
    165 			}
    166 			if(ret != ARok){
    167 				werrstr("auth_proxy rpc write: %s: %r", buf);
    168 				goto Error;
    169 			}
    170 			break;
    171 		default:
    172 			werrstr("auth_proxy rpc: %r");
    173 			goto Error;
    174 		}
    175 	}
    176 Error:
    177 	free(buf);
    178 	return nil;
    179 }
    180 
    181 AuthInfo*
    182 auth_proxy(int fd, AuthGetkey *getkey, char *fmt, ...)
    183 {
    184 	char *p;
    185 	va_list arg;
    186 	AuthInfo *ai;
    187 	AuthRpc *rpc;
    188 
    189 	quotefmtinstall();	/* just in case */
    190 	va_start(arg, fmt);
    191 	p = vsmprint(fmt, arg);
    192 	va_end(arg);
    193 
    194 	rpc = auth_allocrpc();
    195 	if(rpc == nil){
    196 		free(p);
    197 		return nil;
    198 	}
    199 
    200 	ai = fauth_proxy(fd, rpc, getkey, p);
    201 	free(p);
    202 	auth_freerpc(rpc);
    203 	return ai;
    204 }
    205 
    206 /*
    207  *  this just proxies what the factotum tells it to.
    208  */
    209 AuthInfo*
    210 fsfauth_proxy(CFid *fid, AuthRpc *rpc, AuthGetkey *getkey, char *params)
    211 {
    212 	char *buf;
    213 	int m, n, ret;
    214 	AuthInfo *a;
    215 	char oerr[ERRMAX];
    216 
    217 	rerrstr(oerr, sizeof oerr);
    218 	werrstr("UNKNOWN AUTH ERROR");
    219 
    220 	if(dorpc(rpc, "start", params, strlen(params), getkey) != ARok){
    221 		werrstr("fauth_proxy start: %r");
    222 		return nil;
    223 	}
    224 
    225 	buf = malloc(AuthRpcMax);
    226 	if(buf == nil)
    227 		return nil;
    228 	for(;;){
    229 		switch(dorpc(rpc, "read", nil, 0, getkey)){
    230 		case ARdone:
    231 			free(buf);
    232 			a = auth_getinfo(rpc);
    233 			errstr(oerr, sizeof oerr);	/* no error, restore whatever was there */
    234 			return a;
    235 		case ARok:
    236 			if(fswrite(fid, rpc->arg, rpc->narg) != rpc->narg){
    237 				werrstr("auth_proxy write fid: %r");
    238 				goto Error;
    239 			}
    240 			break;
    241 		case ARphase:
    242 			n = 0;
    243 			memset(buf, 0, AuthRpcMax);
    244 			while((ret = dorpc(rpc, "write", buf, n, getkey)) == ARtoosmall){
    245 				if(atoi(rpc->arg) > AuthRpcMax)
    246 					break;
    247 				m = fsread(fid, buf+n, atoi(rpc->arg)-n);
    248 				if(m <= 0){
    249 					if(m == 0)
    250 						werrstr("auth_proxy short read: %s", buf);
    251 					goto Error;
    252 				}
    253 				n += m;
    254 			}
    255 			if(ret != ARok){
    256 				werrstr("auth_proxy rpc write: %s: %r", buf);
    257 				goto Error;
    258 			}
    259 			break;
    260 		default:
    261 			werrstr("auth_proxy rpc: %r");
    262 			goto Error;
    263 		}
    264 	}
    265 Error:
    266 	free(buf);
    267 	return nil;
    268 }
    269 
    270 AuthInfo*
    271 fsauth_proxy(CFid *fid, AuthGetkey *getkey, char *fmt, ...)
    272 {
    273 	char *p;
    274 	va_list arg;
    275 	AuthInfo *ai;
    276 	AuthRpc *rpc;
    277 
    278 	quotefmtinstall();	/* just in case */
    279 	va_start(arg, fmt);
    280 	p = vsmprint(fmt, arg);
    281 	va_end(arg);
    282 
    283 	rpc = auth_allocrpc();
    284 	if(rpc == nil){
    285 		free(p);
    286 		return nil;
    287 	}
    288 
    289 	ai = fsfauth_proxy(fid, rpc, getkey, p);
    290 	free(p);
    291 	auth_freerpc(rpc);
    292 	return ai;
    293 }