Compare commits

..

No commits in common. "d48ca89d20d98d93379b0d0555d390588a822797" and "9f44a9cffdd25267a1041d8b3ad79aab86c3b02f" have entirely different histories.

8 changed files with 50 additions and 46 deletions

View File

@ -16,7 +16,7 @@ When the GoSmartKeyboard client is started, it does the following:
if len(os.Args) > 1 {
@{get client fifo input file from environment}
@{setup client}
if clientFifoInputFileEnvExists {
if clientFifoInputFileExists {
@{start client with fifo}
os.Exit(0)
}
@ -97,8 +97,6 @@ if !strings.HasPrefix(connectionURL, "ws://") && !strings.HasPrefix(connectionUR
var inputString string
syscall.Mkfifo(clientFifoInputFile, syscall.S_IFIFO|0666)
for {
input, err := ioutil.ReadFile(clientFifoInputFile)
if err != nil {
@ -120,6 +118,7 @@ for {
```
## Sending keys from stdin
@ -188,7 +187,6 @@ package main
import (
"strings"
"io/ioutil"
"syscall"
"io"
"bufio"
"log"

View File

@ -24,13 +24,14 @@ We use sha3 to hash authentication tokens. It is not in the crypto standard libr
---
# keylogger
# sendkeys
We use keylogger to get keyboard input on the client and simulate keystrokes on the server.
--- keylogger import string
In order to avoid coding key press simulation for every major platform, we use [sendkeys](https://github.com/yunginnanet/sendkeys). This is a cross-platform library that uses the OS's native key press simulation using [keybd_event](https://github.com/micmonay/keybd_event)
"github.com/MarinX/keylogger"
--- sendkeys import string
"github.com/EgosOwn/sendkeys"
---

View File

@ -7,7 +7,7 @@ Some users may always want xdotool, see the [Streaming.md](Streaming.md) file fo
``` go
--- always use xdotool environment variable
var alwaysUseXdotool = false
var alwaysUseXdotool := false
alwaysUseXdotoolEnv, alwaysUseXdotoolExists := os.LookupEnv("KEYBOARD_ALWAYS_USE_XDOTOOL")
if alwaysUseXdotoolExists {
if alwaysUseXdotoolEnv == "true" || alwaysUseXdotoolEnv == "1" {
@ -46,7 +46,7 @@ authTokenInput, authTokenInputExists := os.LookupEnv("KEYBOARD_AUTH")
--- get client fifo input file from environment
clientFifoInputFile, clientFifoInputFileEnvExists := os.LookupEnv("KEYBOARD_FIFO")
clientFifoInputFile, clientFifoInputFileExists := os.LookupEnv("KEYBOARD_FIFO")
---

View File

@ -1,25 +1,39 @@
# uinput streaming approach
# Send keys streaming approach
When applicable to use send keys, we need to detect Enter, Tab, and BackSpace and use the applicatble functions.
We test if it meets the characterRegex, and if so we iterate for each character and send the corresponding key.
Otherwise we send the entire string at once.
``` go
--- do streaming keylogger approach
key := ""
if strings.HasPrefix(message_string, "{KEYDWN}") {
key = strings.TrimPrefix(string(message_string), "{KEYDWN}")
k.Write(1, key)
} else if strings.HasPrefix(message_string, "{KEYUP}") {
key = strings.TrimPrefix(string(message_string), "{KEYUP}")
k.Write(0, key)
} else{
for _, key := range message_string {
// write once will simulate keyboard press/release, for long press or release, lookup at Write
k.WriteOnce(string(key))
--- do streaming sendkeys approach
if characterRegex.MatchString(message_string) {
for _, character := range message_string {
charString := string(character)
if charString == "\n" {
keyboard.Enter()
continue
}
if charString == "\t" {
keyboard.Tab()
continue
}
if charString == "\b" {
keyboard.BackSpace()
continue
}
err = keyboard.Type(charString)
if err != nil {
log.Println("type:", err)
}
continue
}
continue
}
err = keyboard.Type(message_string)
if err != nil {
log.Println("type:", err)
}
---
```

View File

@ -68,7 +68,7 @@ import(
"log"
"keyboard.voidnet.tech/auth"
@{gorilla/websocket import string}
@{keylogger import string}
@{sendkeys import string}
)
var listener net.Listener

View File

@ -2,9 +2,9 @@
We use the Gorilla websocket library to handle the websocket connection.
Most of the time, we can use the keylogger library (which uses uinput) to effeciently press keys. However, if we need to send a character that keylogger doesn't know about, we can use the xdotool command. xdotool is also useful if one does not want to use root.
Most of the time, we can use sendkeys (which uses libinput) to effeciently press keys. However, if we need to send a character that sendkeys doesn't know about, we can use the xdotool command. xdotool is also useful if one does not want to use root.
xdotool spawns a new process for each keypress, so it's not as effecient as keylogger.
xdotool spawns a new process for each keypress, so it's not as effecient as sendkeys.
To specify xdotool usage, the client should send a message with the format `{kb_cmd:xdotool}:message` where message is a utf-8 string.
@ -14,20 +14,7 @@ To specify xdotool usage, the client should send a message with the format `{kb_
func clientConnected(w http.ResponseWriter, r *http.Request) {
// regex if string has characters we need to convert to key presses
characterRegex, _ := regexp.Compile(`[^\x08]\x08|\t|\n`)
// find keyboard device, does not require a root permission
keyboard := keylogger.FindKeyboardDevice()
// check if we found a path to keyboard
if len(keyboard) <= 0 {
return
}
k, err := keylogger.New(keyboard)
if err != nil {
return
}
defer k.Close()
keyboard, err := sendkeys.NewKBWrapWithOptions(sendkeys.Noisy)
@{always use xdotool environment variable}
@ -97,7 +84,7 @@ doXDoTool := func(command string, keys string)(err error) {
@{handle xdotoool commands}
@{do streaming keylogger approach}
@{do streaming sendkeys approach}
---
```

View File

@ -4,6 +4,10 @@ Currently the two commands are `type` and `key`. `type` is used to type a charac
`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
``` go
``` go
--- handle xdotoool commands

View File

@ -19,7 +19,7 @@ import (
func main(){
var input string
@{get client input file from environment}
@{get client fifo input file from environment}
if ! clientFifoInputFileExists {
os.Exit(1)
}