v0.1.7 - Fixing black and white lists

This commit is contained in:
Your Name
2025-11-13 10:21:26 -04:00
parent 533c7f29f2
commit 455aab1eac
29 changed files with 1070 additions and 10 deletions

View File

@@ -10,8 +10,8 @@
// Version information (auto-updated by build system)
#define VERSION_MAJOR 0
#define VERSION_MINOR 1
#define VERSION_PATCH 6
#define VERSION "v0.1.6"
#define VERSION_PATCH 7
#define VERSION "v0.1.7"
#include <stddef.h>
#include <stdint.h>

View File

@@ -1508,6 +1508,20 @@ if (!config_loaded /* && !initialize_server_config() */) {
// For other operations, validation failure means auth failure
const char *message = result.reason[0] ? result.reason : "Authentication failed";
const char *details = "Authentication validation failed";
// Determine appropriate status code based on violation type
int status_code = 401; // Default: Unauthorized (no auth or invalid auth)
const char *violation_type = nostr_request_validator_get_last_violation_type();
// If auth rules denied the request, use 403 Forbidden instead of 401 Unauthorized
if (violation_type && (
strcmp(violation_type, "pubkey_blacklist") == 0 ||
strcmp(violation_type, "hash_blacklist") == 0 ||
strcmp(violation_type, "whitelist_violation") == 0 ||
strcmp(violation_type, "mime_blacklist") == 0 ||
strcmp(violation_type, "mime_whitelist_violation") == 0)) {
status_code = 403; // Forbidden: authenticated but not authorized
}
// Always include event JSON in details when auth header is provided for debugging
if (auth_header) {
@@ -1526,8 +1540,8 @@ if (!config_loaded /* && !initialize_server_config() */) {
}
}
send_error_response(401, "authentication_failed", message, details);
log_request(request_method, request_uri, "auth_failed", 401);
send_error_response(status_code, "authentication_failed", message, details);
log_request(request_method, request_uri, "auth_failed", status_code);
continue;
}
}

View File

@@ -810,8 +810,17 @@ int nostr_validate_unified_request(const nostr_unified_request_t *request,
"checking database rules\n");
// Check database rules for authorization
// For Blossom uploads, use hash from event 'x' tag instead of URI
const char *hash_for_rules = request->resource_hash;
if (event_kind == 24242 && strlen(expected_hash_from_event) == 64) {
hash_for_rules = expected_hash_from_event;
char hash_msg[256];
sprintf(hash_msg, "VALIDATOR_DEBUG: Using hash from Blossom event for rules: %.16s...\n", hash_for_rules);
validator_debug_log(hash_msg);
}
int rules_result = check_database_auth_rules(
extracted_pubkey, request->operation, request->resource_hash);
extracted_pubkey, request->operation, hash_for_rules);
if (rules_result != NOSTR_SUCCESS) {
validator_debug_log(
"VALIDATOR_DEBUG: STEP 14 FAILED - Database rules denied request\n");
@@ -1334,9 +1343,10 @@ static int check_database_auth_rules(const char *pubkey, const char *operation,
}
// Step 1: Check pubkey blacklist (highest priority)
// Match both exact operation and wildcard '*'
const char *blacklist_sql =
"SELECT rule_type, description FROM auth_rules WHERE rule_type = "
"'pubkey_blacklist' AND rule_target = ? AND operation = ? AND enabled = "
"'pubkey_blacklist' AND rule_target = ? AND (operation = ? OR operation = '*') AND enabled = "
"1 ORDER BY priority LIMIT 1";
rc = sqlite3_prepare_v2(db, blacklist_sql, -1, &stmt, NULL);
if (rc == SQLITE_OK) {
@@ -1369,9 +1379,10 @@ static int check_database_auth_rules(const char *pubkey, const char *operation,
// Step 2: Check hash blacklist
if (resource_hash) {
// Match both exact operation and wildcard '*'
const char *hash_blacklist_sql =
"SELECT rule_type, description FROM auth_rules WHERE rule_type = "
"'hash_blacklist' AND rule_target = ? AND operation = ? AND enabled = "
"'hash_blacklist' AND rule_target = ? AND (operation = ? OR operation = '*') AND enabled = "
"1 ORDER BY priority LIMIT 1";
rc = sqlite3_prepare_v2(db, hash_blacklist_sql, -1, &stmt, NULL);
if (rc == SQLITE_OK) {
@@ -1408,9 +1419,10 @@ static int check_database_auth_rules(const char *pubkey, const char *operation,
}
// Step 3: Check pubkey whitelist
// Match both exact operation and wildcard '*'
const char *whitelist_sql =
"SELECT rule_type, description FROM auth_rules WHERE rule_type = "
"'pubkey_whitelist' AND rule_target = ? AND operation = ? AND enabled = "
"'pubkey_whitelist' AND rule_target = ? AND (operation = ? OR operation = '*') AND enabled = "
"1 ORDER BY priority LIMIT 1";
rc = sqlite3_prepare_v2(db, whitelist_sql, -1, &stmt, NULL);
if (rc == SQLITE_OK) {
@@ -1436,9 +1448,10 @@ static int check_database_auth_rules(const char *pubkey, const char *operation,
"not whitelisted\n");
// Step 4: Check if any whitelist rules exist - if yes, deny by default
// Match both exact operation and wildcard '*'
const char *whitelist_exists_sql =
"SELECT COUNT(*) FROM auth_rules WHERE rule_type = 'pubkey_whitelist' "
"AND operation = ? AND enabled = 1 LIMIT 1";
"AND (operation = ? OR operation = '*') AND enabled = 1 LIMIT 1";
rc = sqlite3_prepare_v2(db, whitelist_exists_sql, -1, &stmt, NULL);
if (rc == SQLITE_OK) {
sqlite3_bind_text(stmt, 1, operation ? operation : "", -1, SQLITE_STATIC);