304 lines
13 KiB
C
304 lines
13 KiB
C
/*
|
|
* Ginxsom Blossom Server Header
|
|
*
|
|
* This header contains all function declarations and type definitions
|
|
* organized by BUD (Blossom Unified Draft) sections.
|
|
*/
|
|
|
|
#ifndef GINXSOM_H
|
|
#define GINXSOM_H
|
|
// Version information (auto-updated by build system)
|
|
#define VERSION_MAJOR 0
|
|
#define VERSION_MINOR 1
|
|
#define VERSION_PATCH 18
|
|
#define VERSION "v0.1.18"
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <time.h>
|
|
#include <fcgi_stdio.h>
|
|
#include <sqlite3.h>
|
|
#include "../nostr_core_lib/cjson/cJSON.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
// BUD 01 - Basic Protocol Flow
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Database connection management
|
|
extern sqlite3* db;
|
|
int init_database(void);
|
|
void close_database(void);
|
|
|
|
// Global configuration variables (defined in main.c)
|
|
extern char g_db_path[4096];
|
|
extern char g_storage_dir[4096];
|
|
|
|
// SHA-256 extraction and validation
|
|
const char* extract_sha256_from_uri(const char* uri);
|
|
|
|
// HEAD request handling
|
|
void handle_head_request(const char* uri);
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
// BUD 02 - Upload & Authentication
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Request validation system - implemented in request_validator.c
|
|
// Functions implemented in src/request_validator.c
|
|
|
|
// NOSTR result constants
|
|
#define NOSTR_SUCCESS 0
|
|
#define NOSTR_ERROR_INVALID_JSON -1
|
|
#define NOSTR_ERROR_MISSING_FIELD -2
|
|
#define NOSTR_ERROR_INVALID_SIGNATURE -3
|
|
#define NOSTR_ERROR_INVALID_PUBKEY -4
|
|
#define NOSTR_ERROR_DATABASE -10
|
|
#define NOSTR_ERROR_UNAUTHORIZED -11
|
|
#define NOSTR_ERROR_MEMORY -12
|
|
|
|
// NIP-42 modes
|
|
typedef enum {
|
|
NIP42_MODE_DISABLED = 0,
|
|
NIP42_MODE_OPTIONAL = 1,
|
|
NIP42_MODE_REQUIRED = 2
|
|
} nip42_mode_t;
|
|
|
|
// Request validation types and enums (matching ginxsom usage)
|
|
typedef struct {
|
|
const char* operation; // Operation type ("upload", "delete", "list", "publish", "admin")
|
|
const char* auth_header; // Raw authorization header (optional)
|
|
cJSON* event; // Parsed NOSTR event for validation (optional)
|
|
const char* resource_hash; // Resource hash (SHA-256, optional)
|
|
const char* mime_type; // MIME type (optional)
|
|
long file_size; // File size (optional)
|
|
const char* relay_url; // Relay URL for NIP-42 validation (optional)
|
|
const char* challenge_id; // Challenge ID for NIP-42 verification (optional)
|
|
int nip42_mode; // NIP-42 mode: 0=disabled, 1=optional, 2=required
|
|
const char* client_ip; // Client IP address (optional)
|
|
void* app_context; // Application context (unused, for compatibility)
|
|
} nostr_request_t;
|
|
|
|
// Extended request structure for unified API
|
|
typedef struct {
|
|
const char* operation; // Operation type ("upload", "delete", "list", "publish", "admin")
|
|
const char* auth_header; // Raw authorization header (optional)
|
|
cJSON* event; // Parsed NOSTR event for validation (optional)
|
|
const char* resource_hash; // Resource hash (SHA-256, optional)
|
|
const char* mime_type; // MIME type (optional)
|
|
long file_size; // File size (optional)
|
|
const char* request_url; // Request URL for NIP-42 relay URL validation (optional)
|
|
const char* challenge_id; // Challenge ID for NIP-42 verification (optional)
|
|
int nip42_enabled; // Whether NIP-42 authentication is enabled
|
|
const char* client_ip; // Client IP address (optional)
|
|
void* app_context; // Application context (unused, for compatibility)
|
|
} nostr_unified_request_t;
|
|
|
|
typedef struct {
|
|
int valid; // 0 = invalid/denied, 1 = valid/allowed
|
|
int error_code; // NOSTR_SUCCESS or specific error code
|
|
char reason[256]; // Human-readable reason for denial/acceptance
|
|
char pubkey[65]; // Extracted pubkey from validated event (if available)
|
|
|
|
// NEW: File data for upload operations (Option 1 implementation)
|
|
unsigned char *file_data; // File content buffer (malloc'd by validator)
|
|
size_t file_size; // Size of file data in bytes
|
|
char expected_hash[65]; // Expected SHA-256 hash from Blossom event
|
|
int owns_file_data; // 1 if validator owns memory, 0 if not
|
|
} nostr_request_result_t;
|
|
|
|
// Challenge structure for NIP-42
|
|
typedef struct {
|
|
char challenge_id[65];
|
|
time_t expires_at;
|
|
} nostr_nip42_challenge_t;
|
|
|
|
// Function declarations for nostr_core_lib functions used by ginxsom
|
|
int nostr_validate_event(cJSON* event);
|
|
int nostr_validate_event_structure(cJSON* event);
|
|
int nostr_verify_event_signature(cJSON* event);
|
|
int nostr_sha256(const unsigned char* data, size_t len, unsigned char* hash);
|
|
void nostr_bytes_to_hex(const unsigned char* bytes, size_t len, char* hex_out);
|
|
int nostr_crypto_init(void);
|
|
|
|
// Unified API function (main entry point)
|
|
int nostr_validate_unified_request(const nostr_unified_request_t* request, nostr_request_result_t* result);
|
|
int ginxsom_request_validator_init(const char* db_path, const char* app_name);
|
|
int nostr_auth_rules_enabled(void);
|
|
void ginxsom_request_validator_cleanup(void);
|
|
void nostr_request_validator_force_cache_refresh(void);
|
|
int nostr_request_validator_generate_nip42_challenge(void* challenge_struct, const char* client_ip);
|
|
|
|
// New NIP-42 challenge management functions
|
|
int nostr_generate_nip42_challenge(char* challenge_out, size_t challenge_size, const char* client_ip);
|
|
const char* nostr_request_validator_get_last_violation_type(void);
|
|
void nostr_request_validator_clear_violation(void);
|
|
|
|
// File data cleanup function
|
|
void nostr_request_result_free_file_data(nostr_request_result_t* result);
|
|
|
|
// Upload handling
|
|
void handle_upload_request(void);
|
|
void handle_upload_request_with_validation(nostr_request_result_t* validation_result);
|
|
|
|
// Blob metadata structure
|
|
typedef struct {
|
|
char sha256[65];
|
|
long size;
|
|
char type[128];
|
|
long uploaded_at;
|
|
char filename[256];
|
|
int found;
|
|
} blob_metadata_t;
|
|
|
|
// Blob metadata database operations
|
|
int insert_blob_metadata(const char* sha256, long size, const char* type,
|
|
long uploaded_at, const char* uploader_pubkey,
|
|
const char* filename);
|
|
int get_blob_metadata(const char* sha256, blob_metadata_t* metadata);
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
// BUD 04 - Mirroring
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Mirror request handling
|
|
void handle_mirror_request(void);
|
|
|
|
// URL validation for mirroring
|
|
int validate_mirror_url(const char* url);
|
|
|
|
// Content type detection for mirrored blobs
|
|
const char* determine_blob_content_type(const char* url, const char* header_content_type,
|
|
const unsigned char* data, size_t size);
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
// BUD 06 - Upload Requirements
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Upload policy management (for future implementation)
|
|
void handle_upload_requirements_request(void);
|
|
|
|
// BUD-06 specific functions
|
|
void handle_head_upload_request(void);
|
|
int validate_upload_headers(const char** sha256, const char** content_type,
|
|
long* content_length, char* error_reason, size_t reason_size);
|
|
void send_upload_error_response(int status_code, const char* error_type,
|
|
const char* message, const char* x_reason);
|
|
void send_upload_success_response(const char* sha256, const char* content_type, long content_length);
|
|
int validate_content_length(const char* content_length_str, long* parsed_length);
|
|
int check_blob_exists(const char* sha256);
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
// BUD 09 - Blob Report (NIP-56 Report Events)
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Report event validation
|
|
int validate_report_event_structure(cJSON* event);
|
|
int extract_blob_hashes_from_report(cJSON* event, char blob_hashes[][65], int max_hashes);
|
|
int validate_report_types(cJSON* event);
|
|
|
|
// Report storage and handling
|
|
int store_blob_report(const char* event_json, const char* reporter_pubkey);
|
|
void handle_report_request(void);
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
// BUD 08 - NIP-94 File Metadata Tags
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// NIP-94 configuration and control
|
|
int nip94_is_enabled(void);
|
|
int nip94_get_origin(char* out, size_t out_size);
|
|
|
|
// MIME type and file extension handling
|
|
const char* mime_to_extension(const char* mime_type);
|
|
void nip94_build_blob_url(const char* origin, const char* sha256, const char* mime_type, char* out, size_t out_size);
|
|
|
|
// Image dimension parsing
|
|
int parse_png_dimensions(const unsigned char* data, size_t size, int* width, int* height);
|
|
int parse_jpeg_dimensions(const unsigned char* data, size_t size, int* width, int* height);
|
|
int parse_webp_dimensions(const unsigned char* data, size_t size, int* width, int* height);
|
|
int nip94_get_dimensions(const unsigned char* data, size_t size, const char* mime_type, int* width, int* height);
|
|
|
|
// NIP-94 metadata emission
|
|
void nip94_emit_field(const char* url, const char* mime, const char* sha256, long size, int width, int height);
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
// UTILITY FUNCTIONS
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// HTTP response helpers
|
|
void send_error_response(int status_code, const char* error_type, const char* message, const char* details);
|
|
void send_json_response(int status_code, const char* json_content);
|
|
|
|
// Logging utilities
|
|
void log_request(const char* method, const char* uri, const char* auth_status, int status_code);
|
|
|
|
// Centralized application logging (writes to logs/app/app.log)
|
|
typedef enum {
|
|
LOG_DEBUG = 0,
|
|
LOG_INFO = 1,
|
|
LOG_WARN = 2,
|
|
LOG_ERROR = 3
|
|
} log_level_t;
|
|
|
|
void app_log(log_level_t level, const char* format, ...);
|
|
|
|
// SHA-256 validation helper (used by multiple BUDs)
|
|
int validate_sha256_format(const char* sha256);
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
// ADMIN API ENDPOINTS
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Admin API request handler
|
|
void handle_admin_api_request(const char* method, const char* uri, const char* validated_pubkey, int is_authenticated);
|
|
|
|
// Admin event handler (Kind 23458/23459)
|
|
void handle_admin_event_request(void);
|
|
|
|
// Admin interface handler (serves embedded web UI)
|
|
void handle_admin_interface_request(const char* path);
|
|
|
|
// Individual endpoint handlers
|
|
void handle_stats_api(void);
|
|
void handle_config_get_api(void);
|
|
void handle_config_put_api(void);
|
|
void handle_config_key_put_api(const char* key);
|
|
void handle_files_api(void);
|
|
void handle_health_api(void);
|
|
|
|
// Admin authentication functions
|
|
int authenticate_admin_request(const char* auth_header);
|
|
int is_admin_enabled(void);
|
|
int verify_admin_pubkey(const char* event_pubkey);
|
|
|
|
// Admin API utility functions
|
|
void send_json_response(int status, const char* json_content);
|
|
void send_json_error(int status, const char* error, const char* message);
|
|
int parse_query_params(const char* query_string, char params[][256], int max_params);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif // GINXSOM_H
|