Show local identities in the ssb app.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3964 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
parent
69991abbb4
commit
357d944a8d
@ -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"}}
|
{"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"}}
|
@ -2,11 +2,9 @@
|
|||||||
[Back to index](#index)
|
[Back to index](#index)
|
||||||
|
|
||||||
## MVP2
|
## MVP2
|
||||||
- multiple identities per user, in database
|
|
||||||
- make a cool independent app
|
- make a cool independent app
|
||||||
- indicate when workspace differs from installed
|
- indicate when workspace differs from installed
|
||||||
- / => Something good.
|
- / => Something good.
|
||||||
- confirm posting all new messages
|
|
||||||
- administrators config
|
- administrators config
|
||||||
- update README
|
- update README
|
||||||
- update docs
|
- update docs
|
||||||
@ -20,14 +18,17 @@
|
|||||||
- placeholder/missing images
|
- placeholder/missing images
|
||||||
- connections 2.0
|
- connections 2.0
|
||||||
- no denial of service
|
- no denial of service
|
||||||
- expose loads of stats
|
|
||||||
- package standalone executable
|
- package standalone executable
|
||||||
- make a better connections API
|
- make a better connections API
|
||||||
- tf account timeout why
|
- tf account timeout why
|
||||||
- attribute blob wants to messages
|
- attribute blob wants to messages
|
||||||
- editor without app iframe
|
- editor without app iframe
|
||||||
|
- jwt for session tokens
|
||||||
|
|
||||||
## Maybe Done
|
## Maybe Done
|
||||||
|
- expose loads of stats
|
||||||
|
- confirm posting all new messages
|
||||||
|
- multiple identities per user, in database
|
||||||
- auto-populate data on initial launch
|
- auto-populate data on initial launch
|
||||||
- make the docker image good / test it / use it
|
- make the docker image good / test it / use it
|
||||||
- leaking imports / exports
|
- leaking imports / exports
|
||||||
|
@ -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"}}
|
{"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"}}
|
@ -464,6 +464,7 @@ async function refresh_internal(whoami, selected, force) {
|
|||||||
g_following_deep_cache = {};
|
g_following_deep_cache = {};
|
||||||
await tfrpc.rpc.clear();
|
await tfrpc.rpc.clear();
|
||||||
await tfrpc.rpc.set_identities(await ssb.getIdentities());
|
await tfrpc.rpc.set_identities(await ssb.getIdentities());
|
||||||
|
await tfrpc.rpc.set('all_identities', await ssb.getAllIdentities());
|
||||||
await tfrpc.rpc.set('selected', selected);
|
await tfrpc.rpc.set('selected', selected);
|
||||||
var db = await database("ssb");
|
var db = await database("ssb");
|
||||||
g_sequence = {};
|
g_sequence = {};
|
||||||
|
@ -189,6 +189,8 @@
|
|||||||
<md-subheader>Connections</md-subheader>
|
<md-subheader>Connections</md-subheader>
|
||||||
<md-list-item v-for="connection in connections" v-bind:key="'connection-' + JSON.stringify(connection)"><tf-user :id="connection"></tf-user></md-list-item>
|
<md-list-item v-for="connection in connections" v-bind:key="'connection-' + JSON.stringify(connection)"><tf-user :id="connection"></tf-user></md-list-item>
|
||||||
<md-list-item @click="show_connect_dialog = true">Connect</md-list-item>
|
<md-list-item @click="show_connect_dialog = true">Connect</md-list-item>
|
||||||
|
<md-subheader>Local Accounts</md-subheader>
|
||||||
|
<md-list-item v-for="identity in all_identities" v-bind:key="'connection-identity-' + identity"><tf-user :id="identity"></tf-user></md-list-item>
|
||||||
</md-list>
|
</md-list>
|
||||||
</md-tab>
|
</md-tab>
|
||||||
</md-tabs>
|
</md-tabs>
|
||||||
|
@ -4,6 +4,7 @@ import * as tfshared from './tf-shared.js';
|
|||||||
export var g_data = {
|
export var g_data = {
|
||||||
whoami: null,
|
whoami: null,
|
||||||
selected: null,
|
selected: null,
|
||||||
|
all_identities: [],
|
||||||
identities: [],
|
identities: [],
|
||||||
connections: [],
|
connections: [],
|
||||||
messages: [],
|
messages: [],
|
||||||
|
47
src/main.c
47
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_post(const char* file, int argc, char* argv[]);
|
||||||
static int _tf_command_check(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_usage(const char* file, int argc, char* argv[]);
|
||||||
|
static int _tf_command_private(const char* file, int argc, char* argv[]);
|
||||||
|
|
||||||
typedef struct _command_t {
|
typedef struct _command_t {
|
||||||
const char* name;
|
const char* name;
|
||||||
@ -79,6 +80,7 @@ const command_t k_commands[] = {
|
|||||||
{ "export", _tf_command_export, "Export apps from SSB." },
|
{ "export", _tf_command_export, "Export apps from SSB." },
|
||||||
{ "test", _tf_command_test, "Test SSB." },
|
{ "test", _tf_command_test, "Test SSB." },
|
||||||
{ "check", _tf_command_check, "Validate messages in the SSB database." },
|
{ "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()
|
void shedPrivileges()
|
||||||
@ -618,6 +620,51 @@ xopt_help:
|
|||||||
return 1;
|
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[])
|
static int _tf_command_usage(const char* file, int argc, char* argv[])
|
||||||
{
|
{
|
||||||
printf("Usage: %s command [command-options]\n", file);
|
printf("Usage: %s command [command-options]\n", file);
|
||||||
|
57
src/ssb.db.c
57
src/ssb.db.c
@ -7,6 +7,9 @@
|
|||||||
|
|
||||||
#include <base64c.h>
|
#include <base64c.h>
|
||||||
#include <sodium/crypto_hash_sha256.h>
|
#include <sodium/crypto_hash_sha256.h>
|
||||||
|
#include <sodium/crypto_scalarmult.h>
|
||||||
|
#include <sodium/crypto_scalarmult_curve25519.h>
|
||||||
|
#include <sodium/crypto_secretbox.h>
|
||||||
#include <sodium/crypto_sign.h>
|
#include <sodium/crypto_sign.h>
|
||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -795,3 +798,57 @@ bool tf_ssb_db_identity_get_private_key(tf_ssb_t* ssb, const char* user, const c
|
|||||||
}
|
}
|
||||||
return success;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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(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);
|
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);
|
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);
|
||||||
|
Loading…
Reference in New Issue
Block a user