actually implement torrent-based sharing of tor browser
This commit is contained in:
@ -77,6 +77,7 @@ type TBDownloader struct {
|
|||||||
Mirror string
|
Mirror string
|
||||||
Verbose bool
|
Verbose bool
|
||||||
Profile *embed.FS
|
Profile *embed.FS
|
||||||
|
listener net.Listener
|
||||||
}
|
}
|
||||||
|
|
||||||
// OS is the operating system of the TBDownloader.
|
// OS is the operating system of the TBDownloader.
|
||||||
@ -118,12 +119,13 @@ func (t *TBDownloader) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// Serve runs ServeHTTP on an I2P listener
|
// Serve runs ServeHTTP on an I2P listener
|
||||||
func (t *TBDownloader) Serve() {
|
func (t *TBDownloader) Serve() {
|
||||||
samlistener, err := sam.I2PListener("tor-mirror", "127.0.0.1:7656", "tor-mirror")
|
var err error
|
||||||
|
t.listener, err = sam.I2PListener("tor-mirror", "127.0.0.1:7656", "tor-mirror")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
defer samlistener.Close()
|
defer t.listener.Close()
|
||||||
http.Serve(samlistener, t)
|
http.Serve(t.listener, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRuntimePair returns the runtime.GOOS and runtime.GOARCH pair.
|
// GetRuntimePair returns the runtime.GOOS and runtime.GOARCH pair.
|
||||||
|
155
get/torrent.go
Normal file
155
get/torrent.go
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
package tbget
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/eyedeekay/sam3/i2pkeys"
|
||||||
|
cp "github.com/otiai10/copy"
|
||||||
|
"github.com/xgfone/bt/bencode"
|
||||||
|
"github.com/xgfone/bt/metainfo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (t *TBDownloader) DownloadedFilesList() ([]string, error) {
|
||||||
|
files, err := ioutil.ReadDir(t.DownloadPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var list []string
|
||||||
|
for _, f := range files {
|
||||||
|
list = append(list, f.Name())
|
||||||
|
}
|
||||||
|
return list, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TBDownloader) GenerateMissingTorrents() error {
|
||||||
|
files, err := t.DownloadedFilesList()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, f := range files {
|
||||||
|
fp := filepath.Join(t.DownloadPath, f+".torrent")
|
||||||
|
af := filepath.Join(t.DownloadPath, f)
|
||||||
|
if !strings.HasSuffix(af, ".torrent") {
|
||||||
|
os.Remove(fp)
|
||||||
|
log.Println("Generating torrent for", fp)
|
||||||
|
meta, err := t.GenerateTorrent(af, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
file, err := os.Create(fp)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
meta.Write(file)
|
||||||
|
file.Close()
|
||||||
|
}
|
||||||
|
snark, err := FundSnarkDirectory()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sf := filepath.Join(snark, f)
|
||||||
|
sfp := filepath.Join(snark, f+".torrent")
|
||||||
|
log.Println("Copying", af, "to", sf)
|
||||||
|
cp.Copy(af, sf)
|
||||||
|
log.Println("Copying", fp, "to", sfp)
|
||||||
|
cp.Copy(fp, sfp)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TBDownloader) GenerateTorrent(file string, announces []string) (*metainfo.MetaInfo, error) {
|
||||||
|
info, err := metainfo.NewInfoFromFilePath(file, 5120)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("GenerateTorrent:", err)
|
||||||
|
}
|
||||||
|
info.Name = filepath.Base(file)
|
||||||
|
|
||||||
|
var mi metainfo.MetaInfo
|
||||||
|
mi.InfoBytes, err = bencode.EncodeBytes(info)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("GenerateTorrent:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch len(announces) {
|
||||||
|
case 0:
|
||||||
|
mi.Announce = "http://mb5ir7klpc2tj6ha3xhmrs3mseqvanauciuoiamx2mmzujvg67uq.b32.i2p/a"
|
||||||
|
case 1:
|
||||||
|
mi.Announce = announces[0]
|
||||||
|
default:
|
||||||
|
mi.AnnounceList = metainfo.AnnounceList{announces}
|
||||||
|
}
|
||||||
|
var url *url.URL
|
||||||
|
if t.listener != nil {
|
||||||
|
url, err = url.Parse("http://" + t.listener.Addr().(i2pkeys.I2PAddr).Base32() + "/" + filepath.Base(file))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("GenerateTorrent:", err)
|
||||||
|
}
|
||||||
|
if t.Mirror != "" {
|
||||||
|
mi.URLList = []string{url.String()}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &mi, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func FundSnarkDirectory() (string, error) {
|
||||||
|
// Snark could be at:
|
||||||
|
// or: $I2P_CONFIG/i2psnark/
|
||||||
|
// or: $I2P/i2psnark/
|
||||||
|
// or: $HOME/.i2p/i2psnark/
|
||||||
|
// or: /var/lib/i2p/i2p-config/i2psnark/
|
||||||
|
// or: %LOCALAPPDATA\i2p\i2psnark\
|
||||||
|
// or: %APPDATA\i2p\i2psnark\
|
||||||
|
|
||||||
|
I2P_CONFIG := os.Getenv("I2P_CONFIG")
|
||||||
|
if I2P_CONFIG != "" {
|
||||||
|
checkfori2pcustom := filepath.Join(I2P_CONFIG, "i2psnark")
|
||||||
|
if FileExists(checkfori2pcustom) {
|
||||||
|
return checkfori2pcustom, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
I2P := os.Getenv("I2P")
|
||||||
|
if I2P != "" {
|
||||||
|
checkfori2p := filepath.Join(I2P, "i2psnark")
|
||||||
|
if FileExists(checkfori2p) {
|
||||||
|
return checkfori2p, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
home, err := os.UserHomeDir()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
// Start by getting the home directory
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "windows":
|
||||||
|
checkfori2plocal := filepath.Join(home, "AppData", "Local", "i2p", "i2psnark")
|
||||||
|
if FileExists(checkfori2plocal) {
|
||||||
|
return checkfori2plocal, nil
|
||||||
|
}
|
||||||
|
checkfori2proaming := filepath.Join(home, "AppData", "Roaming", "i2p", "i2psnark")
|
||||||
|
if FileExists(checkfori2proaming) {
|
||||||
|
return checkfori2proaming, nil
|
||||||
|
}
|
||||||
|
case "linux":
|
||||||
|
checkfori2phome := filepath.Join(home, ".i2p", "i2psnark")
|
||||||
|
if FileExists(checkfori2phome) {
|
||||||
|
return checkfori2phome, nil
|
||||||
|
}
|
||||||
|
checkfori2pservice := filepath.Join("/var/lib/i2p/i2p-config", "i2psnark")
|
||||||
|
if FileExists(checkfori2pservice) {
|
||||||
|
return checkfori2pservice, nil
|
||||||
|
}
|
||||||
|
case "darwin":
|
||||||
|
return "", fmt.Errorf("Automatic torrent generation is not supported on MacOS for now, for now copy the files manually.")
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("Unable to find snark directory")
|
||||||
|
}
|
1
go.mod
1
go.mod
@ -69,6 +69,7 @@ require (
|
|||||||
github.com/sirupsen/logrus v1.4.2 // indirect
|
github.com/sirupsen/logrus v1.4.2 // indirect
|
||||||
github.com/src-d/gcfg v1.4.0 // indirect
|
github.com/src-d/gcfg v1.4.0 // indirect
|
||||||
github.com/xanzy/ssh-agent v0.2.1 // indirect
|
github.com/xanzy/ssh-agent v0.2.1 // indirect
|
||||||
|
github.com/xgfone/bt v0.4.1 // indirect
|
||||||
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
|
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
|
||||||
github.com/zieckey/goini v0.0.0-20180118150432-0da17d361d26 // indirect
|
github.com/zieckey/goini v0.0.0-20180118150432-0da17d361d26 // indirect
|
||||||
golang.org/x/text v0.3.6 // indirect
|
golang.org/x/text v0.3.6 // indirect
|
||||||
|
2
go.sum
2
go.sum
@ -395,6 +395,8 @@ github.com/veandco/go-sdl2 v0.4.0/go.mod h1:FB+kTpX9YTE+urhYiClnRzpOXbiWgaU3+5F2
|
|||||||
github.com/walle/targz v0.0.0-20140417120357-57fe4206da5a/go.mod h1:nccQrXCnc5SjsThFLmL7hYbtT/mHJcuolPifzY5vJqE=
|
github.com/walle/targz v0.0.0-20140417120357-57fe4206da5a/go.mod h1:nccQrXCnc5SjsThFLmL7hYbtT/mHJcuolPifzY5vJqE=
|
||||||
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
|
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
|
||||||
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
|
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
|
||||||
|
github.com/xgfone/bt v0.4.1 h1:51j3Mv9wqn415JsYJTYUIlMgcB3dAdQgnNPXDhwS78E=
|
||||||
|
github.com/xgfone/bt v0.4.1/go.mod h1:/GuvKo3WdkvlVahN84cjVWyia9ZJoxx/3BFIFZ5eGI4=
|
||||||
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
|
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
|
||||||
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
|
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
|
||||||
github.com/ybbus/jsonrpc v2.1.2+incompatible h1:V4mkE9qhbDQ92/MLMIhlhMSbz8jNXdagC3xBR5NDwaQ=
|
github.com/ybbus/jsonrpc v2.1.2+incompatible h1:V4mkE9qhbDQ92/MLMIhlhMSbz8jNXdagC3xBR5NDwaQ=
|
||||||
|
9
main.go
9
main.go
@ -85,7 +85,7 @@ var (
|
|||||||
//mirror = flag.String("mirror", "http://dist.torproject.i2p/torbrowser/", "Mirror to use")
|
//mirror = flag.String("mirror", "http://dist.torproject.i2p/torbrowser/", "Mirror to use")
|
||||||
mirror = flag.String("mirror", "http://dist.torproject.org/torbrowser/", "Mirror to use")
|
mirror = flag.String("mirror", "http://dist.torproject.org/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")*/
|
||||||
|
|
||||||
)
|
)
|
||||||
@ -233,6 +233,13 @@ func main() {
|
|||||||
}
|
}
|
||||||
client.TBS.UnpackI2PAppData()
|
client.TBS.UnpackI2PAppData()
|
||||||
client.TBS.UnpackI2PData()
|
client.TBS.UnpackI2PData()
|
||||||
|
if *torrent {
|
||||||
|
log.Println("Generating I2P torrents of Tor packages")
|
||||||
|
if err := client.TBD.GenerateMissingTorrents(); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if *i2pbrowser {
|
if *i2pbrowser {
|
||||||
if err := client.TBS.RunI2PBWithLang(); err != nil {
|
if err := client.TBS.RunI2PBWithLang(); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
Reference in New Issue
Block a user