]> git.ozlabs.org Git - ccan/blob - ccan/rune/_info
aaed15d871eb21ea37b521c94e8943a1a2c14ad8
[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  *              s64 t;
44  *              gettimeofday(&now, NULL);
45  *              t = now.tv_sec;
46  *              return rune_alt_single(ctx, alt, NULL, &t);
47  *      }
48  *      if (streq(alt->fieldname, "uid")) {
49  *              return rune_alt_single(ctx, alt, uid, NULL);
50  *      }
51  *      // Otherwise, field is missing
52  *      return rune_alt_single(ctx, alt, NULL, NULL);
53  * }
54  * 
55  * int main(int argc, char *argv[])
56  * {
57  *      struct rune *master, *rune;
58  * 
59  *      if (argc < 3)
60  *              goto usage;
61  * 
62  *      if (streq(argv[1], "generate")) {
63  *              // Make master, derive a unique_id'd rune.
64  *              if (argc != 3 && argc != 4)
65  *                      goto usage;
66  *              master = rune_new(NULL, (u8 *)argv[2], strlen(argv[2]), NULL);
67  *              rune = rune_derive_start(NULL, master, argv[3]);
68  *      } else if (streq(argv[1], "add")) {
69  *              // Add a restriction
70  *              struct rune_restr *restr;
71  *              if (argc != 4)
72  *                      goto usage;
73  *              rune = rune_from_base64(NULL, argv[2]);
74  *              if (!rune)
75  *                      errx(1, "Bad rune");
76  *              restr = rune_restr_from_string(NULL, argv[3], strlen(argv[3]));
77  *              if (!restr)
78  *                      errx(1, "Bad restriction string");
79  *              rune_add_restr(rune, restr);
80  *      } else if (streq(argv[1], "test")) {
81  *              const char *err;
82  *              if (argc != 5)
83  *                      goto usage;
84  *              master = rune_new(NULL, (u8 *)argv[2], strlen(argv[2]), NULL);
85  *              if (!master)
86  *                      errx(1, "Bad master rune");
87  *              rune = rune_from_base64(NULL, argv[3]);
88  *              if (!rune)
89  *                      errx(1, "Bad rune");
90  *              err = rune_test(NULL, master, rune, check, argv[4]);
91  *              if (err)
92  *                      printf("FAILED: %s\n", err);
93  *              else
94  *                      printf("PASSED\n");
95  *              return 0;
96  *      } else
97  *              goto usage;
98  * 
99  *      printf("%s\n", rune_to_base64(NULL, rune));
100  *      return 0;
101  * 
102  * usage:
103  *      errx(1, "Usage: %s generate <secret> <uniqueid> OR\n"
104  *           "%s add <rune> <restriction> OR\n"
105  *           "%s test <secret> <rune> <uid>", argv[0], argv[0], argv[0]);
106  * }
107  */
108 int main(int argc, char *argv[])
109 {
110         /* Expect exactly one argument */
111         if (argc != 2)
112                 return 1;
113
114         if (strcmp(argv[1], "depends") == 0) {
115                 printf("ccan/base64\n");
116                 printf("ccan/crypto/sha256\n");
117                 printf("ccan/endian\n");
118                 printf("ccan/short_types\n");
119                 printf("ccan/str/hex\n");
120                 printf("ccan/tal/str\n");
121                 printf("ccan/tal\n");
122                 printf("ccan/typesafe_cb\n");
123                 return 0;
124         }
125         if (strcmp(argv[1], "testdepends") == 0) {
126                 printf("ccan/tal/grab_file\n");
127                 return 0;
128         }
129
130         return 1;
131 }