Projects/3BIT/winter-semester/ISA/include/secret.h
2026-04-14 19:28:46 +02:00

486 lines
17 KiB
C

/*
* ==================================================================================
* Main Header - ICMP Covert Channel File Transfer Application
*
* ISA Project
* Author: Roman Necas (xnecasr00)
* Date: 13. October 2025
*
* PURPOSE:
* This is the main application header that aggregates all modular headers and
* defines the high-level application structures and entry points. It serves as
* the central include point for the entire application.
*
* ARCHITECTURE:
* This application follows a modular architecture with 9 core modules:
*
* 1. secret.c - Main entry point and mode selection (client vs server)
* 2. argument_parser.c - Command-line argument processing
* 3. network_interface.c - Raw ICMP socket operations
* 4. protocol.c - IFTP (ICMP File Transfer Protocol) implementation
* 5. crypto_engine.c - AES-256-CBC encryption/decryption
* 6. file_manager.c - Chunk-based file I/O
* 7. client_engine.c - Client transfer logic
* 8. server_engine.c - Server reception logic
* 9. state_machine.c - Protocol state machines
* 10. error.c - Centralized error handling
* 11. utils.c - Utility functions
*
* HEADER ORGANIZATION:
* - common.h: Shared includes, constants, macros, config_t structure
* - error.h: Error codes and error handling functions
* - crypto.h: Cryptographic types and functions (AES-256-CBC)
* - network.h: Network interface types and ICMP operations
* - protocol.h: IFTP protocol structures and functions
* - file_io.h: File manager types and functions
* - state_machine.h: State machine types and functions
* - secret.h: This header - aggregates all above, defines server_session_t
*
* APPLICATION MODES:
* - Client mode: Send file via ICMP to specified destination
* Usage: secret -r <file> -s <ip|hostname>
*
* - Server mode: Listen for ICMP file transfers, save to current directory
* Usage: secret -l
*
* PROTOCOL OVERVIEW:
* IFTP (ICMP File Transfer Protocol) is a custom protocol for reliable file
* transfer over ICMP Echo-Request/Reply messages:
*
* 1. Client sends START packet with metadata (filename, size, IV, salt)
* 2. Server responds with START-ACK
* 3. Client sends DATA packets with encrypted file chunks
* 4. Server responds with DATA-ACK for each chunk
* 5. Client sends END packet when complete
* 6. Server responds with END-ACK
*
* SECURITY FEATURES:
* - AES-256-CBC encryption with PBKDF2 key derivation (600,000 iterations)
* - CRC32 checksums for packet integrity
* - Path traversal prevention (basename extraction)
* - Secure session IDs (cryptographically random)
* - Per-transfer unique IV and salt
* ==================================================================================
*/
#ifndef SECRET_H
#define SECRET_H
/*
* ==================================================================================
* MODULAR HEADER INCLUDES
* ==================================================================================
*/
/*
* common.h - Common definitions, constants, and configuration structure
*
* Provides:
* - Standard library includes (stdio.h, stdlib.h, string.h, etc.)
* - Network includes (netinet/ip.h, netinet/icmp6.h, etc.)
* - Application constants (MAX_PAYLOAD_SIZE, PBKDF2_ITERATIONS, etc.)
* - Utility macros (SAFE_FREE, SAFE_CLOSE, MIN, MAX)
* - config_t structure for command-line configuration
*/
#include "common.h"
/*
* error.h - Error handling and reporting
*
* Provides:
* - error_code_t enum with all error codes (ERR_SUCCESS, ERR_MEMORY_ALLOC, etc.)
* - ERROR_SET macro for setting error context
* - error_print_last() for printing errors to stderr
* - Thread-safe error context management
*/
#include "error.h"
/*
* crypto.h - Cryptographic operations
*
* Provides:
* - crypto_engine_t structure for AES-256-CBC encryption state
* - crypto_init(), crypto_encrypt(), crypto_decrypt() functions
* - PBKDF2 key derivation with 600,000 iterations
* - Secure memory wiping (crypto_secure_zero)
*/
#include "crypto.h"
/*
* network.h - Network interface and ICMP operations
*
* Provides:
* - network_interface_t structure for raw socket management
* - network_init(), network_send_packet(), network_recv_packet() functions
* - Dual-stack IPv4/IPv6 support
* - ICMP checksum calculation (IPv4 only, kernel handles IPv6)
* - Network statistics tracking (network_stats_t)
*/
#include "network.h"
/*
* protocol.h - IFTP protocol implementation
*
* Provides:
* - iftp_header_t structure (24-byte fixed-size header)
* - iftp_metadata_t structure (filename, file_size, IV, salt)
* - iftp_error_t enum for NACK error codes
* - protocol_session_t structure for protocol state
* - Message type constants (MSG_TYPE_START, MSG_TYPE_DATA, MSG_TYPE_END, etc.)
* - protocol_create_*() functions for packet creation
* - protocol_parse_*() functions for packet parsing
* - CRC32 checksum validation
*/
#include "protocol.h"
/*
* file_io.h - File management and I/O
*
* Provides:
* - file_manager_t structure for chunk-based file I/O
* - file_manager_open_read(), file_manager_read_chunk() for client
* - file_manager_open_write(), file_manager_write_chunk() for server
* - Path security functions (path_is_safe, file_manager_get_basename)
* - File transfer statistics (file_transfer_stats_t)
*/
#include "file_io.h"
/*
* state_machine.h - Protocol state machines
*
* Provides:
* - client_state_machine_t for client-side state tracking
* - server_state_machine_t for server-side state tracking
* - client_state_t enum (CLIENT_IDLE, CLIENT_DATA_TRANSFER, etc.)
* - server_state_t enum (SERVER_LISTENING, SERVER_RECEIVING_DATA, etc.)
* - protocol_event_t enum (EVENT_TIMEOUT, EVENT_ACK_RECEIVED, etc.)
* - State transition functions (client_sm_transition, server_sm_transition)
* - Timeout handling with exponential backoff
* - Error recovery logic
*/
#include "state_machine.h"
/*
* ==================================================================================
* SERVER SESSION STRUCTURE
* ==================================================================================
*/
/*
* server_session_t - Server-side session state for client connection
*
* This structure maintains all state required for a single file transfer session
* on the server side. The server can handle multiple sessions concurrently by
* maintaining an array of server_session_t structures, indexed by session_id.
*
* LIFECYCLE:
* 1. Created when START packet received from new client
* 2. Initialized with metadata from START packet
* 3. Updated as DATA packets received
* 4. Cleaned up when END packet received or session times out
*
* USAGE (Server):
* server_session_t sessions[MAX_SESSIONS];
* // On START packet:
* server_session_t *session = find_free_session(sessions);
* session->session_id = start_packet->session_id;
* session->expected_seq = 0;
* session->active = 1;
* memcpy(&session->client_addr, &src_addr, sizeof(src_addr));
* // On DATA packet:
* validate_session_id(packet, session);
* validate_sequence_number(packet, session);
* decrypt_and_write_chunk(packet, session);
* session->expected_seq++;
* // On END packet or timeout:
* cleanup_session(session);
*
* THREAD SAFETY:
* This structure is NOT thread-safe. If server uses multiple threads to handle
* concurrent sessions, each session must be protected by a mutex.
*
* MEMORY MANAGEMENT:
* - reassembly_buffer and received_fragments are dynamically allocated
* - Must call cleanup function to free these before discarding structure
*/
typedef struct {
/*
* session_id - Unique session identifier (16-bit)
*
* Extracted from START packet's IFTP header.
* Used to match DATA/END packets to this session.
*
* Range: 0 to 65535
* Generated by client using cryptographically secure random number.
*
* Multiple sessions can exist simultaneously if server handles multiple
* clients concurrently. Each session MUST have unique session_id.
*/
uint16_t session_id;
/*
* expected_seq - Expected sequence number in next DATA packet
*
* Initialized to 0 when START packet received.
* Incremented after each valid DATA packet processed.
*
* Used to:
* - Validate received DATA packet has correct seq_num
* - Detect duplicate packets (seq_num < expected_seq) → ignore or resend ACK
* - Detect skipped packets (seq_num > expected_seq) → NACK with SEQUENCE_ERROR
*
* Range: 0 to UINT32_MAX
*/
uint32_t expected_seq;
/*
* reassembly_buffer - Buffer for reassembling fragmented packets
*
* Dynamically allocated buffer large enough to hold one complete chunk
* (MAX_PAYLOAD_SIZE = 1400 bytes) that may arrive in multiple fragments.
*
* Allocation: malloc(MAX_PAYLOAD_SIZE) when session created
* Deallocation: SAFE_FREE when session cleanup
*
* Usage:
* - Fragment packets are assembled here before decryption
* - Once all fragments for a chunk received, decrypt and write to file
* - Buffer reused for each chunk
*
* Note: Current implementation may not use fragmentation (chunk_size ≤ 1400),
* but this buffer enables future support for larger chunks.
*/
uint8_t *reassembly_buffer;
/*
* received_fragments - Bitmap tracking received fragment numbers
*
* Dynamically allocated bitmap to track which fragments have been received
* for the current chunk. Each bit represents one fragment number.
*
* Allocation: malloc(fragment_total / 8 + 1) when chunk reception starts
* Deallocation: SAFE_FREE when chunk complete or session cleanup
*
* Usage:
* - Set bit N when fragment N received
* - Check if all fragments received: count set bits == fragment_total
* - Prevents duplicate fragment processing
*
* Example (fragment_total = 3):
* - Initially: [0, 0, 0]
* - Fragment 0 received: [1, 0, 0]
* - Fragment 2 received: [1, 0, 1]
* - Fragment 1 received: [1, 1, 1] → all received, decrypt chunk
*/
uint8_t *received_fragments;
/*
* file_size - Expected total file size in bytes
*
* Extracted from START packet metadata.
* Used to:
* - Validate transfer completion (bytes_written == file_size)
* - Prevent buffer overflows (reject writes exceeding file_size)
* - Calculate expected number of DATA packets
* - Display progress percentage
*
* Range: 0 to UINT64_MAX (theoretical max ~16 exabytes)
*/
uint64_t file_size;
/*
* filename - Basename of file being received
*
* Extracted from START packet metadata using file_manager_get_basename().
* Directory components are stripped for security (path traversal prevention).
*
* Size: MAX_FILENAME_LEN + 1 (256 + 1 = 257 bytes)
* Content: Null-terminated string, basename only
*
* Examples:
* - Received: "/etc/passwd" → Stored: "passwd"
* - Received: "../../../evil" → Stored: "evil"
* - Received: "file.txt" → Stored: "file.txt"
*
* File is created in server's current working directory with this name.
*/
char filename[MAX_FILENAME_LEN + 1];
/*
* crypto - Crypto engine for decryption
*
* Initialized when START packet received:
* - Extracts IV and salt from metadata
* - Derives key using PBKDF2 from login password
* - Configures for decryption mode
*
* Used to decrypt each DATA packet payload.
*
* Must call crypto_cleanup() when session ends to securely wipe key material.
*/
crypto_engine_t crypto;
/*
* file_mgr - File manager for writing received chunks
*
* Initialized when START packet received:
* - Opens file for writing (file_manager_open_write)
* - Sets expected file_size from metadata
* - Tracks bytes_written progress
*
* Used to write decrypted chunks to disk.
*
* Must call file_manager_cleanup() when session ends to close file.
*/
file_manager_t file_mgr;
/*
* client_addr - Source address of client
*
* Extracted from recvfrom() when START packet received.
* Used to:
* - Send ACK/NACK responses back to client
* - Validate that DATA/END packets come from same client
* (prevents session hijacking)
*
* Type: sockaddr_storage (polymorphic, holds IPv4 or IPv6)
* Size: 128 bytes (platform-dependent)
*
* Cast to sockaddr_in or sockaddr_in6 based on client_addr.ss_family:
* - AF_INET: IPv4 client
* - AF_INET6: IPv6 client
*/
struct sockaddr_storage client_addr;
/*
* client_addr_len - Actual length of client_addr
*
* Typical values:
* - IPv4: sizeof(struct sockaddr_in) = 16 bytes
* - IPv6: sizeof(struct sockaddr_in6) = 28 bytes
*
* Used by sendto() when sending ACK/NACK to client.
*/
socklen_t client_addr_len;
/*
* active - Session active flag
*
* Values:
* - 1: Session active, processing packets
* - 0: Session inactive, slot available for new client
*
* Set to 1 when START packet received and session initialized.
* Set to 0 when:
* - END packet received and ACK sent (success)
* - Session timeout (client disconnected)
* - Error occurred (file write failure, decryption error, etc.)
*
* Used by find_free_session() to locate available session slot.
*/
int active;
/*
* session_start - Session start timestamp (Unix time)
*
* Set when START packet received using time(NULL).
* Used to:
* - Calculate total session duration
* - Display session age
* - Statistics reporting
*/
time_t session_start;
/*
* last_activity - Last packet received timestamp
*
* Updated when valid packet received from client (START, DATA, or END).
* Used to detect session timeout:
* if (time(NULL) - last_activity) > SESSION_TIMEOUT:
* cleanup_session(session)
*
* Default timeout: SESSION_TIMEOUT (30 seconds)
*
* Prevents resource leaks from clients that crash or disconnect without
* sending END packet.
*/
time_t last_activity;
} server_session_t;
/*
* ==================================================================================
* MAIN APPLICATION ENTRY POINTS
* ==================================================================================
*/
/*
* client_run - Execute client mode (send file)
*
* This function implements the complete client-side file transfer protocol:
* 1. Initialize network interface (create raw ICMP socket)
* 2. Open file for reading
* 3. Initialize crypto engine (generate IV/salt, derive key)
* 4. Send START packet with metadata
* 5. Wait for START-ACK
* 6. Loop: Read chunk → Encrypt → Send DATA → Wait for ACK
* 7. Send END packet
* 8. Wait for END-ACK
* 9. Clean up resources
*
* ERROR HANDLING:
* - Implements retry logic with exponential backoff (max 5 retries)
* - Returns -1 on failure (network error, file error, max retries exceeded)
* - Returns 0 on success
*
* REQUIRES:
* - Root privileges (raw socket)
* - Readable source file
* - Network connectivity to destination
*
* @param config: Configuration structure with:
* - config->filename: Path to file to send
* - config->server_address: Destination IP or hostname
* - config->timeout: Initial timeout in seconds (default: 2)
*
* @return:
* 0: Success - file transferred successfully
* -1: Failure - error details in error context (use error_print_last())
*/
int client_run(const config_t *config);
/*
* server_run - Execute server mode (receive files)
*
* This function implements the complete server-side file reception protocol:
* 1. Initialize network interface (create raw ICMP socket)
* 2. Enter listening loop:
* a. Poll for incoming ICMP packets (non-blocking)
* b. Validate packet (magic number, CRC32)
* c. Match packet to session (or create new session for START)
* d. Process packet based on type:
* - START: Create session, extract metadata, open file, send START-ACK
* - DATA: Validate sequence, decrypt chunk, write to file, send DATA-ACK
* - END: Finalize file, send END-ACK, clean up session
* e. Check for session timeouts, clean up inactive sessions
* 3. Handle signals (Ctrl+C) for graceful shutdown
* 4. Clean up all active sessions before exit
*
* ERROR HANDLING:
* - Sends NACK on recoverable errors (invalid sequence, checksum error)
* - Cleans up session on unrecoverable errors (file write failure, decryption error)
* - Continues listening after error (does not exit)
* - Returns -1 only on fatal errors (socket creation failure)
*
* REQUIRES:
* - Root privileges (raw socket)
* - Write permission in current directory (for received files)
*
* @param config: Configuration structure (server_mode = 1)
*
* @return:
* 0: Success - server shutdown gracefully
* -1: Failure - fatal error occurred (use error_print_last())
*/
int server_run(const config_t *config);
#endif /* SECRET_H */