| 358 | } |
| 359 | |
| 360 | static void try_command(struct node_id *peer, |
| 361 | u64 idnum, |
| 362 | const u8 *msg, size_t msglen) |
| 363 | { |
| 364 | struct commando *incoming = tal(plugin, struct commando); |
| 365 | const jsmntok_t *toks, *method, *params, *rune; |
| 366 | const char *buf = (const char *)msg, *failmsg; |
| 367 | struct out_req *req; |
| 368 | |
| 369 | incoming->peer = *peer; |
| 370 | incoming->id = idnum; |
| 371 | |
| 372 | toks = json_parse_simple(incoming, buf, msglen); |
| 373 | if (!toks) { |
| 374 | commando_error(incoming, COMMANDO_ERROR_REMOTE, |
| 375 | "Invalid JSON"); |
| 376 | return; |
| 377 | } |
| 378 | |
| 379 | if (toks[0].type != JSMN_OBJECT) { |
| 380 | commando_error(incoming, COMMANDO_ERROR_REMOTE, |
| 381 | "Not a JSON object"); |
| 382 | return; |
| 383 | } |
| 384 | method = json_get_member(buf, toks, "method"); |
| 385 | if (!method) { |
| 386 | commando_error(incoming, COMMANDO_ERROR_REMOTE, |
| 387 | "No method"); |
| 388 | return; |
| 389 | } |
| 390 | params = json_get_member(buf, toks, "params"); |
| 391 | if (!params || (params->type != JSMN_OBJECT && params->type != JSMN_ARRAY)) { |
| 392 | commando_error(incoming, COMMANDO_ERROR_REMOTE, |
| 393 | "Params must be object or array"); |
| 394 | return; |
| 395 | } |
| 396 | rune = json_get_member(buf, toks, "rune"); |
| 397 | |
| 398 | failmsg = check_rune(tmpctx, incoming, peer, buf, method, params, rune); |
| 399 | if (failmsg) { |
| 400 | commando_error(incoming, COMMANDO_ERROR_REMOTE_AUTH, |
| 401 | "Not authorized: %s", failmsg); |
| 402 | return; |
| 403 | } |
| 404 | |
| 405 | /* We handle success and failure the same */ |
| 406 | req = jsonrpc_request_whole_object_start(plugin, NULL, |
| 407 | json_strdup(tmpctx, buf, |
| 408 | method), |
| 409 | cmd_done, incoming); |
| 410 | if (params) { |
| 411 | size_t i; |
| 412 | const jsmntok_t *t; |
| 413 | |
| 414 | /* FIXME: This is ugly! */ |
| 415 | if (params->type == JSMN_OBJECT) { |
| 416 | json_object_start(req->js, "params"); |
| 417 | json_for_each_obj(i, t, params) { |
no test coverage detected