package testing import ( "git.openprivacy.ca/cwtch.im/tapir" "git.openprivacy.ca/cwtch.im/tapir/applications" "git.openprivacy.ca/cwtch.im/tapir/networks/tor" "git.openprivacy.ca/cwtch.im/tapir/primitives" torProvider "git.openprivacy.ca/openprivacy/connectivity/tor" "git.openprivacy.ca/openprivacy/log" "golang.org/x/crypto/ed25519" "io/ioutil" "os" "runtime" "sync" "testing" "time" ) func TestTapirMaliciousRemote(t *testing.T) { numRoutinesStart := runtime.NumGoroutine() log.SetLevel(log.LevelDebug) log.Infof("Number of goroutines open at start: %d", runtime.NumGoroutine()) // Connect to Tor os.MkdirAll("./tor/", 0700) builder := new(torProvider.TorrcBuilder) builder.WithHashedPassword("tapir-integration-test").Build("./tor/torrc") // Connect to Tor torDataDir := "" var err error if torDataDir, err = ioutil.TempDir("./tor/", "data-dir-"); err != nil { t.Fatalf("could not create data dir") } // Connect to Tor acn, err := torProvider.NewTorACNWithAuth("./", "", torDataDir, 9051, torProvider.HashedPasswordAuthenticator{Password: "tapir-integration-test"}) if err != nil { t.Fatalf("could not launch ACN %v", err) } acn.WaitTillBootstrapped() // Generate Server Keys, not we generate two sets id, _ := primitives.InitializeEphemeralIdentity() id2, sk2 := primitives.InitializeEphemeralIdentity() // Init the Server running the Simple App. service := new(tor.BaseOnionService) // Initialize an onion service with one identity, but the auth app with another, this should // trigger a failure in authentication protocol service.Init(acn, sk2, &id) // Goroutine Management sg := new(sync.WaitGroup) sg.Add(1) go func() { service.Listen(new(applications.AuthApp)) sg.Done() }() // Wait for server to come online time.Sleep(time.Second * 30) wg := new(sync.WaitGroup) wg.Add(1) // Init a Client to Connect to the Server log.Infof("initializing the client....") client, _ := genclient(acn) go connectclientandfail(client, id2.PublicKey(), wg, t) wg.Wait() // Wait for Server to Sync time.Sleep(time.Second * 2) log.Infof("closing ACN...") client.Shutdown() service.Shutdown() acn.Close() sg.Wait() time.Sleep(time.Second * 5) // wait for goroutines to finish... log.Infof("Number of goroutines open at close: %d", runtime.NumGoroutine()) if numRoutinesStart != runtime.NumGoroutine() { t.Errorf("Potential goroutine leak: Num Start:%v NumEnd: %v", numRoutinesStart, runtime.NumGoroutine()) } } // Client will Connect and launch it's own Echo App goroutine. func connectclientandfail(client tapir.Service, key ed25519.PublicKey, group *sync.WaitGroup, t *testing.T) { client.Connect(torProvider.GetTorV3Hostname(key), new(applications.AuthApp)) // Once connected, it shouldn't take long to authenticate and run the application. So for the purposes of this demo // we will wait a little while then exit. time.Sleep(time.Second * 5) log.Infof("Checking connection status...") conn, err := client.GetConnection(torProvider.GetTorV3Hostname(key)) if err == nil { group.Done() t.Errorf("Connection should have failed! %v %v", conn, err) } log.Infof("Successfully failed to authenticate...") group.Done() }