Skip to main content

Bi-directional file transfer tools for air-gapped and isolated environments

Project description

Airgap Transfer

License: MIT Python 3.9+ Version Status

Bi-directional file transfer tools for air-gapped and isolated environments.

Transfer files to and from isolated systems (VDI, bastion hosts, air-gapped networks) using keyboard input simulation and QR code video streams.

中文文档 | English

Features

🎹 Keyboard Transfer

  • Transfer files via keyboard input - Send files by simulating keyboard typing
  • Auto-execution - Scripts execute automatically on the remote system
  • SHA256 verification - Built-in checksum validation
  • Speed presets - Optimized for different connection types (local VM, remote desktop, etc.)

📱 QR Code Transfer

  • Encode files to QR codes - Generate video streams for screen sharing
  • Decode from video - Extract files from screen recordings
  • High error correction - Robust against video quality issues
  • Progress tracking - Real-time feedback during encoding/decoding

🛠️ Professional Design

  • Unified CLI - Single airgap command with intuitive subcommands
  • Clean Python API - Use as a library in your own projects
  • Type hints - Full type annotations for better IDE support
  • Modular - Well-organized codebase for easy contribution

Quick Start

Installation

Note: This project is currently in v0.1.0 and not yet published to PyPI. Install from source:

# Clone the repository
git clone https://github.com/RLHQ/airgap-transfer.git
cd airgap-transfer

# Install using uv (recommended)
uv sync                              # Base package
uv sync --extra all                  # With QR code support
uv sync --extra all --extra dev      # With development tools

# Or using pip (compatible way)
pip install -e .
pip install -e ".[all]"
pip install -e ".[all,dev]"

Once published to PyPI (future):

pip install airgap-transfer         # Base package
pip install airgap-transfer[all]    # With QR code support

Usage Examples

Keyboard Transfer

# Development environment (using uv)
uv run airgap send myfile.pdf

# Specify output path on remote system
uv run airgap send myfile.pdf --output /tmp/received.pdf

# Use speed presets
uv run airgap send myfile.pdf --fast    # For local VMs
uv run airgap send myfile.pdf --slow    # For high-latency connections

# Custom countdown
uv run airgap send myfile.pdf --countdown 10

# Production (after installation)
airgap send myfile.pdf

QR Code Transfer

# Development environment (using uv)
uv run airgap qr-encode myfile.pdf | ffplay -framerate 1 -f image2pipe -i -

# Or save as video
uv run airgap qr-encode myfile.pdf | ffmpeg -framerate 1 -f image2pipe -i - output.mp4

# Decode from recording (receiver side)
uv run airgap qr-decode recording.mp4 output.pdf

# Verify against original
uv run airgap qr-decode recording.mp4 output.pdf --verify original.pdf

# VDI environment (using python3 with qrcode only)
python3 ~/airgap_tools/qr_sender.py myfile.pdf 5 | ffplay -framerate 1 -f image2pipe -i -

Installer Bundle

# Generate installation bundle for VDI/air-gapped environments
uv run airgap install --generate
# Creates sender-bundle/ with install.sh, qr_sender.py, and README.txt

# Transfer self-contained installer to remote via keyboard
uv run airgap install --transfer
# Transfers install.sh (which includes embedded QR sender)
# Only ONE file needs to be transferred!

# In remote terminal after transfer:
bash install.sh
# Installs QR sender to ~/airgap_tools/qr_sender.py

Python API

from airgap_transfer import KeyboardTransfer, QREncoder, QRDecoder

# Keyboard transfer
transfer = KeyboardTransfer("myfile.pdf")
stats = transfer.send(countdown=5)
print(f"Transferred in {stats['elapsed_time']:.1f}s")

# QR encoding
import sys
encoder = QREncoder("myfile.pdf")
encoder.encode_to_stream(sys.stdout.buffer)

# QR decoding
decoder = QRDecoder("recording.mp4")
success = decoder.decode_to_file("output.pdf")
if success:
    print("File successfully decoded!")

Complete Workflow Example

Scenario: Transfer a configuration file to a VDI environment

# 1. On your external machine
git clone https://github.com/RLHQ/airgap-transfer.git
cd airgap-transfer
uv sync  # Install dependencies using uv

# 2. Start the transfer (you have 5 seconds to switch windows)
uv run airgap send config.yaml --output /home/user/config.yaml

# 3. Switch to VDI terminal window and keep it focused
# 4. Script automatically types and executes
# 5. Verify output on VDI terminal:
#    ✓ File transfer successful! Checksum verified
#    File saved to: /home/user/config.yaml

Use Cases

Scenario 1: VDI Access (Common Use Case)

You need to transfer files to/from a Virtual Desktop Infrastructure (VDI) with:

  • ✅ Screen sharing enabled
  • ✅ Keyboard input allowed
  • ❌ File transfer disabled
  • ❌ Clipboard sharing disabled

Solution: Use keyboard transfer or QR codes

Sending files TO VDI (External → VDI):

# On external machine, run:
uv run airgap send document.pdf --countdown 10

# The script will automatically type into the VDI terminal
# File will be decoded and verified with SHA256

Getting files FROM VDI (VDI → External):

Step 1: Transfer sender tools to VDI (one-time setup)

# On external machine, generate and transfer the installation bundle
uv run airgap install --transfer

# This transfers a self-contained install.sh script that:
# - Contains embedded QR sender tool
# - Only requires ONE keyboard transfer
# - Automatically installs to ~/airgap_tools/qr_sender.py

Alternative: Manual transfer (if preferred)

# On external machine, send just the encoder script
uv run airgap send sender-bundle/qr_sender.py --output ~/qr_sender.py

Step 2: Generate QR codes in VDI

# In VDI terminal (only needs python3 and qrcode package)
python3 ~/airgap_tools/qr_sender.py myfile.pdf 5 | ffplay -framerate 1 -f image2pipe -i -

Step 3: Decode on external machine

# Record the QR code video, then:
uv run airgap qr-decode recording.mp4 output.pdf --verify original.pdf

Scenario 2: Bastion Host

Transfer files through a jump server/bastion host with strict security controls.

# Transfer script to bastion
uv run airgap send deployment_script.sh --output /tmp/deploy.sh

Scenario 3: Air-Gapped Network

Transfer files to completely isolated networks with no connectivity.

# Encode file on connected system (development environment)
uv run airgap qr-encode sensitive_data.gpg | ffplay -framerate 1 -f image2pipe -i -

# Record screen in air-gapped environment
# Decode on air-gapped system (development environment)
uv run airgap qr-decode recording.mp4 sensitive_data.gpg

# Or use python3 on air-gapped system (only needs qrcode package)
python3 qr_sender.py sensitive_data.gpg 5 | ffplay -framerate 1 -f image2pipe -i -

How It Works

Keyboard Transfer

  1. Encode: File is base64-encoded and wrapped in a bash script
  2. Generate: Script includes decoding and verification logic
  3. Type: Content is typed character-by-character via simulated keyboard
  4. Execute: Script auto-executes on the remote terminal
  5. Verify: SHA256 checksum confirms successful transfer

QR Code Transfer

  1. Chunk: File is split into QR-code-sized chunks
  2. Encode: Each chunk is encoded as a QR code image
  3. Stream: QR codes are displayed as a video sequence
  4. Capture: Screen recording captures the QR code sequence
  5. Decode: Video is processed to extract and reassemble the file

Requirements

System Requirements

  • Development environment: Python 3.9 or higher
  • VDI/Air-gapped environment: Python 3.8 or higher (QR sender only)
  • Linux, macOS, or Windows (with GUI support for keyboard transfer)

Python Dependencies

Development Environment (local machine):

  • Package manager: Use uv for dependency management
  • Base package: pynput (keyboard transfer)
  • QR code full features: qrcode, opencv-python, pyzbar
  • Run commands: Use uv run prefix

VDI/Air-gapped Environment (isolated systems, QR sender only):

  • Only requires: qrcode package
  • Python version: 3.8+ compatible
  • Run commands: Use python3 command
  • Not needed: opencv-python, pyzbar (only for decoder side)

External Tools (for QR video)

  • ffplay or ffmpeg (for playing/recording QR code videos)
  • Screen recording software (OBS, QuickTime, etc.) for capturing QR codes

Performance Expectations

File Size Transfer Method Estimated Time Recommended
< 10 KB Keyboard < 1 minute ⭐⭐⭐⭐⭐
10-100 KB Keyboard 1-10 minutes ⭐⭐⭐⭐
< 10 KB QR Code < 30 seconds ⭐⭐⭐⭐⭐
10-50 KB QR Code 30s-2 minutes ⭐⭐⭐⭐
> 100 KB Either > 10 minutes ⭐⭐ (compress first)

Migrating from Legacy Scripts

If you were using the old standalone scripts:

# Old way
python transfer_file_v2.py myfile.pdf

# New way (development environment)
uv run airgap send myfile.pdf

# Old way
python qrtest_pipe.py myfile.pdf 5 | ffplay -framerate 1 -f image2pipe -i -

# New way (development environment)
uv run airgap qr-encode myfile.pdf | ffplay -framerate 1 -f image2pipe -i -

# VDI environment (using python3 only)
python3 qr_sender.py myfile.pdf 5 | ffplay -framerate 1 -f image2pipe -i -

# Old way
python qrdecode_video.py recording.mp4 output.pdf

# New way (development environment)
uv run airgap qr-decode recording.mp4 output.pdf

The legacy scripts are still available in the repository for reference.

Development

# Clone repository
git clone https://github.com/RLHQ/airgap-transfer.git
cd airgap-transfer

# Install all dependencies using uv (recommended)
uv sync --extra all --extra dev

# Run tests (coming soon)
uv run pytest

# Format code
uv run black src/ tests/
uv run ruff check src/ tests/

# Type checking
uv run mypy src/

# Build package
uv run python -m build

Project Structure

airgap-transfer/
├── src/airgap_transfer/     # Main package
│   ├── keyboard/            # Keyboard transfer module
│   ├── qrcode/              # QR code transfer module
│   ├── cli/                 # Command-line interface
│   ├── utils/               # Utility functions
│   └── installer/           # Installer module (planned)
├── tests/                   # Test suite
├── examples/                # Example scripts
├── docs/                    # Documentation
└── scripts/                 # Development scripts

Roadmap

v0.1.0 (Current)

  • ✅ Keyboard transfer
  • ✅ QR code transfer
  • ✅ Unified CLI
  • ✅ Python API
  • ✅ Professional project structure

v0.2.0 (Planned)

  • 🔄 Installer module for air-gapped environments
  • 🔄 Standalone sender package generation
  • 🔄 Configuration file support
  • 🔄 Enhanced documentation

v0.3.0 (Future)

  • 📋 Batch transfer support
  • 📋 Resume/retry functionality
  • 📋 Compression support
  • 📋 Encryption options

Environment Notes

This project is optimized for two different environments:

Development Environment (Local/External Machine)

  • Python version: 3.9+
  • Package manager: uv (recommended) or pip
  • Run commands: uv run airgap <command>
  • Features: Full functionality (keyboard transfer + QR encode/decode)
  • Dependencies: All packages (pynput, qrcode, opencv-python, pyzbar)

VDI/Air-gapped Environment (Isolated Systems)

  • Python version: 3.8+ (using system python3)
  • Package manager: System pip (usually restricted)
  • Run commands: python3 <script>.py
  • Features: QR encoding only (for exporting files from VDI)
  • Dependencies: Only qrcode package (usually pre-installed)
  • Characteristics: Lightweight, minimal dependencies, suitable for restricted environments

Security Considerations

⚠️ Important Security Notes:

  • This tool is designed for legitimate administrative access to isolated systems
  • All transfers should comply with your organization's security policies
  • Files are not encrypted by default - use GPG or similar if needed
  • Screen recordings may be visible to others - be aware of your surroundings
  • Keyboard transfer creates temporary files on the remote system
  • Always verify checksums to ensure data integrity

Contributing

Contributions are welcome! Areas where we'd love help:

  • 📖 Documentation improvements
  • 🧪 More test coverage
  • 🐛 Bug reports and fixes
  • 💡 Feature suggestions
  • 🌍 Translations

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

  • Inspired by real-world challenges in accessing isolated environments
  • Built with pynput, qrcode, and OpenCV
  • Thanks to all contributors and users!

Note: This tool is for authorized use only. Always obtain proper permissions before transferring files to/from isolated systems.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

airgap_transfer-0.1.0.tar.gz (179.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

airgap_transfer-0.1.0-py3-none-any.whl (34.1 kB view details)

Uploaded Python 3

File details

Details for the file airgap_transfer-0.1.0.tar.gz.

File metadata

  • Download URL: airgap_transfer-0.1.0.tar.gz
  • Upload date:
  • Size: 179.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for airgap_transfer-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f69a401e6c67e56f1fcfda07a26019a8ea61224177c4c53a73b33d4055ddee2a
MD5 6ea371b73bbed0537173f1e4952cadfa
BLAKE2b-256 a09e3c3a1ef2e15f0d866ce79d61529bf5280f31a94464fb5020ea77617c7c6a

See more details on using hashes here.

File details

Details for the file airgap_transfer-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for airgap_transfer-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a7eaa56a5a49d6ccee7e05ddb1fb952138163aa54f45e2757301aaa969ad55f4
MD5 55c2d3aae0d29b996035a5c9a412b84b
BLAKE2b-256 0f7ac6e868d03f63a471a8bac53838768ad1dd649a99ab6984b068eb55fc4649

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page