mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 23:24:27 +01:00
commando: remove now-unused internal checking routines.
Separate patch to make the previous diff smaller. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -370,122 +370,8 @@ struct cond_info {
|
||||
|
||||
/* Prefix for commands we execute */
|
||||
const char *cmdid_prefix;
|
||||
|
||||
/* If we have to evaluate params for runes, we populate this */
|
||||
STRMAP(const jsmntok_t *) cached_params;
|
||||
|
||||
/* If it contains a ratelimit check, we populate this */
|
||||
struct usage *usage;
|
||||
};
|
||||
|
||||
static const char *rate_limit_check(const tal_t *ctx,
|
||||
const struct rune *rune,
|
||||
const struct rune_altern *alt,
|
||||
struct cond_info *cinfo)
|
||||
{
|
||||
unsigned long r;
|
||||
char *endp;
|
||||
if (alt->condition != '=')
|
||||
return "rate operator must be =";
|
||||
|
||||
r = strtoul(alt->value, &endp, 10);
|
||||
if (endp == alt->value || *endp || r == 0 || r >= UINT32_MAX)
|
||||
return "malformed rate";
|
||||
|
||||
/* We cache this: we only add usage counter if whole rune succeeds! */
|
||||
if (!cinfo->usage) {
|
||||
cinfo->usage = usage_table_get(usage_table, atol(rune->unique_id));
|
||||
if (!cinfo->usage) {
|
||||
cinfo->usage = tal(plugin, struct usage);
|
||||
cinfo->usage->id = atol(rune->unique_id);
|
||||
cinfo->usage->counter = 0;
|
||||
usage_table_add(usage_table, cinfo->usage);
|
||||
}
|
||||
}
|
||||
|
||||
/* >= becuase if we allow this, counter will increment */
|
||||
if (cinfo->usage->counter >= r)
|
||||
return tal_fmt(ctx, "Rate of %lu per minute exceeded", r);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *check_condition(const tal_t *ctx,
|
||||
const struct rune *rune,
|
||||
const struct rune_altern *alt,
|
||||
struct cond_info *cinfo)
|
||||
{
|
||||
const jsmntok_t *ptok;
|
||||
|
||||
if (streq(alt->fieldname, "time")) {
|
||||
return rune_alt_single_int(ctx, alt, time_now().ts.tv_sec);
|
||||
} else if (streq(alt->fieldname, "id")) {
|
||||
const char *id = node_id_to_hexstr(tmpctx, &cinfo->incoming->peer);
|
||||
return rune_alt_single_str(ctx, alt, id, strlen(id));
|
||||
} else if (streq(alt->fieldname, "method")) {
|
||||
return rune_alt_single_str(ctx, alt,
|
||||
cinfo->buf + cinfo->method->start,
|
||||
cinfo->method->end - cinfo->method->start);
|
||||
} else if (streq(alt->fieldname, "pnum")) {
|
||||
return rune_alt_single_int(ctx, alt, cinfo->params->size);
|
||||
} else if (streq(alt->fieldname, "rate")) {
|
||||
return rate_limit_check(ctx, rune, alt, cinfo);
|
||||
}
|
||||
|
||||
/* Rest are params looksup: generate this once! */
|
||||
if (strmap_empty(&cinfo->cached_params) && cinfo->params) {
|
||||
const jsmntok_t *t;
|
||||
size_t i;
|
||||
|
||||
if (cinfo->params->type == JSMN_OBJECT) {
|
||||
json_for_each_obj(i, t, cinfo->params) {
|
||||
char *pmemname = tal_fmt(tmpctx,
|
||||
"pname%.*s",
|
||||
t->end - t->start,
|
||||
cinfo->buf + t->start);
|
||||
size_t off = strlen("pname");
|
||||
/* Remove punctuation! */
|
||||
for (size_t n = off; pmemname[n]; n++) {
|
||||
if (cispunct(pmemname[n]))
|
||||
continue;
|
||||
pmemname[off++] = pmemname[n];
|
||||
}
|
||||
pmemname[off++] = '\0';
|
||||
strmap_add(&cinfo->cached_params, pmemname, t+1);
|
||||
}
|
||||
} else if (cinfo->params->type == JSMN_ARRAY) {
|
||||
json_for_each_arr(i, t, cinfo->params) {
|
||||
char *pmemname = tal_fmt(tmpctx, "parr%zu", i);
|
||||
strmap_add(&cinfo->cached_params, pmemname, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ptok = strmap_get(&cinfo->cached_params, alt->fieldname);
|
||||
if (!ptok)
|
||||
return rune_alt_single_missing(ctx, alt);
|
||||
|
||||
/* Pass through valid integers as integers. */
|
||||
if (ptok->type == JSMN_PRIMITIVE) {
|
||||
s64 val;
|
||||
|
||||
if (json_to_s64(cinfo->buf, ptok, &val)) {
|
||||
plugin_log(plugin, LOG_DBG, "It's an int %"PRId64, val);
|
||||
return rune_alt_single_int(ctx, alt, val);
|
||||
}
|
||||
|
||||
/* Otherwise, treat it as a string (< and > will fail with
|
||||
* "is not an integer field") */
|
||||
}
|
||||
return rune_alt_single_str(ctx, alt,
|
||||
cinfo->buf + ptok->start,
|
||||
ptok->end - ptok->start);
|
||||
}
|
||||
|
||||
static void destroy_cond_info(struct cond_info *cinfo)
|
||||
{
|
||||
strmap_clear(&cinfo->cached_params);
|
||||
}
|
||||
|
||||
static struct cond_info *new_cond_info(const tal_t *ctx,
|
||||
struct commando *incoming,
|
||||
const jsmntok_t *toks STEALS,
|
||||
@@ -516,43 +402,9 @@ static struct cond_info *new_cond_info(const tal_t *ctx,
|
||||
json_tok_full(cinfo->buf, id),
|
||||
json_tok_full_len(id));
|
||||
}
|
||||
|
||||
cinfo->usage = NULL;
|
||||
strmap_init(&cinfo->cached_params);
|
||||
tal_add_destructor(cinfo, destroy_cond_info);
|
||||
|
||||
return cinfo;
|
||||
}
|
||||
|
||||
static UNNEEDED const char *check_rune(const tal_t *ctx,
|
||||
struct cond_info *cinfo,
|
||||
const jsmntok_t *runetok)
|
||||
{
|
||||
struct rune *rune;
|
||||
const char *err;
|
||||
|
||||
if (!runetok)
|
||||
return "Missing rune";
|
||||
|
||||
rune = rune_from_base64n(tmpctx, cinfo->buf + runetok->start,
|
||||
runetok->end - runetok->start);
|
||||
if (!rune)
|
||||
return "Invalid rune";
|
||||
|
||||
if (is_rune_blacklisted(rune))
|
||||
return "Blacklisted rune";
|
||||
|
||||
err = rune_test(tmpctx, master_rune, rune, check_condition, cinfo);
|
||||
/* Just in case they manage to make us speak non-JSON, escape! */
|
||||
if (err)
|
||||
err = json_escape(ctx, err)->s;
|
||||
|
||||
/* If it succeeded, *now* we increment any associated usage counter. */
|
||||
if (!err && cinfo->usage)
|
||||
cinfo->usage->counter++;
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct command_result *execute_command(struct cond_info *cinfo)
|
||||
{
|
||||
struct out_req *req;
|
||||
|
||||
Reference in New Issue
Block a user