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:
idk
2022-03-07 23:08:40 -05:00
parent 093cb34343
commit b165d9e7f8
4 changed files with 136 additions and 13 deletions

View File

@ -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
View File

@ -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

View File

@ -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)

View 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-----