diff --git a/modules/api_rest/api_rest.go b/modules/api_rest/api_rest.go index 48e04832..69fd3d3b 100644 --- a/modules/api_rest/api_rest.go +++ b/modules/api_rest/api_rest.go @@ -176,6 +176,8 @@ func (mod *RestAPI) Configure() error { router.HandleFunc("/api/session", mod.sessionRoute) router.HandleFunc("/api/session/ble", mod.sessionRoute) router.HandleFunc("/api/session/ble/{mac}", mod.sessionRoute) + router.HandleFunc("/api/session/hid", mod.sessionRoute) + router.HandleFunc("/api/session/hid/{mac}", mod.sessionRoute) router.HandleFunc("/api/session/env", mod.sessionRoute) router.HandleFunc("/api/session/gateway", mod.sessionRoute) router.HandleFunc("/api/session/interface", mod.sessionRoute) diff --git a/modules/api_rest/api_rest_controller.go b/modules/api_rest/api_rest_controller.go index 72e94be3..e734739b 100644 --- a/modules/api_rest/api_rest_controller.go +++ b/modules/api_rest/api_rest_controller.go @@ -61,7 +61,7 @@ func (mod *RestAPI) showSession(w http.ResponseWriter, r *http.Request) { mod.toJSON(w, session.I) } -func (mod *RestAPI) showBle(w http.ResponseWriter, r *http.Request) { +func (mod *RestAPI) showBLE(w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) mac := strings.ToLower(params["mac"]) @@ -74,6 +74,19 @@ func (mod *RestAPI) showBle(w http.ResponseWriter, r *http.Request) { } } +func (mod *RestAPI) showHID(w http.ResponseWriter, r *http.Request) { + params := mux.Vars(r) + mac := strings.ToLower(params["mac"]) + + if mac == "" { + mod.toJSON(w, session.I.HID) + } else if dev, found := session.I.HID.Get(mac); found { + mod.toJSON(w, dev) + } else { + http.Error(w, "Not Found", 404) + } +} + func (mod *RestAPI) showEnv(w http.ResponseWriter, r *http.Request) { mod.toJSON(w, session.I.Env) } @@ -90,7 +103,7 @@ func (mod *RestAPI) showModules(w http.ResponseWriter, r *http.Request) { mod.toJSON(w, session.I.Modules) } -func (mod *RestAPI) showLan(w http.ResponseWriter, r *http.Request) { +func (mod *RestAPI) showLAN(w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) mac := strings.ToLower(params["mac"]) @@ -212,7 +225,7 @@ func (mod *RestAPI) sessionRoute(w http.ResponseWriter, r *http.Request) { mod.showModules(w, r) case strings.HasPrefix(path, "/api/session/lan"): - mod.showLan(w, r) + mod.showLAN(w, r) case path == "/api/session/options": mod.showOptions(w, r) @@ -224,7 +237,10 @@ func (mod *RestAPI) sessionRoute(w http.ResponseWriter, r *http.Request) { mod.showStartedAt(w, r) case strings.HasPrefix(path, "/api/session/ble"): - mod.showBle(w, r) + mod.showBLE(w, r) + + case strings.HasPrefix(path, "/api/session/hid"): + mod.showHID(w, r) case strings.HasPrefix(path, "/api/session/wifi"): mod.showWiFi(w, r) diff --git a/modules/hid/hid.go b/modules/hid/hid.go index 6f535413..f0f30af3 100644 --- a/modules/hid/hid.go +++ b/modules/hid/hid.go @@ -38,7 +38,6 @@ type HIDRecon struct { /* TODO: -- make session.Session.HID JSON serializable for the API - fix compilation for unsupported platforms - update docs - test test test diff --git a/network/hid.go b/network/hid.go index e84c73ba..bb8e3605 100644 --- a/network/hid.go +++ b/network/hid.go @@ -1,6 +1,7 @@ package network import ( + "encoding/json" "sync" "time" ) @@ -15,6 +16,10 @@ type HID struct { lostCb HIDDevLostCallback } +type hidJSON struct { + Devices []*HIDDevice `json:"devices"` +} + func NewHID(newcb HIDDevNewCallback, lostcb HIDDevLostCallback) *HID { return &HID{ devices: make(map[string]*HIDDevice), @@ -23,6 +28,18 @@ func NewHID(newcb HIDDevNewCallback, lostcb HIDDevLostCallback) *HID { } } +func (h *HID) MarshalJSON() ([]byte, error) { + doc := hidJSON{ + Devices: make([]*HIDDevice, 0), + } + + for _, dev := range h.devices { + doc.Devices = append(doc.Devices, dev) + } + + return json.Marshal(doc) +} + func (b *HID) Get(id string) (dev *HIDDevice, found bool) { b.RLock() defer b.RUnlock() diff --git a/network/hid_device.go b/network/hid_device.go index 8db4ca7b..d923ffc2 100644 --- a/network/hid_device.go +++ b/network/hid_device.go @@ -1,6 +1,7 @@ package network import ( + "encoding/json" "fmt" "sort" "strings" @@ -45,6 +46,13 @@ type HIDDevice struct { payloadsSz uint64 } +type hidDeviceJSON struct { + LastSeen time.Time `json:"last_seen"` + Type string `json:"type"` + Address string `json:"address"` + Channels []string `json:"channels"` +} + func NormalizeHIDAddress(address string) string { parts := strings.Split(address, ":") for i, p := range parts { @@ -81,6 +89,16 @@ func NewHIDDevice(address []byte, channel int, payload []byte) *HIDDevice { return dev } +func (dev *HIDDevice) MarshalJSON() ([]byte, error) { + doc := hidDeviceJSON{ + LastSeen: dev.LastSeen, + Type: dev.Type.String(), + Address: dev.Address, + Channels: dev.ChannelsList(), + } + return json.Marshal(doc) +} + func (dev *HIDDevice) AddChannel(ch int) { dev.Lock() defer dev.Unlock() @@ -88,7 +106,7 @@ func (dev *HIDDevice) AddChannel(ch int) { dev.channels[ch] = true } -func (dev *HIDDevice) Channels() string { +func (dev *HIDDevice) ChannelsList() []string { dev.Lock() defer dev.Unlock() @@ -98,7 +116,12 @@ func (dev *HIDDevice) Channels() string { } sort.Strings(chans) - return strings.Join(chans, ",") + + return chans +} + +func (dev *HIDDevice) Channels() string { + return strings.Join(dev.ChannelsList(), ",") } // credits to https://github.com/insecurityofthings/jackit/tree/master/jackit/plugins