mirror of
https://github.com/bettercap/bettercap
synced 2025-07-14 09:03:39 -07:00
new: ui module to install/update the UI from github releases
This commit is contained in:
parent
92758d7f7e
commit
fbcaf2989f
2 changed files with 195 additions and 2 deletions
|
@ -24,6 +24,7 @@ import (
|
||||||
"github.com/bettercap/bettercap/modules/syn_scan"
|
"github.com/bettercap/bettercap/modules/syn_scan"
|
||||||
"github.com/bettercap/bettercap/modules/tcp_proxy"
|
"github.com/bettercap/bettercap/modules/tcp_proxy"
|
||||||
"github.com/bettercap/bettercap/modules/ticker"
|
"github.com/bettercap/bettercap/modules/ticker"
|
||||||
|
"github.com/bettercap/bettercap/modules/ui"
|
||||||
"github.com/bettercap/bettercap/modules/update"
|
"github.com/bettercap/bettercap/modules/update"
|
||||||
"github.com/bettercap/bettercap/modules/wifi"
|
"github.com/bettercap/bettercap/modules/wifi"
|
||||||
"github.com/bettercap/bettercap/modules/wol"
|
"github.com/bettercap/bettercap/modules/wol"
|
||||||
|
@ -36,7 +37,6 @@ func LoadModules(sess *session.Session) {
|
||||||
sess.Register(arp_spoof.NewArpSpoofer(sess))
|
sess.Register(arp_spoof.NewArpSpoofer(sess))
|
||||||
sess.Register(api_rest.NewRestAPI(sess))
|
sess.Register(api_rest.NewRestAPI(sess))
|
||||||
sess.Register(ble.NewBLERecon(sess))
|
sess.Register(ble.NewBLERecon(sess))
|
||||||
sess.Register(caplets.NewCapletsModule(sess))
|
|
||||||
sess.Register(dhcp6_spoof.NewDHCP6Spoofer(sess))
|
sess.Register(dhcp6_spoof.NewDHCP6Spoofer(sess))
|
||||||
sess.Register(net_recon.NewDiscovery(sess))
|
sess.Register(net_recon.NewDiscovery(sess))
|
||||||
sess.Register(dns_spoof.NewDNSSpoofer(sess))
|
sess.Register(dns_spoof.NewDNSSpoofer(sess))
|
||||||
|
@ -54,8 +54,11 @@ func LoadModules(sess *session.Session) {
|
||||||
sess.Register(syn_scan.NewSynScanner(sess))
|
sess.Register(syn_scan.NewSynScanner(sess))
|
||||||
sess.Register(tcp_proxy.NewTcpProxy(sess))
|
sess.Register(tcp_proxy.NewTcpProxy(sess))
|
||||||
sess.Register(ticker.NewTicker(sess))
|
sess.Register(ticker.NewTicker(sess))
|
||||||
sess.Register(update.NewUpdateModule(sess))
|
|
||||||
sess.Register(wifi.NewWiFiModule(sess))
|
sess.Register(wifi.NewWiFiModule(sess))
|
||||||
sess.Register(wol.NewWOL(sess))
|
sess.Register(wol.NewWOL(sess))
|
||||||
sess.Register(hid.NewHIDRecon(sess))
|
sess.Register(hid.NewHIDRecon(sess))
|
||||||
|
|
||||||
|
sess.Register(caplets.NewCapletsModule(sess))
|
||||||
|
sess.Register(update.NewUpdateModule(sess))
|
||||||
|
sess.Register(ui.NewUIModule(sess))
|
||||||
}
|
}
|
||||||
|
|
190
modules/ui/ui.go
Normal file
190
modules/ui/ui.go
Normal file
|
@ -0,0 +1,190 @@
|
||||||
|
package ui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
|
"github.com/bettercap/bettercap/session"
|
||||||
|
|
||||||
|
"github.com/google/go-github/github"
|
||||||
|
|
||||||
|
"github.com/evilsocket/islazy/fs"
|
||||||
|
"github.com/evilsocket/islazy/tui"
|
||||||
|
"github.com/evilsocket/islazy/zip"
|
||||||
|
)
|
||||||
|
|
||||||
|
var versionParser = regexp.MustCompile(`name:"ui",version:"([^"]+)"`)
|
||||||
|
|
||||||
|
type UIModule struct {
|
||||||
|
session.SessionModule
|
||||||
|
client *github.Client
|
||||||
|
tmpFile string
|
||||||
|
basePath string
|
||||||
|
uiPath string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUIModule(s *session.Session) *UIModule {
|
||||||
|
mod := &UIModule{
|
||||||
|
SessionModule: session.NewSessionModule("ui", s),
|
||||||
|
client: github.NewClient(nil),
|
||||||
|
}
|
||||||
|
|
||||||
|
mod.AddParam(session.NewStringParameter("ui.basepath",
|
||||||
|
"/usr/local/share/bettercap/",
|
||||||
|
"",
|
||||||
|
"UI base installation path."))
|
||||||
|
|
||||||
|
mod.AddParam(session.NewStringParameter("ui.tmpfile",
|
||||||
|
filepath.Join(os.TempDir(), "ui.zip"),
|
||||||
|
"",
|
||||||
|
"Temporary file to use while downloading UI updates."))
|
||||||
|
|
||||||
|
mod.AddHandler(session.NewModuleHandler("ui.version", "",
|
||||||
|
"Print the currently installed UI version.",
|
||||||
|
func(args []string) error {
|
||||||
|
return mod.showVersion()
|
||||||
|
}))
|
||||||
|
|
||||||
|
mod.AddHandler(session.NewModuleHandler("ui.update", "",
|
||||||
|
"Download the latest available version of the UI and install it.",
|
||||||
|
func(args []string) error {
|
||||||
|
return mod.Start()
|
||||||
|
}))
|
||||||
|
|
||||||
|
return mod
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mod *UIModule) Name() string {
|
||||||
|
return "ui"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mod *UIModule) Description() string {
|
||||||
|
return "A module to manage bettercap's UI updates and installed version."
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mod *UIModule) Author() string {
|
||||||
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mod *UIModule) Configure() (err error) {
|
||||||
|
if err, mod.basePath = mod.StringParam("ui.basepath"); err != nil {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
mod.uiPath = filepath.Join(mod.basePath, "ui")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err, mod.tmpFile = mod.StringParam("ui.tmpfile"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mod *UIModule) Stop() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mod *UIModule) download(version, url string) error {
|
||||||
|
if !fs.Exists(mod.basePath) {
|
||||||
|
mod.Warning("creating ui install path %s ...", mod.basePath)
|
||||||
|
if err := os.MkdirAll(mod.basePath, os.ModePerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := os.Create(mod.tmpFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer out.Close()
|
||||||
|
defer os.Remove(mod.tmpFile)
|
||||||
|
|
||||||
|
mod.Info("downloading ui %s from %s ...", tui.Bold(version), url)
|
||||||
|
|
||||||
|
resp, err := http.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if _, err := io.Copy(out, resp.Body); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if fs.Exists(mod.uiPath) {
|
||||||
|
mod.Warning("removing previously installed UI from %s ...", mod.uiPath)
|
||||||
|
if err := os.RemoveAll(mod.uiPath); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod.Info("installing to %s ...", mod.uiPath)
|
||||||
|
|
||||||
|
if _, err = zip.Unzip(mod.tmpFile, mod.basePath); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
mod.Info("installation complete, you can now run the %s (or https-ui) caplet to start the UI.", tui.Bold("http-ui"))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mod *UIModule) showVersion() error {
|
||||||
|
if err := mod.Configure(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !fs.Exists(mod.uiPath) {
|
||||||
|
return fmt.Errorf("path %s does not exist, ui not installed", mod.uiPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
search := filepath.Join(mod.uiPath, "/main.*.js")
|
||||||
|
matches, err := filepath.Glob(search)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if len(matches) == 0 {
|
||||||
|
return fmt.Errorf("can't find any main.*.js files in %s", mod.uiPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, filename := range matches {
|
||||||
|
if raw, err := ioutil.ReadFile(filename); err != nil {
|
||||||
|
return err
|
||||||
|
} else if m := versionParser.FindStringSubmatch(string(raw)); m != nil {
|
||||||
|
version := m[1]
|
||||||
|
mod.Info("v%s", version)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("can't parse version from %s", search)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mod *UIModule) Start() error {
|
||||||
|
if err := mod.Configure(); err != nil {
|
||||||
|
return err
|
||||||
|
} else if err := mod.SetRunning(true, nil); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer mod.SetRunning(false, nil)
|
||||||
|
|
||||||
|
mod.Info("checking latest stable release ...")
|
||||||
|
|
||||||
|
if releases, _, err := mod.client.Repositories.ListReleases(context.Background(), "bettercap", "ui", nil); err == nil {
|
||||||
|
latest := releases[0]
|
||||||
|
for _, a := range latest.Assets {
|
||||||
|
if *a.Name == "ui.zip" {
|
||||||
|
return mod.download(*latest.TagName, *a.BrowserDownloadURL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mod.Error("error while fetching latest release info from GitHub: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue