From e693fe3caaecc211e6b8e58bdf6e1f70d23c9a74 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 20 Nov 2025 07:53:58 -0400 Subject: [PATCH] v0.1.9 - program generates it's own private keys. --- .gitignore | 1 + .admin_keys => .test_keys | 4 +- Makefile | 2 +- Trash/Ginxsom_Management_System_Design.md | 1389 +++++++++++++++++++++ build/admin_auth.o | Bin 0 -> 16464 bytes build/admin_handlers.o | Bin 0 -> 10376 bytes build/admin_websocket.o | Bin 0 -> 8336 bytes build/ginxsom-fcgi | Bin 249360 -> 280352 bytes build/main.o | Bin 76264 -> 99136 bytes build/request_validator.o | Bin 65608 -> 66008 bytes config/local-nginx.conf | 2 +- db/ginxsom.db | Bin 151552 -> 73728 bytes db/migrations/002_add_relay_seckey.sql | 15 + deploy_lt.sh | 59 +- docs/MANAGEMENT_SYSTEM_DESIGN.md | 994 +++++++++++++++ remote.nginx.config | 20 +- restart-all.sh | 78 +- src/admin_auth.c | 509 ++++++++ src/admin_handlers.c | 216 ++++ src/admin_websocket.c | 163 +++ src/ginxsom.h | 4 +- src/main.c | 639 +++++++++- src/request_validator.c | 10 + src/test_keygen.c | 199 +++ src/test_main.c | 50 + test_blob_1762770636.txt | 7 - test_file.txt | 1 - test_key_generation.sh | 25 + test_mode_verification.sh | 54 + tests/auth_test.sh | 6 +- tests/auth_test_tmp/nip42_challenge | 2 +- tests/file_put_bud02.sh | 17 +- tests/file_put_production.sh | 13 +- tests/list_test_bud02.sh | 191 ++- tests/white_black_list_test.sh | 6 +- update_remote_nginx_conf.sh | 54 + 36 files changed, 4542 insertions(+), 188 deletions(-) rename .admin_keys => .test_keys (50%) create mode 100644 Trash/Ginxsom_Management_System_Design.md create mode 100644 build/admin_auth.o create mode 100644 build/admin_handlers.o create mode 100644 build/admin_websocket.o create mode 100644 db/migrations/002_add_relay_seckey.sql create mode 100644 docs/MANAGEMENT_SYSTEM_DESIGN.md create mode 100644 src/admin_auth.c create mode 100644 src/admin_handlers.c create mode 100644 src/admin_websocket.c create mode 100644 src/test_keygen.c create mode 100644 src/test_main.c delete mode 100644 test_blob_1762770636.txt delete mode 100644 test_file.txt create mode 100755 test_key_generation.sh create mode 100755 test_mode_verification.sh create mode 100755 update_remote_nginx_conf.sh diff --git a/.gitignore b/.gitignore index 12d5b12..d108a66 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ blossom/ logs/ nostr_core_lib/ blobs/ +c-relay/ diff --git a/.admin_keys b/.test_keys similarity index 50% rename from .admin_keys rename to .test_keys index bcd7d85..ccbe9a6 100644 --- a/.admin_keys +++ b/.test_keys @@ -1,4 +1,4 @@ -ADMIN_PRIVKEY='31d3fd4bb38f4f6b60fb66e0a2e5063703bb3394579ce820d5aaf3773b96633f' -ADMIN_PUBKEY='bd109762a8185716ec0fe0f887e911c30d40e36cf7b6bb99f6eef3301e9f6f99' +ADMIN_PRIVKEY='22cc83aa57928a2800234c939240c9a6f0f44a33ea3838a860ed38930b195afd' +ADMIN_PUBKEY='8ff74724ed641b3c28e5a86d7c5cbc49c37638ace8c6c38935860e7a5eedde0e' SERVER_PRIVKEY='c4e0d2ed7d36277d6698650f68a6e9199f91f3abb476a67f07303e81309c48f1' SERVER_PUBKEY='52e366edfa4e9cc6a6d4653828e51ccf828a2f5a05227d7a768f33b5a198681a' diff --git a/Makefile b/Makefile index b15e80a..6973bed 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ BUILDDIR = build TARGET = $(BUILDDIR)/ginxsom-fcgi # Source files -SOURCES = $(SRCDIR)/main.c $(SRCDIR)/admin_api.c $(SRCDIR)/bud04.c $(SRCDIR)/bud06.c $(SRCDIR)/bud08.c $(SRCDIR)/bud09.c $(SRCDIR)/request_validator.c +SOURCES = $(SRCDIR)/main.c $(SRCDIR)/admin_api.c $(SRCDIR)/admin_auth.c $(SRCDIR)/admin_websocket.c $(SRCDIR)/admin_handlers.c $(SRCDIR)/bud04.c $(SRCDIR)/bud06.c $(SRCDIR)/bud08.c $(SRCDIR)/bud09.c $(SRCDIR)/request_validator.c OBJECTS = $(SOURCES:$(SRCDIR)/%.c=$(BUILDDIR)/%.o) # Default target diff --git a/Trash/Ginxsom_Management_System_Design.md b/Trash/Ginxsom_Management_System_Design.md new file mode 100644 index 0000000..84353af --- /dev/null +++ b/Trash/Ginxsom_Management_System_Design.md @@ -0,0 +1,1389 @@ +# Ginxsom Management System Design + +## Executive Summary + +This document outlines the design for a secure management interface for ginxsom, a Blossom media storage server. The design adapts proven patterns from c-relay's management system while addressing ginxsom's specific requirements for blob storage, authentication, and FastCGI architecture. + +**Key Design Principles:** +- **Security First**: NIP-17 gift wrap encryption for all admin commands +- **Database-Centric**: Configuration and state stored in SQLite +- **Unified Handler**: Tag-based routing similar to c-relay +- **Two-Step Confirmation**: Critical operations require explicit confirmation +- **Backwards Compatible**: Integrates with existing admin API without breaking changes + +--- + +## Table of Contents + +1. [System Architecture](#1-system-architecture) +2. [Database Schema](#2-database-schema) +3. [Keypair Management](#3-keypair-management) +4. [Authentication Architecture](#4-authentication-architecture) +5. [Management Commands](#5-management-commands) +6. [API Design](#6-api-design) +7. [File Structure](#7-file-structure) +8. [Implementation Plan](#8-implementation-plan) +9. [Security Considerations](#9-security-considerations) +10. [Migration Strategy](#10-migration-strategy) + +--- + +## 1. System Architecture + +### 1.1 Component Overview + +```mermaid +flowchart TB + subgraph Client["Admin Client"] + CLI[CLI Tool / nak] + WEB[Web Interface] + end + + subgraph Gateway["nginx Gateway"] + NGINX[nginx] + end + + subgraph FastCGI["FastCGI Application"] + MAIN[main.c] + VALIDATOR[request_validator.c] + ADMIN[admin_api.c] + MGMT[management_handler.c
NEW] + DM[dm_admin.c
NEW] + end + + subgraph Storage["Data Layer"] + DB[(SQLite Database)] + BLOBS[Blob Storage] + KEYS[Key Storage
Memory Only] + end + + CLI -->|NIP-17 Gift Wrap| NGINX + WEB -->|NIP-17 Gift Wrap| NGINX + NGINX -->|FastCGI| MAIN + MAIN --> VALIDATOR + VALIDATOR --> ADMIN + ADMIN --> MGMT + MGMT --> DM + DM --> DB + DM --> KEYS + MGMT --> BLOBS + + style MGMT fill:#ff9 + style DM fill:#ff9 + style KEYS fill:#f99 +``` + +### 1.2 Data Flow for Admin Commands + +```mermaid +sequenceDiagram + participant Admin + participant nginx + participant FastCGI + participant Validator + participant DM Handler + participant Database + + Admin->>nginx: POST /admin
NIP-17 Gift Wrap + nginx->>FastCGI: Forward Request + FastCGI->>Validator: Validate Auth + Validator->>Validator: Decrypt Gift Wrap + Validator->>Validator: Verify Admin Pubkey + Validator-->>FastCGI: Auth Result + + alt Auth Failed + FastCGI-->>Admin: 401/403 Error + else Auth Success + FastCGI->>DM Handler: Parse Command + DM Handler->>DM Handler: Extract Tags + DM Handler->>DM Handler: Route to Handler + + alt Critical Operation + DM Handler->>Database: Store Pending Change + DM Handler-->>Admin: Confirmation Required + Admin->>nginx: POST /admin
Confirmation Event + nginx->>FastCGI: Forward Confirmation + FastCGI->>DM Handler: Execute Pending + DM Handler->>Database: Apply Changes + else Non-Critical + DM Handler->>Database: Execute Directly + end + + DM Handler->>DM Handler: Encrypt Response (NIP-44) + DM Handler-->>Admin: Encrypted Result + end +``` + +### 1.3 Integration with Existing System + +The management system integrates with ginxsom's existing architecture: + +**Existing Components (Keep):** +- [`src/main.c`](src/main.c:1): FastCGI request loop and routing +- [`src/request_validator.c`](src/request_validator.c:1): Centralized authentication +- [`src/admin_api.c`](src/admin_api.c:1): Current admin API endpoints +- [`db/schema.sql`](db/schema.sql:1): Base database schema + +**New Components (Add):** +- `src/management_handler.c`: Unified command handler +- `src/dm_admin.c`: NIP-17 gift wrap processing +- `src/keypair_manager.c`: Server and admin key management +- `src/pending_changes.c`: Two-step confirmation system + +**Modified Components:** +- [`src/main.c`](src/main.c:1640): Add `/admin` endpoint routing +- [`src/request_validator.c`](src/request_validator.c:683): Add NIP-17 validation +- [`db/schema.sql`](db/schema.sql:1): Add management tables + +--- + +## 2. Database Schema + +### 2.1 New Tables + +```sql +-- Server keypair (relay identity) +CREATE TABLE IF NOT EXISTS server_keys ( + id INTEGER PRIMARY KEY CHECK (id = 1), -- Singleton table + public_key TEXT NOT NULL CHECK (length(public_key) = 64), + private_key_encrypted TEXT NOT NULL, -- Encrypted with system key + created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')), + last_rotated INTEGER, + UNIQUE(public_key) +); + +-- Admin public keys (authorized administrators) +CREATE TABLE IF NOT EXISTS admin_keys ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + public_key TEXT NOT NULL UNIQUE CHECK (length(public_key) = 64), + name TEXT, -- Human-readable identifier + permissions TEXT NOT NULL DEFAULT 'full', -- JSON array of permissions + created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')), + created_by TEXT, -- Admin pubkey who added this key + last_used INTEGER, + enabled INTEGER NOT NULL DEFAULT 1 CHECK (enabled IN (0, 1)) +); + +-- Pending changes requiring confirmation +CREATE TABLE IF NOT EXISTS pending_changes ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + change_type TEXT NOT NULL, -- 'delete_blob', 'update_config', 'add_admin', etc. + change_data TEXT NOT NULL, -- JSON with change details + requested_by TEXT NOT NULL, -- Admin pubkey + requested_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')), + expires_at INTEGER NOT NULL, -- Confirmation deadline + confirmed INTEGER NOT NULL DEFAULT 0 CHECK (confirmed IN (0, 1)), + confirmed_at INTEGER, + executed INTEGER NOT NULL DEFAULT 0 CHECK (executed IN (0, 1)), + executed_at INTEGER, + result TEXT -- Execution result or error +); + +-- Admin command audit log +CREATE TABLE IF NOT EXISTS admin_audit_log ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + admin_pubkey TEXT NOT NULL, + command TEXT NOT NULL, -- Command tag from event + parameters TEXT, -- JSON with command parameters + success INTEGER NOT NULL CHECK (success IN (0, 1)), + error_message TEXT, + timestamp INTEGER NOT NULL DEFAULT (strftime('%s', 'now')), + client_ip TEXT, + event_id TEXT -- Nostr event ID for traceability +); + +-- NIP-17 gift wrap tracking (prevent replay) +CREATE TABLE IF NOT EXISTS gift_wrap_tracking ( + event_id TEXT PRIMARY KEY, + admin_pubkey TEXT NOT NULL, + processed_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')), + expires_at INTEGER NOT NULL +); + +-- Create indexes for performance +CREATE INDEX IF NOT EXISTS idx_admin_keys_pubkey ON admin_keys(public_key); +CREATE INDEX IF NOT EXISTS idx_admin_keys_enabled ON admin_keys(enabled); +CREATE INDEX IF NOT EXISTS idx_pending_changes_expires ON pending_changes(expires_at); +CREATE INDEX IF NOT EXISTS idx_pending_changes_requested_by ON pending_changes(requested_by); +CREATE INDEX IF NOT EXISTS idx_audit_log_timestamp ON admin_audit_log(timestamp); +CREATE INDEX IF NOT EXISTS idx_audit_log_admin ON admin_audit_log(admin_pubkey); +CREATE INDEX IF NOT EXISTS idx_gift_wrap_expires ON gift_wrap_tracking(expires_at); +``` + +### 2.2 Schema Extensions to Existing Tables + +```sql +-- Add management-related config keys +INSERT OR IGNORE INTO config (key, value, description) VALUES + ('server_pubkey', '', 'Server public key (relay identity)'), + ('admin_dm_enabled', 'true', 'Enable NIP-17 DM-based admin commands'), + ('admin_confirmation_timeout', '300', 'Seconds to confirm critical operations'), + ('admin_session_timeout', '3600', 'Admin session timeout in seconds'), + ('admin_rate_limit', '100', 'Max admin commands per hour per admin'), + ('admin_audit_retention', '2592000', 'Audit log retention in seconds (30 days)'); +``` + +### 2.3 Migration from Current Schema + +The current schema already has: +- [`config`](db/schema.sql:21) table (unified configuration) +- [`blobs`](db/schema.sql:8) table (blob metadata) +- [`auth_rules`](db/schema.sql:47) table (authentication rules) + +**Migration Strategy:** +1. Add new tables without modifying existing ones +2. Populate `admin_keys` from existing `config.admin_pubkey` +3. Generate server keypair on first startup if not exists +4. Maintain backwards compatibility with existing admin API + +--- + +## 3. Keypair Management + +### 3.1 Server Keypair (Relay Identity) + +**Purpose:** Identifies the ginxsom server in Nostr ecosystem + +**Generation:** +```c +// On first startup or explicit generation +int generate_server_keypair(void) { + unsigned char privkey[32]; + unsigned char pubkey[32]; + + // Generate using nostr_core_lib + if (nostr_generate_keypair(privkey, pubkey) != NOSTR_SUCCESS) { + return -1; + } + + // Store in database (encrypted) + char pubkey_hex[65]; + char privkey_hex[65]; + nostr_bytes_to_hex(pubkey, 32, pubkey_hex); + nostr_bytes_to_hex(privkey, 32, privkey_hex); + + // Encrypt private key before storage + char encrypted_privkey[256]; + encrypt_with_system_key(privkey_hex, encrypted_privkey); + + // Store in database + return store_server_keypair(pubkey_hex, encrypted_privkey); +} +``` + +**Storage:** +- Public key: Stored in `server_keys.public_key` and `config.server_pubkey` +- Private key: **NEVER** stored in database - kept in process memory only +- On startup: Load from database, decrypt, keep in memory +- On shutdown: Clear from memory securely + +**Command-Line Options:** +```bash +# Generate new server keypair +ginxsom-fcgi --generate-server-key + +# Import existing keypair +ginxsom-fcgi --import-server-key + +# Show server public key +ginxsom-fcgi --show-server-pubkey +``` + +### 3.2 Admin Keypair Management + +**Purpose:** Authorize administrators to manage the server + +**Initial Setup:** +```bash +# Generate admin keypair (done by admin, not server) +ADMIN_PRIVKEY=$(nak key generate) +ADMIN_PUBKEY=$(echo "$ADMIN_PRIVKEY" | nak key public) + +# Add admin to server (requires existing admin or direct DB access) +sqlite3 db/ginxsom.db << EOF +INSERT INTO admin_keys (public_key, name, permissions, created_by) +VALUES ('$ADMIN_PUBKEY', 'Primary Admin', '["full"]', 'system'); +EOF +``` + +**Runtime Management:** +```bash +# Add new admin (via DM command) +nak event -k 14 --envelope --sec $ADMIN_PRIVKEY \ + --tag command add_admin \ + --tag pubkey $NEW_ADMIN_PUBKEY \ + --tag name "Secondary Admin" \ + --tag permissions '["read","write"]' \ + | curl -X POST http://localhost:9001/admin -d @- + +# List admins +nak event -k 14 --envelope --sec $ADMIN_PRIVKEY \ + --tag command list_admins \ + | curl -X POST http://localhost:9001/admin -d @- + +# Revoke admin +nak event -k 14 --envelope --sec $ADMIN_PRIVKEY \ + --tag command revoke_admin \ + --tag pubkey $ADMIN_TO_REVOKE \ + | curl -X POST http://localhost:9001/admin -d @- +``` + +### 3.3 Key Rotation + +**Server Key Rotation:** +- Generate new keypair +- Update database +- Announce new pubkey via NIP-11 relay info +- Keep old key for 30 days for transition + +**Admin Key Rotation:** +- Admin generates new keypair +- Uses old key to authorize new key +- Old key remains valid during transition period +- Explicit revocation of old key after confirmation + +--- + +## 4. Authentication Architecture + +### 4.1 NIP-17 Gift Wrap Overview + +**Why NIP-17?** +- End-to-end encryption between admin and server +- Prevents eavesdropping on admin commands +- Provides forward secrecy +- Standard Nostr protocol (interoperable) + +**Gift Wrap Structure:** +```json +{ + "kind": 1059, + "content": "", + "tags": [ + ["p", ""] + ], + "pubkey": "", + "created_at": 1234567890, + "sig": "" +} +``` + +**Seal Structure (encrypted in gift wrap):** +```json +{ + "kind": 13, + "content": "", + "tags": [ + ["p", ""] + ], + "pubkey": "", + "created_at": 1234567890 +} +``` + +**Rumor Structure (encrypted in seal):** +```json +{ + "kind": 14, + "content": "", + "tags": [ + ["command", "list_blobs"], + ["limit", "50"], + ["offset", "0"] + ], + "pubkey": "", + "created_at": 1234567890 +} +``` + +### 4.2 Authentication Flow + +```mermaid +sequenceDiagram + participant Admin + participant Server + participant DB + + Admin->>Admin: Create Kind 14 Rumor
(command + params) + Admin->>Admin: Wrap in Kind 13 Seal
(encrypt with server pubkey) + Admin->>Admin: Wrap in Kind 1059 Gift
(encrypt with ephemeral key) + + Admin->>Server: POST /admin
Gift Wrap Event + + Server->>Server: Unwrap Gift
(decrypt with server privkey) + Server->>Server: Unwrap Seal
(decrypt with admin pubkey) + Server->>Server: Extract Rumor
(Kind 14 command) + + Server->>DB: Check admin_pubkey authorized + + alt Not Authorized + Server-->>Admin: 403 Forbidden + else Authorized + Server->>DB: Check gift wrap not replayed + + alt Replayed + Server-->>Admin: 409 Conflict (Replay) + else Fresh + Server->>DB: Store gift wrap ID + Server->>Server: Parse command tags + Server->>Server: Execute command + Server->>DB: Log to audit_log + Server->>Server: Encrypt response (NIP-44) + Server-->>Admin: Encrypted Response + end + end +``` + +### 4.3 Validation Rules + +**Gift Wrap Validation:** +1. Event kind must be 1059 +2. Must have `p` tag with server pubkey +3. Signature must be valid +4. Created_at within acceptable time window (±5 minutes) + +**Seal Validation:** +1. Decryption must succeed with server private key +2. Event kind must be 13 +3. Must have `p` tag with admin pubkey + +**Rumor Validation:** +1. Decryption must succeed with admin public key +2. Event kind must be 14 +3. Admin pubkey must be in `admin_keys` table with `enabled=1` +4. Must have `command` tag +5. Event ID not in `gift_wrap_tracking` (prevent replay) +6. Created_at within acceptable time window + +**Integration with Existing Validator:** + +Add to [`src/request_validator.c`](src/request_validator.c:1): + +```c +// Add to event kind routing (around line 438) +else if (event_kind == 1059) { + // NIP-17 Gift Wrap for admin commands + int gift_wrap_result = validate_gift_wrap_admin(event); + if (gift_wrap_result != NOSTR_SUCCESS) { + result->valid = 0; + result->error_code = gift_wrap_result; + strcpy(result->reason, "Gift wrap validation failed"); + cJSON_Delete(event); + return NOSTR_SUCCESS; + } +} +``` + +--- + +## 5. Management Commands + +### 5.1 Command Categories + +**Blob Operations:** +- `list_blobs` - List blobs with filters +- `get_blob_info` - Get detailed blob metadata +- `delete_blob` - Delete blob (requires confirmation) +- `mirror_blob` - Mirror blob from another server +- `verify_blob` - Verify blob integrity + +**Storage Management:** +- `get_storage_stats` - Get storage usage statistics +- `get_disk_usage` - Get disk space information +- `cleanup_orphans` - Remove orphaned files +- `set_quota` - Set storage quota for user + +**Configuration:** +- `get_config` - Get configuration values +- `set_config` - Set configuration value (requires confirmation) +- `list_auth_rules` - List authentication rules +- `add_auth_rule` - Add authentication rule +- `remove_auth_rule` - Remove authentication rule (requires confirmation) + +**Statistics:** +- `get_stats` - Get server statistics +- `get_upload_stats` - Get upload statistics by time period +- `get_user_stats` - Get per-user statistics +- `get_bandwidth_stats` - Get bandwidth usage + +**System:** +- `get_health` - Get system health status +- `get_version` - Get server version info +- `backup_database` - Create database backup +- `restore_database` - Restore from backup (requires confirmation) +- `rotate_logs` - Rotate log files + +**Admin Management:** +- `list_admins` - List admin keys +- `add_admin` - Add new admin key (requires confirmation) +- `revoke_admin` - Revoke admin key (requires confirmation) +- `get_audit_log` - Get admin audit log + +### 5.2 Command Structure + +**Request Format (Kind 14 Rumor):** +```json +{ + "kind": 14, + "content": "", + "tags": [ + ["command", "list_blobs"], + ["limit", "50"], + ["offset", "0"], + ["filter_type", "image/*"], + ["since", "1234567890"] + ], + "pubkey": "", + "created_at": 1234567890 +} +``` + +**Response Format (NIP-44 Encrypted):** +```json +{ + "status": "success", + "command": "list_blobs", + "data": { + "blobs": [...], + "total": 1234, + "limit": 50, + "offset": 0 + }, + "timestamp": 1234567890 +} +``` + +**Error Response:** +```json +{ + "status": "error", + "command": "list_blobs", + "error": { + "code": "INVALID_PARAMETER", + "message": "Invalid limit value", + "details": "Limit must be between 1 and 1000" + }, + "timestamp": 1234567890 +} +``` + +### 5.3 Two-Step Confirmation + +**Critical Operations Requiring Confirmation:** +- `delete_blob` - Permanent data loss +- `set_config` - System behavior changes +- `add_admin` - Security implications +- `revoke_admin` - Access control changes +- `restore_database` - Data integrity risk + +**Confirmation Flow:** + +**Step 1: Request** +```json +{ + "kind": 14, + "tags": [ + ["command", "delete_blob"], + ["sha256", "abc123..."] + ] +} +``` + +**Step 1: Response** +```json +{ + "status": "confirmation_required", + "command": "delete_blob", + "pending_id": "42", + "details": { + "sha256": "abc123...", + "size": 1048576, + "type": "image/jpeg", + "uploaded_at": 1234567890 + }, + "expires_at": 1234568190, + "message": "This will permanently delete the blob. Send confirmation within 5 minutes." +} +``` + +**Step 2: Confirmation** +```json +{ + "kind": 14, + "tags": [ + ["command", "confirm"], + ["pending_id", "42"] + ] +} +``` + +**Step 2: Response** +```json +{ + "status": "success", + "command": "delete_blob", + "data": { + "sha256": "abc123...", + "deleted": true + }, + "timestamp": 1234567900 +} +``` + +--- + +## 6. API Design + +### 6.1 Endpoint Routing + +**New Endpoint:** +- `POST /admin` - Unified admin command endpoint (NIP-17 gift wrap) + +**Existing Endpoints (Keep):** +- `GET /api/stats` - Statistics (existing admin API) +- `GET /api/config` - Configuration (existing admin API) +- `PUT /api/config` - Update config (existing admin API) +- `GET /api/files` - File listing (existing admin API) +- `GET /api/health` - Health check (existing admin API) + +**Integration Strategy:** +- New `/admin` endpoint for NIP-17 DM-based commands +- Existing `/api/*` endpoints remain for backwards compatibility +- Both systems share same database and authentication +- Gradual migration path for clients + +### 6.2 Request Handling + +**Handler Registration in [`src/main.c`](src/main.c:1640):** + +```c +// Add to main request loop (around line 1640) +else if (strcmp(request_method, "POST") == 0 && + strcmp(request_uri, "/admin") == 0) { + // Handle NIP-17 gift wrap admin commands + handle_admin_dm_request(); +} +``` + +**Unified Handler Pattern:** + +```c +// src/management_handler.c +void handle_admin_dm_request(void) { + // 1. Read gift wrap event from request body + char *event_json = read_request_body(); + + // 2. Validate and unwrap gift wrap + admin_command_t cmd; + int result = unwrap_admin_gift_wrap(event_json, &cmd); + if (result != SUCCESS) { + send_admin_error(result, "Failed to unwrap gift wrap"); + return; + } + + // 3. Check admin authorization + if (!is_admin_authorized(cmd.admin_pubkey)) { + send_admin_error(ERROR_UNAUTHORIZED, "Not authorized"); + return; + } + + // 4. Check for replay + if (is_gift_wrap_replayed(cmd.event_id)) { + send_admin_error(ERROR_REPLAY, "Gift wrap already processed"); + return; + } + + // 5. Route to command handler + admin_response_t response; + result = route_admin_command(&cmd, &response); + + // 6. Log to audit log + log_admin_command(&cmd, result); + + // 7. Encrypt and send response + send_admin_response(&response, cmd.admin_pubkey); +} +``` + +### 6.3 Tag-Based Routing + +**Command Router:** + +```c +int route_admin_command(admin_command_t *cmd, admin_response_t *response) { + const char *command = get_tag_value(cmd->tags, "command"); + + if (!command) { + return ERROR_MISSING_COMMAND; + } + + // Blob operations + if (strcmp(command, "list_blobs") == 0) { + return handle_list_blobs(cmd, response); + } else if (strcmp(command, "get_blob_info") == 0) { + return handle_get_blob_info(cmd, response); + } else if (strcmp(command, "delete_blob") == 0) { + return handle_delete_blob(cmd, response); + } + + // Storage management + else if (strcmp(command, "get_storage_stats") == 0) { + return handle_get_storage_stats(cmd, response); + } else if (strcmp(command, "cleanup_orphans") == 0) { + return handle_cleanup_orphans(cmd, response); + } + + // Configuration + else if (strcmp(command, "get_config") == 0) { + return handle_get_config(cmd, response); + } else if (strcmp(command, "set_config") == 0) { + return handle_set_config(cmd, response); + } + + // Admin management + else if (strcmp(command, "list_admins") == 0) { + return handle_list_admins(cmd, response); + } else if (strcmp(command, "add_admin") == 0) { + return handle_add_admin(cmd, response); + } + + // Confirmation + else if (strcmp(command, "confirm") == 0) { + return handle_confirm_pending(cmd, response); + } + + else { + return ERROR_UNKNOWN_COMMAND; + } +} +``` + +--- + +## 7. File Structure + +### 7.1 New Files + +**Core Management:** +``` +src/management_handler.c - Unified command handler and routing +src/management_handler.h - Handler interface definitions +src/dm_admin.c - NIP-17 gift wrap processing +src/dm_admin.h - Gift wrap interface +src/keypair_manager.c - Server and admin key management +src/keypair_manager.h - Key management interface +src/pending_changes.c - Two-step confirmation system +src/pending_changes.h - Pending changes interface +``` + +**Command Handlers:** +``` +src/commands/blob_commands.c - Blob operation handlers +src/commands/storage_commands.c - Storage management handlers +src/commands/config_commands.c - Configuration handlers +src/commands/stats_commands.c - Statistics handlers +src/commands/admin_commands.c - Admin management handlers +src/commands/system_commands.c - System operation handlers +``` + +**Utilities:** +``` +src/utils/encryption.c - NIP-44 encryption utilities +src/utils/audit_log.c - Audit logging utilities +src/utils/response_builder.c - Response formatting +``` + +### 7.2 Modified Files + +**[`src/main.c`](src/main.c:1):** +- Add `/admin` endpoint routing (line ~1640) +- Initialize management system on startup +- Add cleanup on shutdown + +**[`src/request_validator.c`](src/request_validator.c:1):** +- Add Kind 1059 (gift wrap) validation (line ~438) +- Add gift wrap unwrapping logic +- Add replay prevention checks + +**[`src/admin_api.c`](src/admin_api.c:1):** +- Keep existing endpoints for backwards compatibility +- Add integration hooks for new management system +- Share database access with new handlers + +**[`db/schema.sql`](db/schema.sql:1):** +- Add new tables (server_keys, admin_keys, pending_changes, etc.) +- Add indexes for performance +- Add default configuration values + +**[`Makefile`](Makefile):** +- Add new source files to build +- Add dependencies for new modules +- Update clean targets + +### 7.3 Integration Points + +**With Existing Admin API:** +```c +// src/admin_api.c - Add integration function +void admin_api_notify_config_change(const char *key, const char *value) { + // Called by management system when config changes + // Invalidates cache, triggers reload + nostr_request_validator_force_cache_refresh(); +} +``` + +**With Request Validator:** +```c +// src/request_validator.c - Add gift wrap validation +int validate_gift_wrap_admin(cJSON *event) { + // Validate Kind 1059 structure + // Unwrap and validate seal + // Unwrap and validate rumor + // Check admin authorization + // Check replay prevention + return NOSTR_SUCCESS; +} +``` + +**With Database:** +```c +// All handlers use shared database connection +// Consistent error handling +// Transaction support for atomic operations +``` + +--- + +## 8. Implementation Plan + +### 8.1 Phase 1: Foundation (Week 1-2) + +**Goals:** +- Database schema extensions +- Keypair management +- Basic gift wrap processing + +**Tasks:** +1. Create database migration script +2. Implement `keypair_manager.c` + - Server keypair generation + - Admin keypair storage + - Key loading on startup +3. Implement `dm_admin.c` + - Gift wrap unwrapping + - Seal decryption + - Rumor extraction +4. Add gift wrap validation to `request_validator.c` +5. Create test suite for gift wrap processing + +**Deliverables:** +- Working keypair management +- Gift wrap unwrap/validation +- Database schema updated +- Unit tests passing + +### 8.2 Phase 2: Command Infrastructure (Week 3-4) + +**Goals:** +- Unified command handler +- Tag-based routing +- Response encryption + +**Tasks:** +1. Implement `management_handler.c` + - Request parsing + - Command routing + - Response building +2. Implement `pending_changes.c` + - Two-step confirmation + - Timeout handling + - Execution tracking +3. Add `/admin` endpoint to `main.c` +4. Implement audit logging +5. Create command handler templates + +**Deliverables:** +- Working command routing +- Two-step confirmation system +- Audit logging functional +- Integration tests passing + +### 8.3 Phase 3: Core Commands (Week 5-6) + +**Goals:** +- Implement essential management commands +- Integration with existing systems + +**Tasks:** +1. Implement blob commands + - `list_blobs` + - `get_blob_info` + - `delete_blob` (with confirmation) +2. Implement storage commands + - `get_storage_stats` + - `get_disk_usage` + - `cleanup_orphans` +3. Implement config commands + - `get_config` + - `set_config` (with confirmation) +4. Implement admin commands + - `list_admins` + - `add_admin` (with confirmation) + - `revoke_admin` (with confirmation) +5. Integration testing with existing admin API + +**Deliverables:** +- Core commands functional +- Integration with existing API +- End-to-end tests passing + +### 8.4 Phase 4: Advanced Features (Week 7-8) + +**Goals:** +- Statistics and monitoring +- System operations +- CLI tooling + +**Tasks:** +1. Implement stats commands + - `get_stats` + - `get_upload_stats` + - `get_user_stats` +2. Implement system commands + - `backup_database` + - `restore_database` + - `rotate_logs` +3. Create CLI tool for admin operations +4. Create web interface (optional) +5. Performance optimization +6. Security audit + +**Deliverables:** +- All commands implemented +- CLI tool functional +- Performance benchmarks +- Security review complete + +### 8.5 Phase 5: Documentation & Deployment (Week 9-10) + +**Goals:** +- Complete documentation +- Deployment guides +- Migration tools + +**Tasks:** +1. Write admin documentation +2. Create setup guides +3. Create migration scripts +4. Write troubleshooting guide +5. Create example scripts +6. Production deployment testing + +**Deliverables:** +- Complete documentation +- Migration tools +- Deployment guides +- Production-ready release + +--- + +## 9. Security Considerations + +### 9.1 Threat Model + +**Threats:** +1. **Unauthorized Access**: Attacker gains admin privileges +2. **Replay Attacks**: Reuse of captured gift wrap events +3. **Man-in-the-Middle**: Interception of admin commands +4. **Privilege Escalation**: Regular user gains admin access +5. **Data Exfiltration**: Unauthorized access to blob data +6. **Denial of Service**: Resource exhaustion via admin commands + +**Mitigations:** +1. **NIP-17 Encryption**: End-to-end encryption prevents MITM +2. **Gift Wrap Tracking**: Prevents replay attacks +3. **Admin Key Management**: Strict authorization checks +4. **Two-Step Confirmation**: Prevents accidental critical operations +5. **Audit Logging**: Tracks all admin actions +6. **Rate Limiting**: Prevents DoS via admin commands + +### 9.2 Key Security + +**Server Private Key:** +- **NEVER** stored in database +- Loaded into memory on startup +- Cleared on shutdown +- Protected by OS memory protection +- Consider using secure enclave if available + +**Admin Private Keys:** +- **NEVER** stored on server +- Managed by admin clients only +- Rotated regularly +- Revoked immediately if compromised + +**Database Encryption:** +- Consider encrypting sensitive config values +- Use system keyring for encryption keys +- Implement key rotation mechanism + +### 9.3 Access Control + +**Permission Levels:** +```json +{ + "full": ["*"], + "read": ["list_*", "get_*"], + "write": ["list_*", "get_*", "set_*", "add_*"], + "admin": ["list_*", "get_*", "set_*", "add_*", "delete_*", "revoke_*"] +} +``` + +**Permission Checks:** +```c +int check_admin_permission(const char *admin_pubkey, const char *command) { + // Load admin permissions from database + cJSON *permissions = get_admin_permissions(admin_pubkey); + + // Check if command is allowed + if (has_permission(permissions, command)) { + return 1; + } + + // Check wildcard permissions + if (has_permission(permissions, "*")) { + return 1; + } + + return 0; +} +``` + +### 9.4 Audit Trail + +**What to Log:** +- All admin commands (success and failure) +- Admin key additions/revocations +- Configuration changes +- Critical operations (delete, restore, etc.) +- Authentication failures +- Suspicious activity + +**Log Format:** +```json +{ + "timestamp": 1234567890, + "admin_pubkey": "abc123...", + "command": "delete_blob", + "parameters": {"sha256": "def456..."}, + "success": true, + "client_ip": "192.168.1.100", + "event_id": "ghi789..." +} +``` + +**Log Retention:** +- Keep audit logs for 30 days minimum +- Archive older logs to separate storage +- Implement log rotation +- Protect logs from tampering + +--- + +## 10. Migration Strategy + +### 10.1 Backwards Compatibility + +**Existing Admin API:** +- Keep all existing `/api/*` endpoints +- No breaking changes to current API +- Gradual deprecation over 6 months +- Clear migration documentation + +**Database:** +- Additive schema changes only +- No modifications to existing tables +- Migration script handles upgrades +- Rollback capability + +**Configuration:** +- Existing config keys remain valid +- New config keys added with defaults +- No changes to config file format + +### 10.2 Migration Steps + +**Step 1: Database Migration** +```bash +# Backup existing database +cp db/ginxsom.db db/ginxsom.db.backup + +# Run migration script +sqlite3 db/ginxsom.db < db/migrations/002_add_management_system.sql + +# Verify migration +sqlite3 db/ginxsom.db "SELECT name FROM sqlite_master WHERE type='table';" +``` + +**Step 2: Generate Server Keypair** +```bash +# Generate server keypair +./build/ginxsom-fcgi --generate-server-key + +# Verify keypair +./build/ginxsom-fcgi --show-server-pubkey +``` + +**Step 3: Add Initial Admin** +```bash +# Generate admin keypair +ADMIN_PRIVKEY=$(nak key generate) +ADMIN_PUBKEY=$(echo "$ADMIN_PRIVKEY" | nak key public) + +# Add to database +sqlite3 db/ginxsom.db << EOF +INSERT INTO admin_keys (public_key, name, permissions, created_by) +VALUES ('$ADMIN_PUBKEY', 'Primary Admin', '["full"]', 'system'); +EOF + +# Save admin private key securely +echo "$ADMIN_PRIVKEY" > ~/.config/ginxsom/admin.key +chmod 600 ~/.config/ginxsom/admin.key +``` + +**Step 4: Test New System** +```bash +# Test gift wrap command +nak event -k 14 --envelope --sec $ADMIN_PRIVKEY \ + --tag command list_admins \ + | curl -X POST http://localhost:9001/admin -d @- + +# Verify response +``` + +**Step 5: Update Clients** +- Update admin scripts to use new `/admin` endpoint +- Migrate from `/api/*` to NIP-17 commands +- Test thoroughly before production + +### 10.3 Rollback Plan + +**If Issues Occur:** +1. Stop ginxsom service +2. Restore database backup +3. Revert to previous version +4. Investigate issues +5. Fix and retry migration + +**Database Rollback:** +```bash +# Stop service +systemctl stop ginxsom + +# Restore backup +cp db/ginxsom.db.backup db/ginxsom.db + +# Restart service +systemctl start ginxsom +``` + +--- + +## Appendix A: Command Reference + +### Blob Commands + +**list_blobs** +```json +{ + "command": "list_blobs", + "limit": "50", + "offset": "0", + "filter_type": "image/*", + "since": "1234567890" +} +``` + +**get_blob_info** +```json +{ + "command": "get_blob_info", + "sha256": "abc123..." +} +``` + +**delete_blob** (requires confirmation) +```json +{ + "command": "delete_blob", + "sha256": "abc123..." +} +``` + +### Storage Commands + +**get_storage_stats** +```json +{ + "command": "get_storage_stats" +} +``` + +**cleanup_orphans** +```json +{ + "command": "cleanup_orphans", + "dry_run": "true" +} +``` + +### Configuration Commands + +**get_config** +```json +{ + "command": "get_config", + "key": "max_file_size" +} +``` + +**set_config** (requires confirmation) +```json +{ + "command": "set_config", + "key": "max_file_size", + "value": "209715200" +} +``` + +### Admin Commands + +**list_admins** +```json +{ + "command": "list_admins" +} +``` + +**add_admin** (requires confirmation) +```json +{ + "command": "add_admin", + "pubkey": "def456...", + "name": "Secondary Admin", + "permissions": "[\"read\",\"write\"]" +} +``` + +**revoke_admin** (requires confirmation) +```json +{ + "command": "revoke_admin", + "pubkey": "def456..." +} +``` + +--- + +## Appendix B: Example Scripts + +### Setup Script + +```bash +#!/bin/bash +# setup_admin.sh - Initial admin setup + +set -e + +echo "Ginxsom Admin Setup" +echo "===================" + +# Generate admin keypair +echo "Generating admin keypair..." +ADMIN_PRIVKEY=$(nak key generate) +ADMIN_PUBKEY=$(echo "$ADMIN_PRIVKEY" | nak key public) + +echo "Admin Public Key: $ADMIN_PUBKEY" + +# Save private key +mkdir -p ~/.config/ginxsom +echo "$ADMIN_PRIVKEY" > ~/.config/ginxsom/admin.key +chmod 600 ~/.config/ginxsom/admin.key + +echo "Private key saved to ~/.config/ginxsom/admin.key" + +# Add to database +echo "Adding admin to database..." +sqlite3 db/ginxsom.db << EOF +INSERT INTO admin_keys (public_key, name, permissions, created_by) +VALUES ('$ADMIN_PUBKEY', 'Primary Admin', '["full"]', 'system'); +EOF + +echo "Admin setup complete!" +echo "Test with: ./admin_command.sh list_admins" +``` + +### Admin Command Script + +```bash +#!/bin/bash +# admin_command.sh - Send admin command + +ADMIN_PRIVKEY=$(cat ~/.config/ginxsom/admin.key) +COMMAND=$1 +shift + +# Build tags +TAGS="" +for arg in "$@"; do + KEY=$(echo "$arg" | cut -d= -f1) + VALUE=$(echo "$arg" | cut -d= -f2-) + TAGS="$TAGS --tag $KEY \"$VALUE\"" +done + +# Send command +eval nak event -k 14 --envelope --sec "$ADMIN_PRIVKEY" \ + --tag command "$COMMAND" \ + $TAGS \ + | curl -s -X POST http://localhost:9001/admin -d @- \ + | jq . +``` + +### Usage Examples + +```bash +# List admins +./admin_command.sh list_admins + +# Get storage stats +./admin_command.sh get_storage_stats + +# List blobs +./admin_command.sh list_blobs limit=10 offset=0 + +# Delete blob (with confirmation) +./admin_command.sh delete_blob sha256=abc123... +# Then confirm +./admin_command.sh confirm pending_id=42 +``` + +--- + +## Conclusion + +This design provides a secure, scalable management system for ginxsom that: + +1. **Leverages Proven Patterns**: Adapts c-relay's successful architecture +2. **Maintains Security**: NIP-17 encryption and two-step confirmation +3. **Ensures Compatibility**: Integrates with existing admin API +4. **Enables Growth**: Extensible command system for future features +5. **Provides Auditability**: Complete audit trail of admin actions + +The phased implementation plan allows for incremental development and testing, while the migration strategy ensures smooth transition from the current system. + +**Next Steps:** +1. Review and approve design +2. Begin Phase 1 implementation +3. Set up development environment +4. Create test infrastructure +5. Start coding! \ No newline at end of file diff --git a/build/admin_auth.o b/build/admin_auth.o new file mode 100644 index 0000000000000000000000000000000000000000..4172af0655b11e21c92dc9a98a76a1f6bbdd1c29 GIT binary patch literal 16464 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 dq~9i7q67c{ literal 0 HcmV?d00001 diff --git a/build/admin_handlers.o b/build/admin_handlers.o new file mode 100644 index 0000000000000000000000000000000000000000..1e660cbe52423e26b05f697f1e81f37ca46ff573 GIT binary patch literal 10376 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 literal 0 HcmV?d00001 diff --git a/build/admin_websocket.o b/build/admin_websocket.o new file mode 100644 index 0000000000000000000000000000000000000000..ee5cf972b275c4ccc665113b3c0420ed135e1c4c GIT binary patch literal 8336 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%0AK~Tf^qRcQp?1SAu0iJ0pG(CW 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 z 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 NQqMmu<%E=^_g|hsZgT(t literal 249360 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 literal 76264 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%0D+z`q&foDVpz6Sf16 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 Q^QB{2Yc7;eDNYjoKN5-)*Z=?k diff --git a/build/request_validator.o b/build/request_validator.o index d55703db9310295554115982f32e3f0eeb1bc1aa..50cdadc4980cdc57ece240c3f6c45b69e17f06c1 100644 GIT binary patch literal 66008 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ͨr5a7V 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

Y#+8B}W955`k2Rnya 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 QI2DPBX(gU2M9i@N29a)^djJ3c literal 151552 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 WvfdHlQizZ{2S!kNUeMlmxAp@m;RpHv diff --git a/db/migrations/002_add_relay_seckey.sql b/db/migrations/002_add_relay_seckey.sql new file mode 100644 index 0000000..60f211d --- /dev/null +++ b/db/migrations/002_add_relay_seckey.sql @@ -0,0 +1,15 @@ +-- Migration: Add blossom_seckey table for storing server private key +-- This table stores the Blossom server's secp256k1 private key used for: +-- - Signing admin response events (Kind 23457) +-- - Decrypting admin commands (NIP-44) + +CREATE TABLE IF NOT EXISTS blossom_seckey ( + id INTEGER PRIMARY KEY CHECK (id = 1), -- Only one row allowed + seckey TEXT NOT NULL, -- Private key in hex format (64 chars) + created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')), + CHECK (length(seckey) = 64) -- Ensure valid secp256k1 key length +); + +-- Add blossom_pubkey to config if not exists +INSERT OR IGNORE INTO config (key, value, description) VALUES + ('blossom_pubkey', '', 'Blossom server public key derived from blossom_seckey'); \ No newline at end of file diff --git a/deploy_lt.sh b/deploy_lt.sh index e3a62b2..7323bc7 100755 --- a/deploy_lt.sh +++ b/deploy_lt.sh @@ -13,6 +13,12 @@ print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; } print_error() { echo -e "${RED}[ERROR]${NC} $1"; } +# Parse command line arguments +FRESH_INSTALL=false +if [[ "$1" == "--fresh" ]]; then + FRESH_INSTALL=true +fi + # Configuration REMOTE_HOST="laantungir.net" REMOTE_USER="ubuntu" @@ -68,7 +74,7 @@ print_status "Copying files to remote server..." # Copy entire project directory (excluding unnecessary files) print_status "Copying entire ginxsom project..." -rsync -avz --exclude='.git' --exclude='build' --exclude='logs' --exclude='Trash' --exclude='blobs' --exclude='db/ginxsom.db' --no-g --no-o --no-perms --omit-dir-times . $REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/ +rsync -avz --exclude='.git' --exclude='build' --exclude='logs' --exclude='Trash' --exclude='blobs' --exclude='db' --no-g --no-o --no-perms --omit-dir-times . $REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/ # Build on remote server to ensure compatibility print_status "Building ginxsom on remote server..." @@ -161,25 +167,35 @@ print_status "Setting up database directory..." ssh $REMOTE_USER@$REMOTE_HOST << EOF # Create db directory if it doesn't exist mkdir -p $REMOTE_DIR/db - - # Backup current database if it exists in old location - if [ -f /var/www/html/blossom/ginxsom.db ]; then - echo "Backing up existing database..." - cp /var/www/html/blossom/ginxsom.db /var/www/html/blossom/ginxsom.db.backup.\$(date +%Y%m%d_%H%M%S) - - # Migrate database to new location if not already there - if [ ! -f $REMOTE_DB_PATH ]; then - echo "Migrating database to new location..." - cp /var/www/html/blossom/ginxsom.db $REMOTE_DB_PATH - else - echo "Database already exists at new location" - fi - elif [ ! -f $REMOTE_DB_PATH ]; then - echo "No existing database found - will be created on first run" + + if [ "$FRESH_INSTALL" = "true" ]; then + echo "Fresh install: removing existing database and blobs..." + # Remove existing database + sudo rm -f $REMOTE_DB_PATH + sudo rm -f /var/www/html/blossom/ginxsom.db + # Remove existing blobs + sudo rm -rf $REMOTE_DATA_DIR/* + echo "Existing data removed" else - echo "Database already exists at $REMOTE_DB_PATH" + # Backup current database if it exists in old location + if [ -f /var/www/html/blossom/ginxsom.db ]; then + echo "Backing up existing database..." + cp /var/www/html/blossom/ginxsom.db /var/www/html/blossom/ginxsom.db.backup.\$(date +%Y%m%d_%H%M%S) + + # Migrate database to new location if not already there + if [ ! -f $REMOTE_DB_PATH ]; then + echo "Migrating database to new location..." + cp /var/www/html/blossom/ginxsom.db $REMOTE_DB_PATH + else + echo "Database already exists at new location" + fi + elif [ ! -f $REMOTE_DB_PATH ]; then + echo "No existing database found - will be created on first run" + else + echo "Database already exists at $REMOTE_DB_PATH" + fi fi - + # Set proper permissions - www-data needs write access to db directory for SQLite journal files sudo chown -R www-data:www-data $REMOTE_DIR/db sudo chmod 755 $REMOTE_DIR/db @@ -187,7 +203,7 @@ ssh $REMOTE_USER@$REMOTE_HOST << EOF # Allow www-data to access the application directory for spawn-fcgi chdir chmod 755 $REMOTE_DIR - + echo "Database directory setup complete" EOF @@ -284,4 +300,7 @@ print_status "Ginxsom should now be available at: https://blossom.laantungir.net print_status "Test endpoints:" echo " Health: curl -k https://blossom.laantungir.net/health" echo " Root: curl -k https://blossom.laantungir.net/" -echo " List: curl -k https://blossom.laantungir.net/list" \ No newline at end of file +echo " List: curl -k https://blossom.laantungir.net/list" +if [ "$FRESH_INSTALL" = "true" ]; then + print_warning "Fresh install completed - database and blobs have been reset" +fi \ No newline at end of file diff --git a/docs/MANAGEMENT_SYSTEM_DESIGN.md b/docs/MANAGEMENT_SYSTEM_DESIGN.md new file mode 100644 index 0000000..efbb6e3 --- /dev/null +++ b/docs/MANAGEMENT_SYSTEM_DESIGN.md @@ -0,0 +1,994 @@ +# Ginxsom Management System Design + +## Executive Summary + +This document outlines the design for a secure management interface for ginxsom (Blossom media storage server) based on c-relay's proven admin system architecture. The design uses Kind 23456/23457 events with NIP-44 encryption over WebSocket for real-time admin operations. + +## 1. System Architecture + +### 1.1 High-Level Overview + +```mermaid +graph TB + Admin[Admin Client] -->|WebSocket| WS[WebSocket Handler] + WS -->|Kind 23456| Auth[Admin Authorization] + Auth -->|Decrypt NIP-44| Decrypt[Command Decryption] + Decrypt -->|Parse JSON Array| Router[Command Router] + Router -->|Route by Command Type| Handlers[Unified Handlers] + Handlers -->|Execute| DB[(Database)] + Handlers -->|Execute| FS[File System] + Handlers -->|Generate Response| Encrypt[NIP-44 Encryption] + Encrypt -->|Kind 23457| WS + WS -->|WebSocket| Admin + + style Admin fill:#e1f5ff + style Auth fill:#fff3cd + style Handlers fill:#d4edda + style DB fill:#f8d7da +``` + +### 1.2 Component Architecture + +```mermaid +graph LR + subgraph "Admin Interface" + CLI[CLI Tool] + Web[Web Dashboard] + end + + subgraph "ginxsom FastCGI Process" + WS[WebSocket Endpoint] + Auth[Authorization Layer] + Router[Command Router] + + subgraph "Unified Handlers" + BlobH[Blob Handler] + StorageH[Storage Handler] + ConfigH[Config Handler] + StatsH[Stats Handler] + SystemH[System Handler] + end + + DB[(SQLite Database)] + Storage[Blob Storage] + end + + CLI -->|WebSocket| WS + Web -->|WebSocket| WS + WS --> Auth + Auth --> Router + Router --> BlobH + Router --> StorageH + Router --> ConfigH + Router --> StatsH + Router --> SystemH + + BlobH --> DB + BlobH --> Storage + StorageH --> Storage + ConfigH --> DB + StatsH --> DB + SystemH --> DB + + style Auth fill:#fff3cd + style Router fill:#d4edda +``` + +### 1.3 Data Flow for Admin Commands + +```mermaid +sequenceDiagram + participant Admin + participant WebSocket + participant Auth + participant Handler + participant Database + + Admin->>WebSocket: Kind 23456 Event (NIP-44 encrypted) + WebSocket->>Auth: Verify admin signature + Auth->>Auth: Check pubkey matches admin_pubkey + Auth->>Auth: Verify event signature + Auth->>WebSocket: Authorization OK + WebSocket->>Handler: Decrypt & parse command array + Handler->>Handler: Validate command structure + Handler->>Database: Execute operation + Database-->>Handler: Result + Handler->>Handler: Build response JSON + Handler->>WebSocket: Encrypt response (NIP-44) + WebSocket->>Admin: Kind 23457 Event (encrypted response) +``` + +### 1.4 Integration with Existing Ginxsom + +```mermaid +graph TB + subgraph "Existing Ginxsom" + Main[main.c] + BUD04[bud04.c - Mirror] + BUD06[bud06.c - Requirements] + BUD08[bud08.c - NIP-94] + BUD09[bud09.c - Report] + AdminAPI[admin_api.c - Basic Admin] + Validator[request_validator.c] + end + + subgraph "New Management System" + AdminWS[admin_websocket.c] + AdminAuth[admin_auth.c] + AdminHandlers[admin_handlers.c] + AdminConfig[admin_config.c] + end + + Main -->|Initialize| AdminWS + AdminWS -->|Use| AdminAuth + AdminWS -->|Route to| AdminHandlers + AdminHandlers -->|Query| BUD04 + AdminHandlers -->|Query| BUD06 + AdminHandlers -->|Query| BUD08 + AdminHandlers -->|Query| BUD09 + AdminHandlers -->|Update| AdminConfig + AdminAuth -->|Use| Validator + + style AdminWS fill:#d4edda + style AdminAuth fill:#fff3cd + style AdminHandlers fill:#e1f5ff +``` + +## 2. Database Schema + +### 2.1 Core Tables + +Following c-relay's minimal approach, we need only two tables for key management: + +#### relay_seckey Table +```sql +-- Stores relay's private key (used for signing Kind 23457 responses) +CREATE TABLE relay_seckey ( + private_key_hex TEXT NOT NULL CHECK (length(private_key_hex) = 64), + created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')) +); +``` + +**Note**: This table stores the relay's private key as plain hex (no encryption). The key is used to: +- Sign Kind 23457 response events +- Encrypt responses using NIP-44 (shared secret with admin pubkey) + +#### config Table (Extended) +```sql +-- Existing config table, add admin_pubkey entry +INSERT INTO config (key, value, data_type, description, category, requires_restart) +VALUES ( + 'admin_pubkey', + '<64-char-hex-pubkey>', + 'string', + 'Public key of authorized admin (hex format)', + 'security', + 0 +); +``` + +**Note**: Admin public key is stored in the config table, not a separate table. Admin private key is NEVER stored anywhere. + +### 2.2 Schema Comparison with c-relay + +| c-relay | ginxsom | Purpose | +|---------|---------|---------| +| `relay_seckey` (private_key_hex, created_at) | `relay_seckey` (private_key_hex, created_at) | Relay private key storage | +| `config` table entry for admin_pubkey | `config` table entry for admin_pubkey | Admin authorization | +| No audit log | No audit log | Keep it simple | +| No processed events tracking | No processed events tracking | Stateless processing | + +### 2.3 Key Storage Strategy + +**Relay Private Key**: +- Stored in `relay_seckey` table as plain 64-character hex +- Generated on first startup or provided via `--relay-privkey` CLI option +- Used for signing Kind 23457 responses and NIP-44 encryption +- Never exposed via API + +**Admin Public Key**: +- Stored in `config` table as plain 64-character hex +- Generated on first startup or provided via `--admin-pubkey` CLI option +- Used to verify Kind 23456 command signatures +- Can be queried via admin API + +**Admin Private Key**: +- NEVER stored anywhere in the system +- Kept only by the admin in their client/tool +- Used to sign Kind 23456 commands and decrypt Kind 23457 responses + +## 3. API Design + +### 3.1 Command Structure + +Following c-relay's pattern, all commands use JSON array format: + +```json +["command_name", {"param1": "value1", "param2": "value2"}] +``` + +### 3.2 Event Structure + +#### Kind 23456 - Admin Command Event + +```json +{ + "kind": 23456, + "pubkey": "", + "created_at": 1234567890, + "tags": [ + ["p", ""] + ], + "content": "", + "sig": "" +} +``` + +**Content (decrypted)**: +```json +["blob_list", {"limit": 100, "offset": 0}] +``` + +#### Kind 23457 - Admin Response Event + +```json +{ + "kind": 23457, + "pubkey": "", + "created_at": 1234567890, + "tags": [ + ["p", ""], + ["e", ""] + ], + "content": "", + "sig": "" +} +``` + +**Content (decrypted)**: +```json +{ + "success": true, + "data": { + "blobs": [ + {"sha256": "abc123...", "size": 1024, "type": "image/png"}, + {"sha256": "def456...", "size": 2048, "type": "video/mp4"} + ], + "total": 2 + } +} +``` + +### 3.3 Command Categories + +#### Blob Operations +- `blob_list` - List blobs with pagination +- `blob_info` - Get detailed blob information +- `blob_delete` - Delete blob(s) +- `blob_mirror` - Mirror blob from another server + +#### Storage Management +- `storage_stats` - Get storage usage statistics +- `storage_quota` - Get/set storage quotas +- `storage_cleanup` - Clean up orphaned files + +#### Configuration +- `config_get` - Get configuration value(s) +- `config_set` - Set configuration value(s) +- `config_list` - List all configuration +- `auth_rules_list` - List authentication rules +- `auth_rules_add` - Add authentication rule +- `auth_rules_remove` - Remove authentication rule + +#### Statistics +- `stats_uploads` - Upload statistics +- `stats_bandwidth` - Bandwidth usage +- `stats_storage` - Storage usage over time +- `stats_users` - User activity statistics + +#### System +- `system_info` - Get system information +- `system_restart` - Restart server (graceful) +- `system_backup` - Trigger database backup +- `system_restore` - Restore from backup + +### 3.4 Command Examples + +#### Example 1: List Blobs +```json +// Command (Kind 23456 content, decrypted) +["blob_list", { + "limit": 50, + "offset": 0, + "type": "image/*", + "sort": "created_at", + "order": "desc" +}] + +// Response (Kind 23457 content, decrypted) +{ + "success": true, + "data": { + "blobs": [ + { + "sha256": "abc123...", + "size": 102400, + "type": "image/png", + "created": 1234567890, + "url": "https://blossom.example.com/abc123.png" + } + ], + "total": 150, + "limit": 50, + "offset": 0 + } +} +``` + +#### Example 2: Delete Blob +```json +// Command +["blob_delete", { + "sha256": "abc123...", + "confirm": true +}] + +// Response +{ + "success": true, + "data": { + "deleted": true, + "sha256": "abc123...", + "freed_bytes": 102400 + } +} +``` + +#### Example 3: Get Storage Stats +```json +// Command +["storage_stats", {}] + +// Response +{ + "success": true, + "data": { + "total_blobs": 1500, + "total_bytes": 5368709120, + "total_bytes_human": "5.0 GB", + "disk_usage": { + "used": 5368709120, + "available": 94631291904, + "total": 100000000000, + "percent": 5.4 + }, + "by_type": { + "image/png": {"count": 500, "bytes": 2147483648}, + "image/jpeg": {"count": 300, "bytes": 1610612736}, + "video/mp4": {"count": 200, "bytes": 1610612736} + } + } +} +``` + +#### Example 4: Set Configuration +```json +// Command +["config_set", { + "max_upload_size": 10485760, + "allowed_mime_types": ["image/*", "video/mp4"] +}] + +// Response +{ + "success": true, + "data": { + "updated": ["max_upload_size", "allowed_mime_types"], + "requires_restart": false + } +} +``` + +### 3.5 Error Handling + +All errors follow consistent format: + +```json +{ + "success": false, + "error": { + "code": "BLOB_NOT_FOUND", + "message": "Blob with hash abc123... not found", + "details": { + "sha256": "abc123..." + } + } +} +``` + +**Error Codes**: +- `UNAUTHORIZED` - Invalid admin signature +- `INVALID_COMMAND` - Unknown command or malformed structure +- `INVALID_PARAMS` - Missing or invalid parameters +- `BLOB_NOT_FOUND` - Requested blob doesn't exist +- `STORAGE_FULL` - Storage quota exceeded +- `DATABASE_ERROR` - Database operation failed +- `SYSTEM_ERROR` - Internal server error + +## 4. File Structure + +### 4.1 New Files to Create + +``` +src/ +├── admin_websocket.c # WebSocket endpoint for admin commands +├── admin_websocket.h # WebSocket handler declarations +├── admin_auth.c # Admin authorization (adapted from c-relay) +├── admin_auth.h # Authorization function declarations +├── admin_handlers.c # Unified command handlers +├── admin_handlers.h # Handler function declarations +├── admin_config.c # Configuration management +├── admin_config.h # Config function declarations +└── admin_keys.c # Key generation and storage + admin_keys.h # Key management declarations + +include/ +└── admin_system.h # Public admin system interface +``` + +### 4.2 Files to Adapt from c-relay + +| c-relay File | Purpose | Adaptation for ginxsom | +|--------------|---------|------------------------| +| `dm_admin.c` | Admin event processing | → `admin_websocket.c` (WebSocket instead of DM) | +| `api.c` (lines 768-838) | NIP-44 encryption/response | → `admin_handlers.c` (response generation) | +| `config.c` (lines 500-583) | Key storage/retrieval | → `admin_keys.c` (relay key management) | +| `main.c` (lines 1389-1556) | CLI argument parsing | → `main.c` (add admin CLI options) | + +### 4.3 Integration with Existing Files + +**src/main.c**: +- Add CLI options: `--admin-pubkey`, `--relay-privkey` +- Initialize admin WebSocket endpoint +- Generate keys on first startup + +**src/admin_api.c** (existing): +- Keep existing basic admin API +- Add WebSocket admin endpoint +- Route Kind 23456 events to new handlers + +**db/schema.sql**: +- Add `relay_seckey` table +- Add `admin_pubkey` to config table + +## 5. Implementation Plan + +### 5.1 Phase 1: Foundation (Week 1) + +**Goal**: Set up key management and database schema + +**Tasks**: +1. Create `relay_seckey` table in schema +2. Add `admin_pubkey` to config table +3. Implement `admin_keys.c`: + - `generate_relay_keypair()` + - `generate_admin_keypair()` + - `store_relay_private_key()` + - `load_relay_private_key()` + - `get_admin_pubkey()` +4. Update `main.c`: + - Add CLI options (`--admin-pubkey`, `--relay-privkey`) + - Generate keys on first startup + - Print keys once (like c-relay) +5. Test key generation and storage + +**Deliverables**: +- Working key generation +- Keys stored in database +- CLI options functional + +### 5.2 Phase 2: Authorization (Week 2) + +**Goal**: Implement admin event authorization + +**Tasks**: +1. Create `admin_auth.c` (adapted from c-relay's authorization): + - `verify_admin_event()` - Check Kind 23456 signature + - `check_admin_pubkey()` - Verify against stored admin_pubkey + - `verify_relay_target()` - Check 'p' tag matches relay pubkey +2. Add NIP-44 crypto functions (use existing nostr_core_lib): + - `decrypt_admin_command()` - Decrypt Kind 23456 content + - `encrypt_admin_response()` - Encrypt Kind 23457 content +3. Test authorization flow +4. Test encryption/decryption + +**Deliverables**: +- Working authorization layer +- NIP-44 encryption functional +- Unit tests for auth + +### 5.3 Phase 3: WebSocket Endpoint (Week 3) + +**Goal**: Create WebSocket handler for admin commands + +**Tasks**: +1. Create `admin_websocket.c`: + - WebSocket endpoint at `/admin` or similar + - Receive Kind 23456 events + - Route to authorization layer + - Parse command array from decrypted content + - Route to appropriate handler + - Build Kind 23457 response + - Send encrypted response +2. Integrate with existing FastCGI WebSocket handling +3. Add connection management +4. Test WebSocket communication + +**Deliverables**: +- Working WebSocket endpoint +- Event routing functional +- Response generation working + +### 5.4 Phase 4: Command Handlers (Week 4-5) + +**Goal**: Implement unified command handlers + +**Tasks**: +1. Create `admin_handlers.c` with unified handler pattern: + - `handle_blob_command()` - Blob operations + - `handle_storage_command()` - Storage management + - `handle_config_command()` - Configuration + - `handle_stats_command()` - Statistics + - `handle_system_command()` - System operations +2. Implement each command: + - Blob: list, info, delete, mirror + - Storage: stats, quota, cleanup + - Config: get, set, list, auth_rules + - Stats: uploads, bandwidth, storage, users + - System: info, restart, backup, restore +3. Add validation for each command +4. Test each command individually + +**Deliverables**: +- All commands implemented +- Validation working +- Integration tests passing + +### 5.5 Phase 5: Testing & Documentation (Week 6) + +**Goal**: Comprehensive testing and documentation + +**Tasks**: +1. Create test suite: + - Unit tests for each handler + - Integration tests for full flow + - Security tests for authorization + - Performance tests for WebSocket +2. Create admin CLI tool (simple Node.js/Python script): + - Generate Kind 23456 events + - Send via WebSocket + - Decrypt Kind 23457 responses + - Pretty-print results +3. Write documentation: + - Admin API reference + - CLI tool usage guide + - Security best practices + - Troubleshooting guide +4. Create example scripts + +**Deliverables**: +- Complete test suite +- Working CLI tool +- Full documentation +- Example scripts + +### 5.6 Phase 6: Web Dashboard (Optional, Week 7-8) + +**Goal**: Create web-based admin interface + +**Tasks**: +1. Design web UI (React/Vue/Svelte) +2. Implement WebSocket client +3. Create command forms +4. Add real-time updates +5. Deploy dashboard + +**Deliverables**: +- Working web dashboard +- User documentation +- Deployment guide + +## 6. Security Considerations + +### 6.1 Key Security + +**Relay Private Key**: +- Stored in database as plain hex (following c-relay pattern) +- Never exposed via API +- Used only for signing responses +- Backed up with database + +**Admin Private Key**: +- NEVER stored on server +- Kept only by admin +- Used to sign commands +- Should be stored securely by admin (password manager, hardware key, etc.) + +**Admin Public Key**: +- Stored in config table +- Used for authorization +- Can be rotated by updating config + +### 6.2 Authorization Flow + +1. Receive Kind 23456 event +2. Verify event signature (nostr_verify_event_signature) +3. Check pubkey matches admin_pubkey from config +4. Verify 'p' tag targets this relay +5. Decrypt content using NIP-44 +6. Parse and validate command +7. Execute command +8. Encrypt response using NIP-44 +9. Sign Kind 23457 response +10. Send response + +### 6.3 Attack Mitigation + +**Replay Attacks**: +- Check event timestamp (reject old events) +- Optional: Track processed event IDs (if needed) + +**Unauthorized Access**: +- Strict pubkey verification +- Signature validation +- Relay targeting check + +**Command Injection**: +- Validate all command parameters +- Use parameterized SQL queries +- Sanitize file paths + +**DoS Protection**: +- Rate limit admin commands +- Timeout long-running operations +- Limit response sizes + +## 7. Command Line Interface + +### 7.1 CLI Options (Following c-relay Pattern) + +```bash +ginxsom [OPTIONS] + +Options: + -h, --help Show help message + -v, --version Show version information + -p, --port PORT Override server port + --strict-port Fail if exact port unavailable + -a, --admin-pubkey KEY Override admin public key (hex or npub) + -r, --relay-privkey KEY Override relay private key (hex or nsec) + --debug-level=N Set debug level (0-5) + +Examples: + ginxsom # Start server (auto-generate keys on first run) + ginxsom -p 8080 # Start on port 8080 + ginxsom -a # Set admin pubkey + ginxsom -r # Set relay privkey + ginxsom --debug-level=3 # Enable info-level debugging +``` + +### 7.2 First Startup Behavior + +On first startup (no database exists): + +1. Generate relay keypair +2. Generate admin keypair +3. Print keys ONCE to console: +``` +=== Ginxsom First Startup === + +Relay Keys (for server): + Public Key (npub): npub1... + Private Key (nsec): nsec1... + +Admin Keys (for you): + Public Key (npub): npub1... + Private Key (nsec): nsec1... + +IMPORTANT: Save these keys securely! +The admin private key will NOT be shown again. +The relay private key is stored in the database. + +Database created: .db +``` + +4. Store relay private key in database +5. Store admin public key in config +6. Start server + +### 7.3 Subsequent Startups + +On subsequent startups: + +1. Find existing database file +2. Load relay private key from database +3. Load admin public key from config +4. Apply CLI overrides if provided +5. Start server + +## 8. Comparison with c-relay + +### 8.1 Similarities + +| Feature | c-relay | ginxsom | +|---------|---------|---------| +| Event Types | Kind 23456/23457 | Kind 23456/23457 | +| Encryption | NIP-44 | NIP-44 | +| Command Format | JSON arrays | JSON arrays | +| Key Storage | relay_seckey table | relay_seckey table | +| Admin Auth | config table | config table | +| CLI Options | --admin-pubkey, --relay-privkey | --admin-pubkey, --relay-privkey | +| Response Format | Encrypted JSON | Encrypted JSON | + +### 8.2 Differences + +| Aspect | c-relay | ginxsom | +|--------|---------|---------| +| Transport | WebSocket (Nostr relay) | WebSocket (FastCGI) | +| Commands | Relay-specific (auth, config, stats) | Blossom-specific (blob, storage, mirror) | +| Database | SQLite (events) | SQLite (blobs + metadata) | +| File Storage | N/A | Blob storage on disk | +| Integration | Standalone relay | FastCGI + nginx | + +### 8.3 Architectural Decisions + +**Why follow c-relay's pattern?** +1. Proven in production +2. Simple and secure +3. No complex key management +4. Minimal database schema +5. Easy to understand and maintain + +**What we're NOT doing (from initial design)**: +1. ❌ NIP-17 gift wrap (too complex) +2. ❌ Separate admin_keys table (use config) +3. ❌ Audit log table (keep it simple) +4. ❌ Processed events tracking (stateless) +5. ❌ Key encryption before storage (plain hex) +6. ❌ Migration strategy (new project) + +## 9. Testing Strategy + +### 9.1 Unit Tests + +**admin_keys.c**: +- Key generation produces valid keys +- Keys can be stored and retrieved +- Invalid keys are rejected + +**admin_auth.c**: +- Valid admin events pass authorization +- Invalid signatures are rejected +- Wrong pubkeys are rejected +- Expired events are rejected + +**admin_handlers.c**: +- Each command handler works correctly +- Invalid parameters are rejected +- Error responses are properly formatted + +### 9.2 Integration Tests + +**Full Flow**: +1. Generate admin keypair +2. Create Kind 23456 command +3. Send via WebSocket +4. Verify authorization +5. Execute command +6. Receive Kind 23457 response +7. Decrypt and verify response + +**Security Tests**: +- Unauthorized pubkey rejected +- Invalid signature rejected +- Replay attack prevented +- Command injection prevented + +### 9.3 Performance Tests + +- WebSocket connection handling +- Command processing latency +- Concurrent admin operations +- Large response handling + +## 10. Future Enhancements + +### 10.1 Short Term + +1. **Command History**: Track admin commands for audit +2. **Multi-Admin Support**: Multiple authorized admin pubkeys +3. **Role-Based Access**: Different permission levels +4. **Batch Operations**: Execute multiple commands in one request + +### 10.2 Long Term + +1. **Web Dashboard**: Full-featured web UI +2. **Monitoring Integration**: Prometheus/Grafana metrics +3. **Backup Automation**: Scheduled backups +4. **Replication**: Multi-server blob replication +5. **Advanced Analytics**: Usage patterns, trends, predictions + +## 11. References + +### 11.1 Nostr NIPs + +- **NIP-01**: Basic protocol flow +- **NIP-04**: Encrypted Direct Messages (deprecated, but reference) +- **NIP-19**: bech32-encoded entities (npub, nsec) +- **NIP-44**: Versioned Encryption (used for admin commands) + +### 11.2 Blossom Specifications + +- **BUD-01**: Blob Upload/Download +- **BUD-02**: Blob Descriptor +- **BUD-04**: Mirroring +- **BUD-06**: Upload Requirements +- **BUD-08**: NIP-94 Integration +- **BUD-09**: Blob Reporting + +### 11.3 c-relay Source Files + +- `c-relay/src/dm_admin.c` - Admin event processing +- `c-relay/src/api.c` - NIP-44 encryption +- `c-relay/src/config.c` - Key storage +- `c-relay/src/main.c` - CLI options +- `c-relay/src/sql_schema.h` - Database schema + +## 12. Appendix + +### 12.1 Example Admin CLI Tool (Python) + +```python +#!/usr/bin/env python3 +""" +Ginxsom Admin CLI Tool +Sends admin commands to ginxsom server via WebSocket +""" + +import asyncio +import websockets +import json +from nostr_sdk import Keys, Event, EventBuilder, Kind + +class GinxsomAdmin: + def __init__(self, server_url, admin_nsec, relay_npub): + self.server_url = server_url + self.admin_keys = Keys.parse(admin_nsec) + self.relay_pubkey = Keys.parse(relay_npub).public_key() + + async def send_command(self, command, params): + """Send admin command and wait for response""" + # Build command array + command_array = [command, params] + + # Encrypt with NIP-44 + encrypted = self.admin_keys.nip44_encrypt( + self.relay_pubkey, + json.dumps(command_array) + ) + + # Build Kind 23456 event + event = EventBuilder( + Kind(23456), + encrypted, + [["p", str(self.relay_pubkey)]] + ).to_event(self.admin_keys) + + # Send via WebSocket + async with websockets.connect(self.server_url) as ws: + await ws.send(json.dumps(event.as_json())) + + # Wait for Kind 23457 response + response = await ws.recv() + response_event = Event.from_json(response) + + # Decrypt response + decrypted = self.admin_keys.nip44_decrypt( + self.relay_pubkey, + response_event.content() + ) + + return json.loads(decrypted) + +# Usage +async def main(): + admin = GinxsomAdmin( + "ws://localhost:8080/admin", + "nsec1...", # Admin private key + "npub1..." # Relay public key + ) + + # List blobs + result = await admin.send_command("blob_list", { + "limit": 10, + "offset": 0 + }) + + print(json.dumps(result, indent=2)) + +if __name__ == "__main__": + asyncio.run(main()) +``` + +### 12.2 Database Schema SQL + +```sql +-- Add to db/schema.sql + +-- Relay Private Key Storage +CREATE TABLE relay_seckey ( + private_key_hex TEXT NOT NULL CHECK (length(private_key_hex) = 64), + created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')) +); + +-- Admin Public Key (add to config table) +INSERT INTO config (key, value, data_type, description, category, requires_restart) +VALUES ( + 'admin_pubkey', + '', -- Set during first startup + 'string', + 'Public key of authorized admin (64-char hex)', + 'security', + 0 +); + +-- Relay Public Key (add to config table) +INSERT INTO config (key, value, data_type, description, category, requires_restart) +VALUES ( + 'relay_pubkey', + '', -- Set during first startup + 'string', + 'Public key of this relay (64-char hex)', + 'server', + 0 +); +``` + +### 12.3 Makefile Updates + +```makefile +# Add to Makefile + +# Admin system objects +ADMIN_OBJS = build/admin_websocket.o \ + build/admin_auth.o \ + build/admin_handlers.o \ + build/admin_config.o \ + build/admin_keys.o + +# Update main target +build/ginxsom-fcgi: $(OBJS) $(ADMIN_OBJS) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +# Admin system rules +build/admin_websocket.o: src/admin_websocket.c + $(CC) $(CFLAGS) -c $< -o $@ + +build/admin_auth.o: src/admin_auth.c + $(CC) $(CFLAGS) -c $< -o $@ + +build/admin_handlers.o: src/admin_handlers.c + $(CC) $(CFLAGS) -c $< -o $@ + +build/admin_config.o: src/admin_config.c + $(CC) $(CFLAGS) -c $< -o $@ + +build/admin_keys.o: src/admin_keys.c + $(CC) $(CFLAGS) -c $< -o $@ +``` + +--- + +**Document Version**: 2.0 +**Last Updated**: 2025-01-16 +**Status**: Ready for Implementation \ No newline at end of file diff --git a/remote.nginx.config b/remote.nginx.config index 6ef282d..eb86337 100644 --- a/remote.nginx.config +++ b/remote.nginx.config @@ -15,6 +15,10 @@ server { root /var/www/html; index index.html index.htm; + # CORS for Nostr NIP-05 verification + add_header Access-Control-Allow-Origin * always; + add_header Access-Control-Allow-Methods "GET, OPTIONS" always; + add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range" always; location / { try_files $uri $uri/ =404; @@ -42,6 +46,10 @@ server { root /var/www/html; index index.html index.htm; + # CORS for Nostr NIP-05 verification + add_header Access-Control-Allow-Origin * always; + add_header Access-Control-Allow-Methods "GET, OPTIONS" always; + add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range" always; location / { try_files $uri $uri/ =404; @@ -58,7 +66,7 @@ server { # Blossom subdomains HTTP - redirect to HTTPS (keep for ACME) server { listen 80; - server_name blossom.laantungir.com blossom.laantungir.net blossom.laantungir.org; + server_name blossom.laantungir.net; location /.well-known/acme-challenge/ { root /var/www/certbot; @@ -72,7 +80,7 @@ server { # Blossom subdomains HTTPS - ginxsom FastCGI server { listen 443 ssl; - server_name blossom.laantungir.com blossom.laantungir.net blossom.laantungir.org; + server_name blossom.laantungir.net; ssl_certificate /etc/letsencrypt/live/git.laantungir.net/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/git.laantungir.net/privkey.pem; @@ -241,7 +249,7 @@ server { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_cache_bypass $http_upgrade; - proxy_read_timeout 86400s; + proxy_read_timeout 86400s; proxy_send_timeout 86400s; proxy_connect_timeout 60s; proxy_buffering off; @@ -256,8 +264,8 @@ server { listen 443 ssl; server_name relay.laantungir.com relay.laantungir.net relay.laantungir.org; - ssl_certificate /etc/letsencrypt/live/blossom.laantungir.net/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/blossom.laantungir.net/privkey.pem; + ssl_certificate /etc/letsencrypt/live/git.laantungir.net/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/git.laantungir.net/privkey.pem; location / { proxy_pass http://127.0.0.1:8888; @@ -373,4 +381,4 @@ server { proxy_set_header X-Forwarded-Proto $scheme; proxy_cache_bypass $http_upgrade; } - } + } \ No newline at end of file diff --git a/restart-all.sh b/restart-all.sh index 8f4fd3a..cbfe856 100755 --- a/restart-all.sh +++ b/restart-all.sh @@ -4,8 +4,32 @@ # Configuration +# Parse command line arguments +TEST_MODE=0 +FOLLOW_LOGS=0 + +while [[ $# -gt 0 ]]; do + case $1 in + -t|--test-keys) + TEST_MODE=1 + shift + ;; + --follow) + FOLLOW_LOGS=1 + shift + ;; + *) + echo "Unknown option: $1" + echo "Usage: $0 [-t|--test-keys] [--follow]" + echo " -t, --test-keys Use test mode with keys from .test_keys" + echo " --follow Follow logs in real-time" + exit 1 + ;; + esac +done + # Check for --follow flag -if [[ "$1" == "--follow" ]]; then +if [[ $FOLLOW_LOGS -eq 1 ]]; then echo "=== Following logs in real-time ===" echo "Monitoring: nginx error, nginx access, app stderr, app stdout" echo "Press Ctrl+C to stop following logs" @@ -37,7 +61,12 @@ touch logs/app/stderr.log logs/app/stdout.log logs/nginx/error.log logs/nginx/ac chmod 644 logs/app/stderr.log logs/app/stdout.log logs/nginx/error.log logs/nginx/access.log chmod 755 logs/nginx logs/app -echo -e "${YELLOW}=== Ginxsom Development Environment Restart ===${NC}" +if [ $TEST_MODE -eq 1 ]; then + echo -e "${YELLOW}=== Ginxsom Development Environment Restart (TEST MODE) ===${NC}" + echo "Using test keys from .test_keys file" +else + echo -e "${YELLOW}=== Ginxsom Development Environment Restart ===${NC}" +fi echo "Starting full restart sequence..." # Function to check if a process is running @@ -148,6 +177,42 @@ if [ $? -ne 0 ]; then fi echo -e "${GREEN}Clean rebuild complete${NC}" +# Step 3.5: Handle keys based on mode +echo -e "\n${YELLOW}3.5. Configuring server keys...${NC}" +DB_PATH="$PWD/db/ginxsom.db" + +if [ $TEST_MODE -eq 1 ]; then + # Test mode: verify .test_keys file exists + if [ ! -f ".test_keys" ]; then + echo -e "${RED}ERROR: .test_keys file not found${NC}" + echo -e "${RED}Test mode requires .test_keys file in project root${NC}" + exit 1 + fi + echo -e "${GREEN}Test mode: Will use keys from .test_keys${NC}" +else + # Production mode: check if keys exist, generate if needed + NEED_KEYS=1 + if command -v sqlite3 >/dev/null 2>&1; then + if sqlite3 "$DB_PATH" "SELECT seckey FROM blossom_seckey WHERE id=1" 2>/dev/null | grep -Eq '^[0-9a-f]{64}$'; then + NEED_KEYS=0 + echo -e "${GREEN}Blossom private key found in database${NC}" + fi + else + echo -e "${YELLOW}sqlite3 not found; assuming keys may be missing${NC}" + fi + + if [ $NEED_KEYS -eq 1 ]; then + echo -e "${YELLOW}No blossom key found; generating server keypair...${NC}" + ./build/ginxsom-fcgi --db-path "$DB_PATH" --storage-dir blobs --generate-keys 1>>logs/app/stdout.log 2>>logs/app/stderr.log + if [ $? -ne 0 ]; then + echo -e "${RED}Key generation failed. Check logs/app/stderr.log${NC}" + exit 1 + fi + echo -e "${GREEN}Key generation completed${NC}" + echo -e "${YELLOW}IMPORTANT: Check logs/app/stderr.log for your generated keys!${NC}" + fi +fi + # Step 4: Start FastCGI echo -e "\n${YELLOW}4. Starting FastCGI application...${NC}" echo "Socket: $SOCKET_PATH" @@ -166,9 +231,16 @@ fi echo "Setting GINX_DEBUG environment for pubkey extraction diagnostics" export GINX_DEBUG=1 +# Build command line arguments based on mode +FCGI_ARGS="--db-path $PWD/db/ginxsom.db --storage-dir blobs" +if [ $TEST_MODE -eq 1 ]; then + FCGI_ARGS="$FCGI_ARGS --test-keys" + echo -e "${YELLOW}Starting FastCGI in TEST MODE with test keys${NC}" +fi + # Start FastCGI application with proper logging (daemonized but with redirected streams) echo "FastCGI starting at $(date)" >> logs/app/stderr.log -spawn-fcgi -s "$SOCKET_PATH" -M 666 -u "$USER" -g "$USER" -P "$PID_FILE" -- "$FCGI_BINARY" --storage-dir blobs 1>>logs/app/stdout.log 2>>logs/app/stderr.log +spawn-fcgi -s "$SOCKET_PATH" -M 666 -u "$USER" -g "$USER" -P "$PID_FILE" -- "$FCGI_BINARY" $FCGI_ARGS 1>>logs/app/stdout.log 2>>logs/app/stderr.log if [ $? -eq 0 ] && [ -f "$PID_FILE" ]; then PID=$(cat "$PID_FILE") diff --git a/src/admin_auth.c b/src/admin_auth.c new file mode 100644 index 0000000..4abb05e --- /dev/null +++ b/src/admin_auth.c @@ -0,0 +1,509 @@ +/* + * Ginxsom Admin Authentication Module + * Handles Kind 23456/23457 admin events with NIP-44 encryption + * Based on c-relay's dm_admin.c implementation + */ + +#include "ginxsom.h" +#include "../nostr_core_lib/nostr_core/nostr_common.h" +#include "../nostr_core_lib/nostr_core/nip001.h" +#include "../nostr_core_lib/nostr_core/nip044.h" +#include "../nostr_core_lib/nostr_core/utils.h" +#include +#include +#include +#include +#include +#include + +// Forward declarations +int get_blossom_private_key(char *seckey_out, size_t max_len); +int validate_admin_pubkey(const char *pubkey); + +// Global variables for admin auth +static char g_blossom_seckey[65] = ""; // Cached blossom server private key +static int g_keys_loaded = 0; // Whether keys have been loaded + +// Load blossom server keys if not already loaded +static int ensure_keys_loaded(void) { + if (!g_keys_loaded) { + if (get_blossom_private_key(g_blossom_seckey, sizeof(g_blossom_seckey)) != 0) { + fprintf(stderr, "ERROR: Cannot load blossom private key for admin auth\n"); + return -1; + } + g_keys_loaded = 1; + } + return 0; +} + +// Validate that an event is a Kind 23456 admin command event +int is_admin_command_event(cJSON *event, const char *relay_pubkey) { + if (!event || !relay_pubkey) { + return 0; + } + + // Check kind = 23456 (admin command) + cJSON *kind = cJSON_GetObjectItem(event, "kind"); + if (!cJSON_IsNumber(kind) || kind->valueint != 23456) { + return 0; + } + + // Check tags for 'p' tag with relay pubkey + cJSON *tags = cJSON_GetObjectItem(event, "tags"); + if (!cJSON_IsArray(tags)) { + return 0; + } + + int found_p_tag = 0; + cJSON *tag = NULL; + cJSON_ArrayForEach(tag, tags) { + if (cJSON_IsArray(tag) && cJSON_GetArraySize(tag) >= 2) { + cJSON *tag_name = cJSON_GetArrayItem(tag, 0); + cJSON *tag_value = cJSON_GetArrayItem(tag, 1); + + if (cJSON_IsString(tag_name) && strcmp(tag_name->valuestring, "p") == 0 && + cJSON_IsString(tag_value) && strcmp(tag_value->valuestring, relay_pubkey) == 0) { + found_p_tag = 1; + break; + } + } + } + + return found_p_tag; +} + +// Validate admin event signature and pubkey +int validate_admin_event(cJSON *event) { + if (!event) { + return 0; + } + + // Get event fields + cJSON *pubkey = cJSON_GetObjectItem(event, "pubkey"); + cJSON *sig = cJSON_GetObjectItem(event, "sig"); + + if (!cJSON_IsString(pubkey) || !cJSON_IsString(sig)) { + fprintf(stderr, "AUTH: Invalid event format - missing pubkey or sig\n"); + return 0; + } + + // Check if pubkey matches configured admin pubkey + if (!validate_admin_pubkey(pubkey->valuestring)) { + fprintf(stderr, "AUTH: Pubkey %s is not authorized admin\n", pubkey->valuestring); + return 0; + } + + // TODO: Validate event signature using nostr_core_lib + // For now, assume signature is valid if pubkey matches + // In production, this should verify the signature cryptographically + + return 1; +} + +// Decrypt NIP-44 encrypted admin command +int decrypt_admin_command(cJSON *event, char **decrypted_command_out) { + if (!event || !decrypted_command_out) { + return -1; + } + + // Ensure we have the relay private key + if (ensure_keys_loaded() != 0) { + return -1; + } + + // Get admin pubkey from event + cJSON *admin_pubkey_json = cJSON_GetObjectItem(event, "pubkey"); + if (!cJSON_IsString(admin_pubkey_json)) { + fprintf(stderr, "AUTH: Missing or invalid pubkey in event\n"); + return -1; + } + + // Get encrypted content + cJSON *content = cJSON_GetObjectItem(event, "content"); + if (!cJSON_IsString(content)) { + fprintf(stderr, "AUTH: Missing or invalid content in event\n"); + return -1; + } + + // Convert hex keys to bytes + unsigned char blossom_private_key[32]; + unsigned char admin_public_key[32]; + + if (nostr_hex_to_bytes(g_blossom_seckey, blossom_private_key, 32) != 0) { + fprintf(stderr, "AUTH: Failed to parse blossom private key\n"); + return -1; + } + + if (nostr_hex_to_bytes(admin_pubkey_json->valuestring, admin_public_key, 32) != 0) { + fprintf(stderr, "AUTH: Failed to parse admin public key\n"); + return -1; + } + + // Allocate buffer for decrypted content + char decrypted_buffer[8192]; + + // Decrypt using NIP-44 + int result = nostr_nip44_decrypt( + blossom_private_key, + admin_public_key, + content->valuestring, + decrypted_buffer, + sizeof(decrypted_buffer) + ); + + if (result != NOSTR_SUCCESS) { + fprintf(stderr, "AUTH: NIP-44 decryption failed with error code %d\n", result); + return -1; + } + + // Allocate and copy decrypted content + *decrypted_command_out = malloc(strlen(decrypted_buffer) + 1); + if (!*decrypted_command_out) { + fprintf(stderr, "AUTH: Failed to allocate memory for decrypted content\n"); + return -1; + } + strcpy(*decrypted_command_out, decrypted_buffer); + + return 0; +} + +// Parse decrypted command array +int parse_admin_command(const char *decrypted_content, char ***command_array_out, int *command_count_out) { + if (!decrypted_content || !command_array_out || !command_count_out) { + return -1; + } + + // Parse the decrypted content as JSON array + cJSON *content_json = cJSON_Parse(decrypted_content); + if (!content_json) { + fprintf(stderr, "AUTH: Failed to parse decrypted content as JSON\n"); + return -1; + } + + if (!cJSON_IsArray(content_json)) { + fprintf(stderr, "AUTH: Decrypted content is not a JSON array\n"); + cJSON_Delete(content_json); + return -1; + } + + int array_size = cJSON_GetArraySize(content_json); + if (array_size < 1) { + fprintf(stderr, "AUTH: Command array is empty\n"); + cJSON_Delete(content_json); + return -1; + } + + // Allocate command array + char **command_array = malloc(array_size * sizeof(char *)); + if (!command_array) { + fprintf(stderr, "AUTH: Failed to allocate command array\n"); + cJSON_Delete(content_json); + return -1; + } + + // Parse each array element as string + for (int i = 0; i < array_size; i++) { + cJSON *item = cJSON_GetArrayItem(content_json, i); + if (!cJSON_IsString(item)) { + fprintf(stderr, "AUTH: Command array element %d is not a string\n", i); + // Clean up allocated strings + for (int j = 0; j < i; j++) { + free(command_array[j]); + } + free(command_array); + cJSON_Delete(content_json); + return -1; + } + + command_array[i] = malloc(strlen(item->valuestring) + 1); + if (!command_array[i]) { + fprintf(stderr, "AUTH: Failed to allocate command string\n"); + // Clean up allocated strings + for (int j = 0; j < i; j++) { + free(command_array[j]); + } + free(command_array); + cJSON_Delete(content_json); + return -1; + } + strcpy(command_array[i], item->valuestring); + if (!command_array[i]) { + fprintf(stderr, "AUTH: Failed to duplicate command string\n"); + // Clean up allocated strings + for (int j = 0; j < i; j++) { + free(command_array[j]); + } + free(command_array); + cJSON_Delete(content_json); + return -1; + } + } + + cJSON_Delete(content_json); + *command_array_out = command_array; + *command_count_out = array_size; + + return 0; +} + +// Process incoming admin command event (Kind 23456) +int process_admin_command(cJSON *event, char ***command_array_out, int *command_count_out, char **admin_pubkey_out) { + if (!event || !command_array_out || !command_count_out || !admin_pubkey_out) { + return -1; + } + + // Get blossom server pubkey from config + sqlite3 *db; + sqlite3_stmt *stmt; + char blossom_pubkey[65] = ""; + + if (sqlite3_open_v2("db/ginxsom.db", &db, SQLITE_OPEN_READONLY, NULL) != SQLITE_OK) { + return -1; + } + + const char *sql = "SELECT value FROM config WHERE key = 'blossom_pubkey'"; + if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) == SQLITE_OK) { + if (sqlite3_step(stmt) == SQLITE_ROW) { + const char *pubkey = (const char *)sqlite3_column_text(stmt, 0); + if (pubkey) { + strncpy(blossom_pubkey, pubkey, sizeof(blossom_pubkey) - 1); + } + } + sqlite3_finalize(stmt); + } + sqlite3_close(db); + + if (strlen(blossom_pubkey) != 64) { + fprintf(stderr, "ERROR: Cannot determine blossom pubkey for admin auth\n"); + return -1; + } + + // Check if it's a valid admin command event for us + if (!is_admin_command_event(event, blossom_pubkey)) { + return -1; + } + + // Validate admin authentication (signature and pubkey) + if (!validate_admin_event(event)) { + return -1; + } + + // Get admin pubkey from event + cJSON *admin_pubkey_json = cJSON_GetObjectItem(event, "pubkey"); + if (!cJSON_IsString(admin_pubkey_json)) { + return -1; + } + + *admin_pubkey_out = malloc(strlen(admin_pubkey_json->valuestring) + 1); + if (!*admin_pubkey_out) { + fprintf(stderr, "AUTH: Failed to allocate admin pubkey string\n"); + return -1; + } + strcpy(*admin_pubkey_out, admin_pubkey_json->valuestring); + if (!*admin_pubkey_out) { + return -1; + } + + // Decrypt the command + char *decrypted_content = NULL; + if (decrypt_admin_command(event, &decrypted_content) != 0) { + free(*admin_pubkey_out); + *admin_pubkey_out = NULL; + return -1; + } + + // Parse the command array + if (parse_admin_command(decrypted_content, command_array_out, command_count_out) != 0) { + free(decrypted_content); + free(*admin_pubkey_out); + *admin_pubkey_out = NULL; + return -1; + } + + free(decrypted_content); + return 0; +} + +// Validate admin pubkey against configured admin +int validate_admin_pubkey(const char *pubkey) { + if (!pubkey || strlen(pubkey) != 64) { + return 0; + } + + sqlite3 *db; + sqlite3_stmt *stmt; + int result = 0; + + if (sqlite3_open_v2("db/ginxsom.db", &db, SQLITE_OPEN_READONLY, NULL) != SQLITE_OK) { + return 0; + } + + const char *sql = "SELECT value FROM config WHERE key = 'admin_pubkey'"; + if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) == SQLITE_OK) { + if (sqlite3_step(stmt) == SQLITE_ROW) { + const char *admin_pubkey = (const char *)sqlite3_column_text(stmt, 0); + if (admin_pubkey && strcmp(admin_pubkey, pubkey) == 0) { + result = 1; + } + } + sqlite3_finalize(stmt); + } + sqlite3_close(db); + + return result; +} + +// Create encrypted response for admin (Kind 23457) +int create_admin_response(const char *response_json, const char *admin_pubkey, const char *original_event_id __attribute__((unused)), cJSON **response_event_out) { + if (!response_json || !admin_pubkey || !response_event_out) { + return -1; + } + + // Ensure we have the relay private key + if (ensure_keys_loaded() != 0) { + return -1; + } + + // Get blossom server pubkey from config + sqlite3 *db; + sqlite3_stmt *stmt; + char blossom_pubkey[65] = ""; + + if (sqlite3_open_v2("db/ginxsom.db", &db, SQLITE_OPEN_READONLY, NULL) != SQLITE_OK) { + return -1; + } + + const char *sql = "SELECT value FROM config WHERE key = 'blossom_pubkey'"; + if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) == SQLITE_OK) { + if (sqlite3_step(stmt) == SQLITE_ROW) { + const char *pubkey = (const char *)sqlite3_column_text(stmt, 0); + if (pubkey) { + strncpy(blossom_pubkey, pubkey, sizeof(blossom_pubkey) - 1); + } + } + sqlite3_finalize(stmt); + } + sqlite3_close(db); + + if (strlen(blossom_pubkey) != 64) { + fprintf(stderr, "ERROR: Cannot determine blossom pubkey for response\n"); + return -1; + } + + // Convert hex keys to bytes + unsigned char blossom_private_key[32]; + unsigned char admin_public_key[32]; + + if (nostr_hex_to_bytes(g_blossom_seckey, blossom_private_key, 32) != 0) { + fprintf(stderr, "AUTH: Failed to parse blossom private key\n"); + return -1; + } + + if (nostr_hex_to_bytes(admin_pubkey, admin_public_key, 32) != 0) { + fprintf(stderr, "AUTH: Failed to parse admin public key\n"); + return -1; + } + + // Encrypt response using NIP-44 + char encrypted_content[8192]; + int result = nostr_nip44_encrypt( + blossom_private_key, + admin_public_key, + response_json, + encrypted_content, + sizeof(encrypted_content) + ); + + if (result != NOSTR_SUCCESS) { + fprintf(stderr, "AUTH: NIP-44 encryption failed with error code %d\n", result); + return -1; + } + + // Create Kind 23457 response event + cJSON *response_event = cJSON_CreateObject(); + if (!response_event) { + fprintf(stderr, "AUTH: Failed to create response event JSON\n"); + return -1; + } + + // Set event fields + cJSON_AddNumberToObject(response_event, "kind", 23457); + cJSON_AddStringToObject(response_event, "pubkey", blossom_pubkey); + cJSON_AddNumberToObject(response_event, "created_at", (double)time(NULL)); + cJSON_AddStringToObject(response_event, "content", encrypted_content); + + // Add tags array with 'p' tag for admin + cJSON *tags = cJSON_CreateArray(); + cJSON *p_tag = cJSON_CreateArray(); + cJSON_AddItemToArray(p_tag, cJSON_CreateString("p")); + cJSON_AddItemToArray(p_tag, cJSON_CreateString(admin_pubkey)); + cJSON_AddItemToArray(tags, p_tag); + cJSON_AddItemToObject(response_event, "tags", tags); + + // Sign the event with blossom private key + // Convert private key hex to bytes + unsigned char blossom_private_key_bytes[32]; + if (nostr_hex_to_bytes(g_blossom_seckey, blossom_private_key_bytes, 32) != 0) { + fprintf(stderr, "AUTH: Failed to parse blossom private key for signing\n"); + cJSON_Delete(response_event); + return -1; + } + + // Create a temporary event structure for signing + cJSON* temp_event = cJSON_Duplicate(response_event, 1); + if (!temp_event) { + fprintf(stderr, "AUTH: Failed to create temp event for signing\n"); + cJSON_Delete(response_event); + return -1; + } + + // Sign the event using nostr_core_lib + cJSON* signed_event = nostr_create_and_sign_event( + 23457, // Kind 23457 (admin response) + encrypted_content, // content + cJSON_GetObjectItem(response_event, "tags"), // tags + blossom_private_key_bytes, // private key + (time_t)cJSON_GetNumberValue(cJSON_GetObjectItem(response_event, "created_at")) // timestamp + ); + + if (!signed_event) { + fprintf(stderr, "AUTH: Failed to sign admin response event\n"); + cJSON_Delete(response_event); + cJSON_Delete(temp_event); + return -1; + } + + // Extract id and signature from signed event + cJSON* signed_id = cJSON_GetObjectItem(signed_event, "id"); + cJSON* signed_sig = cJSON_GetObjectItem(signed_event, "sig"); + + if (signed_id && signed_sig) { + cJSON_AddStringToObject(response_event, "id", cJSON_GetStringValue(signed_id)); + cJSON_AddStringToObject(response_event, "sig", cJSON_GetStringValue(signed_sig)); + } else { + fprintf(stderr, "AUTH: Signed event missing id or sig\n"); + cJSON_Delete(response_event); + cJSON_Delete(signed_event); + cJSON_Delete(temp_event); + return -1; + } + + // Clean up temporary structures + cJSON_Delete(signed_event); + cJSON_Delete(temp_event); + + *response_event_out = response_event; + return 0; +} + +// Free command array allocated by parse_admin_command +void free_command_array(char **command_array, int command_count) { + if (command_array) { + for (int i = 0; i < command_count; i++) { + if (command_array[i]) { + free(command_array[i]); + } + } + free(command_array); + } +} \ No newline at end of file diff --git a/src/admin_handlers.c b/src/admin_handlers.c new file mode 100644 index 0000000..a705657 --- /dev/null +++ b/src/admin_handlers.c @@ -0,0 +1,216 @@ +/* + * Ginxsom Admin Command Handlers + * Implements execution of admin commands received via Kind 23456 events + */ + +#include "ginxsom.h" +#include +#include +#include +#include +#include +#include +#include + +// Forward declarations +static cJSON* handle_blob_list(char **args, int arg_count); +static cJSON* handle_blob_info(char **args, int arg_count); +static cJSON* handle_blob_delete(char **args, int arg_count); +static cJSON* handle_storage_stats(char **args, int arg_count); +static cJSON* handle_config_get(char **args, int arg_count); +static cJSON* handle_config_set(char **args, int arg_count); +static cJSON* handle_help(char **args, int arg_count); + +// Command dispatch table +typedef struct { + const char *command; + cJSON* (*handler)(char **args, int arg_count); + const char *description; +} admin_command_t; + +static admin_command_t command_table[] = { + {"blob_list", handle_blob_list, "List all blobs"}, + {"blob_info", handle_blob_info, "Get blob information"}, + {"blob_delete", handle_blob_delete, "Delete a blob"}, + {"storage_stats", handle_storage_stats, "Get storage statistics"}, + {"config_get", handle_config_get, "Get configuration value"}, + {"config_set", handle_config_set, "Set configuration value"}, + {"help", handle_help, "Show available commands"}, + {NULL, NULL, NULL} +}; + +// Execute admin command and return JSON response +int execute_admin_command(char **command_array, int command_count, char **response_json_out) { + if (!command_array || command_count < 1 || !response_json_out) { + return -1; + } + + const char *command = command_array[0]; + + // Find command handler + admin_command_t *cmd = NULL; + for (int i = 0; command_table[i].command != NULL; i++) { + if (strcmp(command_table[i].command, command) == 0) { + cmd = &command_table[i]; + break; + } + } + + cJSON *response; + if (cmd) { + // Execute command handler + response = cmd->handler(command_array + 1, command_count - 1); + } else { + // Unknown command + response = cJSON_CreateObject(); + cJSON_AddStringToObject(response, "status", "error"); + cJSON_AddStringToObject(response, "message", "Unknown command"); + cJSON_AddStringToObject(response, "command", command); + } + + // Convert response to JSON string + char *json_str = cJSON_PrintUnformatted(response); + cJSON_Delete(response); + + if (!json_str) { + return -1; + } + + *response_json_out = json_str; + return 0; +} + +// Command handlers + +static cJSON* handle_blob_list(char **args __attribute__((unused)), int arg_count __attribute__((unused))) { + cJSON *response = cJSON_CreateObject(); + cJSON_AddStringToObject(response, "status", "success"); + cJSON_AddStringToObject(response, "command", "blob_list"); + + // TODO: Implement actual blob listing from database + cJSON *blobs = cJSON_CreateArray(); + cJSON_AddItemToObject(response, "blobs", blobs); + cJSON_AddNumberToObject(response, "count", 0); + + return response; +} + +static cJSON* handle_blob_info(char **args, int arg_count) { + cJSON *response = cJSON_CreateObject(); + + if (arg_count < 1) { + cJSON_AddStringToObject(response, "status", "error"); + cJSON_AddStringToObject(response, "message", "Missing blob hash argument"); + return response; + } + + cJSON_AddStringToObject(response, "status", "success"); + cJSON_AddStringToObject(response, "command", "blob_info"); + cJSON_AddStringToObject(response, "hash", args[0]); + + // TODO: Implement actual blob info retrieval from database + cJSON_AddStringToObject(response, "message", "Not yet implemented"); + + return response; +} + +static cJSON* handle_blob_delete(char **args, int arg_count) { + cJSON *response = cJSON_CreateObject(); + + if (arg_count < 1) { + cJSON_AddStringToObject(response, "status", "error"); + cJSON_AddStringToObject(response, "message", "Missing blob hash argument"); + return response; + } + + cJSON_AddStringToObject(response, "status", "success"); + cJSON_AddStringToObject(response, "command", "blob_delete"); + cJSON_AddStringToObject(response, "hash", args[0]); + + // TODO: Implement actual blob deletion + cJSON_AddStringToObject(response, "message", "Not yet implemented"); + + return response; +} + +static cJSON* handle_storage_stats(char **args __attribute__((unused)), int arg_count __attribute__((unused))) { + cJSON *response = cJSON_CreateObject(); + cJSON_AddStringToObject(response, "status", "success"); + cJSON_AddStringToObject(response, "command", "storage_stats"); + + // Get filesystem stats + struct statvfs stat; + if (statvfs(".", &stat) == 0) { + unsigned long long total = stat.f_blocks * stat.f_frsize; + unsigned long long available = stat.f_bavail * stat.f_frsize; + unsigned long long used = total - available; + + cJSON_AddNumberToObject(response, "total_bytes", (double)total); + cJSON_AddNumberToObject(response, "used_bytes", (double)used); + cJSON_AddNumberToObject(response, "available_bytes", (double)available); + } + + // TODO: Add blob count and total blob size from database + cJSON_AddNumberToObject(response, "blob_count", 0); + cJSON_AddNumberToObject(response, "blob_total_bytes", 0); + + return response; +} + +static cJSON* handle_config_get(char **args, int arg_count) { + cJSON *response = cJSON_CreateObject(); + + if (arg_count < 1) { + cJSON_AddStringToObject(response, "status", "error"); + cJSON_AddStringToObject(response, "message", "Missing config key argument"); + return response; + } + + cJSON_AddStringToObject(response, "status", "success"); + cJSON_AddStringToObject(response, "command", "config_get"); + cJSON_AddStringToObject(response, "key", args[0]); + + // TODO: Implement actual config retrieval from database + cJSON_AddStringToObject(response, "value", ""); + cJSON_AddStringToObject(response, "message", "Not yet implemented"); + + return response; +} + +static cJSON* handle_config_set(char **args, int arg_count) { + cJSON *response = cJSON_CreateObject(); + + if (arg_count < 2) { + cJSON_AddStringToObject(response, "status", "error"); + cJSON_AddStringToObject(response, "message", "Missing config key or value argument"); + return response; + } + + cJSON_AddStringToObject(response, "status", "success"); + cJSON_AddStringToObject(response, "command", "config_set"); + cJSON_AddStringToObject(response, "key", args[0]); + cJSON_AddStringToObject(response, "value", args[1]); + + // TODO: Implement actual config update in database + cJSON_AddStringToObject(response, "message", "Not yet implemented"); + + return response; +} + +static cJSON* handle_help(char **args __attribute__((unused)), int arg_count __attribute__((unused))) { + cJSON *response = cJSON_CreateObject(); + cJSON_AddStringToObject(response, "status", "success"); + cJSON_AddStringToObject(response, "command", "help"); + + cJSON *commands = cJSON_CreateArray(); + for (int i = 0; command_table[i].command != NULL; i++) { + cJSON *cmd = cJSON_CreateObject(); + cJSON_AddStringToObject(cmd, "command", command_table[i].command); + cJSON_AddStringToObject(cmd, "description", command_table[i].description); + cJSON_AddItemToArray(commands, cmd); + } + + cJSON_AddItemToObject(response, "commands", commands); + + return response; +} \ No newline at end of file diff --git a/src/admin_websocket.c b/src/admin_websocket.c new file mode 100644 index 0000000..1c37248 --- /dev/null +++ b/src/admin_websocket.c @@ -0,0 +1,163 @@ +/* + * Ginxsom Admin WebSocket Module + * Handles WebSocket connections for Kind 23456/23457 admin commands + * Based on c-relay's WebSocket implementation + */ + +#include "ginxsom.h" +#include +#include +#include +#include +#include + +// Forward declarations from admin_auth.c +int process_admin_command(cJSON *event, char ***command_array_out, int *command_count_out, char **admin_pubkey_out); +void free_command_array(char **command_array, int command_count); +int create_admin_response(const char *response_json, const char *admin_pubkey, const char *original_event_id, cJSON **response_event_out); + +// Forward declarations from admin_handlers.c (to be created) +int execute_admin_command(char **command_array, int command_count, const char *admin_pubkey, char **response_json_out); + +// Handle WebSocket admin command endpoint (/api/admin) +void handle_admin_websocket_request(void) { + // For now, this is a placeholder for WebSocket implementation + // In a full implementation, this would: + // 1. Upgrade HTTP connection to WebSocket + // 2. Handle WebSocket frames + // 3. Process Kind 23456 events + // 4. Send Kind 23457 responses + + printf("Status: 501 Not Implemented\r\n"); + printf("Content-Type: application/json\r\n\r\n"); + printf("{\n"); + printf(" \"error\": \"websocket_not_implemented\",\n"); + printf(" \"message\": \"WebSocket admin endpoint not yet implemented\",\n"); + printf(" \"note\": \"Use HTTP POST to /api/admin for now\"\n"); + printf("}\n"); +} + +// Handle HTTP POST admin command endpoint (/api/admin) +void handle_admin_command_post_request(void) { + // Read the request body (should contain Kind 23456 event JSON) + const char *content_length_str = getenv("CONTENT_LENGTH"); + if (!content_length_str) { + printf("Status: 400 Bad Request\r\n"); + printf("Content-Type: application/json\r\n\r\n"); + printf("{\n"); + printf(" \"error\": \"missing_content_length\",\n"); + printf(" \"message\": \"Content-Length header required\"\n"); + printf("}\n"); + return; + } + + long content_length = atol(content_length_str); + if (content_length <= 0 || content_length > 1024 * 1024) { // 1MB limit + printf("Status: 400 Bad Request\r\n"); + printf("Content-Type: application/json\r\n\r\n"); + printf("{\n"); + printf(" \"error\": \"invalid_content_length\",\n"); + printf(" \"message\": \"Content-Length must be between 1 and 1MB\"\n"); + printf("}\n"); + return; + } + + // Read the request body + char *request_body = malloc(content_length + 1); + if (!request_body) { + printf("Status: 500 Internal Server Error\r\n"); + printf("Content-Type: application/json\r\n\r\n"); + printf("{\n"); + printf(" \"error\": \"memory_allocation_failed\",\n"); + printf(" \"message\": \"Failed to allocate memory for request body\"\n"); + printf("}\n"); + return; + } + + size_t bytes_read = fread(request_body, 1, content_length, stdin); + if (bytes_read != (size_t)content_length) { + free(request_body); + printf("Status: 400 Bad Request\r\n"); + printf("Content-Type: application/json\r\n\r\n"); + printf("{\n"); + printf(" \"error\": \"incomplete_request_body\",\n"); + printf(" \"message\": \"Failed to read complete request body\"\n"); + printf("}\n"); + return; + } + + request_body[content_length] = '\0'; + + // Parse the JSON event + cJSON *event = cJSON_Parse(request_body); + free(request_body); + + if (!event) { + printf("Status: 400 Bad Request\r\n"); + printf("Content-Type: application/json\r\n\r\n"); + printf("{\n"); + printf(" \"error\": \"invalid_json\",\n"); + printf(" \"message\": \"Request body is not valid JSON\"\n"); + printf("}\n"); + return; + } + + // Process the admin command + char **command_array = NULL; + int command_count = 0; + char *admin_pubkey = NULL; + + int result = process_admin_command(event, &command_array, &command_count, &admin_pubkey); + cJSON_Delete(event); + + if (result != 0) { + printf("Status: 400 Bad Request\r\n"); + printf("Content-Type: application/json\r\n\r\n"); + printf("{\n"); + printf(" \"error\": \"invalid_admin_command\",\n"); + printf(" \"message\": \"Failed to process admin command\"\n"); + printf("}\n"); + return; + } + + // Execute the command + char *response_json = NULL; + int exec_result = execute_admin_command(command_array, command_count, admin_pubkey, &response_json); + free_command_array(command_array, command_count); + free(admin_pubkey); + + if (exec_result != 0) { + printf("Status: 500 Internal Server Error\r\n"); + printf("Content-Type: application/json\r\n\r\n"); + printf("{\n"); + printf(" \"error\": \"command_execution_failed\",\n"); + printf(" \"message\": \"Failed to execute admin command\"\n"); + printf("}\n"); + return; + } + + // Create the response event (Kind 23457) + cJSON *response_event = NULL; + int create_result = create_admin_response(response_json, admin_pubkey, NULL, &response_event); + free(response_json); + + if (create_result != 0) { + printf("Status: 500 Internal Server Error\r\n"); + printf("Content-Type: application/json\r\n\r\n"); + printf("{\n"); + printf(" \"error\": \"response_creation_failed\",\n"); + printf(" \"message\": \"Failed to create admin response\"\n"); + printf("}\n"); + return; + } + + // Return the response event as JSON + char *response_json_str = cJSON_Print(response_event); + cJSON_Delete(response_event); + + printf("Status: 200 OK\r\n"); + printf("Content-Type: application/json\r\n\r\n"); + printf("%s\n", response_json_str); + + free(response_json_str); +} \ No newline at end of file diff --git a/src/ginxsom.h b/src/ginxsom.h index d2884c3..89fb5df 100644 --- a/src/ginxsom.h +++ b/src/ginxsom.h @@ -10,8 +10,8 @@ // Version information (auto-updated by build system) #define VERSION_MAJOR 0 #define VERSION_MINOR 1 -#define VERSION_PATCH 8 -#define VERSION "v0.1.8" +#define VERSION_PATCH 9 +#define VERSION "v0.1.9" #include #include diff --git a/src/main.c b/src/main.c index b942aeb..434c969 100644 --- a/src/main.c +++ b/src/main.c @@ -9,7 +9,6 @@ #include "../nostr_core_lib/nostr_core/utils.h" #include #include -#include #include #include #include @@ -30,6 +29,11 @@ char g_db_path[MAX_PATH_LEN] = "db/ginxsom.db"; char g_storage_dir[MAX_PATH_LEN] = "."; +// Key management variables +char g_admin_pubkey[65] = ""; // Admin public key for authorization +char g_blossom_seckey[65] = ""; // Blossom server private key for decryption/signing +int g_generate_keys = 0; // Flag to generate keys on startup + // Use global configuration variables #define DB_PATH g_db_path @@ -60,6 +64,174 @@ const char *get_config_dir(char *buffer, size_t buffer_size) { } +// Database initialization function +int initialize_database(const char *db_path) { + sqlite3 *db; + char *err_msg = NULL; + int rc; + + // Check if database file exists + struct stat st; + int db_exists = (stat(db_path, &st) == 0); + + // Open database with CREATE flag + rc = sqlite3_open_v2(db_path, &db, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); + if (rc != SQLITE_OK) { + fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db)); + sqlite3_close(db); + return -1; + } + + // If database was just created, initialize schema + if (!db_exists) { + fprintf(stderr, "Database not found, initializing schema...\n"); + + // Enable foreign key constraints + rc = sqlite3_exec(db, "PRAGMA foreign_keys = ON;", NULL, NULL, &err_msg); + if (rc != SQLITE_OK) { + fprintf(stderr, "Failed to enable foreign keys: %s\n", err_msg); + sqlite3_free(err_msg); + sqlite3_close(db); + return -1; + } + + // Create blobs table + const char *create_blobs = + "CREATE TABLE IF NOT EXISTS blobs (" + " sha256 TEXT PRIMARY KEY NOT NULL," + " size INTEGER NOT NULL," + " type TEXT NOT NULL," + " uploaded_at INTEGER NOT NULL," + " uploader_pubkey TEXT," + " filename TEXT," + " CHECK (length(sha256) = 64)," + " CHECK (size >= 0)," + " CHECK (uploaded_at > 0)" + ");"; + + rc = sqlite3_exec(db, create_blobs, NULL, NULL, &err_msg); + if (rc != SQLITE_OK) { + fprintf(stderr, "Failed to create blobs table: %s\n", err_msg); + sqlite3_free(err_msg); + sqlite3_close(db); + return -1; + } + + // Create config table + const char *create_config = + "CREATE TABLE IF NOT EXISTS config (" + " key TEXT PRIMARY KEY NOT NULL," + " value TEXT NOT NULL," + " description TEXT," + " created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now'))," + " updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now'))" + ");"; + + rc = sqlite3_exec(db, create_config, NULL, NULL, &err_msg); + if (rc != SQLITE_OK) { + fprintf(stderr, "Failed to create config table: %s\n", err_msg); + sqlite3_free(err_msg); + sqlite3_close(db); + return -1; + } + + // Create auth_rules table + const char *create_auth_rules = + "CREATE TABLE IF NOT EXISTS auth_rules (" + " id INTEGER PRIMARY KEY AUTOINCREMENT," + " rule_type TEXT NOT NULL," + " rule_target TEXT NOT NULL," + " operation TEXT NOT NULL DEFAULT '*'," + " enabled INTEGER NOT NULL DEFAULT 1," + " priority INTEGER NOT NULL DEFAULT 100," + " description TEXT," + " created_by TEXT," + " created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now'))," + " updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now'))," + " CHECK (rule_type IN ('pubkey_blacklist', 'pubkey_whitelist'," + " 'hash_blacklist', 'mime_blacklist', 'mime_whitelist'))," + " CHECK (operation IN ('upload', 'delete', 'list', '*'))," + " CHECK (enabled IN (0, 1))," + " CHECK (priority >= 0)," + " UNIQUE(rule_type, rule_target, operation)" + ");"; + + rc = sqlite3_exec(db, create_auth_rules, NULL, NULL, &err_msg); + if (rc != SQLITE_OK) { + fprintf(stderr, "Failed to create auth_rules table: %s\n", err_msg); + sqlite3_free(err_msg); + sqlite3_close(db); + return -1; + } + + // Create indexes + const char *create_indexes = + "CREATE INDEX IF NOT EXISTS idx_blobs_uploaded_at ON blobs(uploaded_at);" + "CREATE INDEX IF NOT EXISTS idx_blobs_uploader_pubkey ON blobs(uploader_pubkey);" + "CREATE INDEX IF NOT EXISTS idx_blobs_type ON blobs(type);" + "CREATE INDEX IF NOT EXISTS idx_config_updated_at ON config(updated_at);" + "CREATE INDEX IF NOT EXISTS idx_auth_rules_type_target ON auth_rules(rule_type, rule_target);" + "CREATE INDEX IF NOT EXISTS idx_auth_rules_operation ON auth_rules(operation);" + "CREATE INDEX IF NOT EXISTS idx_auth_rules_enabled ON auth_rules(enabled);" + "CREATE INDEX IF NOT EXISTS idx_auth_rules_priority ON auth_rules(priority);" + "CREATE INDEX IF NOT EXISTS idx_auth_rules_type_operation ON auth_rules(rule_type, operation, enabled);"; + + rc = sqlite3_exec(db, create_indexes, NULL, NULL, &err_msg); + if (rc != SQLITE_OK) { + fprintf(stderr, "Failed to create indexes: %s\n", err_msg); + sqlite3_free(err_msg); + sqlite3_close(db); + return -1; + } + + // Insert default configuration + const char *insert_config = + "INSERT OR IGNORE INTO config (key, value, description) VALUES" + " ('max_file_size', '104857600', 'Maximum file size in bytes (100MB)')," + " ('auth_rules_enabled', 'true', 'Whether authentication rules are enabled for uploads')," + " ('server_name', 'ginxsom', 'Server name for responses')," + " ('admin_pubkey', '', 'Admin public key for API access')," + " ('admin_enabled', 'false', 'Whether admin API is enabled')," + " ('nip42_require_auth', 'false', 'Enable NIP-42 challenge/response authentication')," + " ('nip42_challenge_timeout', '600', 'NIP-42 challenge timeout in seconds')," + " ('nip42_time_tolerance', '300', 'NIP-42 timestamp tolerance in seconds');"; + + rc = sqlite3_exec(db, insert_config, NULL, NULL, &err_msg); + if (rc != SQLITE_OK) { + fprintf(stderr, "Failed to insert default config: %s\n", err_msg); + sqlite3_free(err_msg); + sqlite3_close(db); + return -1; + } + + // Create storage_stats view + const char *create_view = + "CREATE VIEW IF NOT EXISTS storage_stats AS " + "SELECT " + " COUNT(*) as total_blobs, " + " SUM(size) as total_bytes, " + " AVG(size) as avg_blob_size, " + " MIN(uploaded_at) as first_upload, " + " MAX(uploaded_at) as last_upload, " + " COUNT(DISTINCT uploader_pubkey) as unique_uploaders " + "FROM blobs;"; + + rc = sqlite3_exec(db, create_view, NULL, NULL, &err_msg); + if (rc != SQLITE_OK) { + fprintf(stderr, "Failed to create storage_stats view: %s\n", err_msg); + sqlite3_free(err_msg); + sqlite3_close(db); + return -1; + } + + fprintf(stderr, "Database schema initialized successfully\n"); + } + + sqlite3_close(db); + return 0; +} + // Function declarations void handle_options_request(void); void send_error_response(int status_code, const char *error_type, @@ -67,6 +239,13 @@ void send_error_response(int status_code, const char *error_type, void log_request(const char *method, const char *uri, const char *auth_status, int status_code); +// Key management functions +int generate_random_private_key_bytes(unsigned char *key_bytes, size_t len); +int generate_server_keypair(void); +int load_server_keys(void); +int store_blossom_private_key(const char *seckey); +int get_blossom_private_key(char *seckey_out, size_t max_len); + // External validator function declarations const char *nostr_request_validator_get_last_violation_type(void); int nostr_generate_nip42_challenge(char *challenge_out, size_t challenge_size, const char *client_ip); @@ -77,6 +256,262 @@ void handle_auth_challenge_request(void); // Handler function declarations with validation support void handle_delete_request_with_validation(const char *sha256, nostr_request_result_t *validation_result); +// Key management function implementations + +// Generate random private key bytes using /dev/urandom +int generate_random_private_key_bytes(unsigned char *key_bytes, size_t len) { + FILE *fp = fopen("/dev/urandom", "rb"); + if (!fp) { + fprintf(stderr, "ERROR: Cannot open /dev/urandom for key generation\n"); + return -1; + } + + size_t bytes_read = fread(key_bytes, 1, len, fp); + fclose(fp); + + if (bytes_read != len) { + fprintf(stderr, "ERROR: Failed to read %zu bytes from /dev/urandom\n", len); + return -1; + } + + return 0; +} + +// Generate server keypair and store in database +int generate_server_keypair(void) { + fprintf(stderr, "DEBUG: generate_server_keypair() called\n"); + unsigned char seckey_bytes[32]; + char seckey_hex[65]; + char pubkey_hex[65]; + + // Generate random private key + fprintf(stderr, "DEBUG: Generating random private key...\n"); + if (generate_random_private_key_bytes(seckey_bytes, 32) != 0) { + fprintf(stderr, "DEBUG: Failed to generate random bytes\n"); + return -1; + } + + // Validate the private key + if (nostr_ec_private_key_verify(seckey_bytes) != NOSTR_SUCCESS) { + fprintf(stderr, "ERROR: Generated invalid private key\n"); + return -1; + } + + // Convert to hex + nostr_bytes_to_hex(seckey_bytes, 32, seckey_hex); + + // Derive public key + unsigned char pubkey_bytes[32]; + if (nostr_ec_public_key_from_private_key(seckey_bytes, pubkey_bytes) != NOSTR_SUCCESS) { + fprintf(stderr, "ERROR: Failed to derive public key\n"); + return -1; + } + + // Convert public key to hex + nostr_bytes_to_hex(pubkey_bytes, 32, pubkey_hex); + + // Store private key securely + if (store_blossom_private_key(seckey_hex) != 0) { + fprintf(stderr, "ERROR: Failed to store blossom private key\n"); + return -1; + } + + // Store public key in config + sqlite3 *db; + sqlite3_stmt *stmt; + int rc; + + rc = sqlite3_open_v2(DB_PATH, &db, SQLITE_OPEN_READWRITE, NULL); + if (rc) { + fprintf(stderr, "ERROR: Can't open database for config: %s\n", sqlite3_errmsg(db)); + return -1; + } + + const char *sql = "INSERT OR REPLACE INTO config (key, value, description) VALUES (?, ?, ?)"; + rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); + if (rc != SQLITE_OK) { + fprintf(stderr, "ERROR: SQL prepare failed: %s\n", sqlite3_errmsg(db)); + sqlite3_close(db); + return -1; + } + + sqlite3_bind_text(stmt, 1, "blossom_pubkey", -1, SQLITE_STATIC); + sqlite3_bind_text(stmt, 2, pubkey_hex, -1, SQLITE_STATIC); + sqlite3_bind_text(stmt, 3, "Blossom server's public key for Nostr communication", -1, SQLITE_STATIC); + + rc = sqlite3_step(stmt); + sqlite3_finalize(stmt); + sqlite3_close(db); + + if (rc != SQLITE_DONE) { + fprintf(stderr, "ERROR: Failed to store blossom public key in config\n"); + return -1; + } + + // Display keys for admin setup + fprintf(stderr, "========================================\n"); + fprintf(stderr, "SERVER KEYPAIR GENERATED SUCCESSFULLY\n"); + fprintf(stderr, "========================================\n"); + fprintf(stderr, "Blossom Public Key: %s\n", pubkey_hex); + fprintf(stderr, "Blossom Private Key: %s\n", seckey_hex); + fprintf(stderr, "========================================\n"); + fprintf(stderr, "IMPORTANT: Save the private key securely!\n"); + fprintf(stderr, "This key is used for decrypting admin messages.\n"); + fprintf(stderr, "========================================\n"); + + return 0; +} + +// Load server keys from database +int load_server_keys(void) { + fprintf(stderr, "DEBUG: load_server_keys() called\n"); + sqlite3 *db; + sqlite3_stmt *stmt; + int rc; + + // Try to load blossom private key + fprintf(stderr, "DEBUG: Trying to load blossom private key...\n"); + if (get_blossom_private_key(g_blossom_seckey, sizeof(g_blossom_seckey)) != 0) { + fprintf(stderr, "DEBUG: No blossom private key found\n"); + // No private key found - check if we should generate one + if (g_generate_keys) { + fprintf(stderr, "STARTUP: No blossom private key found, generating new keypair...\n"); + if (generate_server_keypair() != 0) { + fprintf(stderr, "ERROR: Failed to generate server keypair\n"); + return -1; + } + } else { + fprintf(stderr, "WARNING: No blossom private key found. Use --generate-keys to create one.\n"); + // This is not fatal - server can still operate without admin features + } + } else { + fprintf(stderr, "STARTUP: Blossom private key loaded successfully\n"); + } + + // Load admin pubkey from command line or config + if (strlen(g_admin_pubkey) == 0) { + // Try to load from database config + rc = sqlite3_open_v2(DB_PATH, &db, SQLITE_OPEN_READONLY, NULL); + if (rc == SQLITE_OK) { + const char *sql = "SELECT value FROM config WHERE key = 'admin_pubkey'"; + rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); + if (rc == SQLITE_OK) { + rc = sqlite3_step(stmt); + if (rc == SQLITE_ROW) { + const char *pubkey = (const char *)sqlite3_column_text(stmt, 0); + if (pubkey && strlen(pubkey) == 64) { + strncpy(g_admin_pubkey, pubkey, sizeof(g_admin_pubkey) - 1); + fprintf(stderr, "STARTUP: Admin pubkey loaded from config: %s\n", g_admin_pubkey); + } + } + sqlite3_finalize(stmt); + } + sqlite3_close(db); + } + } else { + // Store admin pubkey in config if provided via command line + rc = sqlite3_open_v2(DB_PATH, &db, SQLITE_OPEN_READWRITE, NULL); + if (rc == SQLITE_OK) { + const char *sql = "INSERT OR REPLACE INTO config (key, value, description) VALUES (?, ?, ?)"; + rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); + if (rc == SQLITE_OK) { + sqlite3_bind_text(stmt, 1, "admin_pubkey", -1, SQLITE_STATIC); + sqlite3_bind_text(stmt, 2, g_admin_pubkey, -1, SQLITE_STATIC); + sqlite3_bind_text(stmt, 3, "Admin public key for management authentication", -1, SQLITE_STATIC); + sqlite3_step(stmt); + sqlite3_finalize(stmt); + } + sqlite3_close(db); + } + } + + return 0; +} + +// Store blossom private key in dedicated table +int store_blossom_private_key(const char *seckey) { + sqlite3 *db; + sqlite3_stmt *stmt; + int rc; + + // Validate key format + if (!seckey || strlen(seckey) != 64) { + fprintf(stderr, "ERROR: Invalid blossom private key format\n"); + return -1; + } + + // Create blossom_seckey table if it doesn't exist + rc = sqlite3_open_v2(DB_PATH, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); + if (rc) { + fprintf(stderr, "ERROR: Can't open database: %s\n", sqlite3_errmsg(db)); + return -1; + } + + // Create table + const char *create_sql = "CREATE TABLE IF NOT EXISTS blossom_seckey (id INTEGER PRIMARY KEY CHECK (id = 1), seckey TEXT NOT NULL, created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')), CHECK (length(seckey) = 64))"; + rc = sqlite3_exec(db, create_sql, NULL, NULL, NULL); + if (rc != SQLITE_OK) { + fprintf(stderr, "ERROR: Failed to create blossom_seckey table: %s\n", sqlite3_errmsg(db)); + sqlite3_close(db); + return -1; + } + + // Store key + const char *sql = "INSERT OR REPLACE INTO blossom_seckey (id, seckey) VALUES (1, ?)"; + rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); + if (rc != SQLITE_OK) { + fprintf(stderr, "ERROR: SQL prepare failed: %s\n", sqlite3_errmsg(db)); + sqlite3_close(db); + return -1; + } + + sqlite3_bind_text(stmt, 1, seckey, -1, SQLITE_STATIC); + rc = sqlite3_step(stmt); + sqlite3_finalize(stmt); + sqlite3_close(db); + + if (rc != SQLITE_DONE) { + fprintf(stderr, "ERROR: Failed to store blossom private key\n"); + return -1; + } + + return 0; +} + +// Get blossom private key from database +int get_blossom_private_key(char *seckey_out, size_t max_len) { + sqlite3 *db; + sqlite3_stmt *stmt; + int rc; + + rc = sqlite3_open_v2(DB_PATH, &db, SQLITE_OPEN_READONLY, NULL); + if (rc) { + return -1; + } + + const char *sql = "SELECT seckey FROM blossom_seckey WHERE id = 1 LIMIT 1"; + rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); + if (rc != SQLITE_OK) { + sqlite3_close(db); + return -1; + } + + rc = sqlite3_step(stmt); + if (rc == SQLITE_ROW) { + const char *seckey = (const char *)sqlite3_column_text(stmt, 0); + if (seckey && strlen(seckey) == 64 && strlen(seckey) < max_len) { + strcpy(seckey_out, seckey); + sqlite3_finalize(stmt); + sqlite3_close(db); + return 0; + } + } + + sqlite3_finalize(stmt); + sqlite3_close(db); + return -1; +} + // Insert blob metadata into database int insert_blob_metadata(const char *sha256, long size, const char *type, long uploaded_at, const char *uploader_pubkey, @@ -85,7 +520,7 @@ int insert_blob_metadata(const char *sha256, long size, const char *type, sqlite3_stmt *stmt; int rc; - rc = sqlite3_open_v2(DB_PATH, &db, SQLITE_OPEN_READWRITE, NULL); + rc = sqlite3_open_v2(DB_PATH, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); if (rc) { fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); return 0; @@ -140,7 +575,7 @@ int get_blob_metadata(const char *sha256, blob_metadata_t *metadata) { sqlite3_stmt *stmt; int rc; - rc = sqlite3_open_v2(DB_PATH, &db, SQLITE_OPEN_READONLY, NULL); + rc = sqlite3_open_v2(DB_PATH, &db, SQLITE_OPEN_READONLY | SQLITE_OPEN_CREATE, NULL); if (rc) { fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); return 0; @@ -557,7 +992,7 @@ void handle_delete_request_with_validation(const char *sha256, nostr_request_res sqlite3_stmt *stmt; int rc; - rc = sqlite3_open_v2(DB_PATH, &db, SQLITE_OPEN_READWRITE, NULL); + rc = sqlite3_open_v2(DB_PATH, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); if (rc) { send_error_response(500, "database_error", "Failed to access database", @@ -1296,7 +1731,13 @@ void handle_auth_challenge_request(void) { ///////////////////////////////////////////////////////////////////////////////////////// int main(int argc, char *argv[]) { + fprintf(stderr, "DEBUG: main() started\n"); + fflush(stderr); + // Parse command line arguments + int use_test_keys = 0; + char test_server_privkey[65] = ""; + for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "--db-path") == 0 && i + 1 < argc) { strncpy(g_db_path, argv[i + 1], sizeof(g_db_path) - 1); @@ -1305,21 +1746,180 @@ int main(int argc, char *argv[]) { strncpy(g_storage_dir, argv[i + 1], sizeof(g_storage_dir) - 1); i++; // Skip next argument } else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) { - printf("Usage: %s [options]\n", argv[0]); - printf("Options:\n"); - printf(" --db-path PATH Database file path (default: db/ginxsom.db)\n"); - printf(" --storage-dir DIR Storage directory for files (default: blobs)\n"); - printf(" --help, -h Show this help message\n"); + // Use write() directly to avoid FCGI printf redefinition + const char *help_text = + "Usage: ginxsom-fcgi [options]\n" + "Options:\n" + " --db-path PATH Database file path (default: db/ginxsom.db)\n" + " --storage-dir DIR Storage directory for files (default: blobs)\n" + " --admin-pubkey KEY Admin public key for management (64 hex chars)\n" + " --server-privkey KEY Server private key (64 hex chars, for testing)\n" + " --test-keys Use test keys from .test_keys file\n" + " --generate-keys Generate server keypair on startup\n" + " --help, -h Show this help message\n"; + ssize_t written = write(STDOUT_FILENO, help_text, strlen(help_text)); + (void)written; // Suppress unused variable warning return 0; + } else if (strcmp(argv[i], "--admin-pubkey") == 0 && i + 1 < argc) { + strncpy(g_admin_pubkey, argv[i + 1], sizeof(g_admin_pubkey) - 1); + i++; // Skip next argument + } else if (strcmp(argv[i], "--server-privkey") == 0 && i + 1 < argc) { + strncpy(test_server_privkey, argv[i + 1], sizeof(test_server_privkey) - 1); + i++; // Skip next argument + } else if (strcmp(argv[i], "--test-keys") == 0) { + use_test_keys = 1; + } else if (strcmp(argv[i], "--generate-keys") == 0) { + g_generate_keys = 1; } else { fprintf(stderr, "Unknown option: %s\n", argv[i]); fprintf(stderr, "Use --help for usage information\n"); return 1; } } + + // Load test keys if requested + if (use_test_keys) { + FILE *keys_file = fopen(".test_keys", "r"); + if (!keys_file) { + fprintf(stderr, "ERROR: Cannot open .test_keys file\n"); + return 1; + } + + char line[256]; + while (fgets(line, sizeof(line), keys_file)) { + // Parse ADMIN_PUBKEY='...' + if (strncmp(line, "ADMIN_PUBKEY='", 14) == 0) { + char *start = line + 14; + char *end = strchr(start, '\''); + if (end && (end - start) == 64) { + strncpy(g_admin_pubkey, start, 64); + g_admin_pubkey[64] = '\0'; + } + } + // Parse SERVER_PRIVKEY='...' + else if (strncmp(line, "SERVER_PRIVKEY='", 16) == 0) { + char *start = line + 16; + char *end = strchr(start, '\''); + if (end && (end - start) == 64) { + strncpy(test_server_privkey, start, 64); + test_server_privkey[64] = '\0'; + } + } + } + fclose(keys_file); + + fprintf(stderr, "STARTUP: Using test keys from .test_keys\n"); + fprintf(stderr, "STARTUP: Admin pubkey: %s\n", g_admin_pubkey); + fprintf(stderr, "STARTUP: Server privkey loaded from test keys\n"); + } fprintf(stderr, "STARTUP: Using database path: %s\n", g_db_path); fprintf(stderr, "STARTUP: Using storage directory: %s\n", g_storage_dir); + if (strlen(g_admin_pubkey) > 0) { + fprintf(stderr, "STARTUP: Admin pubkey specified: %s\n", g_admin_pubkey); + } + if (g_generate_keys) { + fprintf(stderr, "STARTUP: Will generate server keypair\n"); + } + + fprintf(stderr, "DEBUG: About to initialize database\n"); + + // Initialize database (create if doesn't exist) + fprintf(stderr, "STARTUP: Initializing database...\n"); + if (initialize_database(g_db_path) != 0) { + fprintf(stderr, "FATAL ERROR: Failed to initialize database\n"); + return 1; + } + fprintf(stderr, "STARTUP: Database ready\n"); + + // CRITICAL: Initialize nostr crypto system BEFORE key operations + fprintf(stderr, "STARTUP: Initializing nostr crypto system...\r\n"); + int crypto_init_result = nostr_crypto_init(); + fprintf(stderr, "CRYPTO INIT RESULT: %d\r\n", crypto_init_result); + if (crypto_init_result != 0) { + fprintf(stderr, + "FATAL ERROR: Failed to initialize nostr crypto system\r\n"); + return 1; + } + fprintf(stderr, "STARTUP: nostr crypto system initialized successfully\r\n"); + + // Initialize server keys (now that crypto is initialized) + fprintf(stderr, "STARTUP: Initializing server keys...\n"); + fflush(stderr); + + // If test keys were provided via command line, store them in database + if (test_server_privkey[0] != '\0') { + // Store test private key in database + strncpy(g_blossom_seckey, test_server_privkey, sizeof(g_blossom_seckey) - 1); + g_blossom_seckey[64] = '\0'; + + fprintf(stderr, "STARTUP: Storing test server private key in database...\n"); + if (store_blossom_private_key(test_server_privkey) != 0) { + fprintf(stderr, "ERROR: Failed to store test private key\n"); + return 1; + } + + // Derive and store public key + unsigned char seckey_bytes[32]; + if (nostr_hex_to_bytes(test_server_privkey, seckey_bytes, 32) != NOSTR_SUCCESS) { + fprintf(stderr, "ERROR: Failed to parse test private key\n"); + return 1; + } + + unsigned char pubkey_bytes[32]; + if (nostr_ec_public_key_from_private_key(seckey_bytes, pubkey_bytes) != NOSTR_SUCCESS) { + fprintf(stderr, "ERROR: Failed to derive public key from test private key\n"); + return 1; + } + + char pubkey_hex[65]; + nostr_bytes_to_hex(pubkey_bytes, 32, pubkey_hex); + + // Store server public key in config + sqlite3 *db; + sqlite3_stmt *stmt; + int rc = sqlite3_open_v2(DB_PATH, &db, SQLITE_OPEN_READWRITE, NULL); + if (rc == SQLITE_OK) { + const char *sql = "INSERT OR REPLACE INTO config (key, value, description) VALUES (?, ?, ?)"; + rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); + if (rc == SQLITE_OK) { + sqlite3_bind_text(stmt, 1, "blossom_pubkey", -1, SQLITE_STATIC); + sqlite3_bind_text(stmt, 2, pubkey_hex, -1, SQLITE_STATIC); + sqlite3_bind_text(stmt, 3, "Blossom server's public key (TEST MODE)", -1, SQLITE_STATIC); + sqlite3_step(stmt); + sqlite3_finalize(stmt); + } + sqlite3_close(db); + } + + fprintf(stderr, "STARTUP: Test server keys stored in database\n"); + fprintf(stderr, "STARTUP: Server pubkey: %s\n", pubkey_hex); + fprintf(stderr, "STARTUP: Admin pubkey: %s\n", g_admin_pubkey); + + // Now call load_server_keys to ensure admin_pubkey is also stored + int key_init_result = load_server_keys(); + if (key_init_result != 0) { + fprintf(stderr, "WARNING: Failed to complete key initialization\n"); + } + } else { + // Load keys from database (production mode) + int key_init_result = load_server_keys(); + fprintf(stderr, "KEY INIT RESULT: %d\n", key_init_result); + fflush(stderr); + if (key_init_result != 0) { + fprintf(stderr, "FATAL ERROR: Failed to initialize server keys\n"); + return 1; + } + fprintf(stderr, "STARTUP: Server keys initialized successfully\n"); + } + fflush(stderr); + + // If --generate-keys was specified, exit after key generation + if (g_generate_keys) { + fprintf(stderr, "Key generation completed, exiting.\n"); + fflush(stderr); + return 0; + } // Initialize server configuration and identity // Try file-based config first, then fall back to database config @@ -1327,25 +1927,16 @@ int config_loaded = 0; // Fall back to database configuration if file config failed if (!config_loaded /* && !initialize_server_config() */) { - fprintf( - stderr, - "STARTUP: No configuration found - server starting in setup mode\n"); - fprintf(stderr, "STARTUP: Run interactive setup with: ginxsom --setup\n"); - // For interactive mode (when stdin is available), offer setup + fprintf( + stderr, + "STARTUP: No configuration found - server starting in setup mode\n"); + fprintf(stderr, "STARTUP: Run interactive setup with: ginxsom --setup\n"); + // For interactive mode (when stdin is available), offer setup } else if (!config_loaded) { - fprintf(stderr, "STARTUP: Database configuration loaded successfully\n"); + fprintf(stderr, "STARTUP: Database configuration loaded successfully\n"); } - // CRITICAL: Initialize nostr crypto system for cryptographic operations - fprintf(stderr, "STARTUP: Initializing nostr crypto system...\r\n"); - if (nostr_crypto_init() != 0) { - fprintf(stderr, - "FATAL ERROR: Failed to initialize nostr crypto system\r\n"); - return 1; - } - fprintf(stderr, "STARTUP: nostr crypto system initialized successfully\r\n"); - // Initialize request validator system fprintf(stderr, "STARTUP: Initializing request validator system...\r\n"); int validator_init_result = diff --git a/src/request_validator.c b/src/request_validator.c index b8ab73a..b746476 100644 --- a/src/request_validator.c +++ b/src/request_validator.c @@ -283,6 +283,16 @@ int nostr_validate_unified_request(const nostr_unified_request_t *request, // PHASE 2: NOSTR EVENT VALIDATION (CPU Intensive ~2ms) ///////////////////////////////////////////////////////////////////// + // Check if authentication is disabled first (regardless of header presence) + if (!g_auth_cache.auth_required) { + validator_debug_log("VALIDATOR_DEBUG: STEP 4 PASSED - Authentication " + "disabled, allowing request\n"); + result->valid = 1; + result->error_code = NOSTR_SUCCESS; + strcpy(result->reason, "Authentication disabled"); + return NOSTR_SUCCESS; + } + // Check if this is a BUD-09 report request - allow anonymous reporting if (request->operation && strcmp(request->operation, "report") == 0) { // BUD-09 allows anonymous reporting - pass through to bud09.c for validation diff --git a/src/test_keygen.c b/src/test_keygen.c new file mode 100644 index 0000000..50e5713 --- /dev/null +++ b/src/test_keygen.c @@ -0,0 +1,199 @@ +/* + * Test program for key generation + * Standalone version that doesn't require FastCGI + */ + +#include +#include +#include +#include +#include "../nostr_core_lib/nostr_core/nostr_common.h" +#include "../nostr_core_lib/nostr_core/utils.h" + +// Forward declarations +int generate_random_private_key_bytes(unsigned char *key_bytes, size_t len); +int generate_server_keypair(const char *db_path); +int store_blossom_private_key(const char *db_path, const char *seckey); + +// Generate random private key bytes using /dev/urandom +int generate_random_private_key_bytes(unsigned char *key_bytes, size_t len) { + FILE *fp = fopen("/dev/urandom", "rb"); + if (!fp) { + fprintf(stderr, "ERROR: Cannot open /dev/urandom for key generation\n"); + return -1; + } + + size_t bytes_read = fread(key_bytes, 1, len, fp); + fclose(fp); + + if (bytes_read != len) { + fprintf(stderr, "ERROR: Failed to read %zu bytes from /dev/urandom\n", len); + return -1; + } + + return 0; +} + +// Store blossom private key in dedicated table +int store_blossom_private_key(const char *db_path, const char *seckey) { + sqlite3 *db; + sqlite3_stmt *stmt; + int rc; + + // Validate key format + if (!seckey || strlen(seckey) != 64) { + fprintf(stderr, "ERROR: Invalid blossom private key format\n"); + return -1; + } + + // Create blossom_seckey table if it doesn't exist + rc = sqlite3_open_v2(db_path, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); + if (rc) { + fprintf(stderr, "ERROR: Can't open database: %s\n", sqlite3_errmsg(db)); + return -1; + } + + // Create table + const char *create_sql = "CREATE TABLE IF NOT EXISTS blossom_seckey (id INTEGER PRIMARY KEY CHECK (id = 1), seckey TEXT NOT NULL, created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')), CHECK (length(seckey) = 64))"; + rc = sqlite3_exec(db, create_sql, NULL, NULL, NULL); + if (rc != SQLITE_OK) { + fprintf(stderr, "ERROR: Failed to create blossom_seckey table: %s\n", sqlite3_errmsg(db)); + sqlite3_close(db); + return -1; + } + + // Store key + const char *sql = "INSERT OR REPLACE INTO blossom_seckey (id, seckey) VALUES (1, ?)"; + rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); + if (rc != SQLITE_OK) { + fprintf(stderr, "ERROR: SQL prepare failed: %s\n", sqlite3_errmsg(db)); + sqlite3_close(db); + return -1; + } + + sqlite3_bind_text(stmt, 1, seckey, -1, SQLITE_STATIC); + rc = sqlite3_step(stmt); + sqlite3_finalize(stmt); + sqlite3_close(db); + + if (rc != SQLITE_DONE) { + fprintf(stderr, "ERROR: Failed to store blossom private key\n"); + return -1; + } + + return 0; +} + +// Generate server keypair and store in database +int generate_server_keypair(const char *db_path) { + printf("Generating server keypair...\n"); + unsigned char seckey_bytes[32]; + char seckey_hex[65]; + char pubkey_hex[65]; + + // Generate random private key + printf("Generating random private key...\n"); + if (generate_random_private_key_bytes(seckey_bytes, 32) != 0) { + fprintf(stderr, "Failed to generate random bytes\n"); + return -1; + } + + // Validate the private key + if (nostr_ec_private_key_verify(seckey_bytes) != NOSTR_SUCCESS) { + fprintf(stderr, "ERROR: Generated invalid private key\n"); + return -1; + } + + // Convert to hex + nostr_bytes_to_hex(seckey_bytes, 32, seckey_hex); + + // Derive public key + unsigned char pubkey_bytes[32]; + if (nostr_ec_public_key_from_private_key(seckey_bytes, pubkey_bytes) != NOSTR_SUCCESS) { + fprintf(stderr, "ERROR: Failed to derive public key\n"); + return -1; + } + + // Convert public key to hex + nostr_bytes_to_hex(pubkey_bytes, 32, pubkey_hex); + + // Store private key securely + if (store_blossom_private_key(db_path, seckey_hex) != 0) { + fprintf(stderr, "ERROR: Failed to store blossom private key\n"); + return -1; + } + + // Store public key in config + sqlite3 *db; + sqlite3_stmt *stmt; + int rc; + + rc = sqlite3_open_v2(db_path, &db, SQLITE_OPEN_READWRITE, NULL); + if (rc) { + fprintf(stderr, "ERROR: Can't open database for config: %s\n", sqlite3_errmsg(db)); + return -1; + } + + const char *sql = "INSERT OR REPLACE INTO config (key, value, description) VALUES (?, ?, ?)"; + rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); + if (rc != SQLITE_OK) { + fprintf(stderr, "ERROR: SQL prepare failed: %s\n", sqlite3_errmsg(db)); + sqlite3_close(db); + return -1; + } + + sqlite3_bind_text(stmt, 1, "blossom_pubkey", -1, SQLITE_STATIC); + sqlite3_bind_text(stmt, 2, pubkey_hex, -1, SQLITE_STATIC); + sqlite3_bind_text(stmt, 3, "Blossom server's public key for Nostr communication", -1, SQLITE_STATIC); + + rc = sqlite3_step(stmt); + sqlite3_finalize(stmt); + sqlite3_close(db); + + if (rc != SQLITE_DONE) { + fprintf(stderr, "ERROR: Failed to store blossom public key in config\n"); + return -1; + } + + // Display keys for admin setup + printf("========================================\n"); + printf("SERVER KEYPAIR GENERATED SUCCESSFULLY\n"); + printf("========================================\n"); + printf("Blossom Public Key: %s\n", pubkey_hex); + printf("Blossom Private Key: %s\n", seckey_hex); + printf("========================================\n"); + printf("IMPORTANT: Save the private key securely!\n"); + printf("This key is used for decrypting admin messages.\n"); + printf("========================================\n"); + + return 0; +} + +int main(int argc, char *argv[]) { + const char *db_path = "db/ginxsom.db"; + + if (argc > 1) { + db_path = argv[1]; + } + + printf("Test Key Generation\n"); + printf("===================\n"); + printf("Database: %s\n\n", db_path); + + // Initialize nostr crypto + printf("Initializing nostr crypto system...\n"); + if (nostr_crypto_init() != NOSTR_SUCCESS) { + fprintf(stderr, "FATAL: Failed to initialize nostr crypto\n"); + return 1; + } + printf("Crypto system initialized\n\n"); + + // Generate keypair + if (generate_server_keypair(db_path) != 0) { + fprintf(stderr, "FATAL: Key generation failed\n"); + return 1; + } + + printf("\nKey generation test completed successfully!\n"); + return 0; +} \ No newline at end of file diff --git a/src/test_main.c b/src/test_main.c new file mode 100644 index 0000000..fb77b2c --- /dev/null +++ b/src/test_main.c @@ -0,0 +1,50 @@ +/* + * Minimal test version of main.c to debug startup issues + */ + +#include +#include +#include +#include "ginxsom.h" + +// Copy just the essential parts for testing +char g_db_path[4096] = "db/ginxsom.db"; +char g_storage_dir[4096] = "."; +char g_admin_pubkey[65] = ""; +char g_relay_seckey[65] = ""; +int g_generate_keys = 0; + +int main(int argc, char *argv[]) { + printf("DEBUG: main() started\n"); + fflush(stdout); + + // Parse minimal args + for (int i = 1; i < argc; i++) { + printf("DEBUG: arg %d: %s\n", i, argv[i]); + fflush(stdout); + if (strcmp(argv[i], "--generate-keys") == 0) { + g_generate_keys = 1; + printf("DEBUG: generate-keys flag set\n"); + fflush(stdout); + } else if (strcmp(argv[i], "--help") == 0) { + printf("Usage: test_main [options]\n"); + printf(" --generate-keys Generate keys\n"); + printf(" --help Show help\n"); + return 0; + } + } + + printf("DEBUG: g_generate_keys = %d\n", g_generate_keys); + fflush(stdout); + + if (g_generate_keys) { + printf("DEBUG: Would generate keys here\n"); + fflush(stdout); + return 0; + } + + printf("DEBUG: Normal startup would continue here\n"); + fflush(stdout); + + return 0; +} \ No newline at end of file diff --git a/test_blob_1762770636.txt b/test_blob_1762770636.txt deleted file mode 100644 index b80e07b..0000000 --- a/test_blob_1762770636.txt +++ /dev/null @@ -1,7 +0,0 @@ -Test blob content for Ginxsom Blossom server (PRODUCTION) -Timestamp: 2025-11-10T06:30:36-04:00 -Random data: bb7d8d5206aadf4ecd48829f9674454c160bae68e98c6ce5f7f678f997dbe86a -Test message: Hello from production test! - -This file is used to test the upload functionality -of the Ginxsom Blossom server on blossom.laantungir.net diff --git a/test_file.txt b/test_file.txt deleted file mode 100644 index d7ab9a8..0000000 --- a/test_file.txt +++ /dev/null @@ -1 +0,0 @@ -test file content diff --git a/test_key_generation.sh b/test_key_generation.sh new file mode 100755 index 0000000..47fb65d --- /dev/null +++ b/test_key_generation.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# Test key generation for ginxsom + +echo "=== Testing Key Generation ===" +echo + +# Run the binary with --generate-keys flag +echo "Running: ./build/ginxsom-fcgi --generate-keys --db-path db/ginxsom.db" +echo +./build/ginxsom-fcgi --generate-keys --db-path db/ginxsom.db 2>&1 + +echo +echo "=== Checking if keys were stored ===" +echo + +# Check if blossom_seckey table was created +echo "Checking blossom_seckey table:" +sqlite3 db/ginxsom.db "SELECT COUNT(*) as key_count FROM blossom_seckey" 2>&1 + +echo +echo "Checking blossom_pubkey in config:" +sqlite3 db/ginxsom.db "SELECT value FROM config WHERE key='blossom_pubkey'" 2>&1 + +echo +echo "=== Test Complete ===" \ No newline at end of file diff --git a/test_mode_verification.sh b/test_mode_verification.sh new file mode 100755 index 0000000..20ec35e --- /dev/null +++ b/test_mode_verification.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +echo "=== Test Mode Verification ===" +echo "" + +# Expected test keys from .test_keys +EXPECTED_ADMIN_PUBKEY="8ff74724ed641b3c28e5a86d7c5cbc49c37638ace8c6c38935860e7a5eedde0e" +EXPECTED_SERVER_PUBKEY="52e366edfa4e9cc6a6d4653828e51ccf828a2f5a05227d7a768f33b5a198681a" + +echo "1. Checking database keys (should be OLD keys, not test keys)..." +DB_ADMIN_PUBKEY=$(sqlite3 db/ginxsom.db "SELECT value FROM config WHERE key = 'admin_pubkey'") +DB_BLOSSOM_PUBKEY=$(sqlite3 db/ginxsom.db "SELECT value FROM config WHERE key = 'blossom_pubkey'") +DB_BLOSSOM_SECKEY=$(sqlite3 db/ginxsom.db "SELECT seckey FROM blossom_seckey WHERE id = 1") + +echo " Database admin_pubkey: '$DB_ADMIN_PUBKEY'" +echo " Database blossom_pubkey: '$DB_BLOSSOM_PUBKEY'" +echo " Database blossom_seckey: '$DB_BLOSSOM_SECKEY'" +echo "" + +# Verify database was NOT modified with test keys +if [ "$DB_ADMIN_PUBKEY" = "$EXPECTED_ADMIN_PUBKEY" ]; then + echo " ❌ FAIL: Database admin_pubkey matches test key (should NOT be modified)" + exit 1 +else + echo " ✓ PASS: Database admin_pubkey is different from test key (not modified)" +fi + +if [ "$DB_BLOSSOM_PUBKEY" = "$EXPECTED_SERVER_PUBKEY" ]; then + echo " ❌ FAIL: Database blossom_pubkey matches test key (should NOT be modified)" + exit 1 +else + echo " ✓ PASS: Database blossom_pubkey is different from test key (not modified)" +fi + +echo "" +echo "2. Checking server is running..." +if curl -s http://localhost:9001/ > /dev/null; then + echo " ✓ PASS: Server is responding" +else + echo " ❌ FAIL: Server is not responding" + exit 1 +fi + +echo "" +echo "3. Verifying test keys from .test_keys file..." +echo " Expected admin pubkey: $EXPECTED_ADMIN_PUBKEY" +echo " Expected server pubkey: $EXPECTED_SERVER_PUBKEY" + +echo "" +echo "=== All Tests Passed ===" +echo "Test mode is working correctly:" +echo " - Test keys are loaded in memory" +echo " - Database was NOT modified" +echo " - Server is running with test keys" \ No newline at end of file diff --git a/tests/auth_test.sh b/tests/auth_test.sh index b1a8115..4dc48ed 100755 --- a/tests/auth_test.sh +++ b/tests/auth_test.sh @@ -14,9 +14,9 @@ TESTS_PASSED=0 TESTS_FAILED=0 TOTAL_TESTS=0 -# Test keys for different scenarios -TEST_USER1_PRIVKEY="5c0c523f52a5b6fad39ed2403092df8cebc36318b39383bca6c00808626fab3a" -TEST_USER1_PUBKEY="87d3561f19b74adbe8bf840682992466068830a9d8c36b4a0c99d36f826cb6cb" +# Test keys for different scenarios - Using WSB's keys for TEST_USER1 +TEST_USER1_PRIVKEY="22cc83aa57928a2800234c939240c9a6f0f44a33ea3838a860ed38930b195afd" +TEST_USER1_PUBKEY="8ff74724ed641b3c28e5a86d7c5cbc49c37638ace8c6c38935860e7a5eedde0e" TEST_USER2_PRIVKEY="182c3a5e3b7a1b7e4f5c6b7c8b4a5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2" TEST_USER2_PUBKEY="c95195e5e7de1ad8c4d3c0ac4e8b5c0c4e0c4d3c1e5c8d4c2e7e9f4a5b6c7d8e" diff --git a/tests/auth_test_tmp/nip42_challenge b/tests/auth_test_tmp/nip42_challenge index 9e491be..7b7ba67 100644 --- a/tests/auth_test_tmp/nip42_challenge +++ b/tests/auth_test_tmp/nip42_challenge @@ -1 +1 @@ -e3ba927d32ca105a8a4cafa2e013b97945a165c38e9ce573446a2332dc312fdb +299c28eeb15df327c30c9afd952d4e35c3777443d2094b2caab2fc94599ce607 diff --git a/tests/file_put_bud02.sh b/tests/file_put_bud02.sh index 31a2fe7..53490fb 100755 --- a/tests/file_put_bud02.sh +++ b/tests/file_put_bud02.sh @@ -5,12 +5,14 @@ set -e # Exit on any error -# Configuration +# Configuration - Using WSB's keys # SERVER_URL="http://localhost:9001" SERVER_URL="https://localhost:9443" UPLOAD_ENDPOINT="${SERVER_URL}/upload" TEST_FILE="test_blob_$(date +%s).txt" CLEANUP_FILES=() +NOSTR_PRIVKEY="22cc83aa57928a2800234c939240c9a6f0f44a33ea3838a860ed38930b195afd" +NOSTR_PUBKEY="8ff74724ed641b3c28e5a86d7c5cbc49c37638ace8c6c38935860e7a5eedde0e" # Colors for output RED='\033[0;31m' @@ -128,22 +130,23 @@ calculate_hash() { # Generate nostr event generate_nostr_event() { - log_info "Generating kind 24242 nostr event with nak..." - + log_info "Generating kind 24242 nostr event with nak using Alice's private key..." + # Calculate expiration time (1 hour from now) EXPIRATION=$(date -d '+1 hour' +%s) - - # Generate the event using nak + + # Generate the event using nak with Alice's private key EVENT_JSON=$(nak event -k 24242 -c "" \ + --sec "$NOSTR_PRIVKEY" \ -t "t=upload" \ -t "x=${HASH}" \ -t "expiration=${EXPIRATION}") - + if [[ -z "$EVENT_JSON" ]]; then log_error "Failed to generate nostr event" exit 1 fi - + log_success "Generated nostr event" echo "Event JSON: $EVENT_JSON" } diff --git a/tests/file_put_production.sh b/tests/file_put_production.sh index 010ca65..709e4f0 100755 --- a/tests/file_put_production.sh +++ b/tests/file_put_production.sh @@ -126,22 +126,23 @@ calculate_hash() { # Generate nostr event generate_nostr_event() { - log_info "Generating kind 24242 nostr event with nak..." - + log_info "Generating kind 24242 nostr event with nak using WSB's private key..." + # Calculate expiration time (1 hour from now) EXPIRATION=$(date -d '+1 hour' +%s) - - # Generate the event using nak + + # Generate the event using nak with WSB's private key EVENT_JSON=$(nak event -k 24242 -c "" \ + --sec "22cc83aa57928a2800234c939240c9a6f0f44a33ea3838a860ed38930b195afd" \ -t "t=upload" \ -t "x=${HASH}" \ -t "expiration=${EXPIRATION}") - + if [[ -z "$EVENT_JSON" ]]; then log_error "Failed to generate nostr event" exit 1 fi - + log_success "Generated nostr event" echo "Event JSON: $EVENT_JSON" } diff --git a/tests/list_test_bud02.sh b/tests/list_test_bud02.sh index bb5a4ac..bf8c04f 100755 --- a/tests/list_test_bud02.sh +++ b/tests/list_test_bud02.sh @@ -4,8 +4,8 @@ # This script tests the blob listing functionality BASE_URL="http://localhost:9001" -NOSTR_PRIVKEY="0000000000000000000000000000000000000000000000000000000000000001" -NOSTR_PUBKEY="79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798" +NOSTR_PRIVKEY="22cc83aa57928a2800234c939240c9a6f0f44a33ea3838a860ed38930b195afd" +NOSTR_PUBKEY="8ff74724ed641b3c28e5a86d7c5cbc49c37638ace8c6c38935860e7a5eedde0e" # Colors for output RED='\033[0;31m' @@ -19,128 +19,117 @@ echo # Function to generate a Nostr event for list authorization generate_list_auth() { local content="$1" - local created_at=$(date +%s) - local expiration=$((created_at + 3600)) # 1 hour from now - - # Note: This is a placeholder - in real implementation, you'd use nostr tools - # to generate properly signed events. For now, we'll create the structure. - cat << EOF -{ - "id": "placeholder_id", - "pubkey": "$NOSTR_PUBKEY", - "kind": 24242, - "content": "$content", - "created_at": $created_at, - "tags": [ - ["t", "list"], - ["expiration", "$expiration"] - ], - "sig": "placeholder_signature" -} -EOF + + # Use nak to generate properly signed events with Alice's private key + nak event -k 24242 -c "$content" \ + --sec "$NOSTR_PRIVKEY" \ + -t "t=list" \ + -t "expiration=$(( $(date +%s) + 3600 ))" } # Test 1: List blobs without authorization (should work if optional auth) echo -e "${YELLOW}Test 1: GET /list/ without authorization${NC}" + RESPONSE=$(curl -s -w "\nHTTP_STATUS:%{http_code}" "$BASE_URL/list/$NOSTR_PUBKEY") HTTP_STATUS=$(echo "$RESPONSE" | grep "HTTP_STATUS" | cut -d: -f2) BODY=$(echo "$RESPONSE" | sed '/HTTP_STATUS/d') +echo "Using pubkey: $NOSTR_PUBKEY" +echo "HTTP Status: $HTTP_STATUS" +echo "Response: $BODY" +echo + +# Test 2: List blobs with authorization +echo -e "${YELLOW}Test 2: GET /list/ with authorization${NC}" +LIST_AUTH=$(generate_list_auth "List Blobs") +AUTH_B64=$(echo "$LIST_AUTH" | base64 -w 0) +RESPONSE=$(curl -s -w "\nHTTP_STATUS:%{http_code}" \ + -H "Authorization: Nostr $AUTH_B64" \ + "$BASE_URL/list/$NOSTR_PUBKEY") +HTTP_STATUS=$(echo "$RESPONSE" | grep "HTTP_STATUS" | cut -d: -f2) +BODY=$(echo "$RESPONSE" | sed '/HTTP_STATUS/d') + echo "HTTP Status: $HTTP_STATUS" echo "Response: $BODY" echo -# # Test 2: List blobs with authorization -# echo -e "${YELLOW}Test 2: GET /list/ with authorization${NC}" -# LIST_AUTH=$(generate_list_auth "List Blobs") -# AUTH_B64=$(echo "$LIST_AUTH" | base64 -w 0) -# RESPONSE=$(curl -s -w "\nHTTP_STATUS:%{http_code}" \ -# -H "Authorization: Nostr $AUTH_B64" \ -# "$BASE_URL/list/$NOSTR_PUBKEY") -# HTTP_STATUS=$(echo "$RESPONSE" | grep "HTTP_STATUS" | cut -d: -f2) -# BODY=$(echo "$RESPONSE" | sed '/HTTP_STATUS/d') +# Test 3: List blobs with since parameter +echo -e "${YELLOW}Test 3: GET /list/ with since parameter${NC}" +SINCE_TIMESTAMP=$(($(date +%s) - 86400)) # 24 hours ago +RESPONSE=$(curl -s -w "\nHTTP_STATUS:%{http_code}" \ + "$BASE_URL/list/$NOSTR_PUBKEY?since=$SINCE_TIMESTAMP") +HTTP_STATUS=$(echo "$RESPONSE" | grep "HTTP_STATUS" | cut -d: -f2) +BODY=$(echo "$RESPONSE" | sed '/HTTP_STATUS/d') -# echo "HTTP Status: $HTTP_STATUS" -# echo "Response: $BODY" -# echo +echo "HTTP Status: $HTTP_STATUS" +echo "Response: $BODY" +echo -# # Test 3: List blobs with since parameter -# echo -e "${YELLOW}Test 3: GET /list/ with since parameter${NC}" -# SINCE_TIMESTAMP=$(($(date +%s) - 86400)) # 24 hours ago -# RESPONSE=$(curl -s -w "\nHTTP_STATUS:%{http_code}" \ -# "$BASE_URL/list/$NOSTR_PUBKEY?since=$SINCE_TIMESTAMP") -# HTTP_STATUS=$(echo "$RESPONSE" | grep "HTTP_STATUS" | cut -d: -f2) -# BODY=$(echo "$RESPONSE" | sed '/HTTP_STATUS/d') +# Test 4: List blobs with until parameter +echo -e "${YELLOW}Test 4: GET /list/ with until parameter${NC}" +UNTIL_TIMESTAMP=$(date +%s) # now +RESPONSE=$(curl -s -w "\nHTTP_STATUS:%{http_code}" \ + "$BASE_URL/list/$NOSTR_PUBKEY?until=$UNTIL_TIMESTAMP") +HTTP_STATUS=$(echo "$RESPONSE" | grep "HTTP_STATUS" | cut -d: -f2) +BODY=$(echo "$RESPONSE" | sed '/HTTP_STATUS/d') -# echo "HTTP Status: $HTTP_STATUS" -# echo "Response: $BODY" -# echo +echo "HTTP Status: $HTTP_STATUS" +echo "Response: $BODY" +echo -# # Test 4: List blobs with until parameter -# echo -e "${YELLOW}Test 4: GET /list/ with until parameter${NC}" -# UNTIL_TIMESTAMP=$(date +%s) # now -# RESPONSE=$(curl -s -w "\nHTTP_STATUS:%{http_code}" \ -# "$BASE_URL/list/$NOSTR_PUBKEY?until=$UNTIL_TIMESTAMP") -# HTTP_STATUS=$(echo "$RESPONSE" | grep "HTTP_STATUS" | cut -d: -f2) -# BODY=$(echo "$RESPONSE" | sed '/HTTP_STATUS/d') +# Test 5: List blobs with both since and until parameters +echo -e "${YELLOW}Test 5: GET /list/ with since and until parameters${NC}" +SINCE_TIMESTAMP=$(($(date +%s) - 86400)) # 24 hours ago +UNTIL_TIMESTAMP=$(date +%s) # now +RESPONSE=$(curl -s -w "\nHTTP_STATUS:%{http_code}" \ + "$BASE_URL/list/$NOSTR_PUBKEY?since=$SINCE_TIMESTAMP&until=$UNTIL_TIMESTAMP") +HTTP_STATUS=$(echo "$RESPONSE" | grep "HTTP_STATUS" | cut -d: -f2) +BODY=$(echo "$RESPONSE" | sed '/HTTP_STATUS/d') -# echo "HTTP Status: $HTTP_STATUS" -# echo "Response: $BODY" -# echo +echo "HTTP Status: $HTTP_STATUS" +echo "Response: $BODY" +echo -# # Test 5: List blobs with both since and until parameters -# echo -e "${YELLOW}Test 5: GET /list/ with since and until parameters${NC}" -# SINCE_TIMESTAMP=$(($(date +%s) - 86400)) # 24 hours ago -# UNTIL_TIMESTAMP=$(date +%s) # now -# RESPONSE=$(curl -s -w "\nHTTP_STATUS:%{http_code}" \ -# "$BASE_URL/list/$NOSTR_PUBKEY?since=$SINCE_TIMESTAMP&until=$UNTIL_TIMESTAMP") -# HTTP_STATUS=$(echo "$RESPONSE" | grep "HTTP_STATUS" | cut -d: -f2) -# BODY=$(echo "$RESPONSE" | sed '/HTTP_STATUS/d') +# Test 6: List blobs for non-existent pubkey +echo -e "${YELLOW}Test 6: GET /list/${NC}" +FAKE_PUBKEY="1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" +RESPONSE=$(curl -s -w "\nHTTP_STATUS:%{http_code}" "$BASE_URL/list/$FAKE_PUBKEY") +HTTP_STATUS=$(echo "$RESPONSE" | grep "HTTP_STATUS" | cut -d: -f2) +BODY=$(echo "$RESPONSE" | sed '/HTTP_STATUS/d') -# echo "HTTP Status: $HTTP_STATUS" -# echo "Response: $BODY" -# echo +if [ "$HTTP_STATUS" = "200" ]; then + echo -e "${GREEN}✓ Correctly returned 200 with empty array${NC}" +else + echo "HTTP Status: $HTTP_STATUS" +fi +echo "Response: $BODY" +echo -# # Test 6: List blobs for non-existent pubkey -# echo -e "${YELLOW}Test 6: GET /list/${NC}" -# FAKE_PUBKEY="1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" -# RESPONSE=$(curl -s -w "\nHTTP_STATUS:%{http_code}" "$BASE_URL/list/$FAKE_PUBKEY") -# HTTP_STATUS=$(echo "$RESPONSE" | grep "HTTP_STATUS" | cut -d: -f2) -# BODY=$(echo "$RESPONSE" | sed '/HTTP_STATUS/d') +# Test 7: List blobs with invalid pubkey format +echo -e "${YELLOW}Test 7: GET /list/${NC}" +INVALID_PUBKEY="invalid_pubkey" +RESPONSE=$(curl -s -w "\nHTTP_STATUS:%{http_code}" "$BASE_URL/list/$INVALID_PUBKEY") +HTTP_STATUS=$(echo "$RESPONSE" | grep "HTTP_STATUS" | cut -d: -f2) +BODY=$(echo "$RESPONSE" | sed '/HTTP_STATUS/d') -# if [ "$HTTP_STATUS" = "200" ]; then -# echo -e "${GREEN}✓ Correctly returned 200 with empty array${NC}" -# else -# echo "HTTP Status: $HTTP_STATUS" -# fi -# echo "Response: $BODY" -# echo +if [ "$HTTP_STATUS" = "400" ]; then + echo -e "${GREEN}✓ Correctly returned 400 for invalid pubkey format${NC}" +else + echo "HTTP Status: $HTTP_STATUS" +fi +echo "Response: $BODY" +echo -# # Test 7: List blobs with invalid pubkey format -# echo -e "${YELLOW}Test 7: GET /list/${NC}" -# INVALID_PUBKEY="invalid_pubkey" -# RESPONSE=$(curl -s -w "\nHTTP_STATUS:%{http_code}" "$BASE_URL/list/$INVALID_PUBKEY") -# HTTP_STATUS=$(echo "$RESPONSE" | grep "HTTP_STATUS" | cut -d: -f2) -# BODY=$(echo "$RESPONSE" | sed '/HTTP_STATUS/d') +# Test 8: List blobs with invalid since/until parameters +echo -e "${YELLOW}Test 8: GET /list/ with invalid timestamp parameters${NC}" +RESPONSE=$(curl -s -w "\nHTTP_STATUS:%{http_code}" \ + "$BASE_URL/list/$NOSTR_PUBKEY?since=invalid&until=invalid") +HTTP_STATUS=$(echo "$RESPONSE" | grep "HTTP_STATUS" | cut -d: -f2) +BODY=$(echo "$RESPONSE" | sed '/HTTP_STATUS/d') -# if [ "$HTTP_STATUS" = "400" ]; then -# echo -e "${GREEN}✓ Correctly returned 400 for invalid pubkey format${NC}" -# else -# echo "HTTP Status: $HTTP_STATUS" -# fi -# echo "Response: $BODY" -# echo - -# # Test 8: List blobs with invalid since/until parameters -# echo -e "${YELLOW}Test 8: GET /list/ with invalid timestamp parameters${NC}" -# RESPONSE=$(curl -s -w "\nHTTP_STATUS:%{http_code}" \ -# "$BASE_URL/list/$NOSTR_PUBKEY?since=invalid&until=invalid") -# HTTP_STATUS=$(echo "$RESPONSE" | grep "HTTP_STATUS" | cut -d: -f2) -# BODY=$(echo "$RESPONSE" | sed '/HTTP_STATUS/d') - -# echo "HTTP Status: $HTTP_STATUS" -# echo "Response: $BODY" -# echo +echo "HTTP Status: $HTTP_STATUS" +echo "Response: $BODY" +echo # echo "=== List Tests Complete ===" # echo diff --git a/tests/white_black_list_test.sh b/tests/white_black_list_test.sh index 7b2f14a..469f264 100755 --- a/tests/white_black_list_test.sh +++ b/tests/white_black_list_test.sh @@ -14,10 +14,10 @@ TESTS_PASSED=0 TESTS_FAILED=0 TOTAL_TESTS=0 -# Test keys for different scenarios +# Test keys for different scenarios - Using WSB's keys for TEST_USER1 # Generated using: nak key public -TEST_USER1_PRIVKEY="5c0c523f52a5b6fad39ed2403092df8cebc36318b39383bca6c00808626fab3a" -TEST_USER1_PUBKEY="87d3561f19b74adbe8bf840682992466068830a9d8c36b4a0c99d36f826cb6cb" +TEST_USER1_PRIVKEY="22cc83aa57928a2800234c939240c9a6f0f44a33ea3838a860ed38930b195afd" +TEST_USER1_PUBKEY="8ff74724ed641b3c28e5a86d7c5cbc49c37638ace8c6c38935860e7a5eedde0e" TEST_USER2_PRIVKEY="182c3a5e3b7a1b7e4f5c6b7c8b4a5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2" TEST_USER2_PUBKEY="0396b426090284a28294078dce53fe73791ab623c3fc46ab4409fea05109a6db" diff --git a/update_remote_nginx_conf.sh b/update_remote_nginx_conf.sh new file mode 100755 index 0000000..c007e26 --- /dev/null +++ b/update_remote_nginx_conf.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +# update_remote_nginx_conf.sh +# Updates the remote nginx configuration on laantungir.net +# Copies contents of ./remote.nginx.config to /etc/nginx/conf.d/default.conf + +set -e + +echo "=== Updating Remote Nginx Configuration ===" +echo "Server: laantungir.net" +echo "User: ubuntu" +echo "Local config: ./remote.nginx.config" +echo "Remote config: /etc/nginx/conf.d/default.conf" +echo + +# Check if local config exists +if [[ ! -f "./remote.nginx.config" ]]; then + echo "ERROR: ./remote.nginx.config not found" + exit 1 +fi + +echo "Copying remote.nginx.config to laantungir.net:/etc/nginx/conf.d/default.conf..." + +# Copy the config file to the remote server (using user's home directory) +scp ./remote.nginx.config ubuntu@laantungir.net:~/remote.nginx.config + +# Move to final location and backup old config +ssh ubuntu@laantungir.net << 'EOF' + echo "Creating backup of current config..." + sudo cp /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.backup.$(date +%Y%m%d_%H%M%S) + + echo "Installing new config..." + sudo cp ~/remote.nginx.config /etc/nginx/conf.d/default.conf + + echo "Testing nginx configuration..." + if sudo nginx -t; then + echo "✅ Nginx config test passed" + echo "Reloading nginx..." + sudo nginx -s reload + echo "✅ Nginx reloaded successfully" + else + echo "❌ Nginx config test failed" + echo "Restoring backup..." + sudo cp /etc/nginx/conf.d/default.conf.backup.* /etc/nginx/conf.d/default.conf 2>/dev/null || true + exit 1 + fi + + echo "Cleaning up temporary file..." + rm ~/remote.nginx.config +EOF + +echo +echo "=== Update Complete ===" +echo "The remote nginx configuration has been updated."