2022-01-16 17:06:29 -05:00
|
|
|
package tbserve
|
|
|
|
|
|
|
|
import (
|
2022-02-14 23:42:08 -05:00
|
|
|
"context"
|
2022-01-23 13:40:14 -05:00
|
|
|
"embed"
|
2022-02-21 23:57:32 -05:00
|
|
|
"fmt"
|
2022-01-29 01:18:37 -05:00
|
|
|
"io/ioutil"
|
2022-01-21 22:47:18 -05:00
|
|
|
"log"
|
2022-01-22 00:32:39 -05:00
|
|
|
"net/http"
|
2022-02-25 00:17:12 -05:00
|
|
|
"path"
|
2022-01-16 17:06:29 -05:00
|
|
|
"path/filepath"
|
2022-01-29 01:18:37 -05:00
|
|
|
"strconv"
|
2022-01-16 17:06:29 -05:00
|
|
|
|
2022-01-23 11:42:23 -05:00
|
|
|
"github.com/justinas/nosurf"
|
2022-01-29 01:18:37 -05:00
|
|
|
cp "github.com/otiai10/copy"
|
2022-01-16 17:06:29 -05:00
|
|
|
tbget "i2pgit.org/idk/i2p.plugins.tor-manager/get"
|
2022-02-25 00:30:41 -05:00
|
|
|
i2pdotonion "i2pgit.org/idk/i2p.plugins.tor-manager/onion"
|
2022-01-21 22:47:18 -05:00
|
|
|
TBSupervise "i2pgit.org/idk/i2p.plugins.tor-manager/supervise"
|
2022-01-16 17:06:29 -05:00
|
|
|
)
|
|
|
|
|
2022-02-07 15:34:45 -05:00
|
|
|
// Client manages and supervises a Tor Browser instance.
|
2022-01-21 22:47:18 -05:00
|
|
|
type Client struct {
|
|
|
|
hostname string
|
|
|
|
TBD *tbget.TBDownloader
|
|
|
|
TBS *TBSupervise.Supervisor
|
2022-02-25 00:30:41 -05:00
|
|
|
Onion *i2pdotonion.I2POnionService
|
2022-01-28 01:46:35 -05:00
|
|
|
DarkMode bool
|
2022-01-29 01:18:37 -05:00
|
|
|
Host string
|
|
|
|
Port int
|
2022-02-14 23:42:08 -05:00
|
|
|
server http.Server
|
2022-01-21 22:47:18 -05:00
|
|
|
}
|
|
|
|
|
2022-02-07 15:34:45 -05:00
|
|
|
// NewClient creates a new Client.
|
2022-02-15 00:24:30 -05:00
|
|
|
func NewClient(verbose bool, lang, os, arch, mirror string, content *embed.FS) (*Client, error) {
|
2022-01-21 22:47:18 -05:00
|
|
|
m := &Client{
|
2022-01-30 01:50:53 -05:00
|
|
|
TBD: tbget.NewTBDownloader(lang, os, arch, content),
|
2022-01-21 22:47:18 -05:00
|
|
|
}
|
2022-02-15 00:24:30 -05:00
|
|
|
m.TBD.Mirror = mirror
|
2022-01-30 01:50:53 -05:00
|
|
|
m.TBD.Verbose = verbose
|
2022-01-23 13:40:14 -05:00
|
|
|
m.TBD.MakeTBDirectory()
|
2022-02-28 19:59:47 -05:00
|
|
|
var err error
|
|
|
|
m.Onion, err = i2pdotonion.NewOnionService(m.TBD.DownloadPath)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2022-01-21 22:47:18 -05:00
|
|
|
tgz, sig, err := m.TBD.DownloadUpdaterForLang(lang)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
var home string
|
|
|
|
if home, err = m.TBD.CheckSignature(tgz, sig); err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
} else {
|
2022-02-21 23:57:32 -05:00
|
|
|
_, err = m.TBD.UnpackUpdater(tgz)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("unpacking updater: %v", err)
|
|
|
|
}
|
2022-01-21 22:47:18 -05:00
|
|
|
log.Printf("Signature check passed: %s %s", tgz, sig)
|
|
|
|
}
|
|
|
|
m.TBS = TBSupervise.NewSupervisor(home, lang)
|
2022-02-25 00:30:41 -05:00
|
|
|
go m.TBS.RunTorWithLang()
|
2022-01-21 22:47:18 -05:00
|
|
|
return m, nil
|
|
|
|
}
|
|
|
|
|
2022-02-21 18:08:49 -05:00
|
|
|
// NewFirefoxClient creates a new Client.
|
|
|
|
func NewFirefoxClient(verbose bool, lang, os, arch, mirror string, content *embed.FS) (*Client, error) {
|
|
|
|
m := &Client{
|
|
|
|
TBD: tbget.NewFirefoxDownloader(lang, os, arch, content),
|
|
|
|
}
|
|
|
|
m.TBD.Mirror = mirror
|
|
|
|
m.TBD.Verbose = verbose
|
|
|
|
m.TBD.MakeTBDirectory()
|
|
|
|
tgz, sig, err := m.TBD.DownloadFirefoxUpdaterForLang(lang)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
var home string
|
2022-02-21 23:57:32 -05:00
|
|
|
if home, err = m.TBD.CheckFirefoxSignature(tgz, sig); err != nil {
|
2022-02-21 18:08:49 -05:00
|
|
|
log.Fatal(err)
|
|
|
|
} else {
|
|
|
|
log.Printf("Signature check passed: %s %s", tgz, sig)
|
|
|
|
}
|
|
|
|
m.TBS = TBSupervise.NewSupervisor(home, lang)
|
|
|
|
return m, nil
|
|
|
|
}
|
|
|
|
|
2022-02-07 15:34:45 -05:00
|
|
|
// GetHost returns the hostname of the client.
|
2022-01-29 01:18:37 -05:00
|
|
|
func (m *Client) GetHost() string {
|
|
|
|
if m.Host == "" {
|
|
|
|
m.Host = "127.0.0.1"
|
|
|
|
}
|
|
|
|
return m.Host
|
|
|
|
}
|
|
|
|
|
2022-02-07 15:34:45 -05:00
|
|
|
// GetPort returns the port of the client.
|
2022-01-29 01:18:37 -05:00
|
|
|
func (m *Client) GetPort() string {
|
|
|
|
if m.Port == 0 {
|
|
|
|
m.Port = 7695
|
|
|
|
}
|
|
|
|
return strconv.Itoa(m.Port)
|
|
|
|
}
|
|
|
|
|
2022-02-07 15:34:45 -05:00
|
|
|
// GetAddress returns the address of the client.
|
2022-01-29 01:18:37 -05:00
|
|
|
func (m *Client) GetAddress() string {
|
|
|
|
return m.GetHost() + ":" + m.GetPort()
|
|
|
|
}
|
|
|
|
|
2022-02-07 15:34:45 -05:00
|
|
|
// ServeHTTP handles HTTP requests.
|
2022-01-22 00:42:10 -05:00
|
|
|
func (m *Client) ServeHTTP(rw http.ResponseWriter, rq *http.Request) {
|
2022-02-25 00:17:12 -05:00
|
|
|
path := path.Clean(rq.URL.Path)
|
2022-01-29 01:18:37 -05:00
|
|
|
rq.URL.Path = path
|
2022-01-22 01:09:18 -05:00
|
|
|
log.Printf("ServeHTTP: '%s'", path)
|
2022-01-22 23:36:48 -05:00
|
|
|
fileextension := filepath.Ext(path)
|
|
|
|
switch fileextension {
|
|
|
|
case ".json":
|
|
|
|
m.serveJSON(rw, rq)
|
|
|
|
return
|
|
|
|
case ".css":
|
|
|
|
m.serveCSS(rw, rq)
|
|
|
|
return
|
|
|
|
case ".js":
|
|
|
|
m.serveJS(rw, rq)
|
|
|
|
return
|
|
|
|
case ".png":
|
|
|
|
m.servePNG(rw, rq)
|
|
|
|
return
|
|
|
|
case ".ico":
|
|
|
|
m.serveICO(rw, rq)
|
|
|
|
return
|
|
|
|
case ".svg":
|
|
|
|
m.serveSVG(rw, rq)
|
|
|
|
return
|
2022-01-22 00:32:39 -05:00
|
|
|
default:
|
2022-01-22 23:36:48 -05:00
|
|
|
switch path {
|
|
|
|
case "/launch-tor-browser":
|
|
|
|
log.Println("Starting Tor Browser")
|
|
|
|
go m.TBS.RunTBWithLang()
|
|
|
|
http.Redirect(rw, rq, "/", http.StatusFound)
|
|
|
|
case "/launch-i2p-browser":
|
|
|
|
log.Println("Starting I2P Browser")
|
|
|
|
go m.TBS.RunI2PBWithLang()
|
|
|
|
http.Redirect(rw, rq, "/", http.StatusFound)
|
|
|
|
case "/start-tor":
|
|
|
|
log.Println("Starting Tor")
|
|
|
|
go m.TBS.RunTorWithLang()
|
|
|
|
http.Redirect(rw, rq, "/", http.StatusFound)
|
|
|
|
case "/stop-tor":
|
|
|
|
log.Println("Stopping Tor")
|
|
|
|
go m.TBS.StopTor()
|
|
|
|
http.Redirect(rw, rq, "/", http.StatusFound)
|
2022-01-29 01:18:37 -05:00
|
|
|
case "/switch-theme":
|
|
|
|
log.Println("Switching theme")
|
|
|
|
m.DarkMode = !m.DarkMode
|
|
|
|
http.Redirect(rw, rq, "/", http.StatusFound)
|
2022-01-22 23:36:48 -05:00
|
|
|
default:
|
|
|
|
b, _ := m.Page()
|
|
|
|
rw.Header().Set("Content-Type", "text/html")
|
|
|
|
rw.Write([]byte(b))
|
2022-01-22 00:32:39 -05:00
|
|
|
}
|
|
|
|
}
|
2022-01-22 23:36:48 -05:00
|
|
|
|
2022-01-22 00:32:39 -05:00
|
|
|
}
|
|
|
|
|
2022-02-07 15:34:45 -05:00
|
|
|
// Serve serve the control panel locally
|
2022-01-22 00:42:10 -05:00
|
|
|
func (m *Client) Serve() error {
|
|
|
|
//http.Handle("/", m)
|
2022-01-29 01:18:37 -05:00
|
|
|
mirrorjson, err := m.GenerateMirrorJSON()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-02-14 23:42:08 -05:00
|
|
|
m.server = http.Server{
|
|
|
|
Addr: m.GetAddress(),
|
|
|
|
Handler: nosurf.New(m),
|
|
|
|
}
|
2022-01-29 01:18:37 -05:00
|
|
|
ioutil.WriteFile(filepath.Join(m.TBD.DownloadPath, "mirror.json"), []byte(mirrorjson), 0644)
|
|
|
|
cp.Copy(m.TBS.I2PProfilePath(), filepath.Join(m.TBD.DownloadPath, "i2p.firefox"))
|
2022-02-14 23:42:08 -05:00
|
|
|
return m.server.ListenAndServe() //http.ListenAndServe(m.GetAddress(), nosurf.New(m))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Client) Shutdown(ctx context.Context) error {
|
|
|
|
m.TBS.StopTor()
|
|
|
|
return m.server.Shutdown(ctx)
|
2022-01-22 00:42:10 -05:00
|
|
|
}
|