chibipub

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 1bb5a9fce6f04f11de5c876e00180488cfb6dd9d
parent 39d28abd18a4cc30f7e811e3f19b38bd5429797a
Author: William Casarin <jb55@jb55.com>
Date:   Sat, 16 Jan 2021 15:12:58 -0800

initial sigcheck code

Signed-off-by: William Casarin <jb55@jb55.com>

Diffstat:
MMakefile | 3+++
Msrc/cursor.h | 1+
Asrc/io.c | 24++++++++++++++++++++++++
Asrc/io.h | 9+++++++++
Msrc/json.c | 37++++---------------------------------
Msrc/json.h | 4+++-
Asrc/sigcheck.c | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/sigcheck.h | 12++++++++++++
Msrc/test_json.c | 16+---------------
Msrc/ubjson.c | 53++++++++++++++++++++++++++++++++++++++++++++++++-----
Msrc/ubjson.h | 2++
Asrc/util.c | 33+++++++++++++++++++++++++++++++++
Msrc/util.h | 4++++
Msrc/wolfsocks.c | 22++++++++++++++++++++--
14 files changed, 223 insertions(+), 56 deletions(-)

diff --git a/Makefile b/Makefile @@ -8,6 +8,9 @@ OBJS = src/http.o \ src/json.o \ src/ubjson.o \ src/ap_json.o \ + src/io.o \ + src/util.o \ + src/sigcheck.o \ deps/sha256/sha256.o \ deps/blake3/blake3.a diff --git a/src/cursor.h b/src/cursor.h @@ -184,4 +184,5 @@ static inline int cursor_remaining_capacity(struct cursor *cursor) return cursor->end - cursor->p; } + #endif diff --git a/src/io.c b/src/io.c @@ -0,0 +1,24 @@ + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/mman.h> +#include <unistd.h> +#include <fcntl.h> + +#include "io.h" + +int map_file(const char *filename, unsigned char **p, size_t *flen) +{ + struct stat st; + int des; + stat(filename, &st); + *flen = st.st_size; + + des = open(filename, O_RDONLY); + + *p = mmap(NULL, *flen, PROT_READ, MAP_PRIVATE, des, 0); + close(des); + + return *p != MAP_FAILED; +} + diff --git a/src/io.h b/src/io.h @@ -0,0 +1,9 @@ + +#ifndef WOLFSOCKS_IO +#define WOLFSOCKS_IO + +#include <stddef.h> + +int map_file(const char *filename, unsigned char **p, size_t *flen); + +#endif /* WOLFSOCKS_IO */ diff --git a/src/json.c b/src/json.c @@ -2,6 +2,7 @@ #include "cursor.h" #include "json.h" #include "parse.h" +#include "util.h" #include <assert.h> #include <ctype.h> @@ -30,34 +31,6 @@ void init_json_handlers(struct json_handlers *h) memset(h, 0, sizeof(*h)); } -#define max(a,b) ((a) > (b) ? (a) : (b)) -static void print_around(struct cursor *cur, int range) -{ - unsigned char *c; - - c = max(cur->p - range, cur->start); - for (; c < cur->end && c < (cur->p + range); c++) { - if (*c < 32) - printf("%02x", *c); - else - printf("%c", *c); - } - printf("\n"); - - c = max(cur->p - range, cur->start); - for (; c < cur->end && c < (cur->p + range); c++) { - if (c == cur->p) { - printf("^"); - continue; - } - if (*c < 32) - printf(" "); - else - printf(" "); - } - printf("\n"); -} - static void consume_whitespace(struct cursor *cur) { for (; cur->p < cur->end; cur->p++) { @@ -619,8 +592,8 @@ void make_compact_handlers(struct json_handlers *h, struct json_pusher *out) h->token = handle_token; } -static void init_json_parser(struct json_parser *p, unsigned char *buf, - size_t buf_size, struct json_handlers *h) +void init_json_parser(struct json_parser *p, unsigned char *buf, size_t buf_size, + struct json_handlers *h) { memset(p, 0, sizeof(*p)); make_cursor(buf, buf + buf_size, &p->cur); @@ -628,10 +601,8 @@ static void init_json_parser(struct json_parser *p, unsigned char *buf, copy_json_handlers(h, &p->handlers); } -int parse_json(unsigned char *buf, size_t buf_size, struct json_parser *p, - struct json_handlers *handlers) +int parse_json(struct json_parser *p) { - init_json_parser(p, buf, buf_size, handlers); return parse_array_or_object(p); } diff --git a/src/json.h b/src/json.h @@ -39,12 +39,14 @@ int handle_null(struct json_handlers *h); int handle_number(struct json_handlers *h, unsigned int number); int handle_token(struct json_handlers *h, char type, unsigned int **len); +void init_json_parser(struct json_parser *p, unsigned char *buf, size_t buf_size, struct json_handlers *h); void init_json_strtok(struct json_strtok *str); void init_json_pusher_with(struct json_pusher *p, struct cursor *out); void init_json_pusher(struct json_pusher *p, unsigned char *buf, size_t size); void init_json_handlers(struct json_handlers *h); void make_compact_handlers(struct json_handlers *h, struct json_pusher *out); -int parse_json(unsigned char *buf, size_t buf_size, struct json_parser *, struct json_handlers *); +int parse_json(struct json_parser *); +int push_escaped(struct cursor *cur, unsigned char *text, int size); void copy_json_handlers(struct json_handlers *src, struct json_handlers *dst); #endif diff --git a/src/sigcheck.c b/src/sigcheck.c @@ -0,0 +1,59 @@ + +#define SCRATCH_SIZE 1048576 + +#include <sys/mman.h> +#include <stdlib.h> +#include <assert.h> + +#include "json.h" +#include "ubjson.h" +#include "io.h" +#include "sigcheck.h" +#include "util.h" + +static int verify_signature(struct cursor cur) +{ + struct ubjson ubjson; + struct json val; + + init_ubjson(&ubjson, cur.start, cur.p - cur.start); + ubjson.data_end = cur.p; + + const char *path[] = {"@wsheaders", "Signature"}; + assert(ubjson_lookup(&ubjson, path, 2, &val)); + printf("sig: %.*s\n", val.len, val.string); + //print_around(&val.container.cur, 10); + + return 1; +} + +int sigcheck(struct sigcheck *check) +{ + int count = 0; + unsigned char *p, *scratch; + size_t flen; + struct json_parser jsonp; + struct json_handlers handlers; + struct cursor in_cur, out_cur; + + scratch = malloc(SCRATCH_SIZE); + map_file(check->activity_file, &p, &flen); + + init_json_handlers(&handlers); + make_cursor(p, p + flen, &in_cur); + make_cursor(scratch, scratch + SCRATCH_SIZE, &out_cur); + make_ubjson_handlers(&handlers, &out_cur); + init_json_parser(&jsonp, p, flen, &handlers); + + while (parse_json(&jsonp)) { + printf("success! %d\n", ++count); + + if (!verify_signature(out_cur)) { + printf("bad signature\n"); + } + } + + munmap(p, flen); + + return 1; +} diff --git a/src/sigcheck.h b/src/sigcheck.h @@ -0,0 +1,12 @@ + +#ifndef WOLFSOCKS_SIGCHECK +#define WOLFSOCKS_SIGCHECK + +struct sigcheck +{ + const char *activity_file; +}; + +int sigcheck(struct sigcheck *check); + +#endif /* WOLFSOCKS_SIGCHECK */ diff --git a/src/test_json.c b/src/test_json.c @@ -2,6 +2,7 @@ #include "json.h" #include "ubjson.h" #include "cursor.h" +#include "io.h" #include <assert.h> #include <stdio.h> @@ -13,21 +14,6 @@ #include <unistd.h> #include <stdlib.h> -int map_file(const char *filename, unsigned char **p, size_t *flen) -{ - struct stat st; - int des; - stat(filename, &st); - *flen = st.st_size; - - des = open(filename, O_RDONLY); - - *p = mmap(NULL, *flen, PROT_READ, MAP_PRIVATE, des, 0); - close(des); - - return *p != MAP_FAILED; -} - static void write_data(unsigned char *data, int data_size) { FILE *file; diff --git a/src/ubjson.c b/src/ubjson.c @@ -2,6 +2,7 @@ #include "ubjson.h" #include "json.h" #include "parse.h" + #include <assert.h> static inline int push_ubjson_null(struct cursor *ubjson) @@ -139,20 +140,61 @@ static int push_ubjson_num(struct cursor *ubjson, unsigned int len) return 1; } +static inline int is_escape_char(char c) +{ + return c == '"' || c == '\\' || c == '/' || c == 'b' || c == 'f' || + c == 'n' || c == 'r' || c == 't'; +} + +static int count_skipped(unsigned char *text, int size) +{ + unsigned char *p; + int skipped = 0; + + for (p = text; p < text+size; p++) { + if (*p == '\\' && (p+1 < text+size) && is_escape_char(*(p+1))) { + p++; + skipped++; + } + } + + return skipped; +} + +static int push_unescaped(struct cursor *cur, unsigned char *text, int size) +{ + unsigned char *p; + + for (p = text; p < text+size; p++) { + if (*p == '\\' && (p+1 < text+size) && is_escape_char(*(p+1))) { + p++; + } + + if (!push_byte(cur, *p)) { + return 0; + } + } + + return 1; +} + + static int push_ubjson_str(struct cursor *ubjson, unsigned char *text, unsigned int size) { + int skipped; if (!push_byte(ubjson, 'S')) { return 0; } - if (!push_ubjson_num(ubjson, size)) { + skipped = count_skipped(text, size); + + if (!push_ubjson_num(ubjson, size-skipped)) { return 0; } - /* TODO push string without escapes */ - if (!push_data(ubjson, text, size)) { + if (!push_unescaped(ubjson, text, size)) { return 0; } @@ -390,7 +432,7 @@ static int handle_ubjson_token(struct json_handlers *h, char token, unsigned int return 1; } -static void make_ubjson_handlers(struct json_handlers *h, struct cursor *ubjson) +void make_ubjson_handlers(struct json_handlers *h, struct cursor *ubjson) { h->data = (void*)ubjson; @@ -409,7 +451,8 @@ int parse_ubjson(unsigned char *buf, size_t buf_size, struct ubjson *out) make_ubjson_handlers(&h, &out->cur); - ok = parse_json(buf, buf_size, &p, &h); + init_json_parser(&p, buf, buf_size, &h); + ok = parse_json(&p); out->data_end = out->cur.p; out->cur.p = out->cur.start; diff --git a/src/ubjson.h b/src/ubjson.h @@ -4,6 +4,7 @@ #include "cursor.h" #include "errors.h" +#include "json.h" struct ubjson { struct cursor cur; @@ -33,6 +34,7 @@ struct json { }; }; +void make_ubjson_handlers(struct json_handlers *h, struct cursor *ubjson); void init_ubjson(struct ubjson *ubjson, unsigned char *buf, size_t bufsize); int print_ubjson(struct ubjson *json); int parse_ubjson(unsigned char *buf, size_t buf_size, struct ubjson *out); diff --git a/src/util.c b/src/util.c @@ -0,0 +1,33 @@ + +#include "util.h" + +#include <stdio.h> + +#define max(a,b) ((a) > (b) ? (a) : (b)) +void print_around(struct cursor *cur, int range) +{ + unsigned char *c; + + c = max(cur->p - range, cur->start); + for (; c < cur->end && c < (cur->p + range); c++) { + if (*c < 32) + printf("%02x", *c); + else + printf("%c", *c); + } + printf("\n"); + + c = max(cur->p - range, cur->start); + for (; c < cur->end && c < (cur->p + range); c++) { + if (c == cur->p) { + printf("^"); + continue; + } + if (*c < 32) + printf(" "); + else + printf(" "); + } + printf("\n"); +} +#undef max diff --git a/src/util.h b/src/util.h @@ -5,6 +5,8 @@ #include <ctype.h> #include <string.h> +#include "cursor.h" + static inline int stricmp(const char *a, const char *b) { int len, i; @@ -19,4 +21,6 @@ static inline int stricmp(const char *a, const char *b) { return 1; } +void print_around(struct cursor *cur, int range); + #endif diff --git a/src/wolfsocks.c b/src/wolfsocks.c @@ -16,6 +16,7 @@ #include "ap_json.h" #include "inbox.h" #include "json.h" +#include "sigcheck.h" #define BUF_SIZE 1048576 #define ARENA_SIZE 134217728 /* 128 MB virtual mem arena */ @@ -186,7 +187,8 @@ static int handle_inbox_request(struct http_req *req, struct cursor *arena) start = arena->p; init_json_pusher_with(&push, arena); - if (!parse_json(req->body, req->body_len, &pull, &ap_handler)) { + init_json_parser(&pull, req->body, req->body_len, &ap_handler); + if (!parse_json(&pull)) { note_error(&req->errs, "json parse failed"); return 0; } @@ -458,7 +460,7 @@ void run_http_server() free(arena); } -static void load_config() +static void load_config() { if (!get_hostname()) { printf("WOLFSOCKS_HOST env not set\n"); @@ -466,8 +468,24 @@ static void load_config() } } +static int checksigs() +{ + struct sigcheck check; + check.activity_file = "activities.json"; + if (!sigcheck(&check)) { + printf("sigcheck failed\n"); + return 1; + } + printf("ok\n"); + return 0; +} + int main(int argc, char *argv[]) { + if (argc >= 1 && !strcmp(argv[1], "checksigs")) { + return checksigs(); + } + load_config(); run_http_server();