2022-07-20 13:18:28 -04:00
//go:build !darwin
// +build !darwin
2022-03-03 23:23:15 -05:00
package main
import (
2022-03-04 12:40:25 -05:00
"embed"
2022-03-03 23:23:15 -05:00
"io"
"log"
"net/http"
"os"
2022-07-10 04:08:23 -04:00
flag "github.com/spf13/pflag"
2022-04-11 11:12:21 -04:00
"fyne.io/systray"
2022-03-03 23:23:15 -05:00
"i2pgit.org/idk/blizzard/icon"
"git.torproject.org/pluggable-transports/snowflake.git/common/safelog"
sf "git.torproject.org/pluggable-transports/snowflake.git/proxy/lib"
)
2022-03-04 12:40:25 -05:00
//go:embed tor-browser/www/home.css
//go:embed tor-browser/www/index.html
//go:embed tor-browser/www/blizzard.png
var snowflakeContent embed . FS
2022-03-03 23:23:15 -05:00
var snowflakeProxy sf . SnowflakeProxy
var (
capacity = flag . Uint ( "snowflake-capacity" , 0 , "maximum concurrent clients" )
stunURL = flag . String ( "snowflake-stun" , sf . DefaultSTUNURL , "broker URL" )
logFilename = flag . String ( "snowflake-log" , "" , "log filename" )
rawBrokerURL = flag . String ( "snowflake-broker" , sf . DefaultBrokerURL , "broker URL" )
unsafeLogging = flag . Bool ( "snowflake-unsafe-logging" , false , "prevent logs from being scrubbed" )
keepLocalAddresses = flag . Bool ( "snowflake-keep-local-addresses" , false , "keep local LAN address ICE candidates" )
relayURL = flag . String ( "snowflake-relay" , sf . DefaultRelayURL , "websocket relay URL" )
snowflakeDirectory = flag . String ( "snowflake-directory" , "" , "directory with a page to serve locally for your snowflake. If empty, no local page is served." )
snowflakePort = flag . String ( "snowflake-port" , "7676" , "port to serve info page(directory) on" )
)
func SnowflakeFlag ( ) {
snowflake = flag . Bool ( "snowflake" , false , "Offer a Snowflake to other Tor Browser users" )
}
func Snowflake ( ) {
snowflakeProxy = sf . SnowflakeProxy {
Capacity : uint ( * capacity ) ,
STUNURL : * stunURL ,
BrokerURL : * rawBrokerURL ,
KeepLocalAddresses : * keepLocalAddresses ,
RelayURL : * relayURL ,
}
var logOutput io . Writer = os . Stderr
log . SetFlags ( log . LstdFlags | log . LUTC )
log . SetFlags ( log . LstdFlags | log . LUTC )
if * logFilename != "" {
f , err := os . OpenFile ( * logFilename , os . O_CREATE | os . O_WRONLY | os . O_APPEND , 0600 )
if err != nil {
log . Fatal ( err )
}
defer f . Close ( )
logOutput = io . MultiWriter ( os . Stderr , f )
}
if * unsafeLogging {
log . SetOutput ( logOutput )
} else {
log . SetOutput ( & safelog . LogScrubber { Output : logOutput } )
}
go func ( ) {
2022-03-04 12:40:25 -05:00
if * directory != "" {
http . Handle ( "/" , http . FileServer ( http . Dir ( * snowflakeDirectory ) ) )
} else {
http . Handle ( "/" , http . FileServer ( http . FS ( snowflakeContent ) ) )
}
2022-03-03 23:23:15 -05:00
log . Printf ( "Serving %s on HTTP localhost:snowflakePort: %s\n" , * snowflakeDirectory , * snowflakePort )
log . Fatal ( http . ListenAndServe ( "localhost:" + * snowflakePort , nil ) )
} ( )
err := snowflakeProxy . Start ( )
if err != nil {
log . Fatal ( err )
}
}
func onSnowflakeReady ( ) {
2022-03-03 23:37:47 -05:00
if ! * snowflake {
return
}
mSnowflakeQuit := systray . AddMenuItem ( "Stop Snowflake" , "Close the application and stop your snowflake." )
2022-03-03 23:23:15 -05:00
// Sets the icon of a menu item. Only available on Mac and Windows.
2022-03-03 23:37:47 -05:00
mSnowflakeQuit . SetIcon ( icon . Data )
2022-03-03 23:23:15 -05:00
runloop := true
for runloop {
select {
2022-03-03 23:37:47 -05:00
case <- mSnowflakeQuit . ClickedCh :
2022-03-03 23:23:15 -05:00
snowflakeProxy . Stop ( )
runloop = false
2022-03-03 23:37:47 -05:00
log . Println ( "Snowflake stopped" )
2022-03-03 23:23:15 -05:00
}
}
}
func onSnowflakeExit ( ) {
2022-03-07 16:25:34 -05:00
if ! * snowflake {
return
}
2022-03-03 23:23:15 -05:00
log . Println ( "Stopping the Snowflake" )
2022-03-07 16:25:34 -05:00
snowflakeProxy . Stop ( )
2022-03-03 23:23:15 -05:00
}