Compare commits

..

No commits in common. "a2e9ce6aeb8c9b7fe9bf08f16d8cabc33003da8f" and "3d9a31f4af05adb71a7be368307554a4e8b86450" have entirely different histories.

9 changed files with 34 additions and 73 deletions

View File

@ -7,11 +7,12 @@ 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.
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}`.
6. If KEYBOARD_FIFO is specified as an environment variable, we read from the path specified there instead as a named pipe.
``` go
--- handle client command
if len(os.Args) > 1 {
@{get client fifo input file from environment}
@{setup client}
@ -35,7 +36,6 @@ 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,24 +91,23 @@ 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 {
readData, err := ioutil.ReadFile(clientFifoInputFile)
input, err := ioutil.ReadFile(clientFifoInputFile)
if err != nil {
log.Fatal(err)
}
inputString = addXDoToolIfNonQWERTY(string(readData))
input := []byte(inputString)
inputString = addXDoToolIfNonQWERTY(string(input))
input = []byte(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)
@ -147,6 +146,7 @@ for {
}
log.Fatal(err)
}
fmt.Println("send" + strings.Replace(key, " ", "space", 10))
err = client.WriteMessage(websocket.TextMessage, []byte(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, "@{use xdotool cmd}") {
if strings.HasPrefix(message, "{kb_cmd:xdotool}:") {
return message
}
for _, char := range message {
if char < 32 || char > 126 {
if char != 8 && char != 9 && char != 10 {
return "@{use xdotool cmd}" + message
return "{kb_cmd:xdotool}:" + message
}
}
}

View File

@ -1,13 +1,11 @@
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 server/StringCommands.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 security/ThreatModel.md Client.md tools/Tools.md tools/Editor.md tools/Input.md \
tools/RawCapture.md tools/TUI.md
clean:
rm -rf docs

View File

@ -6,7 +6,7 @@ Copyright [Kevin Froman](https://chaoswebs.net/) [Licensed under GPLv3](LICENSE.
Work in progress
--- version
3.0.0
0.0.1
---

View File

@ -5,14 +5,14 @@
--- do streaming keylogger approach
key := ""
if strings.HasPrefix(message_string, "@{keydown cmd}") {
key = strings.TrimPrefix(string(message_string), "@{keydown cmd}")
if strings.HasPrefix(message_string, "{KEYDWN}") {
key = strings.TrimPrefix(string(message_string), "{KEYDWN}")
k.Write(1, key)
} else if strings.HasPrefix(message_string, "@{keyup cmd}") {
key = strings.TrimPrefix(string(message_string), "@{keyup cmd}")
} else if strings.HasPrefix(message_string, "{KEYUP}") {
key = strings.TrimPrefix(string(message_string), "{KEYUP}")
k.Write(0, key)
} else if strings.HasPrefix(message_string, "@{keyheld cmd}") {
key = strings.TrimPrefix(string(message_string), "@{keyheld cmd}")
} else if strings.HasPrefix(message_string, "{KEYHLD}") {
key = strings.TrimPrefix(string(message_string), "{KEYHLD}")
k.Write(2, key)
} else{
for _, key := range message_string {

View File

@ -102,6 +102,7 @@ package server
import(
"net"
"time"
"os"
"os/exec"
"strings"

View File

@ -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 `@{use xdotool cmd}message` where message is a utf-8 string.
To specify xdotool usage, the client should send a message with the format `{kb_cmd:xdotool}:message` where message is a utf-8 string.
``` go
--- streaming keyboard input
@ -57,6 +57,7 @@ func clientConnected(w http.ResponseWriter, r *http.Request) {
c.WriteMessage(websocket.TextMessage, []byte("authenticated"))
for {
time.Sleep(25 * time.Millisecond)
_, message, err := c.ReadMessage()
if err != nil {
log.Println("read:", err)
@ -67,10 +68,8 @@ 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}
}
@{send keys to system}
}
}

View File

@ -1,37 +0,0 @@
# 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}
---

View File

@ -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 '@{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`.
`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`.
``` go
--- handle xdotoool commands
if alwaysUseXdotool || strings.HasPrefix(message_string, "@{use xdotool cmd}") {
message_string = strings.TrimPrefix(message_string, "@{use xdotool cmd}")
if alwaysUseXdotool || strings.HasPrefix(message_string, "{kb_cmd:xdotool}:") {
message_string = strings.TrimPrefix(message_string, "{kb_cmd:xdotool}:")
if message_string == "" {
message_string = "\n"
}
@ -37,8 +37,8 @@ if alwaysUseXdotool || strings.HasPrefix(message_string, "@{use xdotool cmd}") {
doXDoTool("type", message_string)
}
continue
} else if strings.HasPrefix(message_string, "@{use xdotool key cmd}") {
message_string = strings.TrimPrefix(message_string, "@{use xdotool key cmd}")
} else if strings.HasPrefix(message_string, "{kb_cmd:kxdotool}:") {
message_string = strings.TrimPrefix(message_string, "{kb_cmd:kxdotool}:")
if message_string == "" {
message_string = "\n"
}

View File

@ -248,13 +248,13 @@ try:
except KeyError:
print("Unknown key: " + str(e_code))
if event.value == 1:
key_str = "@{payload delimiter}@{keydown cmd}" + key_str
key_str = "{KEYDWN}" + key_str
log.append(e_code)
quit_if_necessry(log)
elif event.value == 0:
key_str = "@{payload delimiter}@{keyup cmd}" + key_str
key_str = "{KEYUP}" + key_str
elif event.value == 2:
key_str = "@{payload delimiter}@{keyheld cmd}" + key_str
key_str = "{KEYHLD}" + key_str
else:
print("Unknown value: " + str(event.value))
continue