Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow frontend to be served statically #49

Merged
merged 7 commits into from Aug 6, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
@@ -1,6 +1,12 @@
## 0.3.0.0
**Breaking API Changes**
In this version, TermPair clients from previous versions cannot connect to this TermPair server

* Use new key sharing scheme: Different keys used in different directions; keys rotated; secret keys retrieved via RSA public key rather than embedding in the URL
* [bugfix] Terminal dimensions in browser match upon initial connection, instead of after resizing
* Allow static site to route terminal traffic through other server. If static site is detected, user can enter the terminal id and server url in the browser UI.
* Allow Terminal ID to be entered on landing page


## 0.2.0.0
* Add ability to copy+paste using keystrokes (copy with ctrl+shift+c or ctrl+shift+x, and paste with ctrl+shift+v)
Expand Down
18 changes: 14 additions & 4 deletions CONTRIBUTING.md
Expand Up @@ -33,18 +33,28 @@ yarn install
```
to install dependencies.

You'll then be able to build the frontend app using:
You'll then be able to view and hot reload changes to the frontend app using:

```bash
yarn build
yarn start
```

The TermPair server does not need to be reloaded, so you can just refresh the webpage to view changes.

Changes that don't require an actively connected terminal can be tested much more easily with hot reloading by running:
If you want to connect a terminal to the frontend, in a new terminal run
```
nox -s serve
```
then share a terminal with
```
nox -s broadcast
```
open the browser at `http://localhost:3000` and enter the terminal id and url (`http://localhost:8000`).

If you are testing something that needs a full build, you can build and statically serve the frontend with

```bash
yarn start
yarn build
```

## Releasing new versions to PyPI
Expand Down
35 changes: 24 additions & 11 deletions README.md
Expand Up @@ -26,7 +26,7 @@ TermPair lets developers securely share and control terminals in real time.

First start the TermPair server with `termpair serve`, or use the one already running at [https://chadsmith.dev/termpair](https://chadsmith.dev/termpair).

The server is used to route encrypted data between terminals and connected browsers.
The server is used to route encrypted data between terminals and connected browsers -- it doen't actually start sharing any terminals just by running it.
cs01 marked this conversation as resolved.
Show resolved Hide resolved

```
> termpair serve --port 8000
Expand All @@ -42,15 +42,15 @@ Then share your terminal by running `termpair share`.
This connects your terminal to the server, and allows browsers to access the terminal.

```
> termpair share --port 8000
--------------------------------------------------------------------------------
> termpair share
---------------------------------------------------------------------------------------------------------------------------------
Connection established with end-to-end encryption 🔒
Sharing '/bin/bash' at

http://localhost:8000/?terminal_id=fd96c0f84adc6be776872950e19caecc

Terminal ID: e8add1d61a63599b91c0f5ba8779319d
TermPair Server URL: http://localhost:8000/
Sharable link (expires when this process ends):
http://localhost:8000/?terminal_id=e8add1d61a63599b91c0f5ba8779319d
Type 'exit' or close terminal to stop sharing.
--------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------
```

The URL printed contains a unique terminal ID. You can share the URL with whoever you like. **Anyone who has it can access your terminal while the `termpair share` process is running.**
Expand All @@ -76,13 +76,13 @@ TermPair consists of three pieces:
2. server
3. browser client(s)

First, the termpair server is started (`termpair serve`). The server acts as a router that blindly forwards encrypted data between TermPair terminal clients and connected browsers. The serve listens for termpair websocket connections from unix terminal clients, and maintains a mapping to any connected browsers.
First, the termpair server is started (`termpair serve`). The server acts as a router that blindly forwards encrypted data between TermPair terminal clients and connected browsers. The server listens for termpair websocket connections from unix terminal clients, and maintains a mapping to any connected browsers.

Before the TermPair client sends terminal output to the server, it creates two AES encryption keys and uses one of them to encrypt the output so the server cannot read it. The other is used by the browser to encrypt user input.
Before the TermPair client sends terminal output to the server, it creates two AES encryption keys. One is used to encrypt the terminals output to the browsers so the server cannot read it. The other is used by the browser when sending input from the browser to the terminal.

The server then forwards that data to connected browsers. When the browsers receive the data, they use the secret key to decrypt and display the terminal output.

The browser obtains the secret AES keys by requesting them from the broadcasting terminal along with a public RSA key generated in the browser at runtime. The broadcasting terminal responds with AES keys encrypted with the public key. The AES keys are rotated periodically.
The browser obtains the secret AES keys without the server seeing them by using public key encryption. The browser generates an RSA key pair at runtime, then sends the public key to the broadcasting terminal. The broadcasting terminal responds with the AES keys encrypted with the public key. The AES keys are rotated periodically.
cs01 marked this conversation as resolved.
Show resolved Hide resolved

When a browser sends input to the terminal, it is encrypted in the browser, forwarded from the server to the terminal, then decrypted in the terminal by TermPair, and finally written to the terminal's input.

Expand Down Expand Up @@ -149,6 +149,19 @@ server {
}
```

## Static Hosting
As an optional additional security measure, TermPair supports staticallly serving the JavaScript web app. In this arrangement, you can build the webapp yourself and host on your computer, or statically host on something like GitHub pages or Vercel. That way you can guarantee the server is not providing a malicious JavaScript web app.

Then, you can connect to it and specify the Terminal ID and TermPair server that routes the encrypted data.

To build the web app, see [CONTRIBUTING.md](https://github.com/cs01/termpair/blob/master/CONTRIBUTING.md).

Then you can deploy to GitHub pages, Vercel, etc. or self-serve with
```shell
$ cd termpair/termpair/frontend_build
$ python3 -m http.server 7999 --bind 127.0.0.1
```

## CLI API

```
Expand Down
10 changes: 5 additions & 5 deletions docs/termpair_architecture.excalidraw
Expand Up @@ -143,8 +143,8 @@
},
{
"type": "text",
"version": 961,
"versionNonce": 1627041225,
"version": 966,
"versionNonce": 139749130,
"isDeleted": false,
"id": "e-Wl_LzVogxM43annJJMP",
"fillStyle": "hachure",
Expand All @@ -158,15 +158,15 @@
"strokeColor": "#000000",
"backgroundColor": "transparent",
"width": 560,
"height": 325,
"height": 300,
"seed": 676973041,
"groupIds": [],
"strokeSharpness": "sharp",
"boundElementIds": [],
"fontSize": 20,
"fontFamily": 1,
"text": "- Each browser creates a new RSA key pair, then\nrequests the AES keys from the broadcasting terminal\n- The terminal replies with AES keys that are encrypted\nwith the browser's public key\n- The browser decrypts with its private key and stores\nthe two AES keys used to encrypt/decrypt the terminal\ndata\n- Encrypted terminal data is received\nfrom server, decrypted, and rendered\n- User input to browser terminal is also\nencrypted, then\nsent to the TermPair server, which sends to the\nuser broadcasting",
"baseline": 318,
"text": "- Each browser creates a new RSA key pair, then\nrequests the AES keys from the broadcasting terminal\n- The terminal replies with AES keys that are encrypted\nwith the browser's public key\n- The browser decrypts with its private key and stores\nthe two AES keys used to encrypt/decrypt the terminal\ndata\n- Encrypted terminal data is received\nfrom server, decrypted, and rendered\n- User input to browser terminal is also\nencrypted, then sent to the TermPair server, \nwhich sends to the user broadcasting",
"baseline": 293,
"textAlign": "left",
"verticalAlign": "top"
},
Expand Down
Binary file modified docs/termpair_architecture.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion termpair/frontend_src/package.json
Expand Up @@ -30,7 +30,6 @@
"test": "craco test",
"eject": "craco eject"
},
"proxy": "http://localhost:8000",
"homepage": ".",
"eslintConfig": {
"extends": "react-app"
Expand Down