Update branch

parent 2d148eca
#!/bin/bash #!/bin/bash
# WSSSH: Warp-Powered Stefy's Spatial Secure Hyperdrive Build Script # build.sh - Main build script for wsssh project
# Build script for WSSSH tools (wssshd, wssshc, wsscp, etc.) # Handles building wssshd2 server and wssshtools client components
# #
# Copyright (C) 2024 Stefy Lanza <stefy@nexlab.net> and SexHack.me # Copyright (C) 2024 Stefy Lanza <stefy@nexlab.net> and SexHack.me
# #
...@@ -18,368 +18,297 @@ ...@@ -18,368 +18,297 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 # Parse command line arguments
BUILD_DEBIAN=false SERVER_ONLY=false
BUILD_DEBIAN_ONLY=false WSSSHTOOLS_ONLY=false
BUILD_SERVER_ONLY=false DEBIAN_BUILD=false
BUILD_NO_SERVER=false CLEANUP=false
BUILD_WSSSHTOOLS_ONLY=false
BUILD_PACKAGES=false
BUILD_CLEAN=false
BUILD_NO_VENV=false
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
case $1 in 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) --server-only)
BUILD_SERVER_ONLY=true SERVER_ONLY=true
BUILD_DEBIAN=true
shift
;;
--no-server)
BUILD_NO_SERVER=true
shift shift
;; ;;
--wssshtools-only) --wssshtools-only)
BUILD_WSSSHTOOLS_ONLY=true WSSSHTOOLS_ONLY=true
shift shift
;; ;;
--clean) --debian)
BUILD_CLEAN=true DEBIAN_BUILD=true
shift shift
;; ;;
--novenv) --clean|--cleanup)
BUILD_NO_VENV=true CLEANUP=true
shift 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" log_error "Unknown option: $1"
echo "Usage: $0 [--debian] [--debian-only] [--packages] [--server-only] [--no-server] [--wssshtools-only] [--clean] [--novenv] [--help]" echo "Usage: $0 [--server-only|--wssshtools-only] [--debian] [--clean|--cleanup]"
echo "Try '$0 --help' for more information."
exit 1 exit 1
;; ;;
esac esac
done 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 [[ "$CLEANUP" == true && "$DEBIAN_BUILD" == true ]]; then
if [ "$BUILD_CLEAN" = true ]; then log_error "--clean/--cleanup cannot be combined with --debian"
echo "Cleaning build artifacts..." exit 1
fi
# 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 # Cleanup function
rm -f cert.pem key.pem cleanup() {
local target="$1"
# Remove logos and icons log_info "Cleaning up $target..."
rm -rf logos/
# Remove C version build artifacts case "$target" in
if [ -d "wssshtools" ]; then "server")
cd wssshtools if [[ -d "wssshd2" ]]; then
make clean 2>/dev/null || true cd wssshd2
rm -f Makefile if [[ -f "Makefile" ]]; then
rm -f configure.sh.stamp make clean >/dev/null 2>&1 || true
rm -f man/*.1.gz 2>/dev/null || true fi
rm -f Makefile configure.sh.stamp
cd .. cd ..
fi fi
# Remove server debian artifacts
# Remove Debian packaging artifacts rm -rf wsssh-server*.deb wsssh-server*.dsc wsssh-server*.changes wsssh-server*.buildinfo
# wsssh-server packages ;;
rm -f dist/wsssh-server*.deb "wssshtools")
rm -f dist/wsssh-server*.dsc if [[ -d "wssshtools" ]]; then
rm -f dist/wsssh-server*.tar.gz cd wssshtools
rm -f dist/wsssh-server*.changes if [[ -f "Makefile" ]]; then
rm -f dist/wsssh-server*.buildinfo make clean >/dev/null 2>&1 || true
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 fi
rm -f Makefile configure.sh.stamp
if [ -d "wssshtools" ]; then cd ..
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 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 # Asset preparation function
echo "Clean complete. Build artifacts removed (Python virtual environment preserved)." prepare_assets() {
else log_info "Preparing assets..."
echo "Clean complete. All build artifacts removed."
fi
exit 0
fi
# Create dist directory if not exists # Create logos directory if it doesn't exist
mkdir -p dist mkdir -p logos
# Skip Python/C building if --debian-only or --wssshtools-only is specified # Generate logo-128.png from image.jpg if imagemagick is available
if [ "$BUILD_DEBIAN_ONLY" = false ] && [ "$BUILD_WSSSHTOOLS_ONLY" = false ]; then if command -v convert >/dev/null 2>&1 && [[ -f "image.jpg" ]]; then
# Check if virtual environment exists, create if not log_info "Generating logo-128.png from image.jpg..."
if [ ! -d "venv" ]; then convert image.jpg -resize 128x128 logos/logo-128.png
echo "Creating virtual environment..." elif [[ ! -f "logos/logo-128.png" ]]; then
python3 -m venv venv 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 fi
# Activate virtual environment # Generate HTML templates for wssshd2
. venv/bin/activate 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 # Copy templates from root templates directory if they exist
pip3 install pyinstaller if [[ -d "templates" ]]; then
# Generate SSL certificates if they don't exist cp -r templates/* wssshd2/templates/ 2>/dev/null || true
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"
fi fi
# Generate logos and icons from image.jpg if it exists (for backward compatibility) log_success "Assets prepared"
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
# Generate icon sizes # Build server function
for size in 16 32 48 64 128 256; do build_server() {
convert image.jpg -resize ${size}x${size} logos/icon-${size}.png log_info "Building wssshd2 server..."
done
# Generate additional assets cd wssshd2
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
echo "Logo generation complete." # Run configure
elif [ -f "image.jpg" ]; then if [[ ! -f "configure.sh.stamp" ]]; then
echo "Warning: ImageMagick not found. Using image.jpg directly without generating logos." log_info "Running configure.sh..."
chmod +x configure.sh
./configure.sh
touch configure.sh.stamp
fi fi
# Build Python binaries # Build
echo "Building Python binaries..." log_info "Compiling wssshd2..."
make
# Build wssshd (server) binary unless --no-server is specified cd ..
if [ "$BUILD_NO_SERVER" = false ]; then log_success "wssshd2 server built successfully"
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
# Build client binaries # Build wssshtools function
if [ "$BUILD_SERVER_ONLY" = false ]; then build_wssshtools() {
# Client binaries are not built in this version log_info "Building wssshtools..."
echo "Client binaries not built in this version"
fi
fi
# 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 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 ./configure.sh
if [ "$BUILD_WSSSHTOOLS_ONLY" = true ]; then touch configure.sh.stamp
# 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 ..
fi fi
fi
# Build Debian package if requested # Build
if [ "$BUILD_DEBIAN" = true ]; then log_info "Compiling wssshtools..."
echo "Checking Debian build dependencies..." make
cd ..
log_success "wssshtools built successfully"
}
# Check for required Debian build tools # Debian packaging function
missing_deps="" build_debian_package() {
for dep in debhelper gcc make pkg-config libssl-dev python3 python3-pip python3-setuptools; do local package_type="$1"
if ! dpkg -l | grep -q "^ii $dep"; then
missing_deps="$missing_deps $dep"
fi
done
if [ -n "$missing_deps" ]; then if ! command -v dpkg-buildpackage >/dev/null 2>&1; then
echo "Error: Missing Debian build dependencies:$missing_deps" log_error "dpkg-buildpackage not found. Please install debian packaging tools."
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"
exit 1 exit 1
fi fi
echo "All Debian build dependencies found." case "$package_type" in
echo "Building Debian packages..." "server")
log_info "Building Debian package for wsssh-server..."
# 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 cd wsssh-server
dpkg-buildpackage -us -uc dpkg-buildpackage -us -uc
cd .. cd ..
# Move deb file to dist ;;
mv ../wsssh-server*.deb dist/ 2>/dev/null || true "wssshtools")
echo "wsssh-server package built successfully." log_info "Building Debian package for wsssh-tools..."
fi
# 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 cd wssshtools
dpkg-buildpackage -us -uc dpkg-buildpackage -us -uc
cd .. cd ..
# Move deb file to dist ;;
mv ../wsssh-tools*.deb dist/ 2>/dev/null || true esac
echo "wsssh-tools package built successfully."
fi
if [ "$BUILD_SERVER_ONLY" = true ] && [ ! -d "wsssh-server" ]; then log_success "Debian package built successfully"
echo "Warning: wsssh-server package not available (missing wsssh-server/ directory)" }
fi
if [ "$BUILD_WSSSHTOOLS_ONLY" = true ] && [ ! -d "wssshtools" ]; then # Main build logic
echo "Warning: wsssh-tools package not available (missing wssshtools/ directory)" if [[ "$CLEANUP" == true ]]; then
# Cleanup mode
if [[ "$SERVER_ONLY" == true ]]; then
cleanup "server"
elif [[ "$WSSSHTOOLS_ONLY" == true ]]; then
cleanup "wssshtools"
else
cleanup "all"
fi fi
log_success "Cleanup completed"
exit 0
fi fi
# Deactivate venv if it was activated # Validate build options
if [ "$BUILD_DEBIAN_ONLY" = false ] && [ "$BUILD_WSSSHTOOLS_ONLY" = false ]; then if [[ "$SERVER_ONLY" == true && "$WSSSHTOOLS_ONLY" == true ]]; then
deactivate log_error "Cannot specify both --server-only and --wssshtools-only"
exit 1
fi fi
if [ "$BUILD_DEBIAN_ONLY" = true ]; then # Prepare assets (needed for server build)
echo "Debian package build complete." if [[ "$SERVER_ONLY" == true || "$DEBIAN_BUILD" == true || ( "$SERVER_ONLY" == false && "$WSSSHTOOLS_ONLY" == false ) ]]; then
echo "Package available in dist/ directory:" prepare_assets
if ls dist/wsssh-tools*.deb >/dev/null 2>&1; then fi
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
else
echo "Build complete. Binaries are in dist/ directory:"
if [ "$BUILD_NO_SERVER" = false ]; then
echo "- dist/wssshd (server with web interface)"
fi
if [ -d "wssshtools" ] && [ -f "wssshtools/wssshc" ]; then # Build components
if [ "$BUILD_NO_SERVER" = true ]; then if [[ "$SERVER_ONLY" == true ]]; then
echo "- wssshtools/wssshc (C client)" build_server
elif [ "$BUILD_SERVER_ONLY" = false ]; then elif [[ "$WSSSHTOOLS_ONLY" == true ]]; then
echo "- wssshtools/wssshc (C client)" build_wssshtools
echo "- wssshtools/wsssh (C SSH wrapper)" else
echo "- wssshtools/wsscp (C SCP wrapper)" # Build both
fi build_server
fi build_wssshtools
fi
if [ "$BUILD_DEBIAN" = true ]; then # Debian packaging
echo "Debian packages available in dist/ directory:" if [[ "$DEBIAN_BUILD" == true ]]; then
if ls dist/wsssh-server*.deb >/dev/null 2>&1; then if [[ "$SERVER_ONLY" == true ]]; then
echo "- dist/wsssh-server*.deb (wssshd server Debian package)" build_debian_package "server"
fi elif [[ "$WSSSHTOOLS_ONLY" == true ]]; then
if ls dist/wsssh-tools*.deb >/dev/null 2>&1; then build_debian_package "wssshtools"
echo "- dist/wsssh-tools*.deb (C tools Debian package)" else
fi build_debian_package "server"
build_debian_package "wssshtools"
fi fi
fi fi
log_success "Build completed successfully!"
#!/bin/bash #!/bin/bash
# WSSSH: Warp-Powered Stefy's Spatial Secure Hyperdrive Clean Script # clean.sh - Cleanup script for wsssh project
# Clean script for removing build artifacts from WSSSH tools # Calls build.sh --clean with all passed arguments
# #
# Copyright (C) 2024 Stefy Lanza <stefy@nexlab.net> and SexHack.me # Copyright (C) 2024 Stefy Lanza <stefy@nexlab.net> and SexHack.me
# #
...@@ -18,5 +18,8 @@ ...@@ -18,5 +18,8 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
# Use build.sh --clean for consistent cleaning SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
./build.sh --clean --novenv 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): ...@@ -241,6 +241,9 @@ async def shutdown_server(ws_server, cleanup_coro, flask_thread):
async def run_server(): async def run_server():
"""Main server function""" """Main server function"""
# Create new process group to avoid receiving SIGINT from terminal
os.setpgrp()
args = load_config() args = load_config()
# Set global variables # Set global variables
......
...@@ -29,8 +29,8 @@ extern const char *terminal_html; ...@@ -29,8 +29,8 @@ extern const char *terminal_html;
extern const char *users_html; extern const char *users_html;
// Embedded images // Embedded images
extern const unsigned char *image_jpg; extern unsigned char image_jpg[];
extern size_t image_jpg_len; extern unsigned int image_jpg_len;
// Function to get asset by path // Function to get asset by path
const char *get_embedded_asset(const char *path, size_t *size); 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 @@ ...@@ -34,7 +34,9 @@
#include "assets.h" #include "assets.h"
#include "websocket.h" #include "websocket.h"
#include "html_pages/index_page.h" #include "html_pages/index_page.h"
#include "html_pages/login_page.h"
#include "html_pages/terminal_page.h" #include "html_pages/terminal_page.h"
#include "html_pages/users_page.h"
// Embedded web assets are defined in assets.c // Embedded web assets are defined in assets.c
...@@ -377,8 +379,7 @@ static void handle_request(int client_fd, const http_request_t *req) { ...@@ -377,8 +379,7 @@ static void handle_request(int client_fd, const http_request_t *req) {
char *html = generate_index_html(username, is_admin); char *html = generate_index_html(username, is_admin);
send_response(client_fd, 200, "OK", "text/html", html, strlen(html), NULL, NULL); send_response(client_fd, 200, "OK", "text/html", html, strlen(html), NULL, NULL);
} else if (strcmp(req->path, "/login") == 0) { } else if (strcmp(req->path, "/login") == 0) {
const char *asset = get_embedded_asset("/login", NULL); send_response(client_fd, 200, "OK", "text/html", login_page_html, strlen(login_page_html), NULL, NULL);
send_response(client_fd, 200, "OK", "text/html", asset, strlen(asset), NULL, NULL);
} else if (strcmp(req->path, "/logout") == 0) { } else if (strcmp(req->path, "/logout") == 0) {
send_response(client_fd, 302, "Found", "text/html", NULL, 0, "session_id=; Max-Age=0; Path=/", NULL); send_response(client_fd, 302, "Found", "text/html", NULL, 0, "session_id=; Max-Age=0; Path=/", NULL);
return; return;
...@@ -387,8 +388,7 @@ static void handle_request(int client_fd, const http_request_t *req) { ...@@ -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); send_response(client_fd, 403, "Forbidden", "text/html", "Access denied", 13, NULL, NULL);
return; return;
} }
const char *asset = get_embedded_asset("/users.html", NULL); send_response(client_fd, 200, "OK", "text/html", users_page_html, strlen(users_page_html), NULL, NULL);
send_response(client_fd, 200, "OK", "text/html", asset, strlen(asset), NULL, NULL);
} else if (strncmp(req->path, "/terminal/", 9) == 0) { } else if (strncmp(req->path, "/terminal/", 9) == 0) {
if (!username) { if (!username) {
send_response(client_fd, 302, "Found", "text/html", NULL, 0, NULL, NULL); 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 ...@@ -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 // Limit to 10MB to prevent excessive memory allocation
const size_t MAX_PAYLOAD_SIZE = 10 * 1024 * 1024; // 10MB const size_t MAX_PAYLOAD_SIZE = 10 * 1024 * 1024; // 10MB
if (header->payload_len > MAX_PAYLOAD_SIZE) { 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 return false; // Reject frames with excessively large payloads
} }
...@@ -263,17 +261,14 @@ bool ws_perform_handshake(ws_connection_t *conn) { ...@@ -263,17 +261,14 @@ bool ws_perform_handshake(ws_connection_t *conn) {
// Send WebSocket frame // Send WebSocket frame
bool ws_send_frame(ws_connection_t *conn, uint8_t opcode, const void *data, size_t len) { bool ws_send_frame(ws_connection_t *conn, uint8_t opcode, const void *data, size_t len) {
if (!conn) { if (!conn) {
printf("[DEBUG] ws_send_frame: Connection is NULL\n");
return false; return false;
} }
if (conn->state != WS_STATE_OPEN) { if (conn->state != WS_STATE_OPEN) {
printf("[DEBUG] ws_send_frame: Connection not in OPEN state (state=%d)\n", conn->state);
return false; return false;
} }
if (!conn->ssl) { if (!conn->ssl) {
printf("[DEBUG] ws_send_frame: SSL connection is NULL\n");
return false; return false;
} }
...@@ -289,7 +284,6 @@ bool ws_send_frame(ws_connection_t *conn, uint8_t opcode, const void *data, size ...@@ -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; size_t frame_len = header_len + len;
uint8_t *frame = malloc(frame_len); uint8_t *frame = malloc(frame_len);
if (!frame) { if (!frame) {
printf("[DEBUG] ws_send_frame: Failed to allocate frame buffer\n");
return false; return false;
} }
...@@ -317,8 +311,6 @@ bool ws_send_frame(ws_connection_t *conn, uint8_t opcode, const void *data, size ...@@ -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); 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 // Send frame with partial write handling and retry logic
int total_written = 0; int total_written = 0;
int retry_count = 0; int retry_count = 0;
...@@ -329,18 +321,15 @@ bool ws_send_frame(ws_connection_t *conn, uint8_t opcode, const void *data, size ...@@ -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); int written = SSL_write(conn->ssl, frame + total_written, to_write);
if (written <= 0) { if (written <= 0) {
int ssl_error = SSL_get_error(conn->ssl, written); 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 // Check for recoverable SSL errors
if ((ssl_error == SSL_ERROR_WANT_READ || ssl_error == SSL_ERROR_WANT_WRITE || 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) { ssl_error == SSL_ERROR_SSL || ssl_error == SSL_ERROR_SYSCALL) && retry_count < max_retries - 1) {
retry_count++; retry_count++;
printf("[DEBUG] ws_send_frame: Recoverable SSL error, retrying (%d/%d)\n", retry_count, max_retries);
// Exponential backoff: wait longer between retries // Exponential backoff: wait longer between retries
usleep(10000 * (1 << retry_count)); // 10ms, 20ms, 40ms, 80ms usleep(10000 * (1 << retry_count)); // 10ms, 20ms, 40ms, 80ms
continue; // Retry the write operation continue; // Retry the write operation
} else { } 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 // 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 ...@@ -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) { 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); free(frame);
return false; return false;
} }
printf("[DEBUG] ws_send_frame: SSL_write returned %d (expected %zu)\n", total_written, frame_len);
free(frame); free(frame);
return total_written == (int)frame_len; return total_written == (int)frame_len;
} }
...@@ -369,17 +356,12 @@ bool ws_receive_frame(ws_connection_t *conn, uint8_t *opcode, void **data, size_ ...@@ -369,17 +356,12 @@ bool ws_receive_frame(ws_connection_t *conn, uint8_t *opcode, void **data, size_
uint8_t header[14]; uint8_t header[14];
int bytes_read = SSL_read(conn->ssl, header, 2); int bytes_read = SSL_read(conn->ssl, header, 2);
if (bytes_read <= 0) { 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; return false;
} }
if (bytes_read != 2) { if (bytes_read != 2) {
printf("[DEBUG] ws_receive_frame: Expected 2 header bytes, got %d\n", bytes_read);
return false; 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 // Determine minimum header size needed for parsing
uint8_t payload_len_indicator = header[1] & 0x7F; uint8_t payload_len_indicator = header[1] & 0x7F;
size_t min_header_size = 2; size_t min_header_size = 2;
...@@ -396,7 +378,6 @@ bool ws_receive_frame(ws_connection_t *conn, uint8_t *opcode, void **data, size_ ...@@ -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)) { while (total_read < (int)(min_header_size - 2)) {
bytes_read = SSL_read(conn->ssl, header + 2 + total_read, min_header_size - 2 - total_read); bytes_read = SSL_read(conn->ssl, header + 2 + total_read, min_header_size - 2 - total_read);
if (bytes_read <= 0) { if (bytes_read <= 0) {
printf("[DEBUG] ws_receive_frame: Failed to read extended header\n");
return false; return false;
} }
total_read += bytes_read; total_read += bytes_read;
...@@ -409,7 +390,6 @@ bool ws_receive_frame(ws_connection_t *conn, uint8_t *opcode, void **data, size_ ...@@ -409,7 +390,6 @@ bool ws_receive_frame(ws_connection_t *conn, uint8_t *opcode, void **data, size_
if (masked) { if (masked) {
bytes_read = SSL_read(conn->ssl, header + min_header_size, 4); bytes_read = SSL_read(conn->ssl, header + min_header_size, 4);
if (bytes_read != 4) { if (bytes_read != 4) {
printf("[DEBUG] ws_receive_frame: Failed to read masking key\n");
return false; return false;
} }
total_header_size += 4; total_header_size += 4;
...@@ -417,13 +397,11 @@ bool ws_receive_frame(ws_connection_t *conn, uint8_t *opcode, void **data, size_ ...@@ -417,13 +397,11 @@ bool ws_receive_frame(ws_connection_t *conn, uint8_t *opcode, void **data, size_
// Validate header size // Validate header size
if (total_header_size > sizeof(header)) { 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; return false;
} }
ws_frame_header_t frame_header; ws_frame_header_t frame_header;
if (!ws_parse_frame_header(header, total_header_size, &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; return false;
} }
...@@ -439,15 +417,11 @@ bool ws_receive_frame(ws_connection_t *conn, uint8_t *opcode, void **data, size_ ...@@ -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 // Protect against memory exhaustion attacks with reasonable limit
const size_t MAX_SAFE_PAYLOAD = 50 * 1024 * 1024; // 50MB safety limit const size_t MAX_SAFE_PAYLOAD = 50 * 1024 * 1024; // 50MB safety limit
if (frame_header.payload_len > MAX_SAFE_PAYLOAD) { 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; return false;
} }
*data = malloc(frame_header.payload_len + 1); // +1 for null termination *data = malloc(frame_header.payload_len + 1); // +1 for null termination
if (!*data) { 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; return false;
} }
...@@ -460,9 +434,6 @@ bool ws_receive_frame(ws_connection_t *conn, uint8_t *opcode, void **data, size_ ...@@ -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); bytes_read = SSL_read(conn->ssl, (char *)*data + total_read, to_read);
if (bytes_read <= 0) { 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); free(*data);
return false; return false;
} }
...@@ -471,8 +442,6 @@ bool ws_receive_frame(ws_connection_t *conn, uint8_t *opcode, void **data, size_ ...@@ -471,8 +442,6 @@ bool ws_receive_frame(ws_connection_t *conn, uint8_t *opcode, void **data, size_
// Verify we read the complete payload // Verify we read the complete payload
if (total_read != frame_header.payload_len) { 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); free(*data);
return false; return false;
} }
......
...@@ -73,6 +73,9 @@ bool ws_perform_handshake(ws_connection_t *conn); ...@@ -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_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); 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 // Utility functions
char *ws_compute_accept_key(const char *key); char *ws_compute_accept_key(const char *key);
void ws_mask_data(uint8_t *data, size_t len, const uint8_t *mask); 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 ...@@ -45,6 +45,13 @@ if ! pkg-config --exists openssl; then
exit 1 exit 1
fi 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." echo "All required tools found."
# Generate Makefile # Generate Makefile
...@@ -52,8 +59,8 @@ cat > Makefile << 'EOF' ...@@ -52,8 +59,8 @@ cat > Makefile << 'EOF'
# Makefile for wssshtools # Makefile for wssshtools
CC = gcc CC = gcc
CFLAGS = -Wall -Wextra -O2 -D_GNU_SOURCE $(shell pkg-config --cflags openssl) CFLAGS = -Wall -Wextra -O2 -D_GNU_SOURCE $(shell pkg-config --cflags openssl) $(shell pkg-config --cflags zlib)
LDFLAGS = $(shell pkg-config --libs openssl) LDFLAGS = $(shell pkg-config --libs openssl) $(shell pkg-config --libs zlib)
# Source files # 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 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) { ...@@ -1110,6 +1110,7 @@ void *handle_connection(void *arg) {
close(accepted_sock); close(accepted_sock);
return NULL; return NULL;
} }
memset(new_tunnel, 0, sizeof(tunnel_t));
// Initialize tunnel structure // Initialize tunnel structure
generate_request_id(new_tunnel->request_id, sizeof(new_tunnel->request_id)); 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 ...@@ -227,6 +227,7 @@ void handle_tunnel_request(SSL *ssl, const char *request_id, int debug, const ch
pthread_mutex_unlock(&tunnel_mutex); pthread_mutex_unlock(&tunnel_mutex);
return; return;
} }
memset(new_tunnel, 0, sizeof(tunnel_t));
// For wssshc: Connect to target TCP endpoint and forward raw TCP data // For wssshc: Connect to target TCP endpoint and forward raw TCP data
struct sockaddr_in target_addr; struct sockaddr_in target_addr;
...@@ -386,6 +387,7 @@ void handle_tunnel_request_with_enc(SSL *ssl, const char *request_id, int debug, ...@@ -386,6 +387,7 @@ void handle_tunnel_request_with_enc(SSL *ssl, const char *request_id, int debug,
pthread_mutex_unlock(&tunnel_mutex); pthread_mutex_unlock(&tunnel_mutex);
return; return;
} }
memset(new_tunnel, 0, sizeof(tunnel_t));
// For wssshc: Connect to target TCP endpoint and forward raw TCP data // For wssshc: Connect to target TCP endpoint and forward raw TCP data
struct sockaddr_in target_addr; struct sockaddr_in target_addr;
...@@ -538,6 +540,7 @@ void handle_tunnel_request_with_service_and_enc(SSL *ssl, const char *request_id ...@@ -538,6 +540,7 @@ void handle_tunnel_request_with_service_and_enc(SSL *ssl, const char *request_id
pthread_mutex_unlock(&tunnel_mutex); pthread_mutex_unlock(&tunnel_mutex);
return; return;
} }
memset(new_tunnel, 0, sizeof(tunnel_t));
// For wssshc: Connect to target TCP endpoint and forward raw TCP data // For wssshc: Connect to target TCP endpoint and forward raw TCP data
struct sockaddr_in target_addr; struct sockaddr_in target_addr;
...@@ -2016,6 +2019,7 @@ tunnel_setup_result_t setup_tunnel(const char *wssshd_host, int wssshd_port, con ...@@ -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, ""}; tunnel_setup_result_t result = {-1, NULL, NULL, ""};
return result; return result;
} }
memset(new_tunnel, 0, sizeof(tunnel_t));
if (use_buffer) { if (use_buffer) {
new_tunnel->outgoing_buffer = frame_buffer_init(); new_tunnel->outgoing_buffer = frame_buffer_init();
......
...@@ -478,6 +478,7 @@ int main(int argc, char *argv[]) { ...@@ -478,6 +478,7 @@ int main(int argc, char *argv[]) {
pthread_mutex_destroy(&tunnel_mutex); pthread_mutex_destroy(&tunnel_mutex);
return 1; return 1;
} }
memset(new_tunnel, 0, sizeof(tunnel_t));
new_tunnel->outgoing_buffer = NULL; new_tunnel->outgoing_buffer = NULL;
new_tunnel->incoming_buffer = frame_buffer_init(); 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