Giter Club home page Giter Club logo

teleporter's Introduction

Teleporter

Teleporter is a small utility in the vein of netcat to send files quickly from point A to point B. It is more convenient than netcat in that you don't have to run a separate command with file redirection for each file you wish to transfer.

Teleporter lets you pass the destination and a list of files you wish to send and it will create those files with the proper filenames on the receiving end. Each Teleporter binary can act as a client or a server so there's no need to move multiple software packages around.

Teleporter can recursively copy, overwrite, rename, and keep a backup of the destination file.

Teleporter now does delta file transfers using the xxHash3 hashing algorithm for files being overwritten, hashing the entire file as well as splitting the file into a number of smaller chunks.

The protocol Teleporter implements to transfer files is called Teleport and is defined in PROTOCOL.md.

Usage

Receiving Files

To start a teleporter in server (receiving) mode, just run:

teleporter listen

Teleporter will default to listening on 0.0.0.0:9001 for incoming connections.

Here are some additional options for receiving files:

Usage: teleporter listen [OPTIONS]

Options:
      --allow-dangerous-filepath  Allow absolute and relative file paths for transfers (server only)
                                  [WARNING: potentially dangerous option, use at your own risk!]
  -m, --must-encrypt              Require encryption for incoming connections to the server
  -p, --port <PORT>               Port to listen on [default: 9001]
  -h, --help                      Print help

Sending Files

To start a teleporter in client (sending) mode, run:

teleporter send [-d <destination>] -i <file> [[file2] [file3] ...]

Here are some additional arguments for sending files:

Usage: teleporter send [OPTIONS]

Options:
  -i, --input [<INPUT>...]  List of filepaths to files that will be teleported
  -d, --dest <DEST>         Destination teleporter host [default: localhost]
  -p, --port <PORT>         Destination teleporter port [default: 9001]
  -o, --overwrite           Overwrite remote file
  -r, --recursive           Recurse into directories on send
  -e, --encrypt             Encrypt the file transfer using ECDH key-exchange and random keys
  -n, --no-delta            Disable delta transfer (overwrite will transfer entire file)
  -k, --keep-path           Keep path info (recreate directory path on remote server)
  -b, --backup              Backup the destination file to a ".bak" extension if it exists 
                            and is being overwritten (consecutive runs will replace the *.bak file)
  -f, --filename-append     If the destination file exists, append a ".1"(or next available number)
                            to the filename instead of overwriting
  -h, --help                Print help

Teleporter will transfer files with their name information as well as their file permissions. Any file path information will be lost unless the -k option is enabled. All the received files will be written out in the CWD where the server side was started unless the server was started with the --allow-dangerous-filepath option. When overwriting a file with the -o option, additional modifiers can be used, such as -b to make a backup of the original file, or -n to disable delta file transfers and always overwrite the entire file.

Scan for Teleporter Instances

To have teleporter scan the local network for any reachable teleporter instances, run:

teleporter scan

This will iterate through all the network devices (except the loopback device!) and will attempt to locate any teleporter servers listening on a specific port. It will report back if any server is found and what version they are running. This feature is only available on teleporter v0.10.7 and higher.

Here are the additional arguments for scanning:

Scan all network devices for any reachable Teleport listeners

Usage: teleporter scan [OPTIONS]

Options:
  -p, --port <PORT>  Port to scan for [default: 9001]
  -h, --help         Print help

Rename / Copy-To

Teleporter can now set remote file locations, or file renaming, via the : operator. Similar to how Docker allows quick mounting of directory locations, Teleporter will first attempt to open a file by the full given path, if that file does not exist, it will see if there are any colons (:) in the filename. If present, it will split the filepath and attempt to open on the first portion of the name. If that succeeds, Teleporter assumes this is a file rename / copy-to. Teleporter will also need the -k option, to keep filepath information. Otherwise only the file name will be changed.

For example, given the following command:

./teleporter -i ~/Downloads/ubuntu-20.04.3-live-server-arm64.iso:/tmp/ubuntu.iso -k

(and assuming the server was started with --allow-dangerous-filepath), Teleporter will first attempt to open ~/Downloads/ubuntu-20.04.3-live-server-arm64.iso:/tmp/ubuntu.iso, if that fails, it will attempt to split the path on : and open ~/Downloads/ubuntu-20.04.3-live-server-arm64.iso. If that succeeds, then it knows it is a rename / copy-to operation and will set the destination filepath to be the second part of the string: /tmp/ubuntu.iso. On the server, it will only receive the file for /tmp/ubuntu.iso. If the -k argument was omitted, the server would just receive the original file renamed as ubuntu.iso.

Installation

If you have Rust and Cargo installed, Teleporter can be quickly compiled and installed by running the following command:

cargo install --locked teleporter

This will install Teleporter to ~/.cargo/bin/teleporter, which might need to be added to your shell's PATH variable.

Example output

Server (receiving from 2 different clients)

$ teleporter
Teleporter Server 0.6.0 listening for connections on 0.0.0.0:9001
Receiving: ["archlinux-2021.11.01-x86_64.iso", "ubuntu-20.04.3-live-server-arm64.iso"] => Received file: "archlinux-2021.11.01-x86_64.iso" (from: 127.0.0.1:54708 v[0, 6, 0]) (17.67s @ 398.270 Mbps)
Receiving: ["ubuntu-20.04.3-live-server-arm64.iso", "ArchLinuxARM-aarch64-latest.tar"] => Received file: "ubuntu-20.04.3-live-server-arm64.iso" (from: 127.0.0.1:54709 v[0, 6, 0]) (24.55s @ 390.689 Mbps)
Receiving: ["ArchLinuxARM-aarch64-latest.tar", "laughing_man_by_geno.jpg"] => Received file: "laughing_man_by_geno.jpg" (from: 127.0.0.1:54713 v[0, 6, 0]) (952.46µs @ inf Mbps)
Receiving: ["ArchLinuxARM-aarch64-latest.tar", "unnamed.jpg"] => Received file: "unnamed.jpg" (from: 127.0.0.1:54714 v[0, 6, 0]) (832.04µs @ inf Mbps)
Receiving: ["ArchLinuxARM-aarch64-latest.tar"] => Received file: "ArchLinuxARM-aarch64-latest.tar" (from: 127.0.0.1:54712 v[0, 6, 0]) (27.57s @ 388.182 Mbps)
Receiving: []

Client (sending)

$ teleporter -i ~/Downloads/*iso ~/Downloads/ArchLinuxARM-aarch64-latest.tar ~/Downloads/*jpg
Teleporter Client 0.6.0
Sending file 1/5: archlinux-2021.11.01-x86_64.iso
 =>  846.324M of  846.324M (100.00%) done! Time: 17.63s Speed: 398.270 Mbps
Sending file 2/5: ubuntu-20.04.3-live-server-arm64.iso
 =>    1.145G of    1.145G (100.00%) done! Time: 24.51s Speed: 390.689 Mbps
Sending file 3/5: ArchLinuxARM-aarch64-latest.tar
 =>    1.279G of    1.279G (100.00%) done! Time: 27.54s Speed: 388.182 Mbps
Sending file 4/5: laughing_man_by_geno.jpg
 =>   19.230K of   19.230K (100.00%) done! Time: 1.15ms Speed: inf Mbps
Sending file 5/5: unnamed.jpg
 =>   16.374K of   16.374K (100.00%) done! Time: 834.29µs Speed: inf Mbps

teleporter's People

Contributors

aedrax avatar genonullfree avatar wcampbell0x2a avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

teleporter's Issues

Allow sending files to destinations with absolute paths

My use case for teleport is going to be using it programmatically for some system testing-

It would be really nice to be able to keep the preceding slash e.g. /tmp/file when transferring something, as I have some files that may use local paths from the testing directory, and some files that use absolute paths for some configuration changes.

Essentially, would it be possible to find a way to allow absolute path transfers without needing a command-line flag?

add instructions for cross compiling

Add instructions for offline cross-compiling to various architectures.
At least supporting:

  • x86
  • aarch64
  • arm32
  • mips

With either being able to support various glibc versions or static musl builds.

File overwrite skips last data chunk

This if condition in the client send causes an early return during a file overwrite, skipping the last data chunk:

if !hash_list.is_empty() && index < hash_list.len() {
    hasher.update(&buf);

    // early return here if we are at the last hash in the hash list
    if (index == hash_list.len() - 1) && sent + len == header.filesize as usize {
        send_delta_complete(stream, file)?;
        sent += len;
        print_updates(sent as f64, &header);
        break;
    }
    // ...

This results in no transfer (filesize <= chunksize) or an incomplete overwrite (filesize > chunksize).

Version: 0.5.1 (latest)

Dramatic increase in time for hashing (delta overwrite) on MacOS

Perform some binary profiling to determine exact case of slowdown.

Affected versions: v0.6.0, v0.5.5, suspect the following culprits:

  • blake3 on MacOS or M1
  • MacOS caching

Ex Linux machine orig:

 =>  666.433M of  666.433M (100.00%) done! Time: 37.06s Speed: 144.094 Mbps

Linux machine delta overwrite:

 done! Time: 1.18s Speed: 3530.437 Mbps

Ex MacOS machine (M1Max) orig:

 =>    1.145G of    1.145G (100.00%) done! Time: 19.52s Speed: 493.502 Mbps

MacOS machine (M1Max) delta overwrite:

 done! Time: 84.77s Speed: 111.626 Mbps

Add crypto as an option

Bring back ECDH crypto! (optionally)
Add flag -e option to exchange elliptic curve public keys and encrypt the file transfer.
The ecdh branch may yet be of some use to us.

Choose an open source license

Please consider assigning a license to this project.

https://choosealicense.com/no-permission/

If you find software that doesn’t have a license, that generally means you have no permission from the creators of the software to use, modify, or share the software. Although a code host such as GitHub may allow you to view and fork the code, this does not imply that you are permitted to use, modify, or share the software for any purpose.

I tend to prefer the MIT License as it is simple and permissive. It also expressly excludes any warranty.

Encrypt file transfers

Encrypt the file transfers using ECDH to handle the shared secret calculation and then AES-256 CBC for the actual encryption.

Thought about signing messages as well, but that probably wouldnt be useful as keys are ephemeral (per file)

Enable more features in command line arguments

Features:

  • Delta (utilize delta file transfer for overwrite)
  • Backup (cp or mv the original file to preserve a backup)
  • Overwrite (overwrite file on server)
  • Rename (instead of overwriting, copy to ${filename}.1, etc.)

Add benchmarks

Would it even make sense if it's a localhost benchmark...?

Handle errors properly

Handle errors better, and return errors instead of just println!(); return Ok(()) everywhere.

This includes handling TeleportStatus properly! :P

Add confirmation on file transfer overwrite options

Options:

  1. Add a flag -c to confirm every file that will be overwritten with "y/n" inputs
  2. Add a flag -y to assume "yes" to overwrite confirmation input

I'm leaning towards 2, because it feels more correct/safe, but 1 keeps the current behavior.

Investigate connection'd server

Investigate servers with connections to each other...almost sounds p2p, but basically yes where they all have connections to each other and you can cat a file into a portal socket and like 24 it pipes a terminal to your socket

Refactor arguments

Group them into server and client categories and highlight any relationships within them.

Don't fail if the patch version is different

This requires the assurance that the patch version be incremented only on non-protocol breaking changes.

Will allow communications so long as the major and minor versions match.

Remove unmaintained rust-crypto library

output running cargo audit on this library:

> cargo audit
    Fetching advisory database from `https://github.com/RustSec/advisory-db.git`
      Loaded 374 security advisories (from /home/wcampbell/.cargo/advisory-db)
    Updating crates.io index
    Scanning Cargo.lock for vulnerabilities (56 crate dependencies)
Crate:         time
Version:       0.1.44
Title:         Potential segfault in the time crate
Date:          2020-11-18
ID:            RUSTSEC-2020-0071
URL:           https://rustsec.org/advisories/RUSTSEC-2020-0071
Solution:      Upgrade to >=0.2.23
Dependency tree:
time 0.1.44
└── rust-crypto 0.2.36
    └── teleporter 0.7.0

Crate:         rust-crypto
Version:       0.2.36
Warning:       unmaintained
Title:         rust-crypto is unmaintained; switch to a modern alternative
Date:          2016-09-06
ID:            RUSTSEC-2016-0005
URL:           https://rustsec.org/advisories/RUSTSEC-2016-0005
Dependency tree:
rust-crypto 0.2.36
└── teleporter 0.7.0

error: 1 vulnerability found!
warning: 1 allowed warning found

> git show HEAD
commit 288f97e743f385c1e3f555bd3a0a18f9014d6939 (HEAD -> main, origin/main, origin/HEAD)

This leads to the following recommendation: https://rustsec.org/advisories/RUSTSEC-2016-0005

Sorry for being bored late at night ;)

File overwrite does not truncate

If the transferred file is smaller than the file to be overwritten, the overwritten file will not be truncated to the smaller size.

Seen on version 0.4.1 but also reproducible with 5.0.0.

Possible fix:

--- a/src/server.rs
+++ b/src/server.rs
@@ -121,6 +121,7 @@ fn recv(mut stream: TcpStream, recv_list: Arc<Mutex<Vec<String>>>) -> Result<(),
     file = match OpenOptions::new()
         .read(true)
         .write(true)
+        .truncate(true)
         .open(&header.filename)
     {
         Ok(f) => f,

Will do a proper triage later today...

File transfer not working

Version: 0.5.3.0

Sending an 82 byte file (no overwrite) created an empty file on the server. Data appeared to be transferred according to the client output:

Sending file 1/1: "file"
 =>    82.000B of   82.000B (100.00%) done!

82 byte file on the server is just all zeroes. Documenting this for future investigation

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.