2022-01-16 21:23:00 -05:00
|
|
|
package tbsupervise
|
|
|
|
|
|
|
|
import (
|
2022-01-23 12:00:37 -05:00
|
|
|
"embed"
|
2022-01-16 22:04:35 -05:00
|
|
|
"fmt"
|
2022-01-23 12:00:37 -05:00
|
|
|
"io/fs"
|
2022-01-23 12:48:18 -05:00
|
|
|
"io/ioutil"
|
2022-01-16 22:04:35 -05:00
|
|
|
"log"
|
2022-01-22 01:13:30 -05:00
|
|
|
"net"
|
2022-01-16 21:23:00 -05:00
|
|
|
"os"
|
|
|
|
"os/exec"
|
2022-01-30 02:41:45 -05:00
|
|
|
"path"
|
2022-01-16 21:23:00 -05:00
|
|
|
"path/filepath"
|
2022-01-23 12:48:18 -05:00
|
|
|
"strings"
|
2022-01-16 21:23:00 -05:00
|
|
|
|
2022-01-22 23:36:48 -05:00
|
|
|
"github.com/mitchellh/go-ps"
|
2022-01-29 01:18:37 -05:00
|
|
|
cp "github.com/otiai10/copy"
|
2022-01-16 21:23:00 -05:00
|
|
|
tbget "i2pgit.org/idk/i2p.plugins.tor-manager/get"
|
|
|
|
)
|
|
|
|
|
2022-01-21 22:47:18 -05:00
|
|
|
var UNPACK_URL = tbget.UNPACK_PATH
|
|
|
|
var DEFAULT_TB_LANG = tbget.DefaultIETFLang
|
2022-01-16 21:23:00 -05:00
|
|
|
|
2022-01-30 03:17:08 -05:00
|
|
|
func OS() string {
|
|
|
|
return tbget.OS
|
|
|
|
}
|
|
|
|
|
|
|
|
func ARCH() string {
|
|
|
|
return tbget.ARCH
|
|
|
|
}
|
2022-01-16 21:23:00 -05:00
|
|
|
|
2022-01-21 21:05:23 -05:00
|
|
|
type Supervisor struct {
|
|
|
|
UnpackPath string
|
|
|
|
Lang string
|
2022-01-22 01:09:18 -05:00
|
|
|
torcmd *exec.Cmd
|
|
|
|
tbcmd *exec.Cmd
|
|
|
|
ibcmd *exec.Cmd
|
2022-01-23 12:00:37 -05:00
|
|
|
Profile *embed.FS
|
2022-01-21 21:05:23 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Supervisor) TBPath() string {
|
|
|
|
return filepath.Join(s.UnpackPath, "Browser", "start-tor-browser")
|
|
|
|
}
|
|
|
|
|
2022-01-21 22:47:18 -05:00
|
|
|
func (s *Supervisor) FirefoxPath() string {
|
2022-01-30 03:17:08 -05:00
|
|
|
switch OS() {
|
2022-01-23 14:45:12 -05:00
|
|
|
case "linux":
|
|
|
|
return filepath.Join(s.UnpackPath, "Browser", "firefox.real")
|
|
|
|
case "windows":
|
|
|
|
return filepath.Join(s.UnpackPath, "Browser", "firefox.exe")
|
|
|
|
default:
|
|
|
|
return filepath.Join(s.UnpackPath, "Browser", "firefox")
|
|
|
|
}
|
2022-01-21 22:47:18 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Supervisor) TBDirectory() string {
|
|
|
|
return filepath.Join(s.UnpackPath, "Browser")
|
|
|
|
}
|
|
|
|
|
2022-01-21 21:05:23 -05:00
|
|
|
func (s *Supervisor) TorPath() string {
|
2022-01-21 22:47:18 -05:00
|
|
|
return filepath.Join(s.UnpackPath, "Browser", "TorBrowser", "Tor", "tor")
|
2022-01-21 21:05:23 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Supervisor) TorDataPath() string {
|
|
|
|
return filepath.Join(s.UnpackPath, "Browser", "TorBrowser", "Data")
|
|
|
|
}
|
|
|
|
|
2022-01-29 01:18:37 -05:00
|
|
|
func (s *Supervisor) I2PProfilePath() string {
|
|
|
|
fp := filepath.Join(filepath.Dir(s.UnpackPath), ".i2p.firefox")
|
|
|
|
if !tbget.FileExists(fp) {
|
|
|
|
log.Printf("i2p data not found at %s, unpacking", fp)
|
|
|
|
if s.Profile != nil {
|
|
|
|
if err := s.UnpackI2PData(); err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return fp
|
|
|
|
}
|
|
|
|
|
2022-01-21 22:47:18 -05:00
|
|
|
func (s *Supervisor) I2PDataPath() string {
|
2022-01-29 01:18:37 -05:00
|
|
|
fp := s.I2PProfilePath()
|
|
|
|
up := filepath.Join(filepath.Dir(s.UnpackPath), "i2p.firefox")
|
|
|
|
if tbget.FileExists(up) {
|
|
|
|
return up
|
2022-01-23 12:00:37 -05:00
|
|
|
} else {
|
2022-01-29 01:18:37 -05:00
|
|
|
log.Printf("i2p workdir not found at %s, copying", up)
|
2022-01-23 12:00:37 -05:00
|
|
|
if s.Profile != nil {
|
2022-01-29 01:18:37 -05:00
|
|
|
if err := cp.Copy(fp, up); err != nil {
|
2022-01-23 12:00:37 -05:00
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
2022-01-29 01:18:37 -05:00
|
|
|
return up
|
2022-01-23 12:00:37 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Supervisor) UnpackI2PData() error {
|
2022-01-30 02:41:45 -05:00
|
|
|
return fs.WalkDir(s.Profile, ".", func(embedpath string, d fs.DirEntry, err error) error {
|
2022-01-29 01:18:37 -05:00
|
|
|
fp := filepath.Join(filepath.Dir(s.UnpackPath), ".i2p.firefox")
|
2022-01-23 12:00:37 -05:00
|
|
|
if err != nil {
|
2022-01-23 12:48:18 -05:00
|
|
|
log.Fatal(err)
|
2022-01-23 12:00:37 -05:00
|
|
|
}
|
2022-01-30 02:41:45 -05:00
|
|
|
fmt.Println(embedpath, filepath.Join(fp, strings.Replace(embedpath, "tor-browser/unpack/i2p.firefox", "", -1)))
|
2022-01-23 12:48:18 -05:00
|
|
|
if d.IsDir() {
|
2022-01-30 02:41:45 -05:00
|
|
|
os.MkdirAll(filepath.Join(fp, strings.Replace(embedpath, "tor-browser/unpack/i2p.firefox", "", -1)), 0755)
|
2022-01-23 12:00:37 -05:00
|
|
|
} else {
|
2022-01-30 02:41:45 -05:00
|
|
|
fullpath := path.Join(embedpath)
|
2022-01-23 12:48:18 -05:00
|
|
|
bytes, err := s.Profile.ReadFile(fullpath)
|
|
|
|
if err != nil {
|
2022-01-23 12:00:37 -05:00
|
|
|
return err
|
|
|
|
}
|
2022-01-30 02:41:45 -05:00
|
|
|
unpack := filepath.Join(fp, strings.Replace(embedpath, "tor-browser/unpack/i2p.firefox", "", -1))
|
2022-01-23 12:48:18 -05:00
|
|
|
if err := ioutil.WriteFile(unpack, bytes, 0644); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
2022-01-23 12:00:37 -05:00
|
|
|
return nil
|
|
|
|
})
|
2022-01-21 22:47:18 -05:00
|
|
|
}
|
|
|
|
|
2022-01-22 01:09:18 -05:00
|
|
|
func (s *Supervisor) tbbail() error {
|
|
|
|
if s.tbcmd != nil && s.tbcmd.Process != nil && s.tbcmd.ProcessState != nil {
|
|
|
|
if s.tbcmd.ProcessState.Exited() {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return fmt.Errorf("Already running")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-01-21 21:05:23 -05:00
|
|
|
func (s *Supervisor) RunTBWithLang() error {
|
2022-01-30 03:17:08 -05:00
|
|
|
tbget.ARCH = ARCH()
|
2022-01-21 21:05:23 -05:00
|
|
|
if s.Lang == "" {
|
|
|
|
s.Lang = DEFAULT_TB_LANG
|
2022-01-16 21:23:00 -05:00
|
|
|
}
|
2022-01-21 21:05:23 -05:00
|
|
|
if s.UnpackPath == "" {
|
2022-01-21 22:47:18 -05:00
|
|
|
s.UnpackPath = UNPACK_URL
|
2022-01-21 21:05:23 -05:00
|
|
|
}
|
|
|
|
|
2022-01-22 01:09:18 -05:00
|
|
|
if s.tbbail() != nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-01-30 03:17:08 -05:00
|
|
|
log.Println("running tor browser with lang", s.Lang, s.UnpackPath, OS())
|
|
|
|
switch OS() {
|
2022-01-16 21:23:00 -05:00
|
|
|
case "linux":
|
2022-01-21 21:05:23 -05:00
|
|
|
if tbget.FileExists(s.UnpackPath) {
|
|
|
|
log.Println("running tor browser with lang", s.Lang, s.UnpackPath)
|
2022-01-22 01:09:18 -05:00
|
|
|
s.tbcmd = exec.Command(s.TBPath())
|
|
|
|
s.tbcmd.Stdout = os.Stdout
|
|
|
|
s.tbcmd.Stderr = os.Stderr
|
|
|
|
return s.tbcmd.Run()
|
2022-01-21 22:47:18 -05:00
|
|
|
} else {
|
|
|
|
log.Println("tor browser not found at", s.TBPath())
|
|
|
|
return fmt.Errorf("tor browser not found at %s", s.TBPath())
|
|
|
|
}
|
|
|
|
case "darwin":
|
2022-01-22 01:09:18 -05:00
|
|
|
s.tbcmd = exec.Command("/usr/bin/env", "open", "-a", "\"Tor Browser.app\"")
|
|
|
|
s.tbcmd.Dir = s.TBDirectory()
|
|
|
|
return s.tbcmd.Run()
|
2022-01-30 03:17:08 -05:00
|
|
|
case "win":
|
|
|
|
log.Println("Running Windows EXE", s.TBDirectory(), "firefox.exe")
|
|
|
|
s.tbcmd = exec.Command(filepath.Join(s.TBDirectory(), "firefox.exe"))
|
2022-01-22 01:09:18 -05:00
|
|
|
s.tbcmd.Dir = s.TBDirectory()
|
|
|
|
return s.tbcmd.Run()
|
2022-01-21 22:47:18 -05:00
|
|
|
default:
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-01-22 01:09:18 -05:00
|
|
|
func (s *Supervisor) ibbail() error {
|
|
|
|
if s.ibcmd != nil && s.ibcmd.Process != nil && s.ibcmd.ProcessState != nil {
|
|
|
|
if s.ibcmd.ProcessState.Exited() {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return fmt.Errorf("Already running")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-01-21 22:47:18 -05:00
|
|
|
func (s *Supervisor) RunI2PBWithLang() error {
|
2022-01-30 03:17:08 -05:00
|
|
|
tbget.ARCH = ARCH()
|
2022-01-21 22:47:18 -05:00
|
|
|
if s.Lang == "" {
|
|
|
|
s.Lang = DEFAULT_TB_LANG
|
|
|
|
}
|
|
|
|
if s.UnpackPath == "" {
|
|
|
|
s.UnpackPath = UNPACK_URL
|
|
|
|
}
|
|
|
|
|
2022-01-22 01:09:18 -05:00
|
|
|
if s.ibbail() != nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-01-30 03:17:08 -05:00
|
|
|
log.Println("running i2p in tor browser with lang", s.Lang, s.UnpackPath, OS())
|
|
|
|
switch OS() {
|
2022-01-21 22:47:18 -05:00
|
|
|
case "linux":
|
|
|
|
if tbget.FileExists(s.UnpackPath) {
|
|
|
|
log.Println("running Tor browser with lang and I2P Profile", s.Lang, s.UnpackPath, s.FirefoxPath(), "--profile", s.I2PDataPath())
|
2022-01-22 01:09:18 -05:00
|
|
|
s.ibcmd = exec.Command(s.FirefoxPath(), "--profile", s.I2PDataPath())
|
|
|
|
s.ibcmd.Stdout = os.Stdout
|
|
|
|
s.ibcmd.Stderr = os.Stderr
|
|
|
|
return s.ibcmd.Run()
|
2022-01-21 22:47:18 -05:00
|
|
|
} else {
|
|
|
|
log.Println("tor browser not found at", s.FirefoxPath())
|
|
|
|
return fmt.Errorf("tor browser not found at %s", s.FirefoxPath())
|
|
|
|
}
|
|
|
|
case "darwin":
|
2022-01-22 01:09:18 -05:00
|
|
|
s.ibcmd = exec.Command("/usr/bin/env", "open", "-a", "\"Tor Browser.app\"")
|
|
|
|
s.ibcmd.Dir = s.TBDirectory()
|
|
|
|
return s.ibcmd.Run()
|
2022-01-30 03:17:08 -05:00
|
|
|
case "win":
|
2022-01-30 03:24:08 -05:00
|
|
|
log.Println("Running Windows EXE", filepath.Join(s.TBDirectory(), "firefox.exe"), "--profile", s.I2PDataPath())
|
2022-01-30 03:40:15 -05:00
|
|
|
s.ibcmd = exec.Command(filepath.Join(s.TBDirectory(), "firefox.exe"), "--help") //, "--profile", s.I2PDataPath())
|
|
|
|
s.ibcmd.Dir = s.TBDirectory()
|
|
|
|
s.ibcmd.Stdout = os.Stdout
|
|
|
|
s.ibcmd.Stderr = os.Stderr
|
|
|
|
return s.ibcmd.Run()
|
2022-01-21 22:47:18 -05:00
|
|
|
default:
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-01-22 01:09:18 -05:00
|
|
|
func (s *Supervisor) torbail() error {
|
2022-01-30 03:22:55 -05:00
|
|
|
_, err := net.Listen("tcp", "127.0.0.1:9050")
|
2022-01-22 01:13:30 -05:00
|
|
|
if err != nil {
|
2022-01-30 03:22:55 -05:00
|
|
|
log.Println("Already Running on 9050", err)
|
2022-01-22 01:13:30 -05:00
|
|
|
return fmt.Errorf("Already running")
|
|
|
|
}
|
2022-01-22 01:09:18 -05:00
|
|
|
if s.torcmd != nil && s.torcmd.Process != nil && s.torcmd.ProcessState != nil {
|
|
|
|
if s.torcmd.ProcessState.Exited() {
|
2022-01-30 03:22:55 -05:00
|
|
|
log.Println("Tor exited, restarting")
|
2022-01-22 01:09:18 -05:00
|
|
|
return nil
|
|
|
|
}
|
2022-01-30 03:22:55 -05:00
|
|
|
log.Println("Already Running")
|
2022-01-22 01:09:18 -05:00
|
|
|
return fmt.Errorf("Already running")
|
|
|
|
}
|
2022-01-30 03:22:55 -05:00
|
|
|
log.Println("Starting Tor")
|
2022-01-22 01:09:18 -05:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-01-21 22:47:18 -05:00
|
|
|
func (s *Supervisor) RunTorWithLang() error {
|
2022-01-30 03:17:08 -05:00
|
|
|
tbget.ARCH = ARCH()
|
2022-01-21 22:47:18 -05:00
|
|
|
if s.Lang == "" {
|
|
|
|
s.Lang = DEFAULT_TB_LANG
|
|
|
|
}
|
|
|
|
if s.UnpackPath == "" {
|
|
|
|
s.UnpackPath = UNPACK_URL
|
|
|
|
}
|
2022-01-22 01:09:18 -05:00
|
|
|
if err := s.torbail(); err != nil {
|
|
|
|
return nil
|
|
|
|
}
|
2022-01-21 22:47:18 -05:00
|
|
|
|
|
|
|
log.Println("running tor with lang", s.Lang, s.UnpackPath)
|
2022-01-30 03:17:08 -05:00
|
|
|
switch OS() {
|
2022-01-21 22:47:18 -05:00
|
|
|
case "linux":
|
|
|
|
if tbget.FileExists(s.UnpackPath) {
|
|
|
|
log.Println("running tor with lang", s.Lang, s.UnpackPath)
|
2022-01-22 01:09:18 -05:00
|
|
|
s.torcmd = exec.Command(s.TorPath())
|
|
|
|
s.torcmd.Stdout = os.Stdout
|
|
|
|
s.torcmd.Stderr = os.Stderr
|
|
|
|
return s.torcmd.Run()
|
2022-01-16 22:04:35 -05:00
|
|
|
} else {
|
2022-01-21 22:47:18 -05:00
|
|
|
log.Println("tor not found at", s.TorPath())
|
|
|
|
return fmt.Errorf("tor not found at %s", s.TorPath())
|
2022-01-16 22:04:35 -05:00
|
|
|
}
|
2022-01-16 21:23:00 -05:00
|
|
|
case "darwin":
|
2022-01-22 01:09:18 -05:00
|
|
|
s.torcmd = exec.Command("/usr/bin/env", "open", "-a", "\"Tor Browser.app\"")
|
|
|
|
s.torcmd.Dir = s.TBDirectory()
|
|
|
|
return s.torcmd.Run()
|
2022-01-30 03:17:08 -05:00
|
|
|
case "win":
|
2022-01-30 03:22:55 -05:00
|
|
|
log.Println("Running Windows EXE", filepath.Join(s.TBDirectory(), "TorBrowser", "Tor", "tor.exe"))
|
|
|
|
s.torcmd = exec.Command(filepath.Join(s.TBDirectory(), "TorBrowser", "Tor", "tor.exe"))
|
|
|
|
s.torcmd.Dir = s.TBDirectory()
|
|
|
|
return s.torcmd.Run()
|
2022-01-16 21:23:00 -05:00
|
|
|
default:
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
2022-01-21 21:05:23 -05:00
|
|
|
|
2022-01-22 00:42:10 -05:00
|
|
|
func (s *Supervisor) StopTor() error {
|
2022-01-22 01:09:18 -05:00
|
|
|
return s.torcmd.Process.Kill()
|
2022-01-22 00:42:10 -05:00
|
|
|
}
|
|
|
|
|
2022-01-22 23:36:48 -05:00
|
|
|
func (s *Supervisor) TorIsAlive() (bool, bool) {
|
|
|
|
_, err := net.Listen("TCP", "127.0.0.1:9050")
|
|
|
|
if err != nil {
|
|
|
|
return true, false
|
|
|
|
}
|
|
|
|
if s.torcmd != nil && s.torcmd.Process != nil && s.torcmd.ProcessState != nil {
|
|
|
|
return !s.torcmd.ProcessState.Exited(), true
|
|
|
|
}
|
|
|
|
processes, err := ps.Processes()
|
|
|
|
if err != nil {
|
|
|
|
return false, true
|
|
|
|
}
|
|
|
|
for _, p := range processes {
|
|
|
|
if p.Executable() == s.TorPath() {
|
|
|
|
var err error
|
|
|
|
s.torcmd.Process, err = os.FindProcess(p.Pid())
|
|
|
|
if err == nil {
|
|
|
|
return true, true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false, true
|
2022-01-22 22:04:30 -05:00
|
|
|
}
|
|
|
|
|
2022-01-21 21:05:23 -05:00
|
|
|
func NewSupervisor(tbPath, lang string) *Supervisor {
|
|
|
|
return &Supervisor{
|
|
|
|
UnpackPath: tbPath,
|
|
|
|
Lang: lang,
|
|
|
|
}
|
|
|
|
}
|