snapdrop icon indicating copy to clipboard operation
snapdrop copied to clipboard

Internet Transfers

Open willstott101 opened this issue 5 years ago • 21 comments
trafficstars

This project is far more simple than most related WebRTC file transfer projects, which is awesome.

However the limitation of LAN-only transfers seems a little unnecessary to me.

Would you accept a PR that allows internet transfers, where the receiving side would need some (out-of-band) secret from the sending side to establish the connection?

willstott101 avatar Jun 12 '20 17:06 willstott101

This would be a very helpful feature! We certainly would appreciate your efforts. How do you think of implementing this? I have some ideas: It would be nice if the 'secret' (maybe better called room name?) is always generated and always visible somewhere in the UI. By clicking the 'secret' an overlay could be rendered that has a text input element to enter another existing 'secret' to join it. The 'secret' should be easy to read to somebody and to type (not to long, no special chars). It would be nice if the 'secret' were scannable via QR code. But that might also be too much (additional large dependencies, potentially breaking stuff). I am a bit concerned adding more UI elements could make the UI look cluttered, tho'.

PaulSzymanski avatar Jul 12 '20 20:07 PaulSzymanski

Yeah room name would match the vocab in the server, so let's go with that.

I have some hesitations to making the internet room automatically created (implied by permanently visible?)

  1. It exposes people using LAN-only sharing to be contacted by internet users unnecessarily.
  2. If we can make the codes valid for as short a time as possible, then it decreases the time an attacker would have to brute force their way into the room. This is a bit of a strenuous concern though as it probably wouldn't take very many random bits and a short delay in verification in the server to completely deter brute force connections.

I think most people are familiar with sharing files using links, so I propose we focus on that as the primary interface.

The bottom message could be extended to have 2 options (it looks like a link to me already so we could make it a dropdown):

  • Allow me to be discovered by: Everyone in this network.
  • Allow me to be discovered by: Everyone with the link snapdrop.net/frolickinglightpinkmecha 📋

The second bit of UI that I propose would be a line of text (much like the Open Snapdrop on other devices to send files.) which reads "Click here to create invite.", on clicking it, it's replaced with Share link: snapdrop.net/frolickinglightpinkmecha 📋.

This line should be visible regardless of it there are LAN peers online or not.

Does that seem reasonable?

willstott101 avatar Jul 12 '20 21:07 willstott101

I also was thinking that brute forcing room names wouldn't be too much of a concern for the reasons you mentioned. However, I like your idea of incorporating the Allow me to be discovered by to not unnecessarily introduce the risk to people that do not make use of the new feature.

I am not sure with the sharing link:

  1. In my personal scenarios when I happen to use Snapdrop, if it was easy for me to share a sharing link to the target peer (i.e. via messenger), I would probably already just have sent the files via the messenger. Also the text sending feature of Snapdrop seems to be less valuable if I could have just used that messenger in the first place.
  2. The link can not be used via installed PWA.
  3. However, I understand that the link could still be useful to tell it to somebody that never used Snapdrop and has not the PWA installed.

So I believe that it must at least be possible to enter the room name from within the app.

Is the Click here to create invite element necessary? The same action could be served by the Allow me to be discovered by element. This way we wouldn't have to introduce another UI element. However, having that Click here to create invite has less risk of being overlooked by users. With Airdrop I have observed that users don't realise they can change the visibility by clicking that element. You need to know that already.

What are your thoughts, @RobinLinus ?

PaulSzymanski avatar Jul 13 '20 10:07 PaulSzymanski

What also needs to be considered: We do not have TURN server. That means this feature will not work for people that are behind a symmetric NAT.

PaulSzymanski avatar Jul 13 '20 12:07 PaulSzymanski

Related: https://github.com/RobinLinus/snapdrop/issues/38

PaulSzymanski avatar Jul 13 '20 12:07 PaulSzymanski

@willstott101 thanks a lot for your suggestions! I agree with almost all your perspectives. Paul and I just scribbled a possible UI here BA7ED87F-7D36-4406-9D4E-FA77068F8C9F

Basic idea is that you have two types of rooms:

  • LAN
  • Internet

You’re always exactly in one room. Internet rooms have a random 6-digit room number.

  • The creator automatically joins the room when creating it.
  • Others can join the room by entering the 6 digits.
  • When leaving that room you return to your LAN room.

What do you think about these drafts?

RobinLinus avatar Jul 13 '20 22:07 RobinLinus

Looks good to me, I'm a little hesitant about preventing being in multiple rooms at once, but possibly just cause of the way cookies are used atm (preventing multi-tab usage #64). I think you should be able to share on LAN, and the internet in different rooms at the same time.... but possibly just in separate tabs, the UI would be too complicated to support multiple rooms in one tab I think.

  • What happens if you're mid-LAN transfer and you have a go at seeing what the create room button does?
  • Can we keep a link system too? There are plenty of messaging programs that let you share files yes, but usually of limited size and extension. I don't think it's rare to be on discord and wanting to share a file without uploading it to the messaging provider :) Dropping a link is handy, and can be just a #23546 or the like to auto-join a room.

willstott101 avatar Jul 14 '20 12:07 willstott101

Looks good to me, I'm a little hesitant about preventing being in multiple rooms at once, but possibly just cause of the way cookies are used atm (preventing multi-tab usage #64). I think you should be able to share on LAN, and the internet in different rooms at the same time.... but possibly just in separate tabs, the UI would be too complicated to support multiple rooms in one tab I think.

Hmn... I would not want to optimize for multi tab usage since there’s not much value in adding that complexity. I’d say preventing multi tab usage is a good thing.

  • What happens if you're mid-LAN transfer and you have a go at seeing what the create room button does?

Good question. Maybe prevent switching rooms while transfering?

  • Can we keep a link system too? There are plenty of messaging programs that let you share files yes, but usually of limited size and extension. I don't think it's rare to be on discord and wanting to share a file without uploading it to the messaging provider :) Dropping a link is handy, and can be just a #23546 or the like to auto-join a room.

Yep, it’s a good idea to have such an invite link. Maybe you can copy it via another icon in the header.

RobinLinus avatar Jul 14 '20 15:07 RobinLinus

I'm not sure there is any complexity to supporting multiple tabs (I mean native browser tabs), afaict the only change necessary is to remove the cookie with the uuid, instead using SessionStorage to store it and adding it to another header rather than as a cookie. Then multiple browser tabs will be completely independent.

Yeah we can just prevent switching rooms mid-transfer, instead users could make a new tab to share files to someone else :)

willstott101 avatar Jul 15 '20 12:07 willstott101

okay, let's try that!

RobinLinus avatar Jul 18 '20 23:07 RobinLinus

@willstott101 thanks a lot for your suggestions! I agree with almost all your perspectives. Paul and I just scribbled a possible UI here BA7ED87F-7D36-4406-9D4E-FA77068F8C9F

Basic idea is that you have two types of rooms:

* LAN

* Internet

You’re always exactly in one room. Internet rooms have a random 6-digit room number.

* The creator automatically joins the room when creating it.

* Others can join the room by entering the 6 digits.

* When leaving that room you return to your LAN room.

What do you think about these drafts?

honestly, i think 6 digits is way to low. As far as i know, there is no anti-brute-fore mechanism right now. Also anyone could just "hangout" in every room or at least in a decent number of rooms at the same time (sure there is a limit on the server side - depending on how many connections it can hold open at any time). Just by chance a bad actor will catch a naive user that way.

How can is see this feature being implemented?

  • let the client present some proof of work before joining a WAN room to increase the cost of a brute-force attack, not necessarily a captcha, could also be a computational challenge
  • add a sensible limit for the connections tries per room
  • if the room name is the secret: increase the number of room names from 10^6 to something of the order of 2^128 or bigger, which makes it infeasible to share a link on any other way than a messenger.
  • if the room name is not the secret: let the client generate a short password (like TeamViewer one-time-connecetions). Other clients may connect to the room, if the password is correct. (Ideally the passwords should be hashed and salted). The room is closed if the last client disconnects from the room.

A proof of work could be done through a sha-3 hash of a random string, where only part of the random string is given to the client: Client asks server for challenge. The server generates a random string (puzzle-string), hashes the puzzle-string and sends part of the puzzle-string and the hash to the client. The client has to find the complete puzzle-string by trying all possibilities by hashing each candidate and comparing it so the provided hash. If the client has found the puzzle-string, it sends the complete puzzle-string as well a the wan-room-information (name and possible password) to the server. The server first checks the proof of work by comparing the actual puzzle-string to the solution offered by the client. If the check fails, it connects the client to a dummy-room which will never be joined by anyone. If it succeeded: If the room doesn't exist yet, the server creates the wan-room and adds the client. If the room does exist, it checks the password (if present). If the password check fails, respond to client with "wrong password". Otherwise add the client to the room.

Please let me know what i might have overseen or where i made a false assumption. Thanks you!

najtin avatar Sep 21 '20 16:09 najtin

Here's a concept: Add an option to allow the viewing of all devices on the website in or out of the LAN in the config. (This would be opt-in oc) as a sort of stop-gap until this gets implemented

reesericci avatar Nov 25 '20 20:11 reesericci

Is there a Figma/Adobe XD/ Sketch file we can see?

quacksire avatar Nov 25 '20 20:11 quacksire

@najtin I appreciate your concern about sitting in loads of rooms, and I'm sure it'd be worth investing a bit more thought than we have RE security.

I propose a simple solution to drastically improve security from the original sketches, but without complicating anything too much.

  • Add a simple server-side delay when connecting to the room - like the login delay with SSH on an invalid password.
  • Add some connection rate-limiting per-IP address.
  • Introduce some letters into the room names, let's say: 123456789BCDEFGHJKMNPQRSTUXYZ or something.

If this still doesn't seem satisfactory...

I'm not sure I can get on board with enforcing link-sharing over short read-able secrets. Being next to someone on 5G shouldn't require establishing a connection beyond your keyboards to join the room IMO.

So... we could decouple the room name from the connection secret - but I think this would drastically reduce usability. In that system users could be given a room name and an "Invite" button, which would show a short-lived secret (in readable and linkable form). Secrets would be valid for only around 1 minute perhaps, and the UI would reflect invalidation of secrets kinda like discord invites (if they still do that). After a secret is used it would not re-appear as a secret for some amount of time, to prevent slow users from accidentally joining other rooms.

willstott101 avatar Nov 25 '20 21:11 willstott101

Just for reference/inspiration: The folks from ShareDrop have implemented the room feature in a quite nice and minimalistic way (+ button in the upper right of the website).

loilo avatar Dec 17 '20 12:12 loilo

@najtin I appreciate your concern about sitting in loads of rooms, and I'm sure it'd be worth investing a bit more thought than we have RE security.

I propose a simple solution to drastically improve security from the original sketches, but without complicating anything too much.

* Add a simple server-side delay when connecting to the room - like the login delay with SSH on an invalid password.

* Add some connection rate-limiting per-IP address.

* Introduce some letters into the room names, let's say: 123456789BCDEFGHJKMNPQRSTUXYZ or something.

If this still doesn't seem satisfactory...

I'm not sure I can get on board with enforcing link-sharing over short read-able secrets. Being next to someone on 5G shouldn't require establishing a connection beyond your keyboards to join the room IMO.

So... we could decouple the room name from the connection secret - but I think this would drastically reduce usability. In that system users could be given a room name and an "Invite" button, which would show a short-lived secret (in readable and linkable form). Secrets would be valid for only around 1 minute perhaps, and the UI would reflect invalidation of secrets kinda like discord invites (if they still do that). After a secret is used it would not re-appear as a secret for some amount of time, to prevent slow users from accidentally joining other rooms.

Yeah, like regen the secret every minute, and delete the secret once the popup window is closed.

reesericci avatar Dec 17 '20 13:12 reesericci

it's done today! https://github.com/laukeng/snapdrop Added Internet support and fixed the bug with Firefox receiving files. Can also work in local network.

laukeng avatar Nov 20 '21 07:11 laukeng

it's done today! https://github.com/laukeng/snapdrop Added Internet support and fixed the bug with Firefox receiving files. Can also work in local network.

looks super cool! @laukeng

reesericci avatar Nov 24 '21 00:11 reesericci

1. In my personal scenarios when I happen to use Snapdrop, if it was easy for me to share a sharing link to the target peer (i.e. via messenger), I would probably already just have sent the files via the messenger. Also the text sending feature of Snapdrop seems to be less valuable if I could have just used that messenger in the first place.

I agree that this is the case when target peer and sending peer are two different people.

Then again I often want to quickly send a URL or file accross my own devices. I would love to have a url to entry a room instantly to speed up the user flow by one step. This way, I could bookmark this one (long) url and connect all my devices in different networks even faster.

Maybe the two approaches can also be combined:

  1. Whenever a new room is created it has a long and secure roomid that is appended to the url as well.
  2. A share menu is opened to invite peers via a 6-digit code
  3. When the share menu is opened, a 6-digit code is created which can be used to enter the room on other devices.
  4. When entering the room via a 6-digit code, the roomid is transfered and the url is changed accordingly.
  5. Whenever the share menu is closed the 6-digit code is invalidated.
  6. Whenever the share menu is opened again a new 6-digit code is created.
  7. Additionaly, the user can simply share the url to invite other peers to the room

This way we would resolve the conflict of security vs. simplicity mentioned by @yjmp14 in https://github.com/RobinLinus/snapdrop/issues/214#issuecomment-977536928_

schlagmichdoch avatar Sep 26 '22 13:09 schlagmichdoch

I gave it a try as a pull request to a working snapdrop fork that already included rooms: https://github.com/yjmp14/wulingate/pull/12

localhost_8080_(Desktop 1080p) (1)

@RobinLinus are you open to include an (optional) Turn server to snapdrop in order to implement rooms outside of the local network?

schlagmichdoch avatar Oct 13 '22 09:10 schlagmichdoch

@RobinLinus has this feature been abandoned?

andreapx avatar May 28 '23 09:05 andreapx