diff --git a/.builder.options.rb b/.builder.options.rb index 2101813..ea8359e 100644 --- a/.builder.options.rb +++ b/.builder.options.rb @@ -1,2 +1,2 @@ -FLAGS="-g -MP -MD -Os -Werror" -LDFLAGS = "-lcurl -lssl -lcrypto" +FLAGS="-g -MP -MD -Os -Werror -flto" +LDFLAGS = "-lcurl -lssl -lcrypto -flto -Os" diff --git a/src/controller/inbox.c b/src/controller/inbox.c index fed7027..b66757c 100644 --- a/src/controller/inbox.c +++ b/src/controller/inbox.c @@ -8,8 +8,10 @@ // Model #include "model/server.h" #include "model/account.h" +#include "model/notification.h" #include "model/ap/activity.h" #include "model/ap/inbox_envelope.h" +#include "model/ap/outbox_envelope.h" #include "model/crypto/http_sign.h" // Stdlib @@ -35,43 +37,30 @@ bool route_inbox( struct http_request* req ) return true; } -bool route_undo_activity( struct ap_activity* act ) + +static bool route_undo_follow( struct ap_activity* act ) { - if( act->object.tag != apaot_activity ) { - // Don't undo activities that are references - return false; - } - if( !act->object.ptr ) { - printf( "No object in activity\n" ); - return false; + const char* target = act->object.ptr->object.ref; + struct account* a = account_from_uri( target ); + if( !a || 0 != strcmp( a->server, g_server_name ) ) { + printf( "Unfollow not targeted at local account. Discarding.\n" ); + return true; } - switch( act->object.ptr->type ) { - case apat_follow: - const char* target = act->object.ptr->object.ref; - struct account* a = account_from_uri( target ); - if( !a || 0 != strcmp( a->server, g_server_name ) ) { - printf( "Unfollow not targeted at local account. Discarding.\n" ); - return true; - } + struct account* follower = account_from_uri( act->actor ); + if( !follower ) { + printf( "Follower account not present local. Active follow not possible. Discarding undo\n" ); + return true; + } - struct account* follower = account_from_uri( act->actor ); - if( !follower ) { - printf( "Follower account not present local. Active follow not possible. Discarding undo\n" ); - return true; - } + account_remove_follower( a, follower ); - printf( "TODO: undo %s following %s\n", act->actor, target ); - return false; - default: - printf( "Unhandled object activity type %d in undo\n", act->object.ptr->type ); - return false; - }; + // TODO: create a notification for unfollow - return false; + return true; } -bool route_follow( struct ap_activity* act ) +static bool route_follow( struct ap_activity* act ) { struct account* follower = NULL; bool res = false; @@ -80,11 +69,13 @@ bool route_follow( struct ap_activity* act ) const char* target = act->object.ref; struct account* a = account_from_uri( target ); + // Don't process follows for remote users if( !a || 0 != strcmp( a->server, g_server_name ) ) { printf( "Unfollow not targeted at local account. Discarding.\n" ); goto success; } + // Get account for the follower follower = account_from_uri( act->actor ); if( !follower ) { follower = account_fetch_from_uri( act->actor ); @@ -94,17 +85,26 @@ bool route_follow( struct ap_activity* act ) goto failed; } + // Add the follower + account_add_follower( a, follower ); + // Create Accept activity accept = ap_activity_create_accept(act); - - char filename[512]; snprintf( filename, 512, "data/outbox/%d.json", accept->local_id ); - char tmp_filename[512]; snprintf( tmp_filename, 512, "%s.tmp", filename ); - FILE* f = fopen(tmp_filename,"w"); - fprintf( f, "to: %d\n", follower->id ); - ap_activity_write_to_FILE( accept, f ); - fclose(f); - - rename( tmp_filename, filename ); + ap_activity_save(accept); + + struct outbox_envelope* env = outbox_envelope_new(); + env->activity_id = accept->local_id; + env->account_id = follower->id; + outbox_envelope_save( env ); + outbox_envelope_free( env ); + + // Create notification for follow + struct notification* note = notification_new(); + note->type = nt_follow; + note->account_id = follower->id; + note->created_at = time(NULL); + notification_save( note ); + notification_free( note ); success: res = true; @@ -113,15 +113,33 @@ cleanup: account_free(a); account_free(follower); - exit(0); - return res; failed: res = false; goto cleanup; } -bool route_activity( struct ap_activity* act ) +static bool route_undo_activity( struct ap_activity* act ) +{ + if( act->object.tag != apaot_activity ) { + // Don't undo activities that are references + return false; + } + if( !act->object.ptr ) { + printf( "No object in activity\n" ); + return false; + } + + switch( act->object.ptr->type ) { + case apat_follow: return route_undo_follow( act ); + default: + printf( "Unhandled object activity type %d in undo\n", act->object.ptr->type ); + return false; + }; + + return false; +} +static bool route_activity( struct ap_activity* act ) { switch( act->type ) { case apat_undo: return route_undo_activity(act); @@ -132,7 +150,7 @@ bool route_activity( struct ap_activity* act ) return false; } -bool process_one() +static bool process_one() { // Items requiring cleanup struct ap_activity* act = NULL; @@ -156,9 +174,6 @@ bool process_one() return false; } - // Validate signature - env->validated = http_signature_validate( env, "post /inbox" ); - // Load activity FILE* f = fmemopen( env->body, strlen(env->body), "r" ); act = ap_activity_from_FILE(f); @@ -167,16 +182,19 @@ bool process_one() // Discard delete requests if( act->type == apat_delete ) { step_tail = true; - goto step; + goto discard; } + // Validate signature + env->validated = http_signature_validate( env, "post /inbox" ); + if( !env->validated ) { goto failed; } printf( "Processing %d\n", id ); step_tail = route_activity( act ); finished: - printf( "handled: %c\n", step_tail ? 'T' : 'F' ); + printf( "step_tail=%c\n", step_tail ? 'T' : 'F' ); if( step_tail ) { fs_list_set( "data/inbox/TAIL", id ); result = true; @@ -184,16 +202,17 @@ finished: ap_activity_free(act); ap_envelope_free(env); + printf( "result=%c\n", result ? 'T' : 'F' ); return result; failed: result = false; goto finished; -step: +discard: result = true; goto finished; } -bool cleanup_inbox() +static bool cleanup_inbox() { int tail_pos = fs_list_get("data/inbox/TAIL"); int dead_pos = fs_list_get("data/inbox/DEAD"); @@ -225,15 +244,11 @@ void process_inbox() while( !terminate ) { bool activity = false; activity |= process_one(); - if( !activity ) { - printf( "TODO: unhandled activity\n" ); - exit(1); - } activity |= cleanup_inbox(); if( !activity ) { fflush(stdout); - sleep(10); + sleep(1); } } } diff --git a/src/controller/main.c b/src/controller/main.c index ef43629..ca7ecf7 100644 --- a/src/controller/main.c +++ b/src/controller/main.c @@ -80,6 +80,7 @@ bool route_asset( struct http_request* req ) const char* where; } fs_mounts[] = { { "assets/soapbox", "/" }, + { "data/config/assets", "/" }, { NULL, NULL } }; diff --git a/src/controller/outbox.c b/src/controller/outbox.c index 510480f..35a061a 100644 --- a/src/controller/outbox.c +++ b/src/controller/outbox.c @@ -11,6 +11,7 @@ #include "model/crypto/http_sign.h" #include "model/account.h" #include "model/ap/activity.h" +#include "model/ap/outbox_envelope.h" #include "model/ap/activity/rsa_signature_2017.h" // Stdlib @@ -25,71 +26,37 @@ static bool process_one( int id ) struct crypto_keys* keys = crypto_keys_new(); FILE* f = NULL; struct ap_activity* act = NULL; - ARRAY_OF(char*) inboxes; - memset( &inboxes, 0, sizeof(inboxes) ); - if( !crypto_keys_load_private( keys, "data/owner/private.pem" ) ) { - printf( "Failed to load private key\n" ); - return false; - } - - char buffer[512]; - snprintf( buffer, 512, "data/outbox/%d.json", id ); - f = fopen( buffer, "r" ); - if( !f ) { - printf( "Unable to open file %s\n", buffer ); - goto discard; + // Get next outbox item + struct outbox_envelope* env = outbox_envelope_load_next(); + if( !env ) { + printf( "? No envelope\n" ); + goto failed; } - // TODO: REWORK to no longer have multiple target inboxes + printf( "account_id=%d\n", env->account_id ); + printf( "activity_id=%d\n", env->activity_id ); - char* toline = NULL; - size_t n; - if( -1 == getline( &toline, &n, f ) ) { - printf( "no to line" ); - free(toline); - goto failed; - } + // Get outbox URL + struct account* to_account = account_from_id( env->account_id ); - if( strlen(toline) < 5 ) { - printf( "too short.\n" ); - goto failed; + // Load crypto keys + if( !crypto_keys_load_private( keys, "data/owner/private.pem" ) ) { + printf( "Failed to load private key\n" ); + return false; } - act = ap_activity_from_FILE(f); + // Load target account + act = ap_activity_from_local_id( env->activity_id ); if( !act ) { - printf( "No activity\n" ); - goto failed; - } - f = NULL; - - char* remainder = NULL; - char* iter = strtok_r( &toline[4],",",&remainder); - - do - { - int id; - if( sscanf( iter, "%d", &id ) ) { - int compare( void* a, void* b ) { return strcmp( (char*)a, (char*)b ); } - - struct account* to_account = account_from_id( id ); - if( to_account ) { - if( to_account->inbox ) { - char* item_to_add = strdup(to_account->inbox); - array_append_unique( &inboxes, sizeof(item_to_add), &item_to_add, compare ); - } - account_free(to_account); - } - } - iter = strtok_r( NULL,",",&remainder); - } while( iter ); - free(toline); - - if( inboxes.count > 1 ) { + printf( "! No activity\n" ); goto failed; } + // Create signature ap_activity_create_rsa_signature_2017( act, keys ); + + // Create post data size_t size; { FILE* f2 = open_memstream( &postdata, &size ); @@ -102,19 +69,16 @@ static bool process_one( int id ) postdata[size] = '\0'; printf( "post: %s\n", postdata ); - int i = 0; - const char* inbox = inboxes.items[i]; - printf( "item[%d] = %s\n", i, inbox ); - struct http_signature hs; - if( !http_signature_make( inboxes.items[i], keys, &hs ) ) { + if( !http_signature_make( to_account->inbox, keys, &hs ) ) { goto failed; } - char date_line[512]; - snprintf( date_line, sizeof(date_line), "Date: %s", hs.date ); - char sign_line[512]; - snprintf( sign_line, sizeof(sign_line), "Signature: keyId=\"https://%s/owner/actor\",headers=\"(request-target) host date\",signature=\"%s\"", + char date_header[512]; + snprintf( date_header, sizeof(date_header), "Date: %s", hs.date ); + + char sign_header[512]; + snprintf( sign_header, sizeof(sign_header), "Signature: keyId=\"https://%s/owner/actor#mainKey\",headers=\"(request-target) host date\",signature=\"%s\"", g_server_name, hs.signature ); @@ -124,10 +88,10 @@ static bool process_one( int id ) long status_code = -1; const void* request[] = { - HTTP_REQ_URL, inbox, + HTTP_REQ_URL, to_account->inbox, HTTP_REQ_HEADER, user_agent, - HTTP_REQ_HEADER, date_line, - HTTP_REQ_HEADER, sign_line, + HTTP_REQ_HEADER, date_header, + HTTP_REQ_HEADER, sign_header, HTTP_REQ_HEADER, "Content-Type: application/activity+json", HTTP_REQ_POSTDATA, postdata, HTTP_REQ_RESULT_STATUS, &status_code, @@ -149,10 +113,9 @@ static bool process_one( int id ) goto failed; cleanup: - void release( void* item ) { free( *(char**)item ); } - array_free( &inboxes, sizeof(char*), release ); - ap_activity_free(act); + account_free(to_account); + outbox_envelope_free(env); free(postdata); crypto_keys_free(keys); @@ -177,6 +140,8 @@ void process_outbox() printf( "Done with outbox/%d.json\n", tail ); fs_list_set( "data/outbox/TAIL", tail + 1 ); } + } else { + printf( "? No processing done\n" ); } exit(0); diff --git a/src/controller/owner.c b/src/controller/owner.c index ddbbf6c..f19d81b 100644 --- a/src/controller/owner.c +++ b/src/controller/owner.c @@ -22,13 +22,44 @@ static void write_public_key( FILE* f ) } } +static bool handle_featured( struct http_request* req ) +{ + struct account* owner_account = account_from_id(0); + + http_request_send_headers( req, 200, "application/activity+json", true ); + FILE* f = http_request_get_response_body(req); + #include "src/view/owner/featured.json.inc" + + return true; +} +static bool handle_followers( struct http_request* req ) +{ + struct account* owner_account = account_from_id(0); + + http_request_send_headers( req, 200, "application/activity+json", true ); + FILE* f = http_request_get_response_body(req); + #include "src/view/owner/followers.json.inc" + + return true; +} +static bool handle_following( struct http_request* req ) +{ + struct account* owner_account = account_from_id(0); + + http_request_send_headers( req, 200, "application/activity+json", true ); + FILE* f = http_request_get_response_body(req); + #include "src/view/owner/following.json.inc" + + return true; +} + static bool handle_owner_actor( struct http_request* req ) { struct account* owner_account = account_from_id(0); http_request_send_headers( req, 200, "application/activity+json", true ); FILE* f = http_request_get_response_body(req); - #include "src/view/owner_actor.json.inc" + #include "src/view/owner/actor.json.inc" return true; } @@ -49,16 +80,16 @@ static bool show_owner_profile_page( struct http_request* req ) bool route_owner( struct http_request* req ) { - if( http_request_route_term( req, "/actor" ) ) { - /* - const char* accept = http_request_get_header( req, "Accept" ); - if( 0 == strcmp(accept,"application/ld+json")) { + if( http_request_route( req, "/actor" ) ) { + if( http_request_route_term( req, "" ) ) { return handle_owner_actor(req); + } else if( http_request_route_term( req, "/following" ) ) { + return handle_following(req); + } else if( http_request_route_term( req, "/followers" ) ) { + return handle_followers(req); } - - return show_owner_profile_page(req); - */ - return handle_owner_actor(req); + } else if( http_request_route_term( req, "/collections/featured" ) ) { + return handle_featured(req); } else if( http_request_route_term( req, "" ) ) { return show_owner_profile_page(req); } diff --git a/src/controller/test/crypto.c b/src/controller/test/crypto.c index 4878b82..65f6014 100644 --- a/src/controller/test/crypto.c +++ b/src/controller/test/crypto.c @@ -67,12 +67,49 @@ static bool test_http_signature() return http_signature_validate( &env, "post /foo?param=value&pet=dog" ); } +static bool test_http_signature_2() +{ + struct crypto_keys* keys = crypto_keys_new(); + crypto_keys_load_private( keys, "assets/test.private.pem" ); + + struct http_signature hs; + if( !http_signature_make( "https://example.com/inbox", keys, &hs ) ) { + return false; + } + + char signature_header[512]; + snprintf( signature_header, sizeof(signature_header), "keyId=\"Test\",headers=\"(request-target) host date\",signature=\"%s\"", hs.signature ); + + //printf( "Signature: %s\n", signature_header ); + + struct http_header headers[] = { + { .key = "Host", .value = "example.com" }, + { .key = "Date", .value = hs.date }, + { .key = "Content-Type", .value = "application/json" }, + { .key = "Digest", .value = "SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=" }, + { .key = "Content-Length", .value = "18" }, + { .key = "Signature", .value = signature_header }, + }; + + struct ap_envelope env = { + .when = "1388957500000000000", + .headers = { + .items = headers, + .count = sizeof(headers) / sizeof(headers[0]), + }, + .validated = false, + .body = "{\"hello\": \"world\"}", + }; + + return http_signature_validate( &env, "post /inbox" ); +} bool test_crypto() { bool result = true; if( !test_signatures() ) { printf( "[FAIL] test_signatures()\n" ); return false; } if( !test_http_signature() ) { printf( "[FAIL] test_http_signature()\n" ); return false; } + if( !test_http_signature_2() ) { printf( "[FAIL] test_http_signature_2()\n" ); return false; } return true; } diff --git a/src/http_client b/src/http_client index 4ea04a0..452952b 160000 --- a/src/http_client +++ b/src/http_client @@ -1 +1 @@ -Subproject commit 4ea04a07127532702b142e699d9e6a0c8559cd10 +Subproject commit 452952bdf2befc174e2b342192fd5a2631011985 diff --git a/src/main.c b/src/main.c index 76548c6..3859647 100644 --- a/src/main.c +++ b/src/main.c @@ -76,7 +76,7 @@ int main( int argc, char* argv[] ) int section = 0; sscanf(argv[1],"--section=%d",§ion); switch( section ) { - case 1: process_inbox(); goto exit; + //case 1: process_inbox(); goto exit; case 2: process_outbox(); goto exit; case 3: built_in_test(); goto exit; @@ -84,7 +84,6 @@ int main( int argc, char* argv[] ) } } - /* int inbox_handler_pid = -1; // Process inbox @@ -93,6 +92,7 @@ int main( int argc, char* argv[] ) process_inbox(); } + /* // Process outbox if( !( inbox_handler_pid = fork() ) ) { prctl(PR_SET_PDEATHSIG, SIGHUP); diff --git a/src/model/account.c b/src/model/account.c index 65122ab..212be6f 100644 --- a/src/model/account.c +++ b/src/model/account.c @@ -253,6 +253,16 @@ void account_save( struct account* a ) json_write_object_layout_to_file( filename, "\t", account_layout, a ); } +void account_add_follower( struct account* a, struct account* follower ) +{ + printf( "TODO: implement account_add_follower()\n" ); +} +void account_remove_follower( struct account* a, struct account* follower ) +{ + printf( "TODO: implement account_remove_follower()\n" ); +} + + // TODO: move to controller/view void account_write_as_json( struct account* a, FILE* f ) { diff --git a/src/model/ap/activity.c b/src/model/ap/activity.c index ad05d7d..66de64f 100644 --- a/src/model/ap/activity.c +++ b/src/model/ap/activity.c @@ -109,8 +109,8 @@ void ap_activity_free_composite( struct ap_activity* act ) struct ap_activity* ap_activity_create_accept( struct ap_activity* act ) { - int id = fs_list_get("data/outbox/HEAD") + 1; - fs_list_set( "data/outbox/HEAD", id ); + int id = fs_list_get("data/activities/HEAD") + 1; + fs_list_set( "data/activities/HEAD", id ); char* act_id; asprintf( &act_id,"https://%s/activity/%d", g_server_name, id ); char* actor; asprintf( &actor, "https://%s/owner/actor", g_server_name ); diff --git a/src/model/ap/activity.h b/src/model/ap/activity.h index 78627c8..25a38b8 100644 --- a/src/model/ap/activity.h +++ b/src/model/ap/activity.h @@ -116,10 +116,13 @@ extern struct json_object_field ap_activity_layout[]; struct ap_activity* ap_activity_new(); struct ap_activity* ap_activity_dup( struct ap_activity* act ); struct ap_activity* ap_activity_from_FILE( FILE* f ); +struct ap_activity* ap_activity_from_local_id( int id ); void ap_activity_free( struct ap_activity* act ); void ap_activity_free_composite( struct ap_activity* act ); void ap_activity_write_to_FILE( struct ap_activity* act, FILE* f ); +void ap_activity_save( struct ap_activity* act ); struct ap_activity* ap_activity_create_accept( struct ap_activity* act ); + diff --git a/src/model/ap/activity/context.c b/src/model/ap/activity/context.c index 09d32e2..7be5799 100644 --- a/src/model/ap/activity/context.c +++ b/src/model/ap/activity/context.c @@ -94,6 +94,8 @@ static bool context_writer( struct json_writer* jw, const char* field_name, void printf( "TODO: context_writer, handle array\n" ); exit(1); } + + return true; } struct json_field_type ap_activity_context_type = { diff --git a/src/model/ap/activity/layout.c b/src/model/ap/activity/layout.c index 4ad7726..48f92ff 100644 --- a/src/model/ap/activity/layout.c +++ b/src/model/ap/activity/layout.c @@ -143,4 +143,25 @@ void ap_activity_write_to_FILE( struct ap_activity* act, FILE* f ) }; json_write_pretty_object_layout( &jw, ap_activity_layout, act ); } +void ap_activity_save( struct ap_activity* act ) +{ + char filename[512]; + snprintf( filename, sizeof(filename), "data/activities/%d.json", act->local_id ); + + json_write_object_layout_to_file( filename, "\t", ap_activity_layout, act ); +} +struct ap_activity* ap_activity_from_local_id( int id ) +{ + struct ap_activity* act = ap_activity_new(); + + char filename[512]; + snprintf( filename, sizeof(filename), "data/activities/%d.json", id ); + + if( !json_read_object_layout_from_file( filename, ap_activity_layout, act ) ) { + ap_activity_free(act); + return NULL; + } + + return act; +} diff --git a/src/model/ap/activity/rsa_signature_2017.c b/src/model/ap/activity/rsa_signature_2017.c index b04bcdd..3cacdf3 100644 --- a/src/model/ap/activity/rsa_signature_2017.c +++ b/src/model/ap/activity/rsa_signature_2017.c @@ -17,7 +17,7 @@ #include #include -extern struct rdf_enum_item ap_activity_type_enum[0]; +extern struct rdf_enum_item ap_activity_type_enum[]; static char* type_filter( const char* name ) { char* res; @@ -130,10 +130,7 @@ bool ap_activity_create_rsa_signature_2017( struct ap_activity* act, struct cryp if( !calculate_hash_for_object( ap_activity_rdf, act, &raw_hash[0] ) ) { return NULL; } if( !calculate_hash_for_object( ap_activity_signature_rdf, &act->signature, &raw_hash[32] ) ) { return NULL; } - char hash[32]; - sha256_easy_hash( raw_hash, 64, &hash[0] ); - - char* sign = crypto_keys_sign( keys, &hash[0], 32 ); + char* sign = crypto_keys_sign( keys, raw_hash, 64 ); act->signature.value = sign; act->signature.type = apst_rsa_signature_2017; printf( "act->signature = %s\n", sign ); diff --git a/src/model/ap/outbox_envelope.c b/src/model/ap/outbox_envelope.c new file mode 100644 index 0000000..fcc64c4 --- /dev/null +++ b/src/model/ap/outbox_envelope.c @@ -0,0 +1,70 @@ +#include "outbox_envelope.h" + +#include "json/layout.h" +#include "ffdb/fs_list.h" + +#include +#include +#include +#include + +static struct json_object_field layout[] = { + { "account", offsetof( struct outbox_envelope, account_id ), true, &json_field_integer }, + { "activity", offsetof( struct outbox_envelope, activity_id ), true, &json_field_integer }, + { NULL }, +}; + +struct outbox_envelope* outbox_envelope_new() +{ + struct outbox_envelope* env; + + env = malloc(sizeof(*env)); + if( !env ) { return NULL; } + memset(env,0,sizeof(*env)); +} +void outbox_envelope_free( struct outbox_envelope* env ) +{ + free(env); +} + +void outbox_envelope_save( struct outbox_envelope* env ) +{ + int id = fs_list_get( "data/outbox/HEAD" ) + 1; + fs_list_set( "data/outbox/HEAD", id ); + + char filename[512]; + snprintf( filename, sizeof(filename), "data/outbox/%d.json", id ); + + json_write_object_layout_to_file( filename, "\t", layout, env ); +} + +struct outbox_envelope* outbox_envelope_load_next() +{ + struct outbox_envelope* env; + + if( !( env = outbox_envelope_new()) ) { return NULL; } + + int id = fs_list_get( "data/outbox/TAIL" ) + 1; + env->id = id; + + char filename[512]; + snprintf( filename, sizeof(filename), "data/outbox/%d.json", id ); + + if( !json_read_object_layout_from_file( filename, layout, env ) ) { + outbox_envelope_free( env ); + return NULL; + } + + return env; +} + +void outbox_envelope_delete( struct outbox_envelope* env ) +{ + char filename[512]; + snprintf( filename, sizeof(filename), "data/outbox/%d.json", env->id ); + + remove(filename); + + outbox_envelope_free(env); +} + diff --git a/src/model/ap/outbox_envelope.h b/src/model/ap/outbox_envelope.h new file mode 100644 index 0000000..cffd3b2 --- /dev/null +++ b/src/model/ap/outbox_envelope.h @@ -0,0 +1,17 @@ +#pragma once + +struct outbox_envelope +{ + int id; + int activity_id; + int account_id; +}; + +struct outbox_envelope* outbox_envelope_new(); +void outbox_envelope_free( struct outbox_envelope* env ); + +void outbox_envelope_save( struct outbox_envelope* env ); +struct outbox_envelope* outbox_envelope_load_next(); +void outbox_envelope_delete( struct outbox_envelope* env ); + + diff --git a/src/model/crypto/http_sign.c b/src/model/crypto/http_sign.c index db46f8b..88ea664 100644 --- a/src/model/crypto/http_sign.c +++ b/src/model/crypto/http_sign.c @@ -46,14 +46,12 @@ bool http_signature_make( const char* inbox, struct crypto_keys* keys, struct ht // Build hash line char hash_line[512]; - snprintf( hash_line, 512, "(request-target): post %s\nhost: %s\ndate: %s", path, host, date ); - printf( "hash_line = %s\n", hash_line ); + int size = snprintf( hash_line, 512, "(request-target): post %s\nhost: %s\ndate: %s", path, host, date ); + //printf( "\nbuilding hash_line = %s|\n\n", hash_line ); - // Hash and sign - char hash[32]; - sha256_easy_hash( hash_line, strlen(hash_line), hash ); - sign->signature = crypto_keys_sign( keys, hash, 32 ); - printf( "Signature: %s\n", sign->signature ); + // sign + sign->signature = crypto_keys_sign( keys, hash_line, strlen(hash_line) ); + //printf( "Signature: %s\n", sign->signature ); return true; } @@ -261,9 +259,6 @@ bool http_signature_validate( struct ap_envelope* env, const char* request_targe hash_line[hash_line_size] = '\0'; //printf( "\nhash_line:\n%s|\n\n", hash_line ); - char raw_hash[32]; - sha256_easy_hash( hash_line, hash_line_size, raw_hash ); - //result = crypto_keys_verify( keys, raw_hash, 32, signature ); result = crypto_keys_verify( keys, hash_line, hash_line_size, signature ); if( !result ) { diff --git a/src/model/notification.c b/src/model/notification.c index c0f4d45..08fd4d0 100644 --- a/src/model/notification.c +++ b/src/model/notification.c @@ -48,7 +48,7 @@ struct notification* notification_new() struct notification* note = malloc(sizeof(struct notification)); memset(note,0,sizeof(*note)); note->id = id; - fs_list_set( "data/notices/TAIL", id ); + fs_list_set( "data/notices/HEAD", id ); return note; } diff --git a/src/view/owner_actor.json.template b/src/view/owner/actor.json.template similarity index 96% rename from src/view/owner_actor.json.template rename to src/view/owner/actor.json.template index 248efe4..f75b17f 100644 --- a/src/view/owner_actor.json.template +++ b/src/view/owner/actor.json.template @@ -21,7 +21,7 @@ }, "discoverable":false, "endpoints":{ - "sharedInbox":"https://%s{g_server_name}/inbox", + "sharedInbox":"https://%s{g_server_name}/inbox" }, "featured":"https://%s{g_server_name}/owner/collections/featured", "followers":"https://%s{g_server_name}/owner/followers", diff --git a/src/view/owner/featured.json.template b/src/view/owner/featured.json.template new file mode 100644 index 0000000..4ed7aa3 --- /dev/null +++ b/src/view/owner/featured.json.template @@ -0,0 +1,10 @@ +{ + "@context":[ + "https://www.w3.org/ns/activitystreams", + {"@language":"und"} + ], + "id":"https://%s{g_server_name}/owner/collections/featured", + "orderedItems":[], + "totalItems":0, + "type":"OrderedCollection" +} diff --git a/src/view/owner/followers.json.template b/src/view/owner/followers.json.template new file mode 100644 index 0000000..4e4e5c4 --- /dev/null +++ b/src/view/owner/followers.json.template @@ -0,0 +1,10 @@ +{ + "@context":[ + "https://www.w3.org/ns/activitystreams", + {"@language":"und"} + ], + "orderedItems":[] + "id":"https://%s{g_server_name}/owner/actor/following", + "totalItems":0, + "type":"OrderedCollection" +} diff --git a/src/view/owner/following.json.template b/src/view/owner/following.json.template new file mode 100644 index 0000000..4e4e5c4 --- /dev/null +++ b/src/view/owner/following.json.template @@ -0,0 +1,10 @@ +{ + "@context":[ + "https://www.w3.org/ns/activitystreams", + {"@language":"und"} + ], + "orderedItems":[] + "id":"https://%s{g_server_name}/owner/actor/following", + "totalItems":0, + "type":"OrderedCollection" +}