Update branch

parent 2d148eca
#!/bin/bash
# WSSSH: Warp-Powered Stefy's Spatial Secure Hyperdrive Build Script
# Build script for WSSSH tools (wssshd, wssshc, wsscp, etc.)
# build.sh - Main build script for wsssh project
# Handles building wssshd2 server and wssshtools client components
#
# Copyright (C) 2024 Stefy Lanza <stefy@nexlab.net> and SexHack.me
#
......@@ -18,368 +18,297 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
WHITE='\033[1;37m'
BLACK='\033[0;30m'
MAGENTA='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# Display flags side by side
display_flags() {
echo -e "\e[41m \e[40m \e[0m \e[48;5;117m \e[0m"
echo -e "\e[41m \e[40m \e[0m \e[48;5;117m \e[0m"
echo -e "\e[41m \e[40m \e[0m \e[48;5;218m \e[0m"
echo -e "\e[41m \e[47m \e[0m \e[48;5;218m \e[0m"
echo -e "\e[41m \e[47m \e[0m \e[48;5;231m \e[0m"
echo -e "\e[41m \e[47m \e[0m \e[48;5;231m \e[0m"
echo -e "\e[41m \e[42m \e[0m \e[48;5;218m \e[0m"
echo -e "\e[41m \e[42m \e[0m \e[48;5;218m \e[0m"
echo -e "\e[41m \e[42m \e[0m \e[48;5;117m \e[0m"
echo -e " \e[48;5;117m \e[0m"
}
# Display flags at startup
display_flags
# Logging functions
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Check if we're in the right directory
if [[ ! -d "wssshd2" || ! -d "wssshtools" ]]; then
log_error "This script must be run from the wsssh project root directory"
exit 1
fi
# Parse command line arguments
BUILD_DEBIAN=false
BUILD_DEBIAN_ONLY=false
BUILD_SERVER_ONLY=false
BUILD_NO_SERVER=false
BUILD_WSSSHTOOLS_ONLY=false
BUILD_PACKAGES=false
BUILD_CLEAN=false
BUILD_NO_VENV=false
SERVER_ONLY=false
WSSSHTOOLS_ONLY=false
DEBIAN_BUILD=false
CLEANUP=false
while [[ $# -gt 0 ]]; do
case $1 in
--debian)
BUILD_DEBIAN=true
shift
;;
--debian-only)
BUILD_DEBIAN_ONLY=true
BUILD_DEBIAN=true
shift
;;
--packages)
BUILD_PACKAGES=true
BUILD_DEBIAN=true
shift
;;
--server-only)
BUILD_SERVER_ONLY=true
BUILD_DEBIAN=true
shift
;;
--no-server)
BUILD_NO_SERVER=true
SERVER_ONLY=true
shift
;;
--wssshtools-only)
BUILD_WSSSHTOOLS_ONLY=true
WSSSHTOOLS_ONLY=true
shift
;;
--clean)
BUILD_CLEAN=true
--debian)
DEBIAN_BUILD=true
shift
;;
--novenv)
BUILD_NO_VENV=true
--clean|--cleanup)
CLEANUP=true
shift
;;
--help|-h)
echo "Usage: $0 [options]"
echo "Options:"
echo " --debian Build Debian packages (wsssh-server and wsssh-tools)"
echo " --debian-only Build only wsssh-tools Debian package (skip binaries and server)"
echo " --packages Build all Debian packages (equivalent to --debian-only)"
echo " --server-only Build only the server (wssshd) and wsssh-server Debian package"
echo " --no-server Skip building the server (wssshd) and wsssh-server package"
echo " --wssshtools-only Build only the C tools (wssshtools) and wsssh-tools package"
echo " --clean Clean build artifacts (equivalent to ./clean.sh)"
echo " --novenv When used with --clean, preserve Python virtual environment"
echo " --help, -h Show this help"
exit 0
;;
*)
echo "Unknown option: $1"
echo "Usage: $0 [--debian] [--debian-only] [--packages] [--server-only] [--no-server] [--wssshtools-only] [--clean] [--novenv] [--help]"
echo "Try '$0 --help' for more information."
log_error "Unknown option: $1"
echo "Usage: $0 [--server-only|--wssshtools-only] [--debian] [--clean|--cleanup]"
exit 1
;;
esac
done
# Validate argument combinations
if [[ "$SERVER_ONLY" == true && "$WSSSHTOOLS_ONLY" == true ]]; then
log_error "--server-only and --wssshtools-only cannot be used together"
exit 1
fi
# Handle clean option first
if [ "$BUILD_CLEAN" = true ]; then
echo "Cleaning build artifacts..."
# Remove PyInstaller build artifacts
rm -rf build/
rm -rf dist/
rm -f *.spec
rm -f wssshd # Remove PyInstaller binary
rm -f wsssd/__pycache__/*.pyc 2>/dev/null || true
rm -f wsssd/__pycache__ 2>/dev/null || true
# Remove virtual environment (unless --novenv is specified)
if [ "$BUILD_NO_VENV" = false ]; then
rm -rf venv/
else
echo "Preserving Python virtual environment (venv/) due to --novenv option"
fi
# Remove SSL certificates
rm -f cert.pem key.pem
# Remove logos and icons
rm -rf logos/
# Remove C version build artifacts
if [ -d "wssshtools" ]; then
cd wssshtools
make clean 2>/dev/null || true
rm -f Makefile
rm -f configure.sh.stamp
rm -f man/*.1.gz 2>/dev/null || true
cd ..
fi
# Remove Debian packaging artifacts
# wsssh-server packages
rm -f dist/wsssh-server*.deb
rm -f dist/wsssh-server*.dsc
rm -f dist/wsssh-server*.tar.gz
rm -f dist/wsssh-server*.changes
rm -f dist/wsssh-server*.buildinfo
rm -f wsssh-server*.deb
rm -f wsssh-server*.dsc
rm -f wsssh-server*.tar.gz
rm -f wsssh-server*.changes
rm -f wsssh-server*.buildinfo
# wsssh-tools packages
rm -f dist/wsssh-tools*.deb
rm -f dist/wsssh-tools*.dsc
rm -f dist/wsssh-tools*.tar.gz
rm -f dist/wsssh-tools*.changes
rm -f dist/wsssh-tools*.buildinfo
rm -f wsssh-tools*.deb
rm -f wsssh-tools*.dsc
rm -f wsssh-tools*.tar.gz
rm -f wsssh-tools*.changes
rm -f wsssh-tools*.buildinfo
# Remove Debian build directory and artifacts
if [ -d "wsssh-server" ]; then
rm -rf wsssh-server/debian/wsssh-server/
rm -f wsssh-server/debian/files
rm -f wsssh-server/debian/*.debhelper*
rm -f wsssh-server/debian/*.substvars
rm -f wsssh-server/debian/debhelper-build-stamp
fi
if [[ "$CLEANUP" == true && "$DEBIAN_BUILD" == true ]]; then
log_error "--clean/--cleanup cannot be combined with --debian"
exit 1
fi
if [ -d "wssshtools" ]; then
rm -rf wssshtools/debian/wsssh-tools/
rm -f wssshtools/debian/files
rm -f wssshtools/debian/*.debhelper*
rm -f wssshtools/debian/*.substvars
rm -f wssshtools/debian/debhelper-build-stamp
fi
# Cleanup function
cleanup() {
local target="$1"
log_info "Cleaning up $target..."
case "$target" in
"server")
if [[ -d "wssshd2" ]]; then
cd wssshd2
if [[ -f "Makefile" ]]; then
make clean >/dev/null 2>&1 || true
fi
rm -f Makefile configure.sh.stamp
cd ..
fi
# Remove server debian artifacts
rm -rf wsssh-server*.deb wsssh-server*.dsc wsssh-server*.changes wsssh-server*.buildinfo
;;
"wssshtools")
if [[ -d "wssshtools" ]]; then
cd wssshtools
if [[ -f "Makefile" ]]; then
make clean >/dev/null 2>&1 || true
fi
rm -f Makefile configure.sh.stamp
cd ..
fi
# Remove wssshtools debian artifacts
rm -rf wsssh-tools*.deb wsssh-tools*.dsc wsssh-tools*.changes wsssh-tools*.buildinfo
;;
"logos")
# Remove logos artifacts
rm -rf logos/
;;
"all")
cleanup "server"
cleanup "wssshtools"
cleanup "logos"
;;
esac
}
if [ "$BUILD_NO_VENV" = true ]; then
echo "Clean complete. Build artifacts removed (Python virtual environment preserved)."
else
echo "Clean complete. All build artifacts removed."
fi
exit 0
fi
# Asset preparation function
prepare_assets() {
log_info "Preparing assets..."
# Create dist directory if not exists
mkdir -p dist
# Create logos directory if it doesn't exist
mkdir -p logos
# Skip Python/C building if --debian-only or --wssshtools-only is specified
if [ "$BUILD_DEBIAN_ONLY" = false ] && [ "$BUILD_WSSSHTOOLS_ONLY" = false ]; then
# Check if virtual environment exists, create if not
if [ ! -d "venv" ]; then
echo "Creating virtual environment..."
python3 -m venv venv
# Generate logo-128.png from image.jpg if imagemagick is available
if command -v convert >/dev/null 2>&1 && [[ -f "image.jpg" ]]; then
log_info "Generating logo-128.png from image.jpg..."
convert image.jpg -resize 128x128 logos/logo-128.png
elif [[ ! -f "logos/logo-128.png" ]]; then
log_warning "ImageMagick not found or image.jpg missing. Using placeholder logo."
# Create a simple placeholder if no logo exists
if command -v convert >/dev/null 2>&1; then
convert -size 128x128 xc:"#4A90E2" -fill white -pointsize 72 -gravity center -annotate +0+0 "WSSSH" logos/logo-128.png
fi
fi
# Activate virtual environment
. venv/bin/activate
# Generate HTML templates for wssshd2
log_info "Generating HTML templates..."
mkdir -p wssshd2/templates
# Install requirements
echo "Installing requirements..."
pip3 install -r requirements.txt
# Install pyinstaller if not already installed
pip3 install pyinstaller
# Generate SSL certificates if they don't exist
if [ ! -f "cert.pem" ] || [ ! -f "key.pem" ]; then
echo "Generating SSL certificates..."
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 36500 -nodes -subj "/C=US/ST=State/L=City/O=Organization/CN=localhost"
# Copy templates from root templates directory if they exist
if [[ -d "templates" ]]; then
cp -r templates/* wssshd2/templates/ 2>/dev/null || true
fi
# Generate logos and icons from image.jpg if it exists (for backward compatibility)
if [ -f "image.jpg" ] && command -v convert &> /dev/null; then
echo "Generating logos and icons from image.jpg..."
mkdir -p logos
# Generate various logo sizes
convert image.jpg -resize 512x512 logos/logo-512.png
convert image.jpg -resize 256x256 logos/logo-256.png
convert image.jpg -resize 128x128 logos/logo-128.png
convert image.jpg -resize 64x64 logos/logo-64.png
log_success "Assets prepared"
}
# Generate icon sizes
for size in 16 32 48 64 128 256; do
convert image.jpg -resize ${size}x${size} logos/icon-${size}.png
done
# Build server function
build_server() {
log_info "Building wssshd2 server..."
# Generate additional assets
convert image.jpg -resize 800x200 logos/banner-800x200.png
convert image.jpg -quality 100 logos/logo-high-quality.png
convert image.jpg -resize 32x32 logos/favicon.ico
cd wssshd2
echo "Logo generation complete."
elif [ -f "image.jpg" ]; then
echo "Warning: ImageMagick not found. Using image.jpg directly without generating logos."
# Run configure
if [[ ! -f "configure.sh.stamp" ]]; then
log_info "Running configure.sh..."
chmod +x configure.sh
./configure.sh
touch configure.sh.stamp
fi
# Build Python binaries
echo "Building Python binaries..."
# Build
log_info "Compiling wssshd2..."
make
# Build wssshd (server) binary unless --no-server is specified
if [ "$BUILD_NO_SERVER" = false ]; then
pyinstaller --onefile --distpath dist --add-data "cert.pem:." --add-data "key.pem:." --add-data "templates:templates" --add-data "image.jpg:." --add-data "logos:logos" --add-data "wsssd:wsssd" --hidden-import wsssd --hidden-import wsssd.config --hidden-import wsssd.websocket --hidden-import wsssd.terminal --hidden-import wsssd.web --hidden-import wsssd.server --hidden-import websockets --hidden-import websockets.server --hidden-import websockets.client --hidden-import websockets.exceptions --hidden-import websockets.protocol --hidden-import websockets.uri --runtime-tmpdir /tmp --clean wssshd.py
fi
cd ..
log_success "wssshd2 server built successfully"
}
# Build client binaries
if [ "$BUILD_SERVER_ONLY" = false ]; then
# Client binaries are not built in this version
echo "Client binaries not built in this version"
fi
fi
# Build wssshtools function
build_wssshtools() {
log_info "Building wssshtools..."
# Build C version if wssshtools directory exists and not debian-only
if [ "$BUILD_DEBIAN_ONLY" = false ] && [ -d "wssshtools" ]; then
echo "Building C version..."
cd wssshtools
if [ -f "configure.sh" ]; then
# Run configure
if [[ ! -f "configure.sh.stamp" ]]; then
log_info "Running configure.sh..."
chmod +x configure.sh
./configure.sh
if [ "$BUILD_WSSSHTOOLS_ONLY" = true ]; then
# Build all C tools for wssshtools-only mode
make
elif [ "$BUILD_NO_SERVER" = true ]; then
# Build only wssshc for no-server mode
make wssshc
elif [ "$BUILD_SERVER_ONLY" = true ]; then
# Skip C tools build for server-only mode
echo "Skipping C tools build for server-only mode"
else
make
fi
cd ..
else
echo "Warning: configure.sh not found in wssshtools/"
cd ..
touch configure.sh.stamp
fi
fi
# Build Debian package if requested
if [ "$BUILD_DEBIAN" = true ]; then
echo "Checking Debian build dependencies..."
# Build
log_info "Compiling wssshtools..."
make
# Check for required Debian build tools
missing_deps=""
for dep in debhelper gcc make pkg-config libssl-dev python3 python3-pip python3-setuptools; do
if ! dpkg -l | grep -q "^ii $dep"; then
missing_deps="$missing_deps $dep"
fi
done
cd ..
log_success "wssshtools built successfully"
}
# Debian packaging function
build_debian_package() {
local package_type="$1"
if [ -n "$missing_deps" ]; then
echo "Error: Missing Debian build dependencies:$missing_deps"
echo "Please install them with: sudo apt-get install$missing_deps"
echo "Or run: sudo apt-get install debhelper gcc make pkg-config libssl-dev python3 python3-pip python3-setuptools"
if ! command -v dpkg-buildpackage >/dev/null 2>&1; then
log_error "dpkg-buildpackage not found. Please install debian packaging tools."
exit 1
fi
echo "All Debian build dependencies found."
echo "Building Debian packages..."
# Build wsssh-server package if it exists and (not wssshtools-only OR server-only) and not debian-only
if ([ "$BUILD_WSSSHTOOLS_ONLY" = false ] || [ "$BUILD_SERVER_ONLY" = true ]) && [ "$BUILD_DEBIAN_ONLY" = false ] && [ -d "wsssh-server" ] && [ -d "wsssh-server/debian" ]; then
echo "Building wsssh-server Debian package..."
cd wsssh-server
dpkg-buildpackage -us -uc
cd ..
# Move deb file to dist
mv ../wsssh-server*.deb dist/ 2>/dev/null || true
echo "wsssh-server package built successfully."
fi
case "$package_type" in
"server")
log_info "Building Debian package for wsssh-server..."
cd wsssh-server
dpkg-buildpackage -us -uc
cd ..
;;
"wssshtools")
log_info "Building Debian package for wsssh-tools..."
cd wssshtools
dpkg-buildpackage -us -uc
cd ..
;;
esac
# Build wssshtools package if it exists and (not server-only OR debian-only)
if ([ "$BUILD_SERVER_ONLY" = false ] || [ "$BUILD_DEBIAN_ONLY" = true ]) && [ -d "wssshtools" ] && [ -d "wssshtools/debian" ]; then
echo "Building wsssh-tools Debian package..."
cd wssshtools
dpkg-buildpackage -us -uc
cd ..
# Move deb file to dist
mv ../wsssh-tools*.deb dist/ 2>/dev/null || true
echo "wsssh-tools package built successfully."
fi
log_success "Debian package built successfully"
}
if [ "$BUILD_SERVER_ONLY" = true ] && [ ! -d "wsssh-server" ]; then
echo "Warning: wsssh-server package not available (missing wsssh-server/ directory)"
# Main build logic
if [[ "$CLEANUP" == true ]]; then
# Cleanup mode
if [[ "$SERVER_ONLY" == true ]]; then
cleanup "server"
elif [[ "$WSSSHTOOLS_ONLY" == true ]]; then
cleanup "wssshtools"
else
cleanup "all"
fi
log_success "Cleanup completed"
exit 0
fi
if [ "$BUILD_WSSSHTOOLS_ONLY" = true ] && [ ! -d "wssshtools" ]; then
echo "Warning: wsssh-tools package not available (missing wssshtools/ directory)"
fi
# Validate build options
if [[ "$SERVER_ONLY" == true && "$WSSSHTOOLS_ONLY" == true ]]; then
log_error "Cannot specify both --server-only and --wssshtools-only"
exit 1
fi
# Deactivate venv if it was activated
if [ "$BUILD_DEBIAN_ONLY" = false ] && [ "$BUILD_WSSSHTOOLS_ONLY" = false ]; then
deactivate
# Prepare assets (needed for server build)
if [[ "$SERVER_ONLY" == true || "$DEBIAN_BUILD" == true || ( "$SERVER_ONLY" == false && "$WSSSHTOOLS_ONLY" == false ) ]]; then
prepare_assets
fi
if [ "$BUILD_DEBIAN_ONLY" = true ]; then
echo "Debian package build complete."
echo "Package available in dist/ directory:"
if ls dist/wsssh-tools*.deb >/dev/null 2>&1; then
echo "- dist/wsssh-tools*.deb (C tools Debian package)"
fi
elif [ "$BUILD_PACKAGES" = true ]; then
echo "Debian package build complete."
echo "Packages available in dist/ directory:"
if ls dist/wsssh-server*.deb >/dev/null 2>&1; then
echo "- dist/wsssh-server*.deb (wssshd server Debian package)"
fi
if ls dist/wsssh-tools*.deb >/dev/null 2>&1; then
echo "- dist/wsssh-tools*.deb (C tools Debian package)"
fi
elif [ "$BUILD_WSSSHTOOLS_ONLY" = true ]; then
echo "C tools build complete."
if [ -d "wssshtools" ] && [ -f "wssshtools/wssshc" ]; then
echo "C tools available in wssshtools/ directory:"
echo "- wssshtools/wssshc (C client)"
echo "- wssshtools/wsssh (C SSH wrapper)"
echo "- wssshtools/wsscp (C SCP wrapper)"
fi
elif [ "$BUILD_SERVER_ONLY" = true ]; then
echo "Server-only build complete."
if [ "$BUILD_NO_SERVER" = false ]; then
echo "Server binary available in dist/ directory:"
echo "- dist/wssshd (server with web interface)"
fi
if ls dist/wsssh-server*.deb >/dev/null 2>&1; then
echo "- dist/wsssh-server*.deb (wssshd server Debian package)"
fi
# Build components
if [[ "$SERVER_ONLY" == true ]]; then
build_server
elif [[ "$WSSSHTOOLS_ONLY" == true ]]; then
build_wssshtools
else
echo "Build complete. Binaries are in dist/ directory:"
if [ "$BUILD_NO_SERVER" = false ]; then
echo "- dist/wssshd (server with web interface)"
fi
# Build both
build_server
build_wssshtools
fi
if [ -d "wssshtools" ] && [ -f "wssshtools/wssshc" ]; then
if [ "$BUILD_NO_SERVER" = true ]; then
echo "- wssshtools/wssshc (C client)"
elif [ "$BUILD_SERVER_ONLY" = false ]; then
echo "- wssshtools/wssshc (C client)"
echo "- wssshtools/wsssh (C SSH wrapper)"
echo "- wssshtools/wsscp (C SCP wrapper)"
fi
# Debian packaging
if [[ "$DEBIAN_BUILD" == true ]]; then
if [[ "$SERVER_ONLY" == true ]]; then
build_debian_package "server"
elif [[ "$WSSSHTOOLS_ONLY" == true ]]; then
build_debian_package "wssshtools"
else
build_debian_package "server"
build_debian_package "wssshtools"
fi
fi
if [ "$BUILD_DEBIAN" = true ]; then
echo "Debian packages available in dist/ directory:"
if ls dist/wsssh-server*.deb >/dev/null 2>&1; then
echo "- dist/wsssh-server*.deb (wssshd server Debian package)"
fi
if ls dist/wsssh-tools*.deb >/dev/null 2>&1; then
echo "- dist/wsssh-tools*.deb (C tools Debian package)"
fi
fi
fi
\ No newline at end of file
log_success "Build completed successfully!"
#!/bin/bash
# WSSSH: Warp-Powered Stefy's Spatial Secure Hyperdrive Clean Script
# Clean script for removing build artifacts from WSSSH tools
# clean.sh - Cleanup script for wsssh project
# Calls build.sh --clean with all passed arguments
#
# Copyright (C) 2024 Stefy Lanza <stefy@nexlab.net> and SexHack.me
#
......@@ -18,5 +18,8 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# Use build.sh --clean for consistent cleaning
./build.sh --clean --novenv
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
# Pass all arguments to build.sh --clean
exec ./build.sh --clean "$@"
......@@ -241,6 +241,9 @@ async def shutdown_server(ws_server, cleanup_coro, flask_thread):
async def run_server():
"""Main server function"""
# Create new process group to avoid receiving SIGINT from terminal
os.setpgrp()
args = load_config()
# Set global variables
......
......@@ -29,8 +29,8 @@ extern const char *terminal_html;
extern const char *users_html;
// Embedded images
extern const unsigned char *image_jpg;
extern size_t image_jpg_len;
extern unsigned char image_jpg[];
extern unsigned int image_jpg_len;
// Function to get asset by path
const char *get_embedded_asset(const char *path, size_t *size);
......
No preview for this file type
No preview for this file type
......@@ -34,7 +34,9 @@
#include "assets.h"
#include "websocket.h"
#include "html_pages/index_page.h"
#include "html_pages/login_page.h"
#include "html_pages/terminal_page.h"
#include "html_pages/users_page.h"
// Embedded web assets are defined in assets.c
......@@ -377,8 +379,7 @@ static void handle_request(int client_fd, const http_request_t *req) {
char *html = generate_index_html(username, is_admin);
send_response(client_fd, 200, "OK", "text/html", html, strlen(html), NULL, NULL);
} else if (strcmp(req->path, "/login") == 0) {
const char *asset = get_embedded_asset("/login", NULL);
send_response(client_fd, 200, "OK", "text/html", asset, strlen(asset), NULL, NULL);
send_response(client_fd, 200, "OK", "text/html", login_page_html, strlen(login_page_html), NULL, NULL);
} else if (strcmp(req->path, "/logout") == 0) {
send_response(client_fd, 302, "Found", "text/html", NULL, 0, "session_id=; Max-Age=0; Path=/", NULL);
return;
......@@ -387,8 +388,7 @@ static void handle_request(int client_fd, const http_request_t *req) {
send_response(client_fd, 403, "Forbidden", "text/html", "Access denied", 13, NULL, NULL);
return;
}
const char *asset = get_embedded_asset("/users.html", NULL);
send_response(client_fd, 200, "OK", "text/html", asset, strlen(asset), NULL, NULL);
send_response(client_fd, 200, "OK", "text/html", users_page_html, strlen(users_page_html), NULL, NULL);
} else if (strncmp(req->path, "/terminal/", 9) == 0) {
if (!username) {
send_response(client_fd, 302, "Found", "text/html", NULL, 0, NULL, NULL);
......
No preview for this file type
No preview for this file type
......@@ -163,8 +163,6 @@ static bool ws_parse_frame_header(const uint8_t *buffer, size_t len, ws_frame_he
// Limit to 10MB to prevent excessive memory allocation
const size_t MAX_PAYLOAD_SIZE = 10 * 1024 * 1024; // 10MB
if (header->payload_len > MAX_PAYLOAD_SIZE) {
printf("[DEBUG] ws_parse_frame_header: Payload too large: %llu bytes (max: %zu)\n",
(unsigned long long)header->payload_len, MAX_PAYLOAD_SIZE);
return false; // Reject frames with excessively large payloads
}
......@@ -263,17 +261,14 @@ bool ws_perform_handshake(ws_connection_t *conn) {
// Send WebSocket frame
bool ws_send_frame(ws_connection_t *conn, uint8_t opcode, const void *data, size_t len) {
if (!conn) {
printf("[DEBUG] ws_send_frame: Connection is NULL\n");
return false;
}
if (conn->state != WS_STATE_OPEN) {
printf("[DEBUG] ws_send_frame: Connection not in OPEN state (state=%d)\n", conn->state);
return false;
}
if (!conn->ssl) {
printf("[DEBUG] ws_send_frame: SSL connection is NULL\n");
return false;
}
......@@ -289,7 +284,6 @@ bool ws_send_frame(ws_connection_t *conn, uint8_t opcode, const void *data, size
size_t frame_len = header_len + len;
uint8_t *frame = malloc(frame_len);
if (!frame) {
printf("[DEBUG] ws_send_frame: Failed to allocate frame buffer\n");
return false;
}
......@@ -317,8 +311,6 @@ bool ws_send_frame(ws_connection_t *conn, uint8_t opcode, const void *data, size
memcpy(frame + header_len, data, len);
}
printf("[DEBUG] ws_send_frame: Sending frame with opcode=%d, len=%zu, frame_len=%zu\n", opcode, len, frame_len);
// Send frame with partial write handling and retry logic
int total_written = 0;
int retry_count = 0;
......@@ -329,18 +321,15 @@ bool ws_send_frame(ws_connection_t *conn, uint8_t opcode, const void *data, size
int written = SSL_write(conn->ssl, frame + total_written, to_write);
if (written <= 0) {
int ssl_error = SSL_get_error(conn->ssl, written);
printf("[DEBUG] ws_send_frame: SSL_write failed at offset %d, ssl_error=%d\n", total_written, ssl_error);
// Check for recoverable SSL errors
if ((ssl_error == SSL_ERROR_WANT_READ || ssl_error == SSL_ERROR_WANT_WRITE ||
ssl_error == SSL_ERROR_SSL || ssl_error == SSL_ERROR_SYSCALL) && retry_count < max_retries - 1) {
retry_count++;
printf("[DEBUG] ws_send_frame: Recoverable SSL error, retrying (%d/%d)\n", retry_count, max_retries);
// Exponential backoff: wait longer between retries
usleep(10000 * (1 << retry_count)); // 10ms, 20ms, 40ms, 80ms
continue; // Retry the write operation
} else {
printf("[DEBUG] ws_send_frame: Fatal SSL error %d after %d retries\n", ssl_error, retry_count);
// Don't mark connection as closed on send failures - let receive failures handle connection closure
}
......@@ -352,11 +341,9 @@ bool ws_send_frame(ws_connection_t *conn, uint8_t opcode, const void *data, size
}
if (total_written < (int)frame_len) {
printf("[DEBUG] ws_send_frame: Write incomplete after retries: %d/%d bytes written\n", total_written, (int)frame_len);
free(frame);
return false;
}
printf("[DEBUG] ws_send_frame: SSL_write returned %d (expected %zu)\n", total_written, frame_len);
free(frame);
return total_written == (int)frame_len;
}
......@@ -369,17 +356,12 @@ bool ws_receive_frame(ws_connection_t *conn, uint8_t *opcode, void **data, size_
uint8_t header[14];
int bytes_read = SSL_read(conn->ssl, header, 2);
if (bytes_read <= 0) {
int ssl_error = SSL_get_error(conn->ssl, bytes_read);
printf("[DEBUG] ws_receive_frame: SSL_read failed, bytes_read=%d, ssl_error=%d\n", bytes_read, ssl_error);
return false;
}
if (bytes_read != 2) {
printf("[DEBUG] ws_receive_frame: Expected 2 header bytes, got %d\n", bytes_read);
return false;
}
printf("[DEBUG] ws_receive_frame: Header bytes: 0x%02x 0x%02x\n", header[0], header[1]);
// Determine minimum header size needed for parsing
uint8_t payload_len_indicator = header[1] & 0x7F;
size_t min_header_size = 2;
......@@ -396,7 +378,6 @@ bool ws_receive_frame(ws_connection_t *conn, uint8_t *opcode, void **data, size_
while (total_read < (int)(min_header_size - 2)) {
bytes_read = SSL_read(conn->ssl, header + 2 + total_read, min_header_size - 2 - total_read);
if (bytes_read <= 0) {
printf("[DEBUG] ws_receive_frame: Failed to read extended header\n");
return false;
}
total_read += bytes_read;
......@@ -409,7 +390,6 @@ bool ws_receive_frame(ws_connection_t *conn, uint8_t *opcode, void **data, size_
if (masked) {
bytes_read = SSL_read(conn->ssl, header + min_header_size, 4);
if (bytes_read != 4) {
printf("[DEBUG] ws_receive_frame: Failed to read masking key\n");
return false;
}
total_header_size += 4;
......@@ -417,13 +397,11 @@ bool ws_receive_frame(ws_connection_t *conn, uint8_t *opcode, void **data, size_
// Validate header size
if (total_header_size > sizeof(header)) {
printf("[DEBUG] ws_receive_frame: Header size %zu exceeds buffer size %zu\n", total_header_size, sizeof(header));
return false;
}
ws_frame_header_t frame_header;
if (!ws_parse_frame_header(header, total_header_size, &frame_header)) {
printf("[DEBUG] ws_receive_frame: Failed to parse complete frame header\n");
return false;
}
......@@ -439,15 +417,11 @@ bool ws_receive_frame(ws_connection_t *conn, uint8_t *opcode, void **data, size_
// Protect against memory exhaustion attacks with reasonable limit
const size_t MAX_SAFE_PAYLOAD = 50 * 1024 * 1024; // 50MB safety limit
if (frame_header.payload_len > MAX_SAFE_PAYLOAD) {
printf("[DEBUG] ws_receive_frame: Payload too large: %llu bytes (max: %zu)\n",
(unsigned long long)frame_header.payload_len, MAX_SAFE_PAYLOAD);
return false;
}
*data = malloc(frame_header.payload_len + 1); // +1 for null termination
if (!*data) {
printf("[DEBUG] ws_receive_frame: Failed to allocate %llu bytes for payload\n",
(unsigned long long)frame_header.payload_len + 1);
return false;
}
......@@ -460,9 +434,6 @@ bool ws_receive_frame(ws_connection_t *conn, uint8_t *opcode, void **data, size_
bytes_read = SSL_read(conn->ssl, (char *)*data + total_read, to_read);
if (bytes_read <= 0) {
int ssl_error = SSL_get_error(conn->ssl, bytes_read);
printf("[DEBUG] ws_receive_frame: SSL_read failed during payload, bytes_read=%d, ssl_error=%d\n",
bytes_read, ssl_error);
free(*data);
return false;
}
......@@ -471,8 +442,6 @@ bool ws_receive_frame(ws_connection_t *conn, uint8_t *opcode, void **data, size_
// Verify we read the complete payload
if (total_read != frame_header.payload_len) {
printf("[DEBUG] ws_receive_frame: Incomplete payload read: %zu/%llu\n",
total_read, (unsigned long long)frame_header.payload_len);
free(*data);
return false;
}
......
......@@ -73,6 +73,9 @@ bool ws_perform_handshake(ws_connection_t *conn);
bool ws_send_frame(ws_connection_t *conn, uint8_t opcode, const void *data, size_t len);
bool ws_receive_frame(ws_connection_t *conn, uint8_t *opcode, void **data, size_t *len);
// Connection health monitoring
bool ws_connection_is_healthy(ws_connection_t *conn);
// Utility functions
char *ws_compute_accept_key(const char *key);
void ws_mask_data(uint8_t *data, size_t len, const uint8_t *mask);
......
No preview for this file type
......@@ -45,6 +45,13 @@ if ! pkg-config --exists openssl; then
exit 1
fi
# Check for zlib development libraries
if ! pkg-config --exists zlib; then
echo "Error: zlib development libraries not found."
echo "Please install zlib-dev or zlib1g-dev package."
exit 1
fi
echo "All required tools found."
# Generate Makefile
......@@ -52,8 +59,8 @@ cat > Makefile << 'EOF'
# Makefile for wssshtools
CC = gcc
CFLAGS = -Wall -Wextra -O2 -D_GNU_SOURCE $(shell pkg-config --cflags openssl)
LDFLAGS = $(shell pkg-config --libs openssl)
CFLAGS = -Wall -Wextra -O2 -D_GNU_SOURCE $(shell pkg-config --cflags openssl) $(shell pkg-config --cflags zlib)
LDFLAGS = $(shell pkg-config --libs openssl) $(shell pkg-config --libs zlib)
# Source files
LIB_SRCS = libwsssht/wssshlib.c libwsssht/websocket.c libwsssht/wssh_ssl.c libwsssht/tunnel.c libwsssht/utils.c libwsssht/modes.c libwsssht/threads.c libwsssht/control_messages.c libwsssht/data_messages.c
......
......@@ -1110,6 +1110,7 @@ void *handle_connection(void *arg) {
close(accepted_sock);
return NULL;
}
memset(new_tunnel, 0, sizeof(tunnel_t));
// Initialize tunnel structure
generate_request_id(new_tunnel->request_id, sizeof(new_tunnel->request_id));
......
......@@ -227,6 +227,7 @@ void handle_tunnel_request(SSL *ssl, const char *request_id, int debug, const ch
pthread_mutex_unlock(&tunnel_mutex);
return;
}
memset(new_tunnel, 0, sizeof(tunnel_t));
// For wssshc: Connect to target TCP endpoint and forward raw TCP data
struct sockaddr_in target_addr;
......@@ -386,6 +387,7 @@ void handle_tunnel_request_with_enc(SSL *ssl, const char *request_id, int debug,
pthread_mutex_unlock(&tunnel_mutex);
return;
}
memset(new_tunnel, 0, sizeof(tunnel_t));
// For wssshc: Connect to target TCP endpoint and forward raw TCP data
struct sockaddr_in target_addr;
......@@ -538,6 +540,7 @@ void handle_tunnel_request_with_service_and_enc(SSL *ssl, const char *request_id
pthread_mutex_unlock(&tunnel_mutex);
return;
}
memset(new_tunnel, 0, sizeof(tunnel_t));
// For wssshc: Connect to target TCP endpoint and forward raw TCP data
struct sockaddr_in target_addr;
......@@ -2016,6 +2019,7 @@ tunnel_setup_result_t setup_tunnel(const char *wssshd_host, int wssshd_port, con
tunnel_setup_result_t result = {-1, NULL, NULL, ""};
return result;
}
memset(new_tunnel, 0, sizeof(tunnel_t));
if (use_buffer) {
new_tunnel->outgoing_buffer = frame_buffer_init();
......
......@@ -478,6 +478,7 @@ int main(int argc, char *argv[]) {
pthread_mutex_destroy(&tunnel_mutex);
return 1;
}
memset(new_tunnel, 0, sizeof(tunnel_t));
new_tunnel->outgoing_buffer = NULL;
new_tunnel->incoming_buffer = frame_buffer_init();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment