]> git.ozlabs.org Git - ccan/blob - ccan/rune/_info
ccan/rune: simplify check helper interfaces, allow explicit string lengths.
[ccan] / ccan / rune / _info
1 #include "config.h"
2 #include <stdio.h>
3 #include <string.h>
4
5 /**
6  * rune - Simple cookies you can extend (a-la Python runes class).
7  *
8  * This code is a form of cookies, but they are user-extensible, and
9  * contain a simple language to define what the cookie allows.
10  *
11  * A "rune" contains the hash of a secret (so the server can
12  * validate), such that you can add, but not subtract, conditions.
13  * This is a simplified form of Macaroons, See
14  * https://research.google/pubs/pub41892/ "Macaroons: Cookies with
15  * Contextual Caveats for Decentralized Authorization in the Cloud".
16  * It has one good idea, some extended ideas nobody implements, and
17  * lots and lots of words.
18  *
19  * License: BSD-MIT
20  * Author: Rusty Russell <rusty@rustcorp.com.au>
21  * Example:
22  * // Given "generate secret 1" outputs kr7AW-eJ2Munhv5ftu4rHqAnhxUpPQM8aOyWOmqiytk9MQ==
23  * // Given "add kr7AW-eJ2Munhv5ftu4rHqAnhxUpPQM8aOyWOmqiytk9MQ== uid=rusty" outputs Xyt5S6FKUnA2ppGB62c6HTPGojt2S7k2n7Cf7Tjj6zM9MSZ1aWQ9cnVzdHk=
24  * // Given "test secret Xyt5S6FKUnA2ppGB62c6HTPGojt2S7k2n7Cf7Tjj6zM9MSZ1aWQ9cnVzdHk= rusty" outputs PASSED
25  * // Given "test secret Xyt5S6FKUnA2ppGB62c6HTPGojt2S7k2n7Cf7Tjj6zM9MSZ1aWQ9cnVzdHk= notrusty" outputs FAILED: uid is not equal to rusty
26  * // Given "add Xyt5S6FKUnA2ppGB62c6HTPGojt2S7k2n7Cf7Tjj6zM9MSZ1aWQ9cnVzdHk= t\<1655958616" outputs _YBFmeAedqlLigWHAmvyyGGHRrnI40BRQGh2hWdSZ9E9MSZ1aWQ9cnVzdHkmdDwxNjU1OTU4NjE2
27  * // Given "test secret _YBFmeAedqlLigWHAmvyyGGHRrnI40BRQGh2hWdSZ9E9MSZ1aWQ9cnVzdHkmdDwxNjU1OTU4NjE2 rusty" outputs FAILED: t is greater or equal to 1655958616
28  * #include <ccan/err/err.h>
29  * #include <ccan/rune/rune.h>
30  * #include <ccan/str/str.h>
31  * #include <stdio.h>
32  * #include <sys/time.h>
33  * 
34  * // We support two values: current time (t), and user id (uid).
35  * static const char *check(const tal_t *ctx,
36  *                          const struct rune *rune,
37  *                          const struct rune_altern *alt,
38  *                          char *uid)
39  * {
40  *      // t= means current time, in seconds, as integer
41  *      if (streq(alt->fieldname, "t")) {
42  *              struct timeval now;
43  *              gettimeofday(&now, NULL);
44  *              return rune_alt_single_int(ctx, alt, now.tv_sec);
45  *      }
46  *      if (streq(alt->fieldname, "uid")) {
47  *              return rune_alt_single_str(ctx, alt, uid, strlen(uid));
48  *      }
49  *      // Otherwise, field is missing
50  *      return rune_alt_single_missing(ctx, alt);
51  * }
52  * 
53  * int main(int argc, char *argv[])
54  * {
55  *      struct rune *master, *rune;
56  * 
57  *      if (argc < 3)
58  *              goto usage;
59  * 
60  *      if (streq(argv[1], "generate")) {
61  *              // Make master, derive a unique_id'd rune.
62  *              if (argc != 3 && argc != 4)
63  *                      goto usage;
64  *              master = rune_new(NULL, (u8 *)argv[2], strlen(argv[2]), NULL);
65  *              rune = rune_derive_start(NULL, master, argv[3]);
66  *      } else if (streq(argv[1], "add")) {
67  *              // Add a restriction
68  *              struct rune_restr *restr;
69  *              if (argc != 4)
70  *                      goto usage;
71  *              rune = rune_from_base64(NULL, argv[2]);
72  *              if (!rune)
73  *                      errx(1, "Bad rune");
74  *              restr = rune_restr_from_string(NULL, argv[3], strlen(argv[3]));
75  *              if (!restr)
76  *                      errx(1, "Bad restriction string");
77  *              rune_add_restr(rune, restr);
78  *      } else if (streq(argv[1], "test")) {
79  *              const char *err;
80  *              if (argc != 5)
81  *                      goto usage;
82  *              master = rune_new(NULL, (u8 *)argv[2], strlen(argv[2]), NULL);
83  *              if (!master)
84  *                      errx(1, "Bad master rune");
85  *              rune = rune_from_base64(NULL, argv[3]);
86  *              if (!rune)
87  *                      errx(1, "Bad rune");
88  *              err = rune_test(NULL, master, rune, check, argv[4]);
89  *              if (err)
90  *                      printf("FAILED: %s\n", err);
91  *              else
92  *                      printf("PASSED\n");
93  *              return 0;
94  *      } else
95  *              goto usage;
96  * 
97  *      printf("%s\n", rune_to_base64(NULL, rune));
98  *      return 0;
99  * 
100  * usage:
101  *      errx(1, "Usage: %s generate <secret> <uniqueid> OR\n"
102  *           "%s add <rune> <restriction> OR\n"
103  *           "%s test <secret> <rune> <uid>", argv[0], argv[0], argv[0]);
104  * }
105  */
106 int main(int argc, char *argv[])
107 {
108         /* Expect exactly one argument */
109         if (argc != 2)
110                 return 1;
111
112         if (strcmp(argv[1], "depends") == 0) {
113                 printf("ccan/base64\n");
114                 printf("ccan/crypto/sha256\n");
115                 printf("ccan/endian\n");
116                 printf("ccan/mem\n");
117                 printf("ccan/short_types\n");
118                 printf("ccan/str/hex\n");
119                 printf("ccan/tal/str\n");
120                 printf("ccan/tal\n");
121                 printf("ccan/typesafe_cb\n");
122                 return 0;
123         }
124         if (strcmp(argv[1], "testdepends") == 0) {
125                 printf("ccan/tal/grab_file\n");
126                 return 0;
127         }
128
129         return 1;
130 }