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:
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();