@@ -221,7 +221,7 @@ func (p *pia) PortForward(ctx context.Context, client *http.Client,
221221 return
222222 }
223223
224- client , err := newPIAHTTPClient (commonName )
224+ privateIPClient , err := newPIAHTTPClient (commonName )
225225 if err != nil {
226226 pfLogger .Error ("aborting because: %s" , err )
227227 return
@@ -246,7 +246,7 @@ func (p *pia) PortForward(ctx context.Context, client *http.Client,
246246
247247 if ! dataFound || expired {
248248 tryUntilSuccessful (ctx , pfLogger , func () error {
249- data , err = refreshPIAPortForwardData (ctx , client , gateway , openFile )
249+ data , err = refreshPIAPortForwardData (ctx , client , privateIPClient , gateway , openFile )
250250 return err
251251 })
252252 if ctx .Err () != nil {
@@ -258,7 +258,10 @@ func (p *pia) PortForward(ctx context.Context, client *http.Client,
258258
259259 // First time binding
260260 tryUntilSuccessful (ctx , pfLogger , func () error {
261- return bindPIAPort (ctx , client , gateway , data )
261+ if err := bindPIAPort (ctx , privateIPClient , gateway , data ); err != nil {
262+ return fmt .Errorf ("cannot bind port: %w" , err )
263+ }
264+ return nil
262265 })
263266 if ctx .Err () != nil {
264267 return
@@ -294,15 +297,15 @@ func (p *pia) PortForward(ctx context.Context, client *http.Client,
294297 }
295298 return
296299 case <- keepAliveTimer .C :
297- if err := bindPIAPort (ctx , client , gateway , data ); err != nil {
298- pfLogger .Error (err )
300+ if err := bindPIAPort (ctx , privateIPClient , gateway , data ); err != nil {
301+ pfLogger .Error ("cannot bind port: " + err . Error () )
299302 }
300303 keepAliveTimer .Reset (keepAlivePeriod )
301304 case <- expiryTimer .C :
302305 pfLogger .Warn ("Forward port has expired on %s, getting another one" , data .Expiration .Format (time .RFC1123 ))
303306 oldPort := data .Port
304307 for {
305- data , err = refreshPIAPortForwardData (ctx , client , gateway , openFile )
308+ data , err = refreshPIAPortForwardData (ctx , client , privateIPClient , gateway , openFile )
306309 if err != nil {
307310 pfLogger .Error (err )
308311 continue
@@ -322,8 +325,8 @@ func (p *pia) PortForward(ctx context.Context, client *http.Client,
322325 if err := writePortForwardedToFile (openFile , filepath , data .Port ); err != nil {
323326 pfLogger .Error (err )
324327 }
325- if err := bindPIAPort (ctx , client , gateway , data ); err != nil {
326- pfLogger .Error (err )
328+ if err := bindPIAPort (ctx , privateIPClient , gateway , data ); err != nil {
329+ pfLogger .Error ("cannot bind port: " + err . Error () )
327330 }
328331 if ! keepAliveTimer .Stop () {
329332 <- keepAliveTimer .C
@@ -357,41 +360,43 @@ func newPIAHTTPClient(serverName string) (client *http.Client, err error) {
357360 if err != nil {
358361 return nil , fmt .Errorf ("cannot parse PIA root certificate: %w" , err )
359362 }
360- // certificate.DNSNames = []string{serverName, "10.0.0.1"}
361- rootCAs := x509 .NewCertPool ()
362- rootCAs .AddCert (certificate )
363- TLSClientConfig := & tls.Config {
364- RootCAs : rootCAs ,
365- MinVersion : tls .VersionTLS12 ,
366- ServerName : serverName ,
367- }
363+
368364 //nolint:gomnd
369- transport := http.Transport {
370- TLSClientConfig : TLSClientConfig ,
371- Proxy : http .ProxyFromEnvironment ,
365+ transport := & http.Transport {
366+ // Settings taken from http.DefaultTransport
367+ Proxy : http .ProxyFromEnvironment ,
372368 DialContext : (& net.Dialer {
373369 Timeout : 30 * time .Second ,
374370 KeepAlive : 30 * time .Second ,
375- DualStack : true ,
376371 }).DialContext ,
377372 ForceAttemptHTTP2 : true ,
378373 MaxIdleConns : 100 ,
379374 IdleConnTimeout : 90 * time .Second ,
380375 TLSHandshakeTimeout : 10 * time .Second ,
381376 ExpectContinueTimeout : 1 * time .Second ,
382377 }
378+ rootCAs := x509 .NewCertPool ()
379+ rootCAs .AddCert (certificate )
380+ transport .TLSClientConfig = & tls.Config {
381+ RootCAs : rootCAs ,
382+ MinVersion : tls .VersionTLS12 ,
383+ ServerName : serverName ,
384+ }
385+
383386 const httpTimeout = 30 * time .Second
384- client = & http.Client {Transport : & transport , Timeout : httpTimeout }
385- return client , nil
387+ return & http.Client {
388+ Transport : transport ,
389+ Timeout : httpTimeout ,
390+ }, nil
386391}
387392
388- func refreshPIAPortForwardData (ctx context.Context , client * http.Client ,
393+ func refreshPIAPortForwardData (ctx context.Context , client , privateIPClient * http.Client ,
389394 gateway net.IP , openFile os.OpenFileFunc ) (data piaPortForwardData , err error ) {
390395 data .Token , err = fetchPIAToken (ctx , openFile , client )
391396 if err != nil {
392397 return data , fmt .Errorf ("cannot obtain token: %w" , err )
393398 }
394- data .Port , data .Signature , data .Expiration , err = fetchPIAPortForwardData (ctx , client , gateway , data .Token )
399+ data .Port , data .Signature , data .Expiration , err = fetchPIAPortForwardData (ctx , privateIPClient , gateway , data .Token )
395400 if err != nil {
396401 return data , fmt .Errorf ("cannot obtain port forwarding data: %w" , err )
397402 }
@@ -448,13 +453,15 @@ func writePIAPortForwardData(openFile os.OpenFileFunc, data piaPortForwardData)
448453}
449454
450455func unpackPIAPayload (payload string ) (port uint16 , token string , expiration time.Time , err error ) {
451- b , err := base64 .RawStdEncoding .DecodeString (payload )
456+ b , err := base64 .StdEncoding .DecodeString (payload )
452457 if err != nil {
453- return 0 , "" , expiration , fmt .Errorf ("cannot decode payload: %w" , err )
458+ return 0 , "" , expiration ,
459+ fmt .Errorf ("cannot decode payload: payload is %q: %w" , payload , err )
454460 }
455461 var payloadData piaPayload
456462 if err := json .Unmarshal (b , & payloadData ); err != nil {
457- return 0 , "" , expiration , fmt .Errorf ("cannot parse payload data: %w" , err )
463+ return 0 , "" , expiration ,
464+ fmt .Errorf ("cannot parse payload data: data is %q: %w" , string (b ), err )
458465 }
459466 return payloadData .Port , payloadData .Token , payloadData .Expiration , nil
460467}
@@ -469,7 +476,7 @@ func packPIAPayload(port uint16, token string, expiration time.Time) (payload st
469476 if err != nil {
470477 return "" , fmt .Errorf ("cannot serialize payload data: %w" , err )
471478 }
472- payload = base64 .RawStdEncoding .EncodeToString (b )
479+ payload = base64 .StdEncoding .EncodeToString (b )
473480 return payload , nil
474481}
475482
@@ -482,16 +489,18 @@ func fetchPIAToken(ctx context.Context, openFile os.OpenFileFunc,
482489 url := url.URL {
483490 Scheme : "https" ,
484491 User : url .UserPassword (username , password ),
485- Host : "10.0.0.1 " ,
486- Path : "/authv3 /generateToken" ,
492+ Host : "privateinternetaccess.com " ,
493+ Path : "/gtoken /generateToken" ,
487494 }
488495 request , err := http .NewRequestWithContext (ctx , http .MethodGet , url .String (), nil )
489496 if err != nil {
490- return "" , err
497+ return "" , replaceInErr (err , map [string ]string {
498+ username : "<username>" , password : "<password>" })
491499 }
492500 response , err := client .Do (request )
493501 if err != nil {
494- return "" , err
502+ return "" , replaceInErr (err , map [string ]string {
503+ username : "<username>" , password : "<password>" })
495504 }
496505 defer response .Body .Close ()
497506 if response .StatusCode != http .StatusOK {
@@ -547,10 +556,12 @@ func fetchPIAPortForwardData(ctx context.Context, client *http.Client, gateway n
547556 }
548557 request , err := http .NewRequestWithContext (ctx , http .MethodGet , url .String (), nil )
549558 if err != nil {
559+ err = replaceInErr (err , map [string ]string {token : "<token>" })
550560 return 0 , "" , expiration , fmt .Errorf ("cannot obtain signature: %w" , err )
551561 }
552562 response , err := client .Do (request )
553563 if err != nil {
564+ err = replaceInErr (err , map [string ]string {token : "<token>" })
554565 return 0 , "" , expiration , fmt .Errorf ("cannot obtain signature: %w" , err )
555566 }
556567 defer response .Body .Close ()
@@ -590,11 +601,17 @@ func bindPIAPort(ctx context.Context, client *http.Client, gateway net.IP, data
590601
591602 request , err := http .NewRequestWithContext (ctx , http .MethodGet , url .String (), nil )
592603 if err != nil {
593- return fmt .Errorf ("cannot bind port: %w" , err )
604+ return replaceInErr (err , map [string ]string {
605+ payload : "<payload>" ,
606+ data .Signature : "<signature>" ,
607+ })
594608 }
595609 response , err := client .Do (request )
596610 if err != nil {
597- return fmt .Errorf ("cannot bind port: %w" , err )
611+ return replaceInErr (err , map [string ]string {
612+ payload : "<payload>" ,
613+ data .Signature : "<signature>" ,
614+ })
598615 }
599616 defer response .Body .Close ()
600617 if response .StatusCode != http .StatusOK {
@@ -607,7 +624,7 @@ func bindPIAPort(ctx context.Context, client *http.Client, gateway net.IP, data
607624 Message string `json:"message"`
608625 }
609626 if err := decoder .Decode (& responseData ); err != nil {
610- return fmt . Errorf ( "cannot bind port: %w" , err )
627+ return err
611628 } else if responseData .Status != "OK" {
612629 return fmt .Errorf ("response received from PIA: %s (%s)" , responseData .Status , responseData .Message )
613630 }
@@ -627,3 +644,12 @@ func writePortForwardedToFile(openFile os.OpenFileFunc,
627644 }
628645 return file .Close ()
629646}
647+
648+ // replaceInErr is used to remove sensitive information from logs.
649+ func replaceInErr (err error , substitutions map [string ]string ) error {
650+ s := err .Error ()
651+ for old , new := range substitutions {
652+ s = strings .ReplaceAll (s , old , new )
653+ }
654+ return errors .New (s )
655+ }
0 commit comments