Moved control commands to their own file
Delimit all messages to fix fifo race condition
This commit is contained in:
parent
a8574dfebe
commit
b941235007
28
Client.md
28
Client.md
@ -7,12 +7,11 @@ When the GoSmartKeyboard client is started, it does the following:
|
||||
3. Connect to the server.
|
||||
4 Send the auth token to the server.
|
||||
5. If the server responds with "authenticated", we start reading keys from stdin and sending them to the server until EOF.
|
||||
6. If KEYBOARD_FIFO is specified as an environment variable, we read from the path specified there instead as a named pipe.
|
||||
|
||||
5.1 If the environment variable `KEYBOARD_FIFO` is set, we read from the path specified there instead as a named pipe.
|
||||
5.2 Regardless, each message is sent to the server with the prefix `@{payload delimiter}`.
|
||||
|
||||
``` go
|
||||
--- handle client command
|
||||
|
||||
if len(os.Args) > 1 {
|
||||
@{get client fifo input file from environment}
|
||||
@{setup client}
|
||||
@ -36,6 +35,7 @@ The base64 authentication token is loaded from the environment variable `KEYBOAR
|
||||
|
||||
--- setup client
|
||||
|
||||
@{handle version command}
|
||||
@{load connection URL from second CLI argument}
|
||||
@{get authTokenInput from environment}
|
||||
@{add xdotool if non qwerty function}
|
||||
@ -91,23 +91,24 @@ if !strings.HasPrefix(connectionURL, "ws://") && !strings.HasPrefix(connectionUR
|
||||
|
||||
## Sending keys from a named pipe
|
||||
|
||||
|
||||
We create a fifo and then continuously read from it in a loop.
|
||||
|
||||
``` go
|
||||
--- start client with fifo
|
||||
|
||||
|
||||
var inputString string
|
||||
|
||||
syscall.Mkfifo(clientFifoInputFile, syscall.S_IFIFO|0666)
|
||||
|
||||
inputString := ""
|
||||
for {
|
||||
input, err := ioutil.ReadFile(clientFifoInputFile)
|
||||
readData, err := ioutil.ReadFile(clientFifoInputFile)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
inputString = addXDoToolIfNonQWERTY(string(input))
|
||||
input = []byte(inputString)
|
||||
|
||||
inputString = addXDoToolIfNonQWERTY(string(readData))
|
||||
input := []byte("@{payload delimiter}" + inputString)
|
||||
if len(input) > 0 {
|
||||
fmt.Println("send" + strings.Replace(string(input), " ", "space", 10))
|
||||
err = client.WriteMessage(websocket.TextMessage, input)
|
||||
if err != nil {
|
||||
log.Fatal("write:", err)
|
||||
@ -146,8 +147,7 @@ for {
|
||||
}
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println("send" + strings.Replace(key, " ", "space", 10))
|
||||
err = client.WriteMessage(websocket.TextMessage, []byte(key))
|
||||
err = client.WriteMessage(websocket.TextMessage, []byte("@{payload delimiter}" + key))
|
||||
if err != nil {
|
||||
log.Fatal("write:", err)
|
||||
}
|
||||
@ -164,13 +164,13 @@ for {
|
||||
--- add xdotool if non qwerty function --- noWeave
|
||||
addXDoToolIfNonQWERTY := func(message string)(string) {
|
||||
|
||||
if strings.HasPrefix(message, "{kb_cmd:xdotool}:") {
|
||||
if strings.HasPrefix(message, "@{use xdotool cmd}") {
|
||||
return message
|
||||
}
|
||||
for _, char := range message {
|
||||
if char < 32 || char > 126 {
|
||||
if char != 8 && char != 9 && char != 10 {
|
||||
return "{kb_cmd:xdotool}:" + message
|
||||
return "@{use xdotool cmd}" + message
|
||||
}
|
||||
}
|
||||
}
|
||||
|
4
Makefile
4
Makefile
@ -1,11 +1,13 @@
|
||||
weave:
|
||||
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 \
|
||||
server/StringCommands.md
|
||||
Client.md tools/Tools.md tools/Editor.md tools/Input.md tools/RawCapture.md tools/TUI.md
|
||||
util/clean.py
|
||||
tangle:
|
||||
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 security/ThreatModel.md Client.md tools/Tools.md tools/Editor.md tools/Input.md \
|
||||
server/Server.md server/Streaming.md server/Sendkeys.md server/XdotoolCommands.md server/StringCommands.md \
|
||||
security/ThreatModel.md Client.md tools/Tools.md tools/Editor.md tools/Input.md \
|
||||
tools/RawCapture.md tools/TUI.md
|
||||
clean:
|
||||
rm -rf docs
|
||||
|
@ -6,7 +6,7 @@ Copyright [Kevin Froman](https://chaoswebs.net/) [Licensed under GPLv3](LICENSE.
|
||||
Work in progress
|
||||
|
||||
--- version
|
||||
0.0.1
|
||||
2.0.0
|
||||
---
|
||||
|
||||
|
||||
|
@ -5,14 +5,14 @@
|
||||
--- do streaming keylogger approach
|
||||
|
||||
key := ""
|
||||
if strings.HasPrefix(message_string, "{KEYDWN}") {
|
||||
key = strings.TrimPrefix(string(message_string), "{KEYDWN}")
|
||||
if strings.HasPrefix(message_string, "@{keydown cmd}") {
|
||||
key = strings.TrimPrefix(string(message_string), "@{keydown cmd}")
|
||||
k.Write(1, key)
|
||||
} else if strings.HasPrefix(message_string, "{KEYUP}") {
|
||||
key = strings.TrimPrefix(string(message_string), "{KEYUP}")
|
||||
} else if strings.HasPrefix(message_string, "@{keyup cmd}") {
|
||||
key = strings.TrimPrefix(string(message_string), "@{keyup cmd}")
|
||||
k.Write(0, key)
|
||||
} else if strings.HasPrefix(message_string, "{KEYHLD}") {
|
||||
key = strings.TrimPrefix(string(message_string), "{KEYHLD}")
|
||||
} else if strings.HasPrefix(message_string, "@{keyheld cmd}") {
|
||||
key = strings.TrimPrefix(string(message_string), "@{keyheld cmd}")
|
||||
k.Write(2, key)
|
||||
} else{
|
||||
for _, key := range message_string {
|
||||
|
@ -102,7 +102,6 @@ package server
|
||||
|
||||
import(
|
||||
"net"
|
||||
"time"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
@ -6,7 +6,7 @@ Most of the time, we can use the keylogger library (which uses uinput) to effeci
|
||||
|
||||
xdotool spawns a new process for each keypress, so it's not as effecient as keylogger.
|
||||
|
||||
To specify xdotool usage, the client should send a message with the format `{kb_cmd:xdotool}:message` where message is a utf-8 string.
|
||||
To specify xdotool usage, the client should send a message with the format `@{use xdotool cmd}message` where message is a utf-8 string.
|
||||
|
||||
``` go
|
||||
--- streaming keyboard input
|
||||
@ -67,10 +67,12 @@ func clientConnected(w http.ResponseWriter, r *http.Request) {
|
||||
if message_string == "" {
|
||||
message_string = "\n"
|
||||
}
|
||||
|
||||
for _, part := range strings.Split(message_string, "@{payload delimiter}") {
|
||||
message_string = part
|
||||
@{send keys to system}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
```
|
||||
|
37
server/StringCommands.md
Normal file
37
server/StringCommands.md
Normal file
@ -0,0 +1,37 @@
|
||||
# String Commands
|
||||
|
||||
To control key events and the input method we use special command strings at the beginning of a message.
|
||||
|
||||
They are as follows:
|
||||
|
||||
Payload delimiter:
|
||||
--- payload delimiter
|
||||
{KB_MSG}
|
||||
---
|
||||
|
||||
|
||||
Xdotool typing:
|
||||
|
||||
--- use xdotool cmd
|
||||
{KEYDOXDOTOOL}:
|
||||
---
|
||||
|
||||
Xdotool key command:
|
||||
|
||||
--- use xdotool key cmd
|
||||
{KEYDOXTOOLKEY}:
|
||||
---
|
||||
|
||||
Send keys commands:
|
||||
|
||||
--- keydown cmd
|
||||
{KEYDWN}
|
||||
---
|
||||
|
||||
--- keyup cmd
|
||||
{KEYUP}
|
||||
---
|
||||
|
||||
--- keyheld cmd
|
||||
{KEYHLD}
|
||||
---
|
@ -2,14 +2,14 @@
|
||||
|
||||
Currently the two commands are `type` and `key`. `type` is used to type a character and `key` is used to type a special character like `Enter` or `Backspace`.
|
||||
|
||||
`type` is specified by '{kb_cmd:xdotool}:', and `key` is specified by '{kb_cmd:kxdotool}:'. If the command is not specified and `alwaysUseXdotool` is set from the environment variable, it will default to `type`.
|
||||
`type` is specified by '@{use xdotool cmd}', and `key` is specified by '@{use xdotool key cmd}'. If the command is not specified and `alwaysUseXdotool` is set from the environment variable, it will default to `type`.
|
||||
|
||||
|
||||
``` go
|
||||
--- handle xdotoool commands
|
||||
|
||||
if alwaysUseXdotool || strings.HasPrefix(message_string, "{kb_cmd:xdotool}:") {
|
||||
message_string = strings.TrimPrefix(message_string, "{kb_cmd:xdotool}:")
|
||||
if alwaysUseXdotool || strings.HasPrefix(message_string, "@{use xdotool cmd}") {
|
||||
message_string = strings.TrimPrefix(message_string, "@{use xdotool cmd}")
|
||||
if message_string == "" {
|
||||
message_string = "\n"
|
||||
}
|
||||
@ -37,8 +37,8 @@ if alwaysUseXdotool || strings.HasPrefix(message_string, "{kb_cmd:xdotool}:") {
|
||||
doXDoTool("type", message_string)
|
||||
}
|
||||
continue
|
||||
} else if strings.HasPrefix(message_string, "{kb_cmd:kxdotool}:") {
|
||||
message_string = strings.TrimPrefix(message_string, "{kb_cmd:kxdotool}:")
|
||||
} else if strings.HasPrefix(message_string, "@{use xdotool key cmd}") {
|
||||
message_string = strings.TrimPrefix(message_string, "@{use xdotool key cmd}")
|
||||
if message_string == "" {
|
||||
message_string = "\n"
|
||||
}
|
||||
|
@ -248,13 +248,13 @@ try:
|
||||
except KeyError:
|
||||
print("Unknown key: " + str(e_code))
|
||||
if event.value == 1:
|
||||
key_str = "{KEYDWN}" + key_str
|
||||
key_str = "@{keydown cmd}" + key_str
|
||||
log.append(e_code)
|
||||
quit_if_necessry(log)
|
||||
elif event.value == 0:
|
||||
key_str = "{KEYUP}" + key_str
|
||||
key_str = "@{keyup cmd}" + key_str
|
||||
elif event.value == 2:
|
||||
key_str = "{KEYHLD}" + key_str
|
||||
key_str = "@{keyheld cmd}" + key_str
|
||||
else:
|
||||
print("Unknown value: " + str(event.value))
|
||||
continue
|
||||
|
Loading…
Reference in New Issue
Block a user