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/tcp_proxy"
|
||||
"github.com/bettercap/bettercap/modules/ticker"
|
||||
"github.com/bettercap/bettercap/modules/ui"
|
||||
"github.com/bettercap/bettercap/modules/update"
|
||||
"github.com/bettercap/bettercap/modules/wifi"
|
||||
"github.com/bettercap/bettercap/modules/wol"
|
||||
|
@ -36,7 +37,6 @@ func LoadModules(sess *session.Session) {
|
|||
sess.Register(arp_spoof.NewArpSpoofer(sess))
|
||||
sess.Register(api_rest.NewRestAPI(sess))
|
||||
sess.Register(ble.NewBLERecon(sess))
|
||||
sess.Register(caplets.NewCapletsModule(sess))
|
||||
sess.Register(dhcp6_spoof.NewDHCP6Spoofer(sess))
|
||||
sess.Register(net_recon.NewDiscovery(sess))
|
||||
sess.Register(dns_spoof.NewDNSSpoofer(sess))
|
||||
|
@ -54,8 +54,11 @@ func LoadModules(sess *session.Session) {
|
|||
sess.Register(syn_scan.NewSynScanner(sess))
|
||||
sess.Register(tcp_proxy.NewTcpProxy(sess))
|
||||
sess.Register(ticker.NewTicker(sess))
|
||||
sess.Register(update.NewUpdateModule(sess))
|
||||
sess.Register(wifi.NewWiFiModule(sess))
|
||||
sess.Register(wol.NewWOL(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