Working on API
This commit is contained in:
197
src/main.c
197
src/main.c
@@ -228,7 +228,10 @@ int nostr_validate_unified_request(const char* json_string, size_t json_length);
|
||||
int handle_configuration_event(cJSON* event, char* error_message, size_t error_size);
|
||||
|
||||
// Forward declaration for admin event processing (kinds 33334 and 33335)
|
||||
int process_admin_event_in_config(cJSON* event, char* error_message, size_t error_size);
|
||||
int process_admin_event_in_config(cJSON* event, char* error_message, size_t error_size, struct lws* wsi);
|
||||
|
||||
// Forward declaration for enhanced admin event authorization
|
||||
int is_authorized_admin_event(cJSON* event, char* error_message, size_t error_size);
|
||||
|
||||
// Forward declaration for NOTICE message support
|
||||
void send_notice_message(struct lws* wsi, const char* message);
|
||||
@@ -3009,6 +3012,109 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru
|
||||
|
||||
return events_sent;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// ADMIN EVENT AUTHORIZATION
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Enhanced admin event authorization function
|
||||
int is_authorized_admin_event(cJSON* event, char* error_buffer, size_t error_buffer_size) {
|
||||
if (!event || !error_buffer) {
|
||||
if (error_buffer && error_buffer_size > 0) {
|
||||
snprintf(error_buffer, error_buffer_size, "Invalid parameters for admin authorization");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Step 1: Verify event kind is admin type
|
||||
cJSON *kind_json = cJSON_GetObjectItem(event, "kind");
|
||||
if (!kind_json || !cJSON_IsNumber(kind_json)) {
|
||||
snprintf(error_buffer, error_buffer_size, "Missing or invalid event kind");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int event_kind = kind_json->valueint;
|
||||
if (event_kind != 33334 && event_kind != 33335 && event_kind != 23455 && event_kind != 23456) {
|
||||
snprintf(error_buffer, error_buffer_size, "Event kind %d is not an admin event type", event_kind);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Step 2: Check if event targets this relay (look for 'p' tag with our relay pubkey)
|
||||
cJSON *tags = cJSON_GetObjectItem(event, "tags");
|
||||
if (!tags || !cJSON_IsArray(tags)) {
|
||||
// No tags array - treat as regular event for different relay
|
||||
log_info("Admin event has no tags array - treating as event for different relay");
|
||||
snprintf(error_buffer, error_buffer_size, "Admin event not targeting this relay (no tags)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int targets_this_relay = 0;
|
||||
cJSON *tag;
|
||||
cJSON_ArrayForEach(tag, tags) {
|
||||
if (cJSON_IsArray(tag)) {
|
||||
cJSON *tag_name = cJSON_GetArrayItem(tag, 0);
|
||||
cJSON *tag_value = cJSON_GetArrayItem(tag, 1);
|
||||
|
||||
if (tag_name && cJSON_IsString(tag_name) &&
|
||||
tag_value && cJSON_IsString(tag_value) &&
|
||||
strcmp(tag_name->valuestring, "p") == 0) {
|
||||
|
||||
// Compare with our relay pubkey
|
||||
const char* relay_pubkey = get_config_value("relay_pubkey");
|
||||
if (relay_pubkey && strcmp(tag_value->valuestring, relay_pubkey) == 0) {
|
||||
targets_this_relay = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!targets_this_relay) {
|
||||
// Admin event for different relay - not an error, just not for us
|
||||
log_info("Admin event targets different relay - treating as regular event");
|
||||
snprintf(error_buffer, error_buffer_size, "Admin event not targeting this relay");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Step 3: Verify admin signature authorization
|
||||
cJSON *pubkey_json = cJSON_GetObjectItem(event, "pubkey");
|
||||
if (!pubkey_json || !cJSON_IsString(pubkey_json)) {
|
||||
log_warning("Unauthorized admin event attempt: missing or invalid pubkey");
|
||||
snprintf(error_buffer, error_buffer_size, "Unauthorized admin event attempt: missing pubkey");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get admin pubkey from configuration
|
||||
const char* admin_pubkey = get_config_value("admin_pubkey");
|
||||
if (!admin_pubkey || strlen(admin_pubkey) == 0) {
|
||||
log_warning("Unauthorized admin event attempt: no admin pubkey configured");
|
||||
snprintf(error_buffer, error_buffer_size, "Unauthorized admin event attempt: no admin configured");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Compare pubkeys
|
||||
if (strcmp(pubkey_json->valuestring, admin_pubkey) != 0) {
|
||||
log_warning("Unauthorized admin event attempt: pubkey mismatch");
|
||||
char warning_msg[256];
|
||||
snprintf(warning_msg, sizeof(warning_msg),
|
||||
"Unauthorized admin event attempt from pubkey: %.32s...", pubkey_json->valuestring);
|
||||
log_warning(warning_msg);
|
||||
snprintf(error_buffer, error_buffer_size, "Unauthorized admin event attempt: invalid admin pubkey");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Step 4: Verify event signature
|
||||
if (nostr_verify_event_signature(event) != 0) {
|
||||
log_warning("Unauthorized admin event attempt: invalid signature");
|
||||
snprintf(error_buffer, error_buffer_size, "Unauthorized admin event attempt: signature verification failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// All checks passed - authorized admin event
|
||||
log_info("Admin event authorization successful");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3266,47 +3372,68 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso
|
||||
}
|
||||
|
||||
if (event_kind == 33334 || event_kind == 33335 || event_kind == 23455 || event_kind == 23456) {
|
||||
// This is an admin event - process it through the admin API instead of normal storage
|
||||
log_info("DEBUG ADMIN: Admin event detected, processing through admin API");
|
||||
// Enhanced admin event security - check authorization first
|
||||
log_info("DEBUG ADMIN: Admin event detected, checking authorization");
|
||||
|
||||
char admin_error[512] = {0};
|
||||
int admin_result = process_admin_event_in_config(event, admin_error, sizeof(admin_error));
|
||||
char auth_error[512] = {0};
|
||||
int auth_result = is_authorized_admin_event(event, auth_error, sizeof(auth_error));
|
||||
|
||||
char debug_admin_msg[256];
|
||||
snprintf(debug_admin_msg, sizeof(debug_admin_msg),
|
||||
"DEBUG ADMIN: process_admin_event_in_config returned %d", admin_result);
|
||||
log_info(debug_admin_msg);
|
||||
|
||||
// Log results for Kind 23455 and 23456 events
|
||||
if (event_kind == 23455 || event_kind == 23456) {
|
||||
if (admin_result == 0) {
|
||||
char success_result_msg[256];
|
||||
snprintf(success_result_msg, sizeof(success_result_msg),
|
||||
"SUCCESS: Kind %d event processed successfully", event_kind);
|
||||
log_success(success_result_msg);
|
||||
} else {
|
||||
char error_result_msg[512];
|
||||
snprintf(error_result_msg, sizeof(error_result_msg),
|
||||
"ERROR: Kind %d event processing failed: %s", event_kind, admin_error);
|
||||
log_error(error_result_msg);
|
||||
}
|
||||
}
|
||||
|
||||
if (admin_result != 0) {
|
||||
log_error("DEBUG ADMIN: Failed to process admin event through admin API");
|
||||
if (auth_result != 0) {
|
||||
// Authorization failed - log and reject
|
||||
log_warning("DEBUG ADMIN: Admin event authorization failed");
|
||||
result = -1;
|
||||
size_t error_len = strlen(admin_error);
|
||||
size_t error_len = strlen(auth_error);
|
||||
size_t copy_len = (error_len < sizeof(error_message) - 1) ? error_len : sizeof(error_message) - 1;
|
||||
memcpy(error_message, admin_error, copy_len);
|
||||
memcpy(error_message, auth_error, copy_len);
|
||||
error_message[copy_len] = '\0';
|
||||
|
||||
char debug_admin_error_msg[600];
|
||||
snprintf(debug_admin_error_msg, sizeof(debug_admin_error_msg),
|
||||
"DEBUG ADMIN ERROR: %.400s", admin_error);
|
||||
log_error(debug_admin_error_msg);
|
||||
char debug_auth_error_msg[600];
|
||||
snprintf(debug_auth_error_msg, sizeof(debug_auth_error_msg),
|
||||
"DEBUG ADMIN AUTH ERROR: %.400s", auth_error);
|
||||
log_warning(debug_auth_error_msg);
|
||||
} else {
|
||||
log_success("DEBUG ADMIN: Admin event processed successfully through admin API");
|
||||
// Admin events are processed by the admin API, not broadcast to subscriptions
|
||||
// Authorization successful - process through admin API
|
||||
log_info("DEBUG ADMIN: Admin event authorized, processing through admin API");
|
||||
|
||||
char admin_error[512] = {0};
|
||||
int admin_result = process_admin_event_in_config(event, admin_error, sizeof(admin_error), wsi);
|
||||
|
||||
char debug_admin_msg[256];
|
||||
snprintf(debug_admin_msg, sizeof(debug_admin_msg),
|
||||
"DEBUG ADMIN: process_admin_event_in_config returned %d", admin_result);
|
||||
log_info(debug_admin_msg);
|
||||
|
||||
// Log results for Kind 23455 and 23456 events
|
||||
if (event_kind == 23455 || event_kind == 23456) {
|
||||
if (admin_result == 0) {
|
||||
char success_result_msg[256];
|
||||
snprintf(success_result_msg, sizeof(success_result_msg),
|
||||
"SUCCESS: Kind %d event processed successfully", event_kind);
|
||||
log_success(success_result_msg);
|
||||
} else {
|
||||
char error_result_msg[512];
|
||||
snprintf(error_result_msg, sizeof(error_result_msg),
|
||||
"ERROR: Kind %d event processing failed: %s", event_kind, admin_error);
|
||||
log_error(error_result_msg);
|
||||
}
|
||||
}
|
||||
|
||||
if (admin_result != 0) {
|
||||
log_error("DEBUG ADMIN: Failed to process admin event through admin API");
|
||||
result = -1;
|
||||
size_t error_len = strlen(admin_error);
|
||||
size_t copy_len = (error_len < sizeof(error_message) - 1) ? error_len : sizeof(error_message) - 1;
|
||||
memcpy(error_message, admin_error, copy_len);
|
||||
error_message[copy_len] = '\0';
|
||||
|
||||
char debug_admin_error_msg[600];
|
||||
snprintf(debug_admin_error_msg, sizeof(debug_admin_error_msg),
|
||||
"DEBUG ADMIN ERROR: %.400s", admin_error);
|
||||
log_error(debug_admin_error_msg);
|
||||
} else {
|
||||
log_success("DEBUG ADMIN: Admin event processed successfully through admin API");
|
||||
// Admin events are processed by the admin API, not broadcast to subscriptions
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Regular event - store in database and broadcast
|
||||
|
||||
Reference in New Issue
Block a user