Garrard.CloudShare.Receiver
0.1.2
See the version list below for details.
dotnet tool install --global Garrard.CloudShare.Receiver --version 0.1.2
dotnet new tool-manifest
dotnet tool install --local Garrard.CloudShare.Receiver --version 0.1.2
#tool dotnet:?package=Garrard.CloudShare.Receiver&version=0.1.2
nuke :add-package Garrard.CloudShare.Receiver --version 0.1.2
cloud-share
A beautiful, secure way to share files and text between computers using Microsoft Dev Tunnels. Install as .NET global tools and enjoy a gorgeous CLI experience powered by Spectre.Console!
โจ Features
- ๐จ Beautiful CLI with Spectre.Console - colors, tables, progress indicators
- ๐ Web UI โ both tools open a local browser UI (Bootstrap 5 + Alpine.js dark theme)
- ๐ Secure sharing with token-based authentication
- ๐ End-to-end encryption โ AES-256-GCM encrypts all content before it leaves the sender
- ๐งฎ Integrity verification โ SHA-512 hash shown on both sides; receiver must confirm match before accessing content
- ๐ File transfers โ upload from sender UI, download via explicit button after hash verification
- ๐ฆ Zip bundles โ bundle multiple files into a zip, with optional AES-256 zip password, and queue it as a single item
- ๐ Text sharing โ paste text in sender UI, copy to clipboard from receiver UI
- ๐ Microsoft Dev Tunnels integration (free tier)
- โก Fast and lightweight .NET 10 global tools
- ๐ No port forwarding or firewall configuration needed
- ๐ค Auto-installs dependencies (devtunnels CLI) with user confirmation
- ๐ Auto-login โ prompts for Microsoft or GitHub account, remembers your choice; automatically re-authenticates if the token expires
- ๐พ Session memory โ receiver remembers the last URL and secret across runs
- ๐ Cross-platform: Windows, macOS (including Apple Silicon), Linux (Ubuntu)
๐ Installation
Option 1: Install as .NET Global Tools (Recommended)
# Install the sender
dotnet tool install --global Garrard.CloudShare.Sender
# Install the receiver
dotnet tool install --global Garrard.CloudShare.Receiver
After installation, you can run the tools from anywhere:
cloud-share-sender [file-path]
cloud-share-receiver
Option 2: Build from Source
git clone https://github.com/garrardkitchen/cloud-share.git
cd cloud-share
dotnet build --configuration Release
๐ Prerequisites
.NET 10 SDK
Download and install from https://dotnet.microsoft.com/download/dotnet/10.0
Verify installation:
dotnet --version # Should be 10.0 or higher
DevTunnels CLI (Auto-installed)
The tools will automatically detect if DevTunnels CLI is missing and offer to install it for you! If you prefer manual installation:
Windows (via winget):
winget install Microsoft.devtunnel
macOS (via Homebrew):
brew install --cask devtunnel
Linux:
curl -sL https://aka.ms/DevTunnelCliInstall | bash
Authentication
On first run the sender will prompt you to choose a login method and launch a browser-based OAuth flow automatically:
? Choose your login method:
> Microsoft account
GitHub account (free tier)
Your choice is saved to ~/<AppData>/CloudShare/preferences.json and reused on every subsequent run โ no need to log in again.
If the login token expires, the sender detects this automatically, re-authenticates using your saved preference (no prompt), and retries the tunnel โ no intervention needed.
To switch accounts or re-authenticate manually, pass --reset:
cloud-share-sender --reset
๐ฏ Usage
Sender
Start the sender (text-only mode):
cloud-share-sender
Start the sender with a file pre-loaded:
cloud-share-sender /path/to/document.pdf
Re-authenticate or switch accounts:
cloud-share-sender --reset
cloud-share-sender /path/to/file.pdf --reset
Check version:
cloud-share-sender --version
The sender starts a local web UI at http://localhost:5000 and opens it in your browser automatically. The UI lets you:
- Text tab โ paste any text and click Share Text to encrypt and queue it
- File tab โ drag-and-drop or browse for a single file and click Upload File
- Zip Bundle tab โ add multiple files to a bundle, set an optional AES-256 zip password, then click Create & Queue Zip to zip, encrypt, and queue the bundle as a single item
- Queue table โ see all queued items with their SHA-512 hash prefix and timestamp; password-protected zips show a ๐ icon; items are marked โ once received
The CLI also prints the tunnel URL and secret token to share with the receiver:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Cloud Share Sender v1.0.0
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ DevTunnels CLI is installed
โ Authenticated with DevTunnels
โญโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ Setting โ Value โ
โโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Secret Token โ aBc123XyZ456 โ
โ File to Shareโ none - text only mode โ
โ Local Port โ 5000 โ
โฐโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
Tunnel URL: https://abc123.uks1.devtunnels.ms:5000
Web UI: http://localhost:5000 (opening in browser...)
Press Ctrl+C to stop sharing.
Receiver
cloud-share-receiver
Check version:
cloud-share-receiver --version
The receiver prompts for the tunnel URL and secret, then starts a local web UI at http://localhost:5001 and opens it in your browser automatically.
Session memory: The URL and secret are saved to ~/<AppData>/CloudShare/receiver-session.json as you type them. On the next run the receiver offers to reuse the previous connection:
โญโ Previous session โโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ URL: https://c84xl717.uks1.devtunnels.ms โ
โ Secret: ************ โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
? Use previous connection? [Y/n]
Answering Y skips the prompts entirely. Answering N overwrites the saved session with new values.
Receiving items:
- When the sender queues an item, it appears in the receiver's queue list in real time (via SSE).
- Click Receive on any queued item.
- The Hash Verification dialog opens showing both the sender's SHA-512 hash and the hash computed by the receiver. Confirm they match before proceeding.
- Mismatch โ the item is permanently deleted from the sender and the content is discarded.
- Text match โ the decrypted text is displayed with a Copy text button to copy it to your clipboard.
- File/Zip match โ a Download File button appears (bottom-left of the dialog); click it to save the file to your browser's download folder. Password-protected zips show a ๐ warning โ you will need the password (shared out-of-band) to extract the zip.
๐๏ธ Architecture
โโโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ cloud-share-sender โ โ cloud-share-receiver โ
โ โ โ โ
โ CLI (Spectre.Console) โ โ CLI (Spectre.Console) โ
โ Web UI localhost:5000 โ โ Web UI localhost:5001 โ
โ โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโ โ โ โโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ AES-256-GCM encryptโ โ Microsoft Dev โ โ Proxy โ sender tunnelโ โ
โ โ SHA-512 hash โ โโโโโโTunnelsโโโโโโโโโโ โ AES-256-GCM decrypt โ โ
โ โ Queue (in-memory) โ โ โ โ SHA-512 verify โ โ
โ โ SSE broadcaster โ โ โ โ SSE proxy โ โ
โ โโโโโโโโโโโโโโโโโโโโโโ โ โ โโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โฒ
โโโโโโโโโโโโโ Share tunnel URL + secret โโโโโโโโโโโโโ
(out-of-band, e.g. chat)
๐ Security Considerations
- ๐ Always share the secret token through a secure channel (encrypted messaging)
- ๐ A new secret is generated each time the sender starts
- ๐ซ Requests without a valid secret receive
401 Unauthorized - โฑ๏ธ Tunnels are temporary and expire when the sender stops
- ๐ Tunnels use HTTPS for encrypted communication
- ๐ All content is encrypted with AES-256-GCM before leaving the sender
- ๐งฎ SHA-512 integrity hash is computed on plaintext; verified by the receiver before content is decrypted โ mismatch permanently deletes the item
- ๐ Uses constant-time comparison to prevent timing attacks
- โ ๏ธ Note: Secrets are passed via query parameters for simplicity. While HTTPS encrypts the entire URL in transit, query parameters may appear in server logs
- ๐ก Best Practice: Stop the sender immediately after file transfer is complete
- ๐ฏ Recommendation: Use this tool for one-time, temporary file sharing only
๐ Network Requirements
The following outbound connections are required. Share this list with your network administrator for firewall rule creation.
Sender machine
| Destination | Port | Protocol | Purpose |
|---|---|---|---|
*.devtunnels.ms |
443 | HTTPS/WSS | Dev Tunnel relay (active while sender is running) |
global.rel.tunnels.api.visualstudio.com |
443 | HTTPS | Dev Tunnels management API (tunnel create/delete) |
login.microsoftonline.com |
443 | HTTPS | Microsoft account login (devtunnel user login) |
login.live.com |
443 | HTTPS | Microsoft account OAuth token exchange |
github.com |
443 | HTTPS | GitHub account login (devtunnel user login -g) |
aka.ms |
443 | HTTPS | DevTunnels CLI installer redirect |
cdn.jsdelivr.net |
443 | HTTPS | Bootstrap 5, Bootstrap Icons, Alpine.js (sender web UI CDN assets) |
Receiver machine
| Destination | Port | Protocol | Purpose |
|---|---|---|---|
*.devtunnels.ms |
443 | HTTPS | Connecting to the sender's tunnel |
cdn.jsdelivr.net |
443 | HTTPS | Bootstrap 5, Bootstrap Icons, Alpine.js (receiver web UI CDN assets) |
Tool installation only (one-time)
| Destination | Port | Protocol | Purpose |
|---|---|---|---|
api.nuget.org |
443 | HTTPS | dotnet tool install package download |
dotnetcli.blob.core.windows.net |
443 | HTTPS | .NET SDK download |
Exact CDN resources loaded by the web UI
Both the sender (localhost:5000) and receiver (localhost:5001) browsers load:
| Resource | URL |
|---|---|
| Bootstrap 5.3 CSS | https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css |
| Bootstrap 5.3 JS | https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js |
| Bootstrap Icons 1.11 CSS | https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css |
| Bootstrap Icons fonts | https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/fonts/bootstrap-icons.woff2 |
| Alpine.js 3 | https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js |
Air-gapped environments: If outbound access to
cdn.jsdelivr.netis blocked, the web UI will not render correctly. In that scenario the CDN<script>and<link>tags insender-ui.htmlandreceiver-ui.htmlcan be replaced with locally hosted copies of the same assets.
๐งช Development
Building
dotnet build --configuration Release
Running Tests
dotnet test --configuration Release
With coverage:
dotnet test --collect:"XPlat Code Coverage" --results-directory ./coverage
Project Structure
cloud-share/
โโโ cloud-share.sln # Solution file
โโโ README.md # This file
โโโ LICENSE # MIT license
โโโ global.json # .NET SDK version
โโโ .github/
โ โโโ workflows/
โ โโโ ci.yml # CI/CD pipeline with tests & coverage
โโโ CloudShare.Core/
โ โโโ CloudShare.Core.csproj # Shared library
โ โโโ CryptoHelper.cs # AES-256-GCM encryption & SHA-512 hashing
โ โโโ DependencyManager.cs # Auto-install, login flow & preferences
โ โโโ SpectreHelper.cs # Markup escaping helpers
โ โโโ VersionInfo.cs # Version information
โโโ TunnelSender/
โ โโโ TunnelSender.csproj # Sender global tool (uses SharpZipLib for zip bundles)
โ โโโ Program.cs # Sender application & web server
โ โโโ sender-ui.html # Embedded sender web UI
โโโ TunnelReceiver/
โ โโโ TunnelReceiver.csproj # Receiver global tool
โ โโโ Program.cs # Receiver application & proxy web server
โ โโโ receiver-ui.html # Embedded receiver web UI
โโโ CloudShare.Tests/
โโโ CloudShare.Tests.csproj # Test project
โโโ DependencyManagerTests.cs
โโโ VersionInfoTests.cs
๐ฆ NuGet Packages
- Garrard.CloudShare.Sender - The sender tool
- Garrard.CloudShare.Receiver - The receiver tool
Install globally:
dotnet tool install --global Garrard.CloudShare.Sender
dotnet tool install --global Garrard.CloudShare.Receiver
Update:
dotnet tool update --global Garrard.CloudShare.Sender
dotnet tool update --global Garrard.CloudShare.Receiver
Uninstall:
dotnet tool uninstall --global Garrard.CloudShare.Sender
dotnet tool uninstall --global Garrard.CloudShare.Receiver
๐ Troubleshooting
"DevTunnels CLI not found"
The tool will offer to install it automatically. If auto-install fails, install manually (see Prerequisites).
"Authentication required" / "Login token expired"
The sender automatically detects expired tokens and re-authenticates using your saved login preference. If the browser flow fails, run devtunnel user login -g (GitHub) or devtunnel user login (Microsoft) manually, then retry. To switch accounts use cloud-share-sender --reset.
"Connection refused"
- Ensure the sender is still running
- Verify you copied the complete tunnel URL
- Check your internet connection
"File not found"
Make sure you specified the file path when starting the sender:
cloud-share-sender /path/to/your/file.pdf
๐ค Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
๐ค Author
Garrard Kitchen
- GitHub: @garrardkitchen
- NuGet: garrardkitchen
๐ Acknowledgments
- Built with .NET 10
- CLI powered by Spectre.Console
- Uses Microsoft Dev Tunnels for secure connectivity
- Tested with xUnit and Moq
๐ Resources
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
This package has no dependencies.