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 }