Set up a system tray application. Download Tor Browser over I2P. This accomplishes all basic features.
This commit is contained in:
@ -43,7 +43,7 @@ The plugin will not start a Tor instance if a SOCKS proxy is open on port 9050.
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
### Primary Goals
|
### Primary Goals(Done):
|
||||||
|
|
||||||
1. Ship known-good public keys, download a current Tor for the platform in the background, authenticate it, and launch it only if necessary.
|
1. Ship known-good public keys, download a current Tor for the platform in the background, authenticate it, and launch it only if necessary.
|
||||||
- Works on Windows, Linux, OSX
|
- Works on Windows, Linux, OSX
|
||||||
@ -54,16 +54,16 @@ The plugin will not start a Tor instance if a SOCKS proxy is open on port 9050.
|
|||||||
4. Work as an I2P Plugin OR as a freestanding app to be compatible with all I2P distributions
|
4. Work as an I2P Plugin OR as a freestanding app to be compatible with all I2P distributions
|
||||||
- Works on Linux, Windows, OSX
|
- Works on Linux, Windows, OSX
|
||||||
5. Download Tor Browser from an in-I2P mirror(or one of a network of in-I2P mirrors)
|
5. Download Tor Browser from an in-I2P mirror(or one of a network of in-I2P mirrors)
|
||||||
- Not done
|
- Works on Linux, Windows, OSX
|
||||||
|
|
||||||
### Secondary Goals:
|
### Secondary Goals(Also done):
|
||||||
|
|
||||||
1. Launch Tor Browser
|
1. Launch Tor Browser
|
||||||
- Works on Linux, Windows, OSX
|
- Works on Linux, Windows, OSX
|
||||||
2. Configure and launch Tor browser for use with I2P
|
2. Configure and launch Tor browser for use with I2P
|
||||||
- Works on Linux, Windows, OSX
|
- Works on Linux, Windows, OSX
|
||||||
|
|
||||||
#### Optional Features I might add if there is interest
|
#### Optional Features I might add if there is interest(Not much stopping me...):
|
||||||
|
|
||||||
1. Mirror the files which it downloads to an I2P Site
|
1. Mirror the files which it downloads to an I2P Site
|
||||||
- Works on Windows, Linux, OSX
|
- Works on Windows, Linux, OSX
|
||||||
|
54
get/get.go
54
get/get.go
@ -24,10 +24,12 @@ import (
|
|||||||
"github.com/itchio/damage"
|
"github.com/itchio/damage"
|
||||||
"github.com/itchio/damage/hdiutil"
|
"github.com/itchio/damage/hdiutil"
|
||||||
"github.com/itchio/headway/state"
|
"github.com/itchio/headway/state"
|
||||||
|
"github.com/magisterquis/connectproxy"
|
||||||
"github.com/ulikunitz/xz"
|
"github.com/ulikunitz/xz"
|
||||||
|
|
||||||
"github.com/jchavannes/go-pgp/pgp"
|
"github.com/jchavannes/go-pgp/pgp"
|
||||||
"golang.org/x/crypto/openpgp"
|
"golang.org/x/crypto/openpgp"
|
||||||
|
"golang.org/x/net/proxy"
|
||||||
)
|
)
|
||||||
|
|
||||||
// WORKING_DIR is the working directory for the application.
|
// WORKING_DIR is the working directory for the application.
|
||||||
@ -74,6 +76,7 @@ type TBDownloader struct {
|
|||||||
DownloadPath string
|
DownloadPath string
|
||||||
Lang string
|
Lang string
|
||||||
OS, ARCH string
|
OS, ARCH string
|
||||||
|
Mirror string
|
||||||
Verbose bool
|
Verbose bool
|
||||||
Profile *embed.FS
|
Profile *embed.FS
|
||||||
}
|
}
|
||||||
@ -252,13 +255,17 @@ func (t *TBDownloader) GetUpdaterForLangFromJSONBytes(jsonBytes []byte, ietf str
|
|||||||
if updater, ok := platform.(map[string]interface{})[rtp]; ok {
|
if updater, ok := platform.(map[string]interface{})[rtp]; ok {
|
||||||
if langUpdater, ok := updater.(map[string]interface{})[ietf]; ok {
|
if langUpdater, ok := updater.(map[string]interface{})[ietf]; ok {
|
||||||
t.Log("GetUpdaterForLangFromJSONBytes()", "Found updater for language")
|
t.Log("GetUpdaterForLangFromJSONBytes()", "Found updater for language")
|
||||||
return langUpdater.(map[string]interface{})["binary"].(string), langUpdater.(map[string]interface{})["sig"].(string), nil
|
bin := langUpdater.(map[string]interface{})["binary"].(string)
|
||||||
|
sig := langUpdater.(map[string]interface{})["sig"].(string)
|
||||||
|
return t.MirrorIze(bin), t.MirrorIze(sig), nil
|
||||||
}
|
}
|
||||||
// If we didn't find the language, try splitting at the hyphen
|
// If we didn't find the language, try splitting at the hyphen
|
||||||
lang := strings.Split(ietf, "-")[0]
|
lang := strings.Split(ietf, "-")[0]
|
||||||
if langUpdater, ok := updater.(map[string]interface{})[lang]; ok {
|
if langUpdater, ok := updater.(map[string]interface{})[lang]; ok {
|
||||||
t.Log("GetUpdaterForLangFromJSONBytes()", "Found updater for backup language")
|
t.Log("GetUpdaterForLangFromJSONBytes()", "Found updater for backup language")
|
||||||
return langUpdater.(map[string]interface{})["binary"].(string), langUpdater.(map[string]interface{})["sig"].(string), nil
|
bin := langUpdater.(map[string]interface{})["binary"].(string)
|
||||||
|
sig := langUpdater.(map[string]interface{})["sig"].(string)
|
||||||
|
return t.MirrorIze(bin), t.MirrorIze(sig), nil
|
||||||
}
|
}
|
||||||
// If we didn't find the language after splitting at the hyphen, try the default
|
// If we didn't find the language after splitting at the hyphen, try the default
|
||||||
t.Log("GetUpdaterForLangFromJSONBytes()", "Last attempt, trying default language")
|
t.Log("GetUpdaterForLangFromJSONBytes()", "Last attempt, trying default language")
|
||||||
@ -269,18 +276,42 @@ func (t *TBDownloader) GetUpdaterForLangFromJSONBytes(jsonBytes []byte, ietf str
|
|||||||
return "", "", fmt.Errorf("t.GetUpdaterForLangFromJSONBytes: %s", ietf)
|
return "", "", fmt.Errorf("t.GetUpdaterForLangFromJSONBytes: %s", ietf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *TBDownloader) MirrorIze(replaceStr string) string {
|
||||||
|
if t.Mirror != "" {
|
||||||
|
return strings.Replace(replaceStr, "https://dist.torproject.org/torbrowser/", t.Mirror, 1)
|
||||||
|
}
|
||||||
|
return replaceStr
|
||||||
|
}
|
||||||
|
|
||||||
// SingleFileDownload downloads a single file from the given URL to the given path.
|
// SingleFileDownload downloads a single file from the given URL to the given path.
|
||||||
// it returns the path to the downloaded file, or an error if one is encountered.
|
// it returns the path to the downloaded file, or an error if one is encountered.
|
||||||
func (t *TBDownloader) SingleFileDownload(url, name string) (string, error) {
|
func (t *TBDownloader) SingleFileDownload(dl, name string) (string, error) {
|
||||||
t.MakeTBDirectory()
|
t.MakeTBDirectory()
|
||||||
path := filepath.Join(t.DownloadPath, name)
|
path := filepath.Join(t.DownloadPath, name)
|
||||||
t.Log("SingleFileDownload()", fmt.Sprintf("Checking for updates %s to %s", url, path))
|
t.Log("SingleFileDownload()", fmt.Sprintf("Checking for updates %s to %s", dl, path))
|
||||||
if !t.BotherToDownload(url, name) {
|
if !t.BotherToDownload(dl, name) {
|
||||||
t.Log("SingleFileDownload()", "File already exists, skipping download")
|
t.Log("SingleFileDownload()", "File already exists, skipping download")
|
||||||
return path, nil
|
return path, nil
|
||||||
}
|
}
|
||||||
|
var d proxy.Dialer
|
||||||
|
if t.MirrorIsI2P() {
|
||||||
|
log.Println("Using I2P mirror, setting up proxy")
|
||||||
|
var err error
|
||||||
|
proxyURL, err := url.Parse("http://127.0.0.1:4444")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
d, err = connectproxy.New(proxyURL, proxy.Direct)
|
||||||
|
if nil != err {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tr := &http.Transport{
|
||||||
|
Dial: d.Dial,
|
||||||
|
}
|
||||||
|
http.DefaultClient.Transport = tr
|
||||||
t.Log("SingleFileDownload()", "Downloading file")
|
t.Log("SingleFileDownload()", "Downloading file")
|
||||||
file, err := http.Get(url)
|
file, err := http.Get(dl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("SingleFileDownload: %s", err)
|
return "", fmt.Errorf("SingleFileDownload: %s", err)
|
||||||
}
|
}
|
||||||
@ -303,17 +334,17 @@ func FileExists(path string) bool {
|
|||||||
|
|
||||||
// BotherToDownload returns true if we need to download a file because we don't have an up-to-date
|
// BotherToDownload returns true if we need to download a file because we don't have an up-to-date
|
||||||
// version yet.
|
// version yet.
|
||||||
func (t *TBDownloader) BotherToDownload(url, name string) bool {
|
func (t *TBDownloader) BotherToDownload(dl, name string) bool {
|
||||||
path := filepath.Join(t.DownloadPath, name)
|
path := filepath.Join(t.DownloadPath, name)
|
||||||
if !FileExists(path) {
|
if !FileExists(path) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
defer ioutil.WriteFile(filepath.Join(t.DownloadPath, name+".last-url"), []byte(url), 0644)
|
defer ioutil.WriteFile(filepath.Join(t.DownloadPath, name+".last-url"), []byte(dl), 0644)
|
||||||
lastURL, err := ioutil.ReadFile(filepath.Join(t.DownloadPath, name+".last-url"))
|
lastURL, err := ioutil.ReadFile(filepath.Join(t.DownloadPath, name+".last-url"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if string(lastURL) == url {
|
if string(lastURL) == dl {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@ -566,3 +597,8 @@ func hTTPProxy(host, port string) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *TBDownloader) MirrorIsI2P() bool {
|
||||||
|
// check if hostname is an I2P hostname
|
||||||
|
return strings.Contains(t.Mirror, ".i2p")
|
||||||
|
}
|
||||||
|
1
go.mod
1
go.mod
@ -25,6 +25,7 @@ require (
|
|||||||
github.com/getlantern/ops v0.0.0-20200403153110-8476b16edcd6 // indirect
|
github.com/getlantern/ops v0.0.0-20200403153110-8476b16edcd6 // indirect
|
||||||
github.com/go-stack/stack v1.8.0 // indirect
|
github.com/go-stack/stack v1.8.0 // indirect
|
||||||
github.com/gtank/cryptopasta v0.0.0-20170601214702-1f550f6f2f69 // indirect
|
github.com/gtank/cryptopasta v0.0.0-20170601214702-1f550f6f2f69 // indirect
|
||||||
|
github.com/magisterquis/connectproxy v0.0.0-20200725203833-3582e84f0c9b // indirect
|
||||||
github.com/mwitkow/go-http-dialer v0.0.0-20161116154839-378f744fb2b8 // indirect
|
github.com/mwitkow/go-http-dialer v0.0.0-20161116154839-378f744fb2b8 // indirect
|
||||||
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect
|
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect
|
||||||
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 // indirect
|
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 // indirect
|
||||||
|
2
go.sum
2
go.sum
@ -273,6 +273,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/magiconair/properties v1.7.4-0.20170902060319-8d7837e64d3c/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
github.com/magiconair/properties v1.7.4-0.20170902060319-8d7837e64d3c/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
|
github.com/magisterquis/connectproxy v0.0.0-20200725203833-3582e84f0c9b h1:xZ59n7Frzh8CwyfAapUZLSg+gXH5m63YEaFCMpDHhpI=
|
||||||
|
github.com/magisterquis/connectproxy v0.0.0-20200725203833-3582e84f0c9b/go.mod h1:uDd4sYVYsqcxAB8j+Q7uhL6IJCs/r1kxib1HV4bgOMg=
|
||||||
github.com/majestrate/i2p-tools v0.0.0-20170507194519-afc8e46afa95/go.mod h1:e/TZ1O6X9t0qitnKc3xvHq8VXDpm/FmYuFf21epEkUc=
|
github.com/majestrate/i2p-tools v0.0.0-20170507194519-afc8e46afa95/go.mod h1:e/TZ1O6X9t0qitnKc3xvHq8VXDpm/FmYuFf21epEkUc=
|
||||||
github.com/mattn/go-colorable v0.0.10-0.20170816031813-ad5389df28cd/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
github.com/mattn/go-colorable v0.0.10-0.20170816031813-ad5389df28cd/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
<figure>
|
<figure>
|
||||||
<img src="screenshot-i2pbrowser.png" alt="" /><figcaption>Screenshot</figcaption>
|
<img src="screenshot-i2pbrowser.png" alt="" /><figcaption>Screenshot</figcaption>
|
||||||
</figure>
|
</figure>
|
||||||
<h3 id="primary-goals">Primary Goals</h3>
|
<h3 id="primary-goalsdone">Primary Goals(Done):</h3>
|
||||||
<ol type="1">
|
<ol type="1">
|
||||||
<li>Ship known-good public keys, download a current Tor for the platform in the background, authenticate it, and launch it only if necessary.</li>
|
<li>Ship known-good public keys, download a current Tor for the platform in the background, authenticate it, and launch it only if necessary.</li>
|
||||||
</ol>
|
</ol>
|
||||||
@ -58,9 +58,9 @@
|
|||||||
<li>Download Tor Browser from an in-I2P mirror(or one of a network of in-I2P mirrors)</li>
|
<li>Download Tor Browser from an in-I2P mirror(or one of a network of in-I2P mirrors)</li>
|
||||||
</ol>
|
</ol>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Not done</li>
|
<li>Works on Linux, Windows, OSX</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h3 id="secondary-goals">Secondary Goals:</h3>
|
<h3 id="secondary-goalsalso-done">Secondary Goals(Also done):</h3>
|
||||||
<ol type="1">
|
<ol type="1">
|
||||||
<li>Launch Tor Browser</li>
|
<li>Launch Tor Browser</li>
|
||||||
</ol>
|
</ol>
|
||||||
@ -73,7 +73,7 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li>Works on Linux, Windows, OSX</li>
|
<li>Works on Linux, Windows, OSX</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h4 id="optional-features-i-might-add-if-there-is-interest">Optional Features I might add if there is interest</h4>
|
<h4 id="optional-features-i-might-add-if-there-is-interestnot-much-stopping-me">Optional Features I might add if there is interest(Not much stopping me…):</h4>
|
||||||
<ol type="1">
|
<ol type="1">
|
||||||
<li>Mirror the files which it downloads to an I2P Site</li>
|
<li>Mirror the files which it downloads to an I2P Site</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
6
main.go
6
main.go
@ -80,10 +80,11 @@ var (
|
|||||||
clearnet = flag.Bool("clearnet", false, "Use clearnet (no Tor or I2P)")
|
clearnet = flag.Bool("clearnet", false, "Use clearnet (no Tor or I2P)")
|
||||||
profile = flag.String("profile", "", "use a custom profile path, normally blank")
|
profile = flag.String("profile", "", "use a custom profile path, normally blank")
|
||||||
help = flag.Bool("help", false, "Print help")
|
help = flag.Bool("help", false, "Print help")
|
||||||
|
mirror = flag.String("mirror", "http://dist.torproject.i2p/torbrowser/", "Mirror to use")
|
||||||
/*onion = flag.Bool("onion", false, "Serve an onion site which shows some I2P propaganda, magnet links, your I2P mirror URL if configured")*/
|
/*onion = flag.Bool("onion", false, "Serve an onion site which shows some I2P propaganda, magnet links, your I2P mirror URL if configured")*/
|
||||||
/*torrent = flag.Bool("torrent", false, "Create a torrent of the downloaded files and seed it over I2P using an Open Tracker")*/
|
/*torrent = flag.Bool("torrent", false, "Create a torrent of the downloaded files and seed it over I2P using an Open Tracker")*/
|
||||||
/*ptop = flag.Bool("p2p", false, "Use bittorrent over I2P to download the initial copy of Tor Browser")*/
|
/*ptop = flag.Bool("p2p", false, "Use bittorrent over I2P to download the initial copy of Tor Browser")*/
|
||||||
/*mirror = flag.String("mirror", "", "Mirror to use")*/
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var client *tbserve.Client
|
var client *tbserve.Client
|
||||||
@ -115,7 +116,6 @@ func main() {
|
|||||||
} else if filename == "firefox" || *clearnet || *offline {
|
} else if filename == "firefox" || *clearnet || *offline {
|
||||||
*clearnet = true
|
*clearnet = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if *profile == "" {
|
if *profile == "" {
|
||||||
if *offline {
|
if *offline {
|
||||||
*profile = filepath.Join(tbget.WORKING_DIR, "profile.firefox.offline")
|
*profile = filepath.Join(tbget.WORKING_DIR, "profile.firefox.offline")
|
||||||
@ -139,7 +139,7 @@ func main() {
|
|||||||
log.Println("Using auto-detected language", *lang)
|
log.Println("Using auto-detected language", *lang)
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
client, err = tbserve.NewClient(*verbose, *lang, *system, *arch, &content)
|
client, err = tbserve.NewClient(*verbose, *lang, *system, *arch, *mirror, &content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Couldn't create client", err)
|
log.Fatal("Couldn't create client", err)
|
||||||
}
|
}
|
||||||
|
@ -28,10 +28,11 @@ type Client struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewClient creates a new Client.
|
// NewClient creates a new Client.
|
||||||
func NewClient(verbose bool, lang string, os string, arch string, content *embed.FS) (*Client, error) {
|
func NewClient(verbose bool, lang, os, arch, mirror string, content *embed.FS) (*Client, error) {
|
||||||
m := &Client{
|
m := &Client{
|
||||||
TBD: tbget.NewTBDownloader(lang, os, arch, content),
|
TBD: tbget.NewTBDownloader(lang, os, arch, content),
|
||||||
}
|
}
|
||||||
|
m.TBD.Mirror = mirror
|
||||||
m.TBD.Verbose = verbose
|
m.TBD.Verbose = verbose
|
||||||
m.TBD.MakeTBDirectory()
|
m.TBD.MakeTBDirectory()
|
||||||
tgz, sig, err := m.TBD.DownloadUpdaterForLang(lang)
|
tgz, sig, err := m.TBD.DownloadUpdaterForLang(lang)
|
||||||
|
Reference in New Issue
Block a user