tauth_proxy.c - plan9port - [fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port
Log
Files
Refs
README
LICENSE
---
tauth_proxy.c (5193B)
---
     1 #include 
     2 #include 
     3 #include 
     4 #include 
     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 }