Garrard.CloudShare.Receiver 0.1.9

dotnet tool install --global Garrard.CloudShare.Receiver --version 0.1.9
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local Garrard.CloudShare.Receiver --version 0.1.9
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=Garrard.CloudShare.Receiver&version=0.1.9
                    
nuke :add-package Garrard.CloudShare.Receiver --version 0.1.9
                    

cloud-share

MIT License CI NuGet Security Docs

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!

๐Ÿ“– Full Documentation โ†’

โœจ 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)
  • ๐Ÿ”’ Authenticated web UI โ€” sender UI gated by a one-time UI token + HttpOnly cookie; receiver UI protected by a local session token
  • ๐Ÿ” End-to-end encryption โ€” AES-256-GCM encrypts all content before it leaves the sender
  • ๐Ÿ”‘ HKDF key derivation โ€” AES key derived via HKDF-SHA256 (RFC 5869 / NIST SP 800-56C), not a raw hash
  • ๐Ÿงฎ Integrity verification โ€” SHA-512 hash shown on both sides; receiver must confirm match before accessing content
  • ๐Ÿ›ก๏ธ Brute-force protection โ€” 10 failed auth attempts triggers a 60-second lockout with HTTP 429
  • ๐Ÿš€ Security hardened โ€” Bearer auth, Anti-CSRF (Origin/Referer), security headers (CSP, CORS, X-Frame-Options), Kestrel size limits, constant-time comparisons, SRI hashes on all CDN dependencies (see full security features โ†’)
  • ๐Ÿ›ก๏ธ Rate limiting โ€” receiver endpoints protected by a fixed-window rate limiter (30 req/10s) to prevent local abuse
  • ๐Ÿ”‘ CLOUDSHARE_SECRET env var โ€” pre-load the shared secret via environment variable on both sender and receiver to avoid process list exposure
  • ๐Ÿ“ 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
  • ๐Ÿ’พ Smart session history โ€” receiver remembers the last 5 tunnel connections; arrow-key to re-select; region selector for DevTunnel geography; type only the 8-char tunnel ID instead of the full URL
  • ๐ŸŒ Cross-platform: Windows, macOS (including Apple Silicon), Linux (Ubuntu)

๐Ÿš€ Installation

# 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 with a pre-loaded secret via environment variable (avoids process list exposure):

export CLOUDSHARE_SECRET="your-secret-here"
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

With a pre-loaded secret (skips the interactive secret prompt entirely):

export CLOUDSHARE_SECRET="your-secret-here"
cloud-share-receiver

Skip interactive prompts entirely with flags:

# Full URL
cloud-share-receiver --url https://mtszwr0l.uks1.devtunnels.ms:5000 --secret aB3kP9mQ2rTs

# Shorthand (--code / -c)
cloud-share-receiver --code mtszwr0l.uks1:5000 --secret aB3kP9mQ2rTs
cloud-share-receiver -c mtszwr0l.uks1        # port defaults to 5000

Check version:

cloud-share-receiver --version

The receiver prompts for the tunnel connection, then starts a local web UI at http://localhost:5001 and opens it in your browser automatically.

Session history: The last 5 connections are saved to ~/<AppData>/CloudShare/receiver-session.json (7-day TTL). On subsequent runs a SelectionPrompt shows recent connections โ€” arrow-key to select and press Enter:

Recent connections

Which tunnel would you like to connect to?

โฏ  mtszwr0l    ยท  uks1    ยท  :5000   (today 14:01)
   c84xl717    ยท  usw2    ยท  :5000   (yesterday 09:31)
   โœŽ  Connect to a new tunnel...

Selecting an existing entry pre-fills the secret:

Use saved secret for mtszwr0l.uks1:5000 (****rTs)? [Y/n]:

First-run / new tunnel structured prompt: Instead of typing the full URL, enter just the short tunnel ID and pick the region from a list:

Tunnel ID: mtszwr0l

Select the DevTunnel region:
โฏ uks1    UK South
  usw2    West US 2
  use1    East US
  euw1    West Europe
  ...

Port (default: 5000): [Enter]

โ†’ https://mtszwr0l.uks1.devtunnels.ms:5000
Enter the secret token: ************

Paste shortcut: Pasting a full URL into the Tunnel ID field skips the region/port sub-prompts automatically.

Receiving items:

  1. When the sender queues an item, it appears in the receiver's queue list in real time (via SSE).
  2. Click Receive on any queued item.
  3. 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

Cloud Share has been subject to a full parallel security audit using OWASP Top 10, NIST SP 800-53, NIST CSF 2.0, STRIDE, and CWE/SANS Top 25. The controls below reflect the implemented findings.

๐Ÿ“‹ Full Security Features Reference โ†’
๐Ÿ” Complete Audit Report โ†’

Transit & Cryptography

Control Detail
AES-256-GCM encryption All content encrypted before leaving the sender (FIPS 197, NIST SP 800-38D)
HKDF-SHA256 key derivation AES key derived via HKDF (RFC 5869 / NIST SP 800-56C) โ€” not a raw SHA-256 hash
SHA-512 integrity hash Computed on plaintext before encryption; verified by the receiver before content is exposed โ€” mismatch permanently deletes the item (FIPS 198-1)
TLS 1.3 transport All tunnel traffic over Microsoft DevTunnels HTTPS (NIST SP 800-52 Rev. 2)
Authorization: Bearer header Shared secret transmitted via HTTP Authorization header only โ€” never in URL query strings
Plaintext zeroed in memory CryptographicOperations.ZeroMemory() clears decrypted buffers immediately after use (NIST SP 800-53 SC-28)

Authentication & Access Control

Control Detail
Sender UI token Separate 128-bit random token gates the sender web UI independently of the encryption secret. Browser URL includes ?token=<uiToken>; first visit sets an HttpOnly SameSite=Strict cookie. Unauthenticated requests receive HTTP 401.
Receiver local session token 128-bit token generated at startup; required on all local receiver endpoints via Bearer header or HttpOnly cookie (for EventSource compatibility).
Brute-force lockout 10 consecutive auth failures โ†’ 60-second lockout โ†’ HTTP 429 with Retry-After header (NIST SP 800-53 AC-7, OWASP A07:2021)
Constant-time comparisons All secret, token, and hash comparisons use CryptographicOperations.FixedTimeEquals() to prevent timing side-channel attacks (CWE-208)
HTTPS-only enforcement Receiver rejects http:// tunnel URLs at startup

HTTP Hardening

Control Detail
Content-Security-Policy default-src 'self' cdn.jsdelivr.net with explicit allowlists on both UIs
X-Frame-Options: DENY Prevents clickjacking via iframe embedding
X-Content-Type-Options: nosniff Blocks MIME-sniffing attacks
Referrer-Policy: no-referrer Suppresses Referer headers on all navigations
CORS โ€” localhost-only Restricted to localhost:<port> only; blocks DNS-rebinding attacks
Anti-CSRF (Origin/Referer) All sender POST/DELETE endpoints validate the Origin or Referer header; browser-originating cross-site requests return HTTP 403 (CWE-352)
Kestrel request body limit 110 MB hard limit at Kestrel level, preventing chunked-encoding bypass of application checks
Subresource Integrity (SRI) All CDN <script> and <link> tags carry integrity= + crossorigin="anonymous" attributes โ€” a CDN compromise cannot inject malicious JavaScript (OWASP A08:2021, NIST SP 800-53 SI-7)

Resource & DoS Protection

Control Detail
SSE connection limit Max 10 concurrent SSE connections; bounded channel (100 items) per client; excess returns HTTP 429
Queue size limit In-memory queue capped at 50 items
File size limits Text: 10 MB ยท Files: 100 MB ยท Zips: 100 MB (aggregate input checked before MemoryStream allocation)
Response size caps Receiver caps /queue responses at 1 MB and item responses at 150 MB โ€” prevents OOM from a malicious sender (CWE-770)
Rate limiting (receiver) Fixed-window limiter: 30 requests per 10 seconds on all receiver endpoints
SSE message validation SSE proxy parses and validates each data: line as JSON; unknown or malformed event types are dropped and logged as SECURITY_EVENT: before reaching the browser
API / SSE client separation API HttpClient: 30-second timeout. SSE HttpClient: InfiniteTimeSpan with CancellationToken โ€” prevents slow-loris attacks on API calls

Secret & Credential Hygiene

Control Detail
Secret masked in console Displayed as ****<last-4> by default; --show-secret to reveal full value
Session file permissions chmod 600 on receiver-session.json on Linux/macOS (NIST SP 800-53 AC-6)
CLOUDSHARE_SECRET env var Both tools read CLOUDSHARE_SECRET at startup โ€” if set, the interactive secret prompt is skipped entirely, preventing the secret appearing in process listings (ps aux / /proc/<pid>/cmdline)
Key separation UI access token and encryption secret are independent values โ€” never reused for each other's purpose

Input Validation

Control Detail
Filename sanitisation Path separators, null bytes, and oversized names stripped on both sender (upload) and receiver (download)
Item ID validation Route {id} validated against ^[a-zA-Z0-9_-]{8,64}$ before forwarding to sender
Exception details suppressed Proxy errors return HTTP 502 โ€” no stack traces or internal paths exposed to HTTP clients

Supply Chain & CI/CD

Control Detail
Vulnerable package scan dotnet list package --vulnerable --include-transitive on every CI build
Dependabot Weekly NuGet dependency scanning with automated PRs (OWASP A06:2021)

Security Event Logging

All security-relevant events are prefixed with SECURITY_EVENT: in the console output at warning level, making them straightforward to grep or pipe to a SIEM:

  • Authentication failures and brute-force lockouts
  • Hash mismatches (potential tampering)
  • Decryption failures
  • Oversized response rejections
  • Unknown or malformed SSE event types
  • Anti-CSRF Origin/Referer violations

Best Practices

  • ๐Ÿ” Always share the secret token through a secure, out-of-band channel (e.g. encrypted messaging)
  • ๐Ÿ”„ A new secret is generated on every sender start โ€” secrets are single-session
  • โฑ๏ธ Stop the sender immediately after file transfer is complete
  • ๐ŸŽฏ This tool is designed 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 SRI Algorithm
Bootstrap 5.3.8 CSS https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css SHA-384
Bootstrap 5.3.8 JS https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js SHA-384
Bootstrap Icons 1.11.3 CSS https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css SHA-256
Bootstrap Icons fonts https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/fonts/bootstrap-icons.woff2 (font, no SRI)
Alpine.js 3.15.8 https://cdn.jsdelivr.net/npm/alpinejs@3.15.8/dist/cdn.min.js SHA-256

All <script> and <link> tags carry integrity= (SRI) and crossorigin="anonymous" attributes. Versions are pinned exactly โ€” no floating @3.x.x wildcards.

Air-gapped environments: If outbound access to cdn.jsdelivr.net is blocked, the web UI will not render correctly. In that scenario the CDN <script> and <link> tags in sender-ui.html and receiver-ui.html can 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 & session history
โ”‚   โ”œโ”€โ”€ DevTunnelRegions.cs     # Known DevTunnel region codes (uks1, usw2, use1, โ€ฆ)
โ”‚   โ”œโ”€โ”€ 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 the tunnel ID, region, and port match what the sender printed (e.g. mtszwr0l ยท uks1 ยท :5000)
  • 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.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

๐Ÿ“„ License

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

๐Ÿ‘ค Author

Garrard Kitchen

๐Ÿ™ Acknowledgments

๐Ÿ”— Resources

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated
0.1.9 121 2/25/2026
0.1.8 104 2/25/2026
0.1.6 118 2/25/2026
0.1.5 106 2/25/2026
0.1.4 103 2/25/2026
0.1.3 116 2/19/2026
0.1.2 104 2/19/2026
0.1.1 108 2/19/2026