// newClient creates a proxy client. func newClient(addr, appName string) *mobileClient { client := client.Client{ Addr: addr, ReadTimeout: 0, // don't timeout WriteTimeout: 0, } err := globals.SetTrustedCAs(clientConfig.getTrustedCerts()) if err != nil { log.Errorf("Unable to configure trusted CAs: %s", err) } hqfd := client.Configure(clientConfig.Client) mClient := &mobileClient{ Client: client, closed: make(chan bool), fronter: hqfd.NewDirectDomainFronter(), appName: appName, } if err := mClient.updateConfig(); err != nil { log.Errorf("Unable to update config: %v", err) } return mClient }
func updateGlobals(cfg *Config) error { globals.InstanceId = cfg.InstanceId err := globals.SetTrustedCAs(cfg.TrustedCACerts()) if err != nil { return fmt.Errorf("Unable to configure trusted CAs: %s", err) } return nil }
// updateConfig attempts to pull a configuration file from the network using // the client proxy itself. func (client *MobileClient) updateConfig() error { var buf []byte var err error if buf, err = pullConfigFile(client.fronter); err != nil { log.Errorf("Could not update config: '%v'", err) return err } if err = clientConfig.updateFrom(buf); err == nil { // Configuration changed, lets reload. err := globals.SetTrustedCAs(clientConfig.getTrustedCerts()) if err != nil { log.Errorf("Unable to configure trusted CAs: %s", err) } hqfc := client.Configure(clientConfig.Client) client.fronter = hqfc.NewDirectDomainFronter() } return err }
// TestCloudFlare tests to make sure that a client and server can communicate // with each other to proxy traffic for an HTTP client using the CloudFlare // protocol. This does not test actually running through CloudFlare and just // uses a local HTTP server to serve the test content. func TestCloudFlare(t *testing.T) { // Set up a mock HTTP server mockServer := &MockServer{} err := mockServer.init() if err != nil { t.Fatalf("Unable to init mock HTTP(S) server: %s", err) } defer mockServer.deleteCerts() mockServer.run(t) waitForServer(HTTP_ADDR, 5*time.Second, t) waitForServer(HTTPS_ADDR, 5*time.Second, t) // Set up a mock CloudFlare cf := &MockCloudFlare{} err = cf.init() if err != nil { t.Fatalf("Unable to init mock CloudFlare: %s", err) } defer cf.deleteCerts() go func() { err := cf.run(t) if err != nil { t.Fatalf("Unable to run mock CloudFlare: %s", err) } }() waitForServer(CF_ADDR, 5*time.Second, t) // Set up common certContext for proxies certContext := &fronted.CertContext{ PKFile: randomTempPath(), ServerCertFile: randomTempPath(), } defer os.Remove(certContext.PKFile) defer os.Remove(certContext.ServerCertFile) // Run server proxy srv := &server.Server{ Addr: SERVER_ADDR, ReadTimeout: 0, // don't timeout WriteTimeout: 0, CertContext: certContext, AllowNonGlobalDestinations: true, } srv.Configure(&server.ServerConfig{}) go func() { err := srv.ListenAndServe(func(update func(*server.ServerConfig) error) { err := config.Update(func(cfg *config.Config) error { return update(cfg.Server) }) if err != nil { log.Errorf("Error while trying to update: %v", err) } }) if err != nil { t.Fatalf("Unable to run server: %s", err) } }() waitForServer(SERVER_ADDR, 5*time.Second, t) // Give servers time to finish startup time.Sleep(250 * time.Millisecond) clt := &client.Client{ Addr: CLIENT_ADDR, ReadTimeout: 0, // don't timeout WriteTimeout: 0, } globals.SetTrustedCAs([]string{ "-----BEGIN CERTIFICATE-----\nMIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG\nA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv\nb3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw\nMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i\nYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT\naWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ\njc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp\nxy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp\n1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG\nsnUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ\nU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8\n9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E\nBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B\nAQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz\nyj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE\n38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP\nAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad\nDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME\nHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==\n-----END CERTIFICATE-----\n", string(cf.certContext.ServerCert.PEMEncoded()), }) clt.Configure(&client.ClientConfig{ MasqueradeSets: map[string][]*fronted.Masquerade{ "cloudflare": []*fronted.Masquerade{ &fronted.Masquerade{ Domain: HOST, }, }, }, FrontedServers: []*client.FrontedServerInfo{ &client.FrontedServerInfo{Host: HOST, Port: CF_PORT, Weight: 100, MasqueradeSet: "cloudflare"}, }, }) go func() { err := clt.ListenAndServe(func() {}) if err != nil { t.Fatalf("Unable to run client: %s", err) } }() waitForServer(CLIENT_ADDR, 2*time.Second, t) // Test various scenarios certPool := mockServer.certContext.ServerCert.PoolContainingCert() testRequest("Plain Text Request", t, mockServer.requests, false, certPool, 200, nil) testRequest("HTTPS Request", t, mockServer.requests, true, certPool, 200, nil) testRequest("HTTPS Request without server Cert", t, mockServer.requests, true, nil, 200, fmt.Errorf("Get https://"+HTTPS_ADDR+": x509: certificate signed by unknown authority")) }