Create directories automatically, mirror Tor Browser and our profile too, allow customizing the ports. Some probably unnecessary defensive coding.

This commit is contained in:
idk
2022-01-29 01:18:37 -05:00
parent b1f6205675
commit d92a5b2369
11 changed files with 278 additions and 22 deletions

View File

@ -11,14 +11,22 @@ Usage:
Usage of ./i2p.plugins.tor-manager-linux-amd64:
-arch string
OS/arch to download (default "64")
-directory string
Directory operate in
-host string
Host to serve on (default "127.0.0.1")
-i2pbrowser
Open I2P in Tor Browser
-lang string
Language to download
-os string
OS/arch to download (default "linux")
-port int
Port to serve on (default 7695)
-torbrowser
Open Tor Browser
-verbose
Verbose output
```
Status:

View File

@ -16,16 +16,27 @@ import (
"strings"
"github.com/cloudfoundry/jibber_jabber"
sam "github.com/eyedeekay/sam3/helper"
"github.com/ulikunitz/xz"
"github.com/jchavannes/go-pgp/pgp"
"golang.org/x/crypto/openpgp"
)
var wd, _ = os.Getwd()
var WORKING_DIR = ""
var UNPACK_PATH = filepath.Join(wd, "unpack")
var DOWNLOAD_PATH = filepath.Join(wd, "tor-browser")
func DefaultDir() string {
if WORKING_DIR == "" {
WORKING_DIR, _ = os.Getwd()
}
if !FileExists(WORKING_DIR) {
os.MkdirAll(WORKING_DIR, 0755)
}
return WORKING_DIR
}
var UNPACK_PATH = filepath.Join(DefaultDir(), "unpack")
var DOWNLOAD_PATH = filepath.Join(DefaultDir(), "tor-browser")
const TOR_UPDATES_URL string = "https://aus1.torproject.org/torbrowser/update_3/release/downloads.json"
@ -57,6 +68,30 @@ func NewTBDownloader(lang string, os, arch string, content *embed.FS) *TBDownloa
}
}
func (t *TBDownloader) ServeHTTP(w http.ResponseWriter, r *http.Request) {
r.URL.Path = strings.Replace(r.URL.Path, "..", "", -1)
ext := filepath.Ext(r.URL.Path)
if ext == ".json" {
w.Header().Set("Content-Type", "application/json")
if FileExists(filepath.Join(t.DownloadPath, "mirror.json")) {
http.ServeFile(w, r, filepath.Join(t.DownloadPath, "mirror.json"))
}
}
if FileExists(filepath.Join(t.DownloadPath, r.URL.Path)) {
http.ServeFile(w, r, filepath.Join(t.DownloadPath, r.URL.Path))
return
}
}
func (t *TBDownloader) Serve() {
samlistener, err := sam.I2PListener("tor-mirror", "127.0.0.1:7656", "tor-mirror")
if err != nil {
log.Fatal(err)
}
defer samlistener.Close()
http.Serve(samlistener, t)
}
func (t *TBDownloader) GetRuntimePair() string {
if t.OS != "" && t.ARCH != "" {
return fmt.Sprintf("%s%s", t.OS, t.ARCH)

2
go.mod
View File

@ -10,10 +10,12 @@ require (
)
require (
github.com/eyedeekay/sam3 v0.32.32
github.com/justinas/nosurf v1.1.1
github.com/mitchellh/go-ps v1.0.0
github.com/onsi/ginkgo v1.16.5 // indirect
github.com/onsi/gomega v1.17.0 // indirect
github.com/otiai10/copy v1.7.0
github.com/russross/blackfriday v1.6.0
github.com/ulikunitz/xz v0.5.10 // indirect
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect

8
go.sum
View File

@ -4,6 +4,8 @@ github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21 h1:tuij
github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21/go.mod h1:po7NpZ/QiTKzBKyrsEAxwnTamCoh8uDk/egRpQ7siIc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/eyedeekay/sam3 v0.32.32 h1:9Ea1Ere5O8Clx8zYxKnvhrWy7R96Q4FvxlPskYf8VW0=
github.com/eyedeekay/sam3 v0.32.32/go.mod h1:qRA9KIIVxbrHlkj+ZB+OoxFGFgdKeGp1vSgPw26eOVU=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
@ -40,6 +42,12 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.17.0 h1:9Luw4uT5HTjHTN8+aNcSThgH1vdXnmdJ8xIfZ4wyTRE=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE=
github.com/otiai10/copy v1.7.0/go.mod h1:rmRl6QPdJj6EiUqXQ/4Nn2lLXoNQjFCQbbNrxgc/t3U=
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
github.com/otiai10/mint v1.3.3/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=

View File

@ -3,7 +3,7 @@ Encoding=UTF-8
Version=1.0
Type=Application
Terminal=false
Exec=/bin/sh -c "mkdir -p $HOME/.i2p/browser && cd $HOME/.i2p/browser && i2pbrowser"
Exec=/bin/sh -c "i2pbrowser -directory=$HOME/.i2p/browser"
Name=I2P in Tor Browser
Categories=Network;WebBrowser;
Icon=/var/lib/i2pbrowser/icons/garliconion.png

17
main.go
View File

@ -9,6 +9,7 @@ import (
"runtime"
"github.com/cloudfoundry/jibber_jabber"
tbget "i2pgit.org/idk/i2p.plugins.tor-manager/get"
tbserve "i2pgit.org/idk/i2p.plugins.tor-manager/serve"
)
@ -49,13 +50,17 @@ var (
i2pbrowser = flag.Bool("i2pbrowser", false, "Open I2P in Tor Browser")
torbrowser = flag.Bool("torbrowser", false, "Open Tor Browser")
verbose = flag.Bool("verbose", false, "Verbose output")
directory = flag.String("directory", "", "Directory operate in")
host = flag.String("host", "127.0.0.1", "Host to serve on")
port = flag.Int("port", 7695, "Port to serve on")
/*mirror = flag.String("mirror", "", "Mirror to use")*/
/*bemirror = flag.Bool("bemirror", false, "Act as an in-I2P mirror when you're done downloading")*/
bemirror = flag.Bool("bemirror", false, "Act as an in-I2P mirror when you're done downloading")
)
func main() {
filename := filepath.Base(os.Args[0])
flag.Parse()
tbget.WORKING_DIR = *directory
if filename == "i2pbrowser" {
log.Println("Starting I2P in Tor Browser")
*i2pbrowser = true
@ -78,16 +83,18 @@ func main() {
if err != nil {
log.Fatal("Couldn't create client", err)
}
//client.TBD.Profile = &content
if *verbose {
client.TBD.Verbose = true
}
client.Host = *host
client.Port = *port
client.TBD.Verbose = *verbose
client.TBS.Profile = &content
if *i2pbrowser {
client.TBS.RunI2PBWithLang()
} else if *torbrowser {
client.TBS.RunTBWithLang()
} else {
if *bemirror {
go client.TBD.Serve()
}
if err := client.Serve(); err != nil {
log.Fatal(err)
}

View File

@ -10,7 +10,26 @@ import (
func (m *Client) Page() (string, error) {
htmlbytes := htmlhead
htmlbytes = append(htmlbytes, []byte("<body>")...)
htmlbytes = append(htmlbytes, []byte(`<body>
<label class="switch">
<input type="checkbox" onclick='handleClick(this);'>
<span class="slider round"></span>
</label>`)...)
htmlbytes = append(htmlbytes, []byte(`<script>
function handleClick(cb) {
var xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", "http://`)...)
htmlbytes = append(htmlbytes, []byte([]byte(m.GetAddress()))...)
htmlbytes = append(htmlbytes, []byte(`/switch-theme", false ); // false for synchronous request
xmlHttp.send( null );
location.reload();
return xmlHttp.responseText;
}
</script>
`)...)
mdbytes := m.PageHTML()
htmlbytes = append(htmlbytes, mdbytes...)
@ -21,7 +40,7 @@ func (m *Client) Page() (string, error) {
htmlbytes = append(htmlbytes, m.TorOffStatusHTML(ours)...)
}
htmlbytes = append(htmlbytes, []byte(`</body>
<html>`)...)
</html>`)...)
return string(htmlbytes), nil
}

View File

@ -2,11 +2,15 @@ package tbserve
import (
"embed"
"io/ioutil"
"log"
"net/http"
"path/filepath"
"strconv"
"strings"
"github.com/justinas/nosurf"
cp "github.com/otiai10/copy"
tbget "i2pgit.org/idk/i2p.plugins.tor-manager/get"
TBSupervise "i2pgit.org/idk/i2p.plugins.tor-manager/supervise"
)
@ -16,6 +20,8 @@ type Client struct {
TBD *tbget.TBDownloader
TBS *TBSupervise.Supervisor
DarkMode bool
Host string
Port int
}
func NewClient(hostname string, lang string, os string, arch string, content *embed.FS) (*Client, error) {
@ -38,8 +44,27 @@ func NewClient(hostname string, lang string, os string, arch string, content *em
return m, nil
}
func (m *Client) GetHost() string {
if m.Host == "" {
m.Host = "127.0.0.1"
}
return m.Host
}
func (m *Client) GetPort() string {
if m.Port == 0 {
m.Port = 7695
}
return strconv.Itoa(m.Port)
}
func (m *Client) GetAddress() string {
return m.GetHost() + ":" + m.GetPort()
}
func (m *Client) ServeHTTP(rw http.ResponseWriter, rq *http.Request) {
path := rq.URL.Path
path := strings.Replace(rq.URL.Path, "..", "", -1)
rq.URL.Path = path
log.Printf("ServeHTTP: '%s'", path)
fileextension := filepath.Ext(path)
switch fileextension {
@ -79,6 +104,10 @@ func (m *Client) ServeHTTP(rw http.ResponseWriter, rq *http.Request) {
log.Println("Stopping Tor")
go m.TBS.StopTor()
http.Redirect(rw, rq, "/", http.StatusFound)
case "/switch-theme":
log.Println("Switching theme")
m.DarkMode = !m.DarkMode
http.Redirect(rw, rq, "/", http.StatusFound)
default:
b, _ := m.Page()
rw.Header().Set("Content-Type", "text/html")
@ -90,6 +119,12 @@ func (m *Client) ServeHTTP(rw http.ResponseWriter, rq *http.Request) {
func (m *Client) Serve() error {
//http.Handle("/", m)
go m.TBS.RunTorWithLang()
return http.ListenAndServe("127.0.0.1:7695", nosurf.New(m))
mirrorjson, err := m.GenerateMirrorJSON()
if err != nil {
return err
}
ioutil.WriteFile(filepath.Join(m.TBD.DownloadPath, "mirror.json"), []byte(mirrorjson), 0644)
cp.Copy(m.TBS.I2PProfilePath(), filepath.Join(m.TBD.DownloadPath, "i2p.firefox"))
go m.TBS.RunTorWithLang()
return http.ListenAndServe(m.GetAddress(), nosurf.New(m))
}

View File

@ -353,6 +353,69 @@ var defaultCSS []byte = []byte(`
width: 100%
}
/* The switch - the box around the slider */
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
/* Hide default HTML checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: #2196F3;
}
input:focus + .slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
`)
var darkDefaultCSS []byte = []byte(`
@ -782,4 +845,68 @@ html {
.NIGHTEYE_TransformZ {
transform: translateZ(0px);
}
/* The switch - the box around the slider */
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
/* Hide default HTML checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: #2196F3;
}
input:focus + .slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
`)

View File

@ -13,6 +13,7 @@ import (
"strings"
"github.com/mitchellh/go-ps"
cp "github.com/otiai10/copy"
tbget "i2pgit.org/idk/i2p.plugins.tor-manager/get"
)
@ -60,24 +61,38 @@ func (s *Supervisor) TorDataPath() string {
return filepath.Join(s.UnpackPath, "Browser", "TorBrowser", "Data")
}
func (s *Supervisor) I2PDataPath() string {
fp := filepath.Join(filepath.Dir(s.UnpackPath), "i2p.firefox")
if tbget.FileExists(fp) {
return fp
} else {
//unpack the embedded profile
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
}
func (s *Supervisor) I2PDataPath() string {
fp := s.I2PProfilePath()
up := filepath.Join(filepath.Dir(s.UnpackPath), "i2p.firefox")
if tbget.FileExists(up) {
return up
} else {
log.Printf("i2p workdir not found at %s, copying", up)
if s.Profile != nil {
if err := cp.Copy(fp, up); err != nil {
log.Fatal(err)
}
}
return up
}
}
func (s *Supervisor) UnpackI2PData() error {
return fs.WalkDir(s.Profile, ".", func(path string, d fs.DirEntry, err error) error {
fp := filepath.Join(filepath.Dir(s.UnpackPath), "i2p.firefox")
fp := filepath.Join(filepath.Dir(s.UnpackPath), ".i2p.firefox")
if err != nil {
log.Fatal(err)
}

View File

@ -3,7 +3,7 @@ Encoding=UTF-8
Version=1.0
Type=Application
Terminal=false
Exec=/bin/sh -c "mkdir -p $HOME/.i2p/browser && cd $HOME/.i2p/browser && torbrowser"
Exec=/bin/sh -c "torbrowser -directory=$HOME/.i2p/browser"
Name=Tor Browser
Categories=Network;WebBrowser;
Icon=/var/lib/i2pbrowser/icons/onion.png