mirror of
https://github.com/andatoshiki/shikigrid.git
synced 2026-06-05 19:56:27 +00:00
197 lines
4.3 KiB
Go
197 lines
4.3 KiB
Go
package main
|
|
|
|
import (
|
|
"os"
|
|
"os/signal"
|
|
"runtime/pprof"
|
|
"time"
|
|
|
|
"github.com/evilsocket/islazy/fs"
|
|
"github.com/evilsocket/islazy/log"
|
|
"github.com/andatoshiki/shikigrid/api"
|
|
"github.com/andatoshiki/shikigrid/crypto"
|
|
"github.com/andatoshiki/shikigrid/mesh"
|
|
"github.com/andatoshiki/shikigrid/models"
|
|
"github.com/andatoshiki/shikigrid/utils"
|
|
"github.com/andatoshiki/shikigrid/version"
|
|
"github.com/joho/godotenv"
|
|
)
|
|
|
|
func cleanup() {
|
|
if cpuProfile != "" {
|
|
log.Info("writing CPU profile to %s ...", cpuProfile)
|
|
pprof.StopCPUProfile()
|
|
}
|
|
|
|
if memProfile != "" {
|
|
log.Info("writing memory profile to %s ...", memProfile)
|
|
f, err := os.Create(memProfile)
|
|
if err != nil {
|
|
log.Fatal("%v", err)
|
|
}
|
|
defer func() {
|
|
if err := f.Close(); err != nil {
|
|
panic(err)
|
|
}
|
|
}()
|
|
if err := pprof.WriteHeapProfile(f); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func setupCore() {
|
|
c := make(chan os.Signal, 1)
|
|
signal.Notify(c, os.Interrupt)
|
|
go func() {
|
|
for sig := range c {
|
|
log.Warning("received signal %v", sig)
|
|
cleanup()
|
|
os.Exit(0)
|
|
}
|
|
}()
|
|
|
|
if cpuProfile != "" {
|
|
f, err := os.Create(cpuProfile)
|
|
if err != nil {
|
|
log.Fatal("%v", err)
|
|
}
|
|
if err := pprof.StartCPUProfile(f); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
if debug {
|
|
log.Level = log.DEBUG
|
|
} else {
|
|
log.Level = log.INFO
|
|
}
|
|
log.OnFatal = log.ExitOnFatal
|
|
}
|
|
|
|
func waitForKeys() {
|
|
privPath := crypto.PrivatePath(keysPath)
|
|
for {
|
|
if !fs.Exists(privPath) {
|
|
log.Debug("waiting for %s ...", privPath)
|
|
time.Sleep(1 * time.Second)
|
|
} else {
|
|
// give it a moment to finish disk sync
|
|
time.Sleep(2 * time.Second)
|
|
log.Info("%s found", privPath)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
func setupMesh() {
|
|
var err error
|
|
|
|
if advertise == false {
|
|
return //this probably doesnt work
|
|
}
|
|
|
|
peer = mesh.MakeLocalPeer(utils.Hostname(), keys)
|
|
if err = peer.StartAdvertising(iface); err != nil {
|
|
log.Fatal("error while starting signaling: %v", err)
|
|
}
|
|
if router, err = mesh.StartRouting(iface, peersPath, peer); err != nil {
|
|
log.Fatal("%v", err)
|
|
} else {
|
|
router.OnNewPeer(func(ident string, peer *mesh.Peer) {
|
|
log.Info("detected new peer %s on channel %d", peer.ID(), peer.Channel)
|
|
})
|
|
router.OnPeerLost(func(ident string, peer *mesh.Peer) {
|
|
log.Info("peer %s lost (inactive for %fs)", peer.ID(), peer.InactiveFor())
|
|
})
|
|
}
|
|
log.Info("peer %s signaling is ready", peer.ID())
|
|
}
|
|
|
|
func setupDB() {
|
|
if err := godotenv.Load(env); err != nil {
|
|
log.Fatal("%v", err)
|
|
}
|
|
if err := models.Setup(); err != nil {
|
|
if nodb {
|
|
log.Warning("%v", err)
|
|
} else {
|
|
log.Fatal("%v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func setupMode() string {
|
|
var err error
|
|
|
|
// in case -inbox was not explicitly passed
|
|
if receiver != "" || loop == true || id > 0 {
|
|
inbox = true
|
|
}
|
|
|
|
// for inbox actions, set the keys to the default path if empty
|
|
if (whoami || inbox) && keysPath == "" {
|
|
keysPath = "/etc/pwnagotchi/"
|
|
}
|
|
|
|
// generate keypair
|
|
if generate {
|
|
if keysPath == "" {
|
|
log.Fatal("no -keys path specified")
|
|
} else if crypto.KeysExist(keysPath) {
|
|
log.Fatal("keypair already exists in %s", keysPath)
|
|
}
|
|
|
|
if _, err = crypto.LoadOrCreate(keysPath, 4096); err != nil {
|
|
log.Fatal("error generating RSA keypair: %v", err)
|
|
} else {
|
|
log.Info("keypair saved to %s", keysPath)
|
|
}
|
|
os.Exit(0)
|
|
}
|
|
|
|
mode := "peer"
|
|
// if keys have been passed explicitly, or one of the inbox actions
|
|
// has been specified, we're running on the unit
|
|
// if keysPath != "" {
|
|
// mode = "peer"
|
|
// }
|
|
|
|
log.Info("shikigrid v%s starting in %s mode ...", version.Version, mode)
|
|
|
|
if mode == "peer" {
|
|
// wait for keys to be generated
|
|
if wait {
|
|
waitForKeys()
|
|
}
|
|
// load the keys
|
|
if keys, err = crypto.Load(keysPath); err != nil {
|
|
log.Fatal("error while loading keys from %s: %v", keysPath, err)
|
|
}
|
|
// print identity and exit
|
|
if whoami {
|
|
if Endpoint == "https://grid-api.toshiki.dev/api/v1" {
|
|
log.Info("https://toshiki.dev/search/%s", keys.FingerprintHex)
|
|
} else {
|
|
log.Info("https://pwnagotchi.ai/pwnfile/#!%s", keys.FingerprintHex)
|
|
}
|
|
os.Exit(0)
|
|
}
|
|
// only start mesh signaling if this is not an inbox action
|
|
if !inbox {
|
|
setupMesh()
|
|
}
|
|
} else if mode == "server" {
|
|
// server side we just need to setup the database connection
|
|
setupDB()
|
|
}
|
|
|
|
// setup the proper routes for either server or peer mode
|
|
err, server = api.Setup(keys, peer, router, Endpoint)
|
|
if err != nil {
|
|
log.Fatal("%v", err)
|
|
}
|
|
|
|
return mode
|
|
}
|