From 357d944a8d1febf935076f9203aae97589f2e011 Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Mon, 15 Aug 2022 02:23:45 +0000 Subject: [PATCH] Show local identities in the ssb app. git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3964 ed5197a5-7fde-0310-b194-c3ffbd925b24 --- apps/cory/docs.json | 2 +- apps/cory/docs/todo.md | 7 ++--- apps/cory/ssb.json | 2 +- apps/cory/ssb/app.js | 1 + apps/cory/ssb/index.html | 2 ++ apps/cory/ssb/tf.js | 1 + src/main.c | 47 +++++++++++++++++++++++++++++++++ src/ssb.db.c | 57 ++++++++++++++++++++++++++++++++++++++++ src/ssb.db.h | 2 ++ 9 files changed, 116 insertions(+), 5 deletions(-) diff --git a/apps/cory/docs.json b/apps/cory/docs.json index 6f5f0b08..42ec69e6 100644 --- a/apps/cory/docs.json +++ b/apps/cory/docs.json @@ -1 +1 @@ -{"type":"tildefriends-app","files":{"app.js":"&rLwYqurncmnUyGeWY+FLEGS2EIJmqw2cutl1gyGiVSk=.sha256","index.md":"&082vPjenwI6mL2vXwQDVEFquyl2jW9t767sGuCFvVNA=.sha256","todo.md":"&nr1x4grS+0J2OirgKs2dpsElUC2yTQwO6BmgiZ/Qb4w=.sha256","structure.md":"&T+CBfT9XP6ooKFvD1ZCI9hsutqsNIamfBxtAho0HtlU=.sha256","guide.md":"&SgnGL0+rjetY2o9A2+lVRbNvHIkqKwMnZr9gXWneIlc=.sha256","id_refactor.md":"&8yoYd14gX2Z3ppktVrPYf4qR78fuwAlvrtsWkSCkWUA=.sha256","ssb.md":"&WMvYIpp4CMZACwXJlX8HMDplJ+XeJB04BYf8zasrL4g=.sha256"}} \ No newline at end of file +{"type":"tildefriends-app","files":{"app.js":"&rLwYqurncmnUyGeWY+FLEGS2EIJmqw2cutl1gyGiVSk=.sha256","index.md":"&082vPjenwI6mL2vXwQDVEFquyl2jW9t767sGuCFvVNA=.sha256","todo.md":"&u4lmFlYFB5zQNfVXVB8t8NMT2jFAeE8ivWfwIiiTKxQ=.sha256","structure.md":"&T+CBfT9XP6ooKFvD1ZCI9hsutqsNIamfBxtAho0HtlU=.sha256","guide.md":"&SgnGL0+rjetY2o9A2+lVRbNvHIkqKwMnZr9gXWneIlc=.sha256","id_refactor.md":"&8yoYd14gX2Z3ppktVrPYf4qR78fuwAlvrtsWkSCkWUA=.sha256","ssb.md":"&WMvYIpp4CMZACwXJlX8HMDplJ+XeJB04BYf8zasrL4g=.sha256"}} \ No newline at end of file diff --git a/apps/cory/docs/todo.md b/apps/cory/docs/todo.md index e03a377f..00b533b1 100644 --- a/apps/cory/docs/todo.md +++ b/apps/cory/docs/todo.md @@ -2,11 +2,9 @@ [Back to index](#index) ## MVP2 -- multiple identities per user, in database - make a cool independent app - indicate when workspace differs from installed - / => Something good. -- confirm posting all new messages - administrators config - update README - update docs @@ -20,14 +18,17 @@ - placeholder/missing images - connections 2.0 - no denial of service -- expose loads of stats - package standalone executable - make a better connections API - tf account timeout why - attribute blob wants to messages - editor without app iframe +- jwt for session tokens ## Maybe Done +- expose loads of stats +- confirm posting all new messages +- multiple identities per user, in database - auto-populate data on initial launch - make the docker image good / test it / use it - leaking imports / exports diff --git a/apps/cory/ssb.json b/apps/cory/ssb.json index 5814bacd..ddaad48a 100644 --- a/apps/cory/ssb.json +++ b/apps/cory/ssb.json @@ -1 +1 @@ -{"type":"tildefriends-app","files":{"app.js":"&5Pyy6krf0jbECZ9Qp+S4FwmW4bka5aqdxQ8Qjjocyqg=.sha256","index.html":"&ye2GeqCrDi3Dbl3UVIfE8H5GzCxN8O46FWj5zhLnZAw=.sha256","vue-material.js":"&K5cdLqXYCENPak/TCINHQhyJhpS4G9DlZHGwoh/LF2g=.sha256","tf-user.js":"&cI/JLy83mOngcqYCEP8Vej8urDvAQAV1WxFsL67/K3M=.sha256","tf-message.js":"&JVARtJEQkq3XjjL0Jv/NUDkO2WZnXGIqkWsqYvTPXBI=.sha256","tf.js":"&54CRUokNTNobXHZ5vHyrz3ToCnyhWV72K7zOS3Rip9w=.sha256","commonmark.min.js":"&EP0OeR9zyLwZannz+0ga4s9AGES2RLvvIIQYHqqV6+k=.sha256","vue.js":"&g1wvA+yHl1sVC+eufTsg9If7ZeVyMTBU+h0tks7ZNzE=.sha256","vue-material-theme-default-dark.css":"&RP2nr+2CR18BpHHw5ST9a5GJUCOG9n0G2kuGkcQioWE=.sha256","vue-material.min.css":"&kGbUM2QgFSyHZRzqQb0b+0S3EVIlZ0AXpdiAVjIhou8=.sha256","roboto.css":"&jJv43Om673mQO5JK0jj7714s5E+5Yrf82H6LcDx7wUs=.sha256","material-icons.css":"&a28PdcVvgq/DxyIvJAx/e+ZOEtOuHnr3kjLWKyzH11M=.sha256","tf-shared.js":"&LXyUSm6zSakN/ghJlZ1Qg2VJfV5alhN0gl8F7txIIOU=.sha256","style.css":"&qegBNCrVUihxffRUxGFuG/6u+0Y6d18zHtfNHBZtZ04=.sha256"}} \ No newline at end of file +{"type":"tildefriends-app","files":{"app.js":"&7dCNJFk5RMHTWZC2qR8/UzjS22bXn7ZsPS6L/LIgUOg=.sha256","index.html":"&c+LsaIXIVMFXYjv5PkbgwjzxQ967QYRER5yy0YgpnZo=.sha256","vue-material.js":"&K5cdLqXYCENPak/TCINHQhyJhpS4G9DlZHGwoh/LF2g=.sha256","tf-user.js":"&cI/JLy83mOngcqYCEP8Vej8urDvAQAV1WxFsL67/K3M=.sha256","tf-message.js":"&JVARtJEQkq3XjjL0Jv/NUDkO2WZnXGIqkWsqYvTPXBI=.sha256","tf.js":"&MBqdk+3/ojaycNh92vOngTgvWk6h24vl8Q67MU4KZdI=.sha256","commonmark.min.js":"&EP0OeR9zyLwZannz+0ga4s9AGES2RLvvIIQYHqqV6+k=.sha256","vue.js":"&g1wvA+yHl1sVC+eufTsg9If7ZeVyMTBU+h0tks7ZNzE=.sha256","vue-material-theme-default-dark.css":"&RP2nr+2CR18BpHHw5ST9a5GJUCOG9n0G2kuGkcQioWE=.sha256","vue-material.min.css":"&kGbUM2QgFSyHZRzqQb0b+0S3EVIlZ0AXpdiAVjIhou8=.sha256","roboto.css":"&jJv43Om673mQO5JK0jj7714s5E+5Yrf82H6LcDx7wUs=.sha256","material-icons.css":"&a28PdcVvgq/DxyIvJAx/e+ZOEtOuHnr3kjLWKyzH11M=.sha256","tf-shared.js":"&LXyUSm6zSakN/ghJlZ1Qg2VJfV5alhN0gl8F7txIIOU=.sha256","style.css":"&qegBNCrVUihxffRUxGFuG/6u+0Y6d18zHtfNHBZtZ04=.sha256"}} \ No newline at end of file diff --git a/apps/cory/ssb/app.js b/apps/cory/ssb/app.js index e08157d5..34d989c1 100644 --- a/apps/cory/ssb/app.js +++ b/apps/cory/ssb/app.js @@ -464,6 +464,7 @@ async function refresh_internal(whoami, selected, force) { g_following_deep_cache = {}; await tfrpc.rpc.clear(); await tfrpc.rpc.set_identities(await ssb.getIdentities()); + await tfrpc.rpc.set('all_identities', await ssb.getAllIdentities()); await tfrpc.rpc.set('selected', selected); var db = await database("ssb"); g_sequence = {}; diff --git a/apps/cory/ssb/index.html b/apps/cory/ssb/index.html index a11b34e9..89f0594d 100644 --- a/apps/cory/ssb/index.html +++ b/apps/cory/ssb/index.html @@ -189,6 +189,8 @@ Connections Connect + Local Accounts + diff --git a/apps/cory/ssb/tf.js b/apps/cory/ssb/tf.js index 6942ef4a..964d5b22 100644 --- a/apps/cory/ssb/tf.js +++ b/apps/cory/ssb/tf.js @@ -4,6 +4,7 @@ import * as tfshared from './tf-shared.js'; export var g_data = { whoami: null, selected: null, + all_identities: [], identities: [], connections: [], messages: [], diff --git a/src/main.c b/src/main.c index 15d3a866..b5c20e49 100644 --- a/src/main.c +++ b/src/main.c @@ -64,6 +64,7 @@ static int _tf_command_sandbox(const char* file, int argc, char* argv[]); static int _tf_command_post(const char* file, int argc, char* argv[]); static int _tf_command_check(const char* file, int argc, char* argv[]); static int _tf_command_usage(const char* file, int argc, char* argv[]); +static int _tf_command_private(const char* file, int argc, char* argv[]); typedef struct _command_t { const char* name; @@ -79,6 +80,7 @@ const command_t k_commands[] = { { "export", _tf_command_export, "Export apps from SSB." }, { "test", _tf_command_test, "Test SSB." }, { "check", _tf_command_check, "Validate messages in the SSB database." }, + { "private", _tf_command_private, "Check for private messages the SSB database (just an experiment)." }, }; void shedPrivileges() @@ -618,6 +620,51 @@ xopt_help: return 1; } +static int _tf_command_private(const char* file, int argc, char* argv[]) +{ + typedef struct args_t { + bool help; + } args_t; + + xoptOption options[] = { + { "help", 'h', offsetof(args_t, help), NULL, XOPT_TYPE_BOOL, NULL, "Shows this help message." }, + XOPT_NULLOPTION, + }; + + args_t args = { 0 }; + const char** extras = NULL; + int extra_count = 0; + const char *err = NULL; + XOPT_PARSE(file, XOPT_CTX_KEEPFIRST | XOPT_CTX_STRICT, options, &args, argc, (const char**)argv, &extra_count, &extras, &err, stderr, "private [options]", "options:", NULL, 15); + if (err) + { + if (extras) + { + free((void*)extras); + } + fprintf(stderr, "Error: %s\n", err); + return 2; + } + + bool result = true; + sqlite3* db = NULL; + sqlite3_open("db.sqlite", &db); + tf_ssb_db_private(db); + sqlite3_close(db); + if (extras) + { + free((void*)extras); + } + return result ? EXIT_SUCCESS : EXIT_FAILURE; + +xopt_help: + if (extras) + { + free((void*)extras); + } + return 1; +} + static int _tf_command_usage(const char* file, int argc, char* argv[]) { printf("Usage: %s command [command-options]\n", file); diff --git a/src/ssb.db.c b/src/ssb.db.c index a0617f54..49b1c9a7 100644 --- a/src/ssb.db.c +++ b/src/ssb.db.c @@ -7,6 +7,9 @@ #include #include +#include +#include +#include #include #include #include @@ -795,3 +798,57 @@ bool tf_ssb_db_identity_get_private_key(tf_ssb_t* ssb, const char* user, const c } return success; } + +static void _test_private(sqlite3* db, const uint8_t* private_key) +{ + sqlite3_stmt* statement = NULL; + if (sqlite3_prepare(db, "SELECT content FROM messages WHERE content LIKE '\"%.box\"'", -1, &statement, NULL) == SQLITE_OK) + { + while (sqlite3_step(statement) == SQLITE_ROW) + { + uint8_t buffer[8192]; + //printf("==> %s\n", sqlite3_column_text(statement, 0)); + int r = base64c_decode(sqlite3_column_text(statement, 0) + 1, sqlite3_column_bytes(statement, 0) - strlen("\".box\""), buffer, sizeof(buffer)); + if (r > 1) + { + uint8_t* nonce = buffer; + uint8_t* public_key = buffer + 24; + if (public_key + 32 < buffer + r) + { + uint8_t shared_secret[crypto_scalarmult_curve25519_SCALARBYTES]; + if (crypto_scalarmult_curve25519(shared_secret, private_key, public_key) == 0) + { + for (uint8_t* p = public_key + 32; p < buffer + r + 49; p += 49) + { + uint8_t out[49]; + if (crypto_secretbox_open_easy(out, p, 49, nonce, shared_secret) == 0) + { + printf("opened secret box!\n"); + } + } + } + } + } + } + sqlite3_finalize(statement); + } +} + +void tf_ssb_db_private(sqlite3* db) +{ + sqlite3_stmt* statement = NULL; + if (sqlite3_prepare(db, "SELECT public_key, private_key FROM identities", -1, &statement, NULL) == SQLITE_OK) + { + while (sqlite3_step(statement) == SQLITE_ROW) + { + uint8_t private_key[crypto_sign_SECRETKEYBYTES]; + printf("-> %s\n", sqlite3_column_text(statement, 0)); + int r = base64c_decode(sqlite3_column_text(statement, 1), sqlite3_column_bytes(statement, 1) - strlen(".ed25519"), private_key, sizeof(private_key)); + if (r > 0) + { + _test_private(db, private_key); + } + } + sqlite3_finalize(statement); + } +} diff --git a/src/ssb.db.h b/src/ssb.db.h index 17f269bc..fa275038 100644 --- a/src/ssb.db.h +++ b/src/ssb.db.h @@ -23,3 +23,5 @@ bool tf_ssb_db_identity_add(tf_ssb_t* ssb, const char* user, const char* public_ void tf_ssb_db_identity_visit(tf_ssb_t* ssb, const char* user, void (*callback)(const char* identity, void* user_data), void* user_data); void tf_ssb_db_identity_visit_all(tf_ssb_t* ssb, void (*callback)(const char* identity, void* user_data), void* user_data); bool tf_ssb_db_identity_get_private_key(tf_ssb_t* ssb, const char* user, const char* public_key, uint8_t* out_private_key, size_t private_key_size); + +void tf_ssb_db_private(sqlite3* db);