1 /* MIT (BSD) license - see LICENSE file for details */
7 #include <ccan/endian/endian.h>
8 #include <ccan/mem/mem.h>
9 #include <ccan/tal/str/str.h>
10 #include <ccan/rune/rune.h>
11 #include <ccan/rune/internal.h>
13 /* Helper to produce an id field */
14 static struct rune_restr *unique_id_restr(const tal_t *ctx,
15 const char *unique_id,
19 struct rune_restr *restr;
21 assert(!strchr(unique_id, '-'));
23 id = tal_fmt(NULL, "%s-%s", unique_id, version);
25 id = tal_strdup(NULL, unique_id);
27 restr = rune_restr_new(ctx);
28 /* We use the empty field for this, since it's always present. */
29 rune_restr_add_altern(restr,
30 take(rune_altern_new(NULL, "", '=', take(id))));
34 /* We pad between fields with something identical to the SHA end marker */
35 void rune_sha256_endmarker(struct sha256_ctx *shactx)
37 static const unsigned char pad[64] = {0x80};
40 sizedesc = cpu_to_be64((uint64_t)shactx->bytes << 3);
41 /* Add '1' bit to terminate, then all 0 bits, up to next block - 8. */
42 sha256_update(shactx, pad, 1 + ((128 - 8 - (shactx->bytes % 64) - 1) % 64));
43 /* Add number of bits of data (big endian) */
44 sha256_update(shactx, &sizedesc, 8);
47 struct rune *rune_new(const tal_t *ctx, const u8 *secret, size_t secret_len,
50 struct rune *rune = tal(ctx, struct rune);
51 assert(secret_len + 1 + 8 <= 64);
54 rune->version = tal_strdup(rune, version);
57 rune->unique_id = NULL;
58 sha256_init(&rune->shactx);
59 sha256_update(&rune->shactx, secret, secret_len);
60 rune_sha256_endmarker(&rune->shactx);
61 rune->restrs = tal_arr(rune, struct rune_restr *, 0);
65 struct rune *rune_dup(const tal_t *ctx, const struct rune *rune TAKES)
70 return tal_steal(ctx, (struct rune *)rune);
72 dup = tal_dup(ctx, struct rune, rune);
73 dup->restrs = tal_arr(dup, struct rune_restr *, tal_count(rune->restrs));
74 for (size_t i = 0; i < tal_count(rune->restrs); i++) {
75 dup->restrs[i] = rune_restr_dup(dup->restrs,
81 struct rune *rune_derive_start(const tal_t *ctx,
82 const struct rune *master,
83 const char *unique_id TAKES)
85 struct rune *rune = rune_dup(ctx, master);
87 /* If they provide a unique_id, it goes first. */
90 rune->unique_id = tal_steal(rune, unique_id);
92 rune->unique_id = tal_strdup(rune, unique_id);
94 rune_add_restr(rune, take(unique_id_restr(NULL,
98 assert(!rune->version);
103 struct rune_altern *rune_altern_new(const tal_t *ctx,
104 const char *fieldname TAKES,
105 enum rune_condition condition,
106 const char *value TAKES)
108 struct rune_altern *altern = tal(ctx, struct rune_altern);
109 altern->condition = condition;
110 altern->fieldname = tal_strdup(altern, fieldname);
111 altern->value = tal_strdup(altern, value);
115 struct rune_altern *rune_altern_dup(const tal_t *ctx,
116 const struct rune_altern *altern TAKES)
118 struct rune_altern *dup;
121 return tal_steal(ctx, (struct rune_altern *)altern);
122 dup = tal(ctx, struct rune_altern);
123 dup->condition = altern->condition;
124 dup->fieldname = tal_strdup(dup, altern->fieldname);
125 dup->value = tal_strdup(dup, altern->value);
129 struct rune_restr *rune_restr_dup(const tal_t *ctx,
130 const struct rune_restr *restr TAKES)
132 struct rune_restr *dup;
136 return tal_steal(ctx, (struct rune_restr *)restr);
138 num_altern = tal_count(restr->alterns);
139 dup = tal(ctx, struct rune_restr);
140 dup->alterns = tal_arr(dup, struct rune_altern *, num_altern);
141 for (size_t i = 0; i < num_altern; i++) {
142 dup->alterns[i] = rune_altern_dup(dup->alterns,
148 struct rune_restr *rune_restr_new(const tal_t *ctx)
150 struct rune_restr *restr = tal(ctx, struct rune_restr);
151 restr->alterns = tal_arr(restr, struct rune_altern *, 0);
155 void rune_restr_add_altern(struct rune_restr *restr,
156 const struct rune_altern *alt TAKES)
158 size_t num = tal_count(restr->alterns);
160 tal_resize(&restr->alterns, num+1);
161 restr->alterns[num] = rune_altern_dup(restr->alterns, alt);
164 static bool is_unique_id(const struct rune_altern *alt)
166 return streq(alt->fieldname, "");
169 /* Return unique_id if valid, and sets *version */
170 static const char *extract_unique_id(const tal_t *ctx,
171 const struct rune_altern *alt,
172 const char **version)
175 /* Condition must be '='! */
176 if (alt->condition != '=')
179 len = strcspn(alt->value, "-");
181 *version = tal_strdup(ctx, alt->value + len + 1);
184 return tal_strndup(ctx, alt->value, len);
187 bool rune_add_restr(struct rune *rune,
188 const struct rune_restr *restr TAKES)
190 size_t num = tal_count(rune->restrs);
192 /* An empty fieldname is additional correctness checks */
193 for (size_t i = 0; i < tal_count(restr->alterns); i++) {
194 if (!is_unique_id(restr->alterns[i]))
197 /* Must be the only alternative */
198 if (tal_count(restr->alterns) != 1)
200 /* Must be the first restriction */
204 rune->unique_id = extract_unique_id(rune,
207 if (!rune->unique_id)
211 tal_resize(&rune->restrs, num+1);
212 rune->restrs[num] = rune_restr_dup(rune->restrs, restr);
214 rune_sha256_add_restr(&rune->shactx, rune->restrs[num]);
223 static const char *rune_restr_test(const tal_t *ctx,
224 const struct rune *rune,
225 const struct rune_restr *restr,
226 const char *(*check)(const tal_t *ctx,
227 const struct rune *rune,
228 const struct rune_altern *alt,
232 size_t num = tal_count(restr->alterns);
233 const char **errs = tal_arr(NULL, const char *, num);
236 /* Only one alternative has to pass! */
237 for (size_t i = 0; i < num; i++) {
238 errs[i] = check(errs, rune, restr->alterns[i], arg);
245 err = tal_fmt(ctx, "%s", errs[0]);
246 for (size_t i = 1; i < num; i++)
247 tal_append_fmt(&err, " AND %s", errs[i]);
252 static const char *cond_test(const tal_t *ctx,
253 const struct rune_altern *alt,
254 const char *complaint,
260 return tal_fmt(ctx, "%s %s %s", alt->fieldname, complaint, alt->value);
263 static const char *integer_compare_valid(const tal_t *ctx,
264 const s64 *fieldval_int,
265 const struct rune_altern *alt,
272 return tal_fmt(ctx, "%s is not an integer field",
276 l = strtol(alt->value, &p, 10);
279 || ((l == LONG_MIN || l == LONG_MAX) && errno == ERANGE))
280 return tal_fmt(ctx, "%s is not a valid integer", alt->value);
286 static int lexo_order(const char *fieldval_str,
287 size_t fieldval_strlen,
290 int ret = strncmp(fieldval_str, alt, fieldval_strlen);
292 /* If alt is same but longer, fieldval is < */
293 if (ret == 0 && strlen(alt) > fieldval_strlen)
298 static const char *rune_alt_single(const tal_t *ctx,
299 const struct rune_altern *alt,
300 const char *fieldval_str,
301 size_t fieldval_strlen,
302 const s64 *fieldval_int)
304 char strfield[STR_MAX_CHARS(s64) + 1];
305 s64 runeval_int = 0 /* gcc v9.4.0 gets upset with uninitiaized var at -O3 */;
308 /* Caller can't set both! */
310 assert(!fieldval_str);
311 sprintf(strfield, "%"PRIi64, *fieldval_int);
312 fieldval_str = strfield;
313 fieldval_strlen = strlen(strfield);
316 switch (alt->condition) {
317 case RUNE_COND_IF_MISSING:
320 return tal_fmt(ctx, "%s is present", alt->fieldname);
321 case RUNE_COND_EQUAL:
323 return tal_fmt(ctx, "%s not present", alt->fieldname);
324 return cond_test(ctx, alt, "is not equal to",
325 memeqstr(fieldval_str, fieldval_strlen, alt->value));
326 case RUNE_COND_NOT_EQUAL:
328 return tal_fmt(ctx, "%s not present", alt->fieldname);
329 return cond_test(ctx, alt, "is equal to",
330 !memeqstr(fieldval_str, fieldval_strlen, alt->value));
331 case RUNE_COND_BEGINS:
333 return tal_fmt(ctx, "%s not present", alt->fieldname);
334 return cond_test(ctx, alt, "does not start with",
335 memstarts_str(fieldval_str, fieldval_strlen, alt->value));
338 return tal_fmt(ctx, "%s not present", alt->fieldname);
339 return cond_test(ctx, alt, "does not end with",
340 memends_str(fieldval_str, fieldval_strlen, alt->value));
341 case RUNE_COND_CONTAINS:
343 return tal_fmt(ctx, "%s not present", alt->fieldname);
344 return cond_test(ctx, alt, "does not contain",
345 memmem(fieldval_str, fieldval_strlen,
346 alt->value, strlen(alt->value)));
347 case RUNE_COND_INT_LESS:
348 err = integer_compare_valid(ctx, fieldval_int,
352 return cond_test(ctx, alt, "is greater or equal to",
353 *fieldval_int < runeval_int);
354 case RUNE_COND_INT_GREATER:
355 err = integer_compare_valid(ctx, fieldval_int,
359 return cond_test(ctx, alt, "is less or equal to",
360 *fieldval_int > runeval_int);
361 case RUNE_COND_LEXO_BEFORE:
363 return tal_fmt(ctx, "%s not present", alt->fieldname);
364 return cond_test(ctx, alt, "is equal to or ordered after",
365 lexo_order(fieldval_str, fieldval_strlen, alt->value) < 0);
366 case RUNE_COND_LEXO_AFTER:
368 return tal_fmt(ctx, "%s not present", alt->fieldname);
369 return cond_test(ctx, alt, "is equal to or ordered before",
370 lexo_order(fieldval_str, fieldval_strlen, alt->value) > 0);
371 case RUNE_COND_COMMENT:
374 /* We should never create any other values! */
378 const char *rune_alt_single_str(const tal_t *ctx,
379 const struct rune_altern *alt,
380 const char *fieldval_str,
381 size_t fieldval_strlen)
383 return rune_alt_single(ctx, alt, fieldval_str, fieldval_strlen, NULL);
386 const char *rune_alt_single_int(const tal_t *ctx,
387 const struct rune_altern *alt,
390 return rune_alt_single(ctx, alt, NULL, 0, &fieldval_int);
393 const char *rune_alt_single_missing(const tal_t *ctx,
394 const struct rune_altern *alt)
396 return rune_alt_single(ctx, alt, NULL, 0, NULL);
399 const char *rune_meets_criteria_(const tal_t *ctx,
400 const struct rune *rune,
401 const char *(*check)(const tal_t *ctx,
402 const struct rune *rune,
403 const struct rune_altern *alt,
407 for (size_t i = 0; i < tal_count(rune->restrs); i++) {
410 /* Don't "check" unique id */
411 if (i == 0 && is_unique_id(rune->restrs[i]->alterns[0]))
414 err = rune_restr_test(ctx, rune, rune->restrs[i], check, arg);
421 const char *rune_test_(const tal_t *ctx,
422 const struct rune *master,
423 const struct rune *rune,
424 const char *(*check)(const tal_t *ctx,
425 const struct rune *rune,
426 const struct rune_altern *alt,
432 err = rune_is_derived(master, rune);
435 return rune_meets_criteria_(ctx, rune, check, arg);
438 bool rune_altern_eq(const struct rune_altern *alt1,
439 const struct rune_altern *alt2)
441 return alt1->condition == alt2->condition
442 && streq(alt1->fieldname, alt2->fieldname)
443 && streq(alt1->value, alt2->value);
446 bool rune_restr_eq(const struct rune_restr *rest1,
447 const struct rune_restr *rest2)
449 if (tal_count(rest1->alterns) != tal_count(rest2->alterns))
452 for (size_t i = 0; i < tal_count(rest1->alterns); i++)
453 if (!rune_altern_eq(rest1->alterns[i], rest2->alterns[i]))
458 /* Equal, as in both NULL, or both non-NULL and matching */
459 bool runestr_eq(const char *a, const char *b)
469 bool rune_eq(const struct rune *rune1, const struct rune *rune2)
471 if (!runestr_eq(rune1->unique_id, rune2->unique_id))
473 if (!runestr_eq(rune1->version, rune2->version))
476 if (memcmp(rune1->shactx.s, rune2->shactx.s, sizeof(rune1->shactx.s)))
478 if (rune1->shactx.bytes != rune2->shactx.bytes)
480 if (memcmp(rune1->shactx.buf.u8, rune2->shactx.buf.u8,
481 rune1->shactx.bytes % 64))
484 if (tal_count(rune1->restrs) != tal_count(rune2->restrs))
487 for (size_t i = 0; i < tal_count(rune1->restrs); i++)
488 if (!rune_restr_eq(rune1->restrs[i], rune2->restrs[i]))