tauth_proxy.c - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       tauth_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 }