rsc | be8b315 | 2004-06-17 03:27:35 +0000 | [diff] [blame] | 1 | #include <u.h> |
| 2 | #include <libc.h> |
| 3 | #include <fcall.h> |
| 4 | #include <auth.h> |
rsc | 648bb6f | 2005-02-08 20:58:10 +0000 | [diff] [blame] | 5 | #include <9pclient.h> |
rsc | be8b315 | 2004-06-17 03:27:35 +0000 | [diff] [blame] | 6 | #include "authlocal.h" |
| 7 | |
| 8 | enum { |
rsc | cbeb0b2 | 2006-04-01 19:24:03 +0000 | [diff] [blame] | 9 | ARgiveup = 100 |
rsc | be8b315 | 2004-06-17 03:27:35 +0000 | [diff] [blame] | 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; |
rsc | a8ec491 | 2005-07-13 21:34:11 +0000 | [diff] [blame] | 94 | a = nil; |
rsc | be8b315 | 2004-06-17 03:27:35 +0000 | [diff] [blame] | 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 | { |
rsc | be8b315 | 2004-06-17 03:27:35 +0000 | [diff] [blame] | 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 | |
rsc | 648bb6f | 2005-02-08 20:58:10 +0000 | [diff] [blame] | 194 | rpc = auth_allocrpc(); |
rsc | be8b315 | 2004-06-17 03:27:35 +0000 | [diff] [blame] | 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); |
rsc | 648bb6f | 2005-02-08 20:58:10 +0000 | [diff] [blame] | 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); |
rsc | be8b315 | 2004-06-17 03:27:35 +0000 | [diff] [blame] | 292 | return ai; |
| 293 | } |
| 294 | |