2020-02-06 20:42:46 -05:00
package pia
import (
"encoding/hex"
"encoding/json"
"fmt"
2020-04-12 20:05:28 +00:00
"net/http"
2020-02-06 20:42:46 -05:00
2020-03-29 19:52:49 -04:00
"github.com/qdm12/golibs/files"
2020-02-06 20:42:46 -05:00
"github.com/qdm12/private-internet-access-docker/internal/constants"
"github.com/qdm12/private-internet-access-docker/internal/models"
)
func ( c * configurator ) GetPortForward ( ) ( port uint16 , err error ) {
2020-04-12 19:07:19 +00:00
c . logger . Info ( "Obtaining port to be forwarded" )
2020-02-06 20:42:46 -05:00
b , err := c . random . GenerateRandomBytes ( 32 )
if err != nil {
return 0 , err
}
clientID := hex . EncodeToString ( b )
url := fmt . Sprintf ( "%s/?client_id=%s" , constants . PIAPortForwardURL , clientID )
content , status , err := c . client . GetContent ( url )
2020-04-12 20:05:28 +00:00
switch {
case err != nil :
2020-02-06 20:42:46 -05:00
return 0 , err
2020-04-12 20:05:28 +00:00
case status != http . StatusOK :
2020-02-06 20:42:46 -05:00
return 0 , fmt . Errorf ( "status is %d for %s; does your PIA server support port forwarding?" , status , url )
2020-04-12 20:05:28 +00:00
case len ( content ) == 0 :
2020-02-06 20:42:46 -05:00
return 0 , fmt . Errorf ( "port forwarding is already activated on this connection, has expired, or you are not connected to a PIA region that supports port forwarding" )
}
body := struct {
Port uint16 ` json:"port" `
} { }
if err := json . Unmarshal ( content , & body ) ; err != nil {
return 0 , fmt . Errorf ( "port forwarding response: %w" , err )
}
2020-04-12 19:07:19 +00:00
c . logger . Info ( "Port forwarded is %d" , body . Port )
2020-02-06 20:42:46 -05:00
return body . Port , nil
}
2020-03-29 19:52:49 -04:00
func ( c * configurator ) WritePortForward ( filepath models . Filepath , port uint16 , uid , gid int ) ( err error ) {
2020-04-12 19:07:19 +00:00
c . logger . Info ( "Writing forwarded port to %s" , filepath )
2020-03-29 19:52:49 -04:00
return c . fileManager . WriteLinesToFile (
string ( filepath ) ,
[ ] string { fmt . Sprintf ( "%d" , port ) } ,
files . Ownership ( uid , gid ) ,
2020-04-12 20:05:28 +00:00
files . Permissions ( 0400 ) )
2020-02-06 20:42:46 -05:00
}
func ( c * configurator ) AllowPortForwardFirewall ( device models . VPNDevice , port uint16 ) ( err error ) {
2020-04-12 19:07:19 +00:00
c . logger . Info ( "Allowing forwarded port %d through firewall" , port )
2020-02-06 20:42:46 -05:00
return c . firewall . AllowInputTrafficOnPort ( device , port )
}
2020-04-09 12:11:36 +00:00
func ( c * configurator ) ClearPortForward ( filepath models . Filepath , uid , gid int ) ( err error ) {
2020-04-12 19:07:19 +00:00
c . logger . Info ( "Clearing forwarded port status file %s" , filepath )
2020-04-12 20:05:28 +00:00
return c . fileManager . WriteToFile ( string ( filepath ) , nil , files . Ownership ( uid , gid ) , files . Permissions ( 0400 ) )
2020-04-09 12:11:36 +00:00
}