Documenting use, cleanup, and script now cleans html file links
This commit is contained in:
parent
b1634b4afe
commit
8d6c2fddbb
@ -9,7 +9,7 @@
|
||||
## Installing srcweave
|
||||
|
||||
1. Install sbcl (steel bank common lisp)
|
||||
2. Install quicklisp (instructions: [https://quicklisp.org/beta/](https://quicklisp.org/beta/])
|
||||
2. Install quicklisp (instructions: [https://quicklisp.org/beta/](https://quicklisp.org/beta/))
|
||||
3. `git clone https://github.com/justinmeiners/srcweave`
|
||||
4. `cd srcweave`
|
||||
5. `make; make install`
|
15
Makefile
15
Makefile
@ -1,9 +1,10 @@
|
||||
weave:
|
||||
srcweave --formatter srcweave-format --weave docs/ ReadMe.md security/Authentication.md EnvironmentVariables.md Dependencies.md server/Server.md server/Streaming.md \
|
||||
server/XdotoolCommands.md ThreatModel.md Client.md
|
||||
util/removefencedcode.py
|
||||
srcweave --formatter srcweave-format --weave docs/ ReadMe.md Building.md Dependencies.md EnvironmentVariables.md LICENSE.md \
|
||||
security/Authentication.md security/ThreatModel.md Plumbing.md server/Server.md server/Streaming.md server/Sendkeys.md server/XdotoolCommands.md \
|
||||
Client.md tools/Tools.md tools/Editor.md tools/Input.md tools/RawCapture.md
|
||||
util/clean.py
|
||||
tangle:
|
||||
srcweave --formatter srcweave-format --tangle smartkeyboard/ ReadMe.md security/Authentication.md EnvironmentVariables.md Dependencies.md \
|
||||
srcweave --formatter srcweave-format --tangle smartkeyboard/ ReadMe.md Plumbing.md security/Authentication.md EnvironmentVariables.md Dependencies.md \
|
||||
server/Server.md server/Streaming.md server/Sendkeys.md server/XdotoolCommands.md ThreatModel.md Client.md tools/Tools.md tools/Editor.md tools/Input.md \
|
||||
tools/RawCapture.md
|
||||
clean:
|
||||
@ -15,12 +16,10 @@ clean:
|
||||
build: tangle
|
||||
- cd smartkeyboard/server && go mod init keyboard.voidnet.tech
|
||||
- cd smartkeyboard/server && go mod tidy
|
||||
- cd smartkeyboard/server && go build -o ../../bin/keyboard
|
||||
- cd smartkeyboard/server && go build -tags osusergo,netgo -o ../../bin/keyboard
|
||||
- cd smartkeyboard/client && go mod init keyboard.voidnet.tech
|
||||
- cd smartkeyboard/client && go mod tidy
|
||||
- cd smartkeyboard/client && go build -o ../../bin/keyboard-client
|
||||
|
||||
|
||||
- cd smartkeyboard/client && go build -tags osusergo,netgo -o ../../bin/keyboard-client
|
||||
|
||||
test: tangle
|
||||
-cd smartkeyboard && go mod init keyboard.voidnet.tech
|
||||
|
12
Plumbing.md
Normal file
12
Plumbing.md
Normal file
@ -0,0 +1,12 @@
|
||||
# Miscelanious plumbing functions
|
||||
|
||||
## Detect version command, print version, and exit
|
||||
|
||||
``` go
|
||||
--- handle version command
|
||||
if len(os.Args) > 1 && os.Args[1] == "version" {
|
||||
fmt.Println("Keyboard version: @{version}")
|
||||
os.Exit(0)
|
||||
}
|
||||
---
|
||||
```
|
83
ReadMe.md
83
ReadMe.md
@ -5,6 +5,11 @@ Copyright [Kevin Froman](https://chaoswebs.net/) [Licensed under GPLv3](LICENSE.
|
||||
|
||||
Work in progress
|
||||
|
||||
--- version
|
||||
0.0.1
|
||||
---
|
||||
|
||||
|
||||
# Introduction
|
||||
|
||||
GoSmartKeyboard is a daemon that allows you to have a more powerful keyboarding experience. It can be used with a secondary device, such as an Android phone or a raspberry pi, or it can run locally. A seperate client binary is provided that reads from a FIFO (named pipe) and sends the data to the server. This allows you to use any program that can write to a FIFO as a source of keyboard input.
|
||||
@ -34,6 +39,7 @@ Examples of what you can do:
|
||||
* On-the-fly spell checking or translation
|
||||
* On-the-fly encryption (ex: PGP sign every message you type), isolated from the perhaps untrusted computer
|
||||
* Easy layout configuration
|
||||
* Key logging
|
||||
* Delay keystrokes by a few dozen or so milliseconds to reduce [key stroke timing biometrics](https://en.wikipedia.org/wiki/Keystroke_dynamics)
|
||||
|
||||
|
||||
@ -51,61 +57,42 @@ markdown book is actually the source code
|
||||
|
||||
# Running
|
||||
|
||||
## Installation
|
||||
|
||||
The server and client are both single static binaries. The only requirement is Linux. This software has been tested
|
||||
with typical US keyboards in QWERTY and Colemak layouts. It should work with any keyboard layout, though.
|
||||
|
||||
### Keyboard weirdness
|
||||
|
||||
Not all keyboards are equal, per the [Linux kernel documentation](https://www.kernel.org/doc/html/latest/input/event-codes.html#ev-key),
|
||||
some keyboards do not autorepeat keys. Autorepeat behavior was also found inconsistent during testing and seems to mess up the rawcapture tool.
|
||||
|
||||
## Server
|
||||
|
||||
`sudo KEYBOARD_TCP_BIND_ADDRESS=0.0 KEYBOARD_TCP_BIND_PORT=8080 ./keyboard`
|
||||
`sudo KEYBOARD_TCP_BIND_ADDRESS=127.1 KEYBOARD_TCP_BIND_PORT=8080 ./keyboard`
|
||||
|
||||
You could also run sudoless by giving your user access to uinput, but it would minimally if at all be more secure.
|
||||
|
||||
On first run it will output your authentication token. Store it in a safe place such as your password manager.
|
||||
|
||||
It is highly recommended to use SSH forwarding (preferred) or a reverse https proxy to access the server.
|
||||
|
||||
### SSH example
|
||||
|
||||
To connect with ssh, run this on the client:
|
||||
|
||||
`ssh -R 8080:localhost:8080 user@myserver`
|
||||
|
||||
|
||||
# Server Entrypoint
|
||||
### Socket file
|
||||
|
||||
It is more secure and mildly more efficient to use a unix socket file. To do this, set the environment variable `KEYBOARD_UNIX_SOCKET_PATH` to the path of the socket file. The server will create the file if it does not exist. The socket is useful for reverse proxies or SSH forwarding.
|
||||
|
||||
## Client
|
||||
|
||||
Right out of the gate, we make sure a token is provisioned. In the future we will use the system keyring.
|
||||
`KEYBOARD_AUTH=your_token_here KEYBOARD_FIFO=keyboard_control_file ./keyboard-client "ws://myserver:8080/sendkeys`
|
||||
|
||||
Then we can start the web server and listen for websocket connections.
|
||||
From here you can use any program that can write to a FIFO to send keystrokes to the server. For example, you could use `cat` to send a file to the server, or `cowsay` to send a cow message to the server.
|
||||
|
||||
``` go
|
||||
### Tools
|
||||
|
||||
--- entrypoint
|
||||
|
||||
func main(){
|
||||
|
||||
tokenBase64, _ := auth.ProvisionToken()
|
||||
if len(tokenBase64) > 0 {
|
||||
fmt.Println("This is your authentication token, it will only be shown once: " + tokenBase64)
|
||||
}
|
||||
|
||||
|
||||
server.StartServer()
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
|
||||
--- /server/main.go
|
||||
package main
|
||||
|
||||
import(
|
||||
"fmt"
|
||||
"keyboard.voidnet.tech/server"
|
||||
"keyboard.voidnet.tech/auth"
|
||||
)
|
||||
|
||||
|
||||
@{entrypoint}
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
--- set network bind globals
|
||||
|
||||
var string unixSocketPath
|
||||
var bool unixSocketPathExists
|
||||
var string tcpBindAddress
|
||||
var bool tcpBindAddressExists
|
||||
var string tcpBindPort
|
||||
var bool tcpBindPortExists
|
||||
|
||||
---
|
||||
```
|
@ -1,6 +0,0 @@
|
||||
# GoSmartKeyboard Threat Model
|
||||
|
||||
|
||||
GoSmartKeyboard assumes that it is running behind a reverse proxy that provides TLS termination. This is a common setup for web applications, and is the default configuration for the [Caddy](https://caddyserver.com/) web server. Alternatively you could use SSH port forwarding to tunnel the traffic to the server.
|
||||
|
||||
The server daemon is intended to be used on a single-user system. The goal is to prevent against well funded attackers without physical access to the machine from authenticating to the service. To prevent this, a 256 bit random token is generated and stored in a file. The token is then displayed to the user, and they are expected to copy it to store it safely. The token cannot be recovered because only a sha256 hash of the token is stored on disk.
|
@ -0,0 +1,6 @@
|
||||
# GoSmartKeyboard Threat Model
|
||||
|
||||
|
||||
GoSmartKeyboard assumes that it is running behind a reverse proxy that provides TLS termination. This is a common setup for web applications, and is the default configuration for the [Caddy](https://caddyserver.com/) web server. Alternatively you could use SSH port forwarding to tunnel the traffic to the server.
|
||||
|
||||
The server daemon is intended to be used on a single-user system. The goal is to prevent against well funded attackers without physical access to the machine from authenticating to the service. To prevent this, a 256 bit random token is generated and stored in a file. The token is then displayed to the user, and they are expected to copy it to store it safely. The token cannot be recovered because only a sha256 hash of the token is stored on disk.
|
@ -1,7 +1,6 @@
|
||||
# uinput streaming approach
|
||||
|
||||
|
||||
|
||||
``` go
|
||||
--- do streaming keylogger approach
|
||||
|
||||
|
@ -4,6 +4,50 @@ The server has two jobs, to authenticate and to accept a stream of key presses f
|
||||
|
||||
For efficiency and security we support use of a unix socket, but tcp can be used instead. In the case of TCP, the server will listen on 127.1 by default but can be configured to listen on a different address and port. In any case, it is highly recommended to run the server behind a reverse proxy supporting HTTPS such as nginx or caddy.
|
||||
|
||||
# Server Entrypoint
|
||||
|
||||
Before main execution, both the server and client check for a version command line argument. If it is present, the program will print the version and exit.
|
||||
|
||||
First, we make sure a token is provisioned. In the future we will use the system keyring.
|
||||
|
||||
Then we can start the web server and listen for websocket connections.
|
||||
|
||||
``` go
|
||||
|
||||
--- entrypoint
|
||||
|
||||
func main(){
|
||||
@{handle version command}
|
||||
tokenBase64, _ := auth.ProvisionToken()
|
||||
if len(tokenBase64) > 0 {
|
||||
fmt.Println("This is your authentication token, it will only be shown once: " + tokenBase64)
|
||||
}
|
||||
|
||||
|
||||
server.StartServer()
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
|
||||
--- /server/main.go
|
||||
package main
|
||||
|
||||
import(
|
||||
"fmt"
|
||||
"os"
|
||||
"keyboard.voidnet.tech/server"
|
||||
"keyboard.voidnet.tech/auth"
|
||||
)
|
||||
|
||||
|
||||
@{entrypoint}
|
||||
|
||||
---
|
||||
|
||||
```
|
||||
|
||||
|
||||
# Picking a socket type and setting the listener
|
||||
|
||||
|
||||
|
@ -2,12 +2,15 @@
|
||||
# Remove fenced code blocks from generated HTML files
|
||||
# We need to do this because srcweave does not support fenced code blocks
|
||||
|
||||
# We also adjust links to use .html
|
||||
|
||||
import glob
|
||||
for f in glob.glob('docs/*.html'):
|
||||
with open(f, 'r') as fin:
|
||||
lines = fin.readlines()
|
||||
|
||||
with open(f, 'w') as fout:
|
||||
for line in lines:
|
||||
if line.startswith('<p>```'):
|
||||
continue
|
||||
fout.write(line)
|
||||
fout.write(line.replace('.md', '.html').replace('.MD', '.html'))
|
Loading…
Reference in New Issue
Block a user