add an arm64 variant, not supported by Tor Project Official but contributed by a community member, to make it work on Raspberry Pi's.
This commit is contained in:
63
get/get.go
63
get/get.go
@ -150,7 +150,7 @@ func (t *TBDownloader) GetRuntimePair() string {
|
|||||||
case "386":
|
case "386":
|
||||||
t.ARCH = "32"
|
t.ARCH = "32"
|
||||||
default:
|
default:
|
||||||
t.ARCH = "unknown"
|
t.ARCH = "64"
|
||||||
}
|
}
|
||||||
if t.OS != "osx" {
|
if t.OS != "osx" {
|
||||||
return fmt.Sprintf("%s%s", t.OS, t.ARCH)
|
return fmt.Sprintf("%s%s", t.OS, t.ARCH)
|
||||||
@ -201,8 +201,13 @@ func (t *TBDownloader) Log(function, message string) {
|
|||||||
func (t *TBDownloader) MakeTBDirectory() {
|
func (t *TBDownloader) MakeTBDirectory() {
|
||||||
os.MkdirAll(t.DownloadPath, 0755)
|
os.MkdirAll(t.DownloadPath, 0755)
|
||||||
|
|
||||||
empath := path.Join("tor-browser", "TPO-signing-key.pub")
|
tpk := "TPO-signing-key.pub"
|
||||||
opath := filepath.Join(t.DownloadPath, "TPO-signing-key.pub")
|
if t.OS == "linux" && runtime.GOARCH == "arm64" {
|
||||||
|
tpk = "NOT-TPO-signing-key.pub"
|
||||||
|
}
|
||||||
|
|
||||||
|
empath := path.Join("tor-browser", tpk)
|
||||||
|
opath := filepath.Join(t.DownloadPath, tpk)
|
||||||
if !FileExists(opath) {
|
if !FileExists(opath) {
|
||||||
t.Log("MakeTBDirectory()", "Initial TPO signing key not found, using the one embedded in the executable")
|
t.Log("MakeTBDirectory()", "Initial TPO signing key not found, using the one embedded in the executable")
|
||||||
bytes, err := t.Profile.ReadFile(empath)
|
bytes, err := t.Profile.ReadFile(empath)
|
||||||
@ -278,6 +283,16 @@ func (t *TBDownloader) GetUpdaterForLangFromJSONBytes(jsonBytes []byte, ietf str
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *TBDownloader) MirrorIze(replaceStr string) string {
|
func (t *TBDownloader) MirrorIze(replaceStr string) string {
|
||||||
|
if t.OS == "linux" && runtime.GOARCH == "arm64" {
|
||||||
|
replaceStr = strings.Replace(replaceStr, "linux64", "linux-arm64", -1)
|
||||||
|
if strings.HasSuffix(replaceStr, ".tar.xz.asc") {
|
||||||
|
//sha256sums-unsigned-build.txt.asc
|
||||||
|
lastElement := filepath.Base(
|
||||||
|
strings.Replace(replaceStr, "https://", strings.Replace(replaceStr, "http://", "", 1), 1),
|
||||||
|
)
|
||||||
|
replaceStr = strings.Replace(replaceStr, lastElement, "sha256sums-unsigned-build.txt.asc", -1)
|
||||||
|
}
|
||||||
|
}
|
||||||
if t.Mirror != "" {
|
if t.Mirror != "" {
|
||||||
return strings.Replace(replaceStr, "https://dist.torproject.org/torbrowser/", t.Mirror, 1)
|
return strings.Replace(replaceStr, "https://dist.torproject.org/torbrowser/", t.Mirror, 1)
|
||||||
}
|
}
|
||||||
@ -326,6 +341,26 @@ func (t *TBDownloader) SingleFileDownload(dl, name string) (string, error) {
|
|||||||
Dial: d.Dial,
|
Dial: d.Dial,
|
||||||
}
|
}
|
||||||
http.DefaultClient.Transport = tr
|
http.DefaultClient.Transport = tr
|
||||||
|
} else {
|
||||||
|
log.Println("Not using I2P mirror, checking if system Tor can be used to download")
|
||||||
|
if !strings.Contains(t.Mirror, "127.0.0.1") {
|
||||||
|
if tmp, torerr := net.Listen("tcp", "127.0.0.1:9050"); torerr != nil {
|
||||||
|
proxyURL, err := url.Parse("http://127.0.0.1:9050")
|
||||||
|
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
|
||||||
|
} else {
|
||||||
|
tmp.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
t.Log("SingleFileDownload()", "Downloading file")
|
t.Log("SingleFileDownload()", "Downloading file")
|
||||||
file, err := http.Get(dl)
|
file, err := http.Get(dl)
|
||||||
@ -392,28 +427,35 @@ func (t *TBDownloader) NamePerPlatform(ietf string) string {
|
|||||||
// DownloadUpdater downloads the updater for the t.Lang. It returns
|
// DownloadUpdater downloads the updater for the t.Lang. It returns
|
||||||
// the path to the downloaded updater and the downloaded detatched signature,
|
// the path to the downloaded updater and the downloaded detatched signature,
|
||||||
// or an error if one is encountered.
|
// or an error if one is encountered.
|
||||||
func (t *TBDownloader) DownloadUpdater() (string, string, error) {
|
func (t *TBDownloader) DownloadUpdater() (string, string, string, error) {
|
||||||
return t.DownloadUpdaterForLang(t.Lang)
|
return t.DownloadUpdaterForLang(t.Lang)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DownloadUpdaterForLang downloads the updater for the given language, overriding
|
// DownloadUpdaterForLang downloads the updater for the given language, overriding
|
||||||
// t.Lang. It returns the path to the downloaded updater and the downloaded
|
// t.Lang. It returns the path to the downloaded updater and the downloaded
|
||||||
// detatched signature, or an error if one is encountered.
|
// detatched signature, or an error if one is encountered.
|
||||||
func (t *TBDownloader) DownloadUpdaterForLang(ietf string) (string, string, error) {
|
func (t *TBDownloader) DownloadUpdaterForLang(ietf string) (string, string, string, error) {
|
||||||
binary, sig, err := t.GetUpdaterForLang(ietf)
|
binary, sig, err := t.GetUpdaterForLang(ietf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", fmt.Errorf("DownloadUpdaterForLang: %s", err)
|
return "", "", "", fmt.Errorf("DownloadUpdaterForLang: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
sigpath, err := t.SingleFileDownload(sig, t.NamePerPlatform(ietf)+".asc")
|
sigpath, err := t.SingleFileDownload(sig, t.NamePerPlatform(ietf)+".asc")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", fmt.Errorf("DownloadUpdaterForLang: %s", err)
|
return "", "", "", fmt.Errorf("DownloadUpdaterForLang: %s", err)
|
||||||
}
|
}
|
||||||
binpath, err := t.SingleFileDownload(binary, t.NamePerPlatform(ietf))
|
binpath, err := t.SingleFileDownload(binary, t.NamePerPlatform(ietf))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", sigpath, fmt.Errorf("DownloadUpdaterForLang: %s", err)
|
return "", sigpath, "", fmt.Errorf("DownloadUpdaterForLang: %s", err)
|
||||||
}
|
}
|
||||||
return binpath, sigpath, nil
|
var sumpath string
|
||||||
|
if t.OS == "linux" && runtime.GOARCH == "arm64" {
|
||||||
|
sumpath, err = t.SingleFileDownload("https://sourceforge.net/projects/tor-browser-ports/files/11.0.6/sha256sums-unsigned-build.txt/download", t.NamePerPlatform(ietf)+".sha256sums")
|
||||||
|
if err != nil {
|
||||||
|
return "", sigpath, sumpath, fmt.Errorf("DownloadUpdaterForLang: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return binpath, sigpath, sumpath, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// BrowserDir returns the path to the directory where the browser is installed.
|
// BrowserDir returns the path to the directory where the browser is installed.
|
||||||
@ -517,6 +559,9 @@ func (t *TBDownloader) UnpackUpdater(binpath string) (string, error) {
|
|||||||
// runs the updater and returns an error if one is encountered.
|
// runs the updater and returns an error if one is encountered.
|
||||||
func (t *TBDownloader) CheckSignature(binpath, sigpath string) (string, error) {
|
func (t *TBDownloader) CheckSignature(binpath, sigpath string) (string, error) {
|
||||||
pk := filepath.Join(t.DownloadPath, "TPO-signing-key.pub")
|
pk := filepath.Join(t.DownloadPath, "TPO-signing-key.pub")
|
||||||
|
if t.OS == "linux" && runtime.GOARCH == "arm64" {
|
||||||
|
pk = filepath.Join(t.DownloadPath, "NOT-TPO-signing-key.pub")
|
||||||
|
}
|
||||||
var err error
|
var err error
|
||||||
if err = Verify(pk, sigpath, binpath); err == nil {
|
if err = Verify(pk, sigpath, binpath); err == nil {
|
||||||
t.Log("CheckSignature: signature", "verified successfully")
|
t.Log("CheckSignature: signature", "verified successfully")
|
||||||
|
13
main.go
13
main.go
@ -30,6 +30,7 @@ TODO: A "Default" config file which uses hardened Tor Browser for clearnet
|
|||||||
//go:embed tor-browser/unpack/i2p.firefox.config/*
|
//go:embed tor-browser/unpack/i2p.firefox.config/*
|
||||||
//go:embed tor-browser/unpack/awo@eyedeekay.github.io.xpi
|
//go:embed tor-browser/unpack/awo@eyedeekay.github.io.xpi
|
||||||
//go:embed tor-browser/TPO-signing-key.pub
|
//go:embed tor-browser/TPO-signing-key.pub
|
||||||
|
//go:embed tor-browser/NOT-TPO-signing-key.pub
|
||||||
//go:embed garliconion.png
|
//go:embed garliconion.png
|
||||||
//go:embed onion.png
|
//go:embed onion.png
|
||||||
//go:embed torbrowser.desktop
|
//go:embed torbrowser.desktop
|
||||||
@ -91,7 +92,7 @@ var (
|
|||||||
if one is unavailable, we download over I2P instead. This is pretty fast these days really, but for
|
if one is unavailable, we download over I2P instead. This is pretty fast these days really, but for
|
||||||
77 or so MB it's noticably delayed still. In "clearnet" modes, it might make sense to default to
|
77 or so MB it's noticably delayed still. In "clearnet" modes, it might make sense to default to
|
||||||
this mirror instead of the I2P one, or maybe offer a convenience option for just the download.*/
|
this mirror instead of the I2P one, or maybe offer a convenience option for just the download.*/
|
||||||
mirror = flag.String("mirror", "https://dist.torproject.org/torbrowser/", "Mirror to use")
|
mirror = flag.String("mirror", Mirror(), "Mirror to use")
|
||||||
solidarity = flag.Bool("onion", false, "Serve an onion site which shows some I2P propaganda")
|
solidarity = flag.Bool("onion", false, "Serve an onion site which shows some I2P propaganda")
|
||||||
torrent = flag.Bool("torrent", tbget.TorrentReady(), "Create a torrent of the downloaded files and seed it over I2P using an Open Tracker")
|
torrent = flag.Bool("torrent", tbget.TorrentReady(), "Create a torrent of the downloaded files and seed it over I2P using an Open Tracker")
|
||||||
destruct = flag.Bool("destruct", false, "Destructively delete the working directory when finished")
|
destruct = flag.Bool("destruct", false, "Destructively delete the working directory when finished")
|
||||||
@ -100,6 +101,16 @@ var (
|
|||||||
/*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")*/
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func Mirror() string {
|
||||||
|
if tbget.TorrentReady() {
|
||||||
|
return "http://127.0.0.1:7657/i2psnark/"
|
||||||
|
}
|
||||||
|
if runtime.GOOS == "linux" && runtime.GOARCH == "arm64" {
|
||||||
|
return "https://sourceforge.net/projects/tor-browser-ports/files"
|
||||||
|
}
|
||||||
|
return "https://dist.torproject.org/torbrowser/"
|
||||||
|
}
|
||||||
|
|
||||||
var snowflake *bool
|
var snowflake *bool
|
||||||
|
|
||||||
var client *tbserve.Client
|
var client *tbserve.Client
|
||||||
|
@ -2,14 +2,19 @@ package tbserve
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/sha256"
|
||||||
"embed"
|
"embed"
|
||||||
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/justinas/nosurf"
|
"github.com/justinas/nosurf"
|
||||||
cp "github.com/otiai10/copy"
|
cp "github.com/otiai10/copy"
|
||||||
@ -31,9 +36,9 @@ type Client struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewClient creates a new Client.
|
// NewClient creates a new Client.
|
||||||
func NewClient(verbose bool, lang, os, arch, mirror 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.Mirror = mirror
|
||||||
m.TBD.Verbose = verbose
|
m.TBD.Verbose = verbose
|
||||||
@ -43,10 +48,51 @@ func NewClient(verbose bool, lang, os, arch, mirror string, content *embed.FS) (
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
tgz, sig, err := m.TBD.DownloadUpdaterForLang(lang)
|
tgz, sig, sums, err := m.TBD.DownloadUpdaterForLang(lang)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
sum := ""
|
||||||
|
if sums != "" {
|
||||||
|
b, err := ioutil.ReadFile(sums)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
// find the line containing the checksum of our tgz file
|
||||||
|
for _, line := range strings.Split(string(b), "\n") {
|
||||||
|
if strings.Contains(line, lang+".tar.xz") {
|
||||||
|
sum = strings.Split(line, " ")[0]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Println("Checksum for ARM:" + sum)
|
||||||
|
// compute the sha256sum of the downloaded tar.xz file
|
||||||
|
f, err := os.Open(tgz)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
h := sha256.New()
|
||||||
|
if _, err := io.Copy(h, f); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
f.Close()
|
||||||
|
if sum != hex.EncodeToString(h.Sum(nil)) {
|
||||||
|
log.Fatal("Checksum mismatch")
|
||||||
|
}
|
||||||
|
var home string
|
||||||
|
if home, err = m.TBD.CheckSignature(sums, sig); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
} else {
|
||||||
|
_, err = m.TBD.UnpackUpdater(tgz)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unpacking updater: %v", err)
|
||||||
|
}
|
||||||
|
log.Printf("Signature check passed: %s %s", tgz, sig)
|
||||||
|
}
|
||||||
|
m.TBS = TBSupervise.NewSupervisor(home, lang)
|
||||||
|
go m.TBS.RunTorWithLang()
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
var home string
|
var home string
|
||||||
if home, err = m.TBD.CheckSignature(tgz, sig); err != nil {
|
if home, err = m.TBD.CheckSignature(tgz, sig); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
21
tor-browser/NOT-TPO-signing-key.pub
Normal file
21
tor-browser/NOT-TPO-signing-key.pub
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
mDMEYLy7zxYJKwYBBAHaRw8BAQdA5PXKfnbxV/lViTGAgW34jh2jVahatLnFgKpU
|
||||||
|
i1aZVqW0HkhlaWtraSBMaW5kaG9sbSA8aG9saW5AaWtpLmZpPoiaBBMWCgBCFiEE
|
||||||
|
JPFBo7mItsNQuTdYavFdHkX9zskFAmC8u88CGwEFCQWjmoAFCwkIBwIDIgIBBhUK
|
||||||
|
CQgLAgQWAgMBAh4HAheAAAoJEGrxXR5F/c7Jp7gBAL8vm5jf36L+SL2+MsiX6pYi
|
||||||
|
uVvEMs0Fqns5UmH+eO9CAP9sTv4e1XUSG3kcNPxDHNhb390EALIKJOafuzIUFOkt
|
||||||
|
AbgzBGC8vBMWCSsGAQQB2kcPAQEHQHkjBFnRo4dXVzwJ0PTECXGk2no5CMTXwqWc
|
||||||
|
XNmrDlfFiPUEGBYKACYWIQQk8UGjuYi2w1C5N1hq8V0eRf3OyQUCYLy8EwIbAgUJ
|
||||||
|
AeEzgACBCRBq8V0eRf3OyXYgBBkWCgAdFiEEnQ+3JDWrYv30FZVUWJDtuAD3xT0F
|
||||||
|
AmC8vBMACgkQWJDtuAD3xT1KHQEAp6gkZRQYzLLCEnFDronvnGgPRMgfnzs3eCFW
|
||||||
|
x843EJoA/RWbZQeuv2tgh7pUYJk5Kzoi6PCklnw2DWuhJST9QPYMxbUBAJeTn5+q
|
||||||
|
fMa1fGLF6rcr1yvf2cO0u5ow45Tft0+jxjMNAQDlp0YaC4vF0dJF8QyWMAwgNbms
|
||||||
|
OfPns7bfiACf4DnrB7g4BGC8vFISCisGAQQBl1UBBQEBB0BZCKDIGp38Qw2HtRXj
|
||||||
|
iZcIrNUjZRKo7QuMcdZy+/gzWgMBCAeIfgQYFgoAJhYhBCTxQaO5iLbDULk3WGrx
|
||||||
|
XR5F/c7JBQJgvLxSAhsMBQkFo5qAAAoJEGrxXR5F/c7Jw8EBAMlDEXhUjZFnuwPy
|
||||||
|
hMSepnihBjoHZnmoI4EdcD40iYoLAQD9FSwq0k5Zs9rQ8U3zyif72YUS89lXoU6N
|
||||||
|
Y7OFUzKJAw==
|
||||||
|
=kH4r
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
Reference in New Issue
Block a user