github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/nat/service_ics_test.go (about)

     1  //go:build windows
     2  
     3  /*
     4   * Copyright (C) 2019 The "MysteriumNetwork/node" Authors.
     5   *
     6   * This program is free software: you can redistribute it and/or modify
     7   * it under the terms of the GNU General Public License as published by
     8   * the Free Software Foundation, either version 3 of the License, or
     9   * (at your option) any later version.
    10   *
    11   * This program is distributed in the hope that it will be useful,
    12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14   * GNU General Public License for more details.
    15   *
    16   * You should have received a copy of the GNU General Public License
    17   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    18   */
    19  
    20  package nat
    21  
    22  import (
    23  	"errors"
    24  	"net"
    25  	"strconv"
    26  	"testing"
    27  
    28  	"github.com/stretchr/testify/assert"
    29  )
    30  
    31  var _ NATService = &serviceICS{}
    32  
    33  func mockedICS(powerShell func(cmd string) ([]byte, error)) *serviceICS {
    34  	return &serviceICS{
    35  		powerShell:      powerShell,
    36  		setICSAddresses: mockICSConfig,
    37  	}
    38  }
    39  
    40  func Test_errorOnGetPublicInterfaceName(t *testing.T) {
    41  	sh := mockPowerShell{err: errors.New("expected error")}
    42  	ics := mockedICS(sh.exec)
    43  	_, err := ics.getPublicInterfaceName()
    44  	assert.EqualError(t, err, "failed to get interface from the default route: expected error")
    45  }
    46  
    47  func Test_parseErrorOnGetPublicInterfaceName(t *testing.T) {
    48  	sh := mockPowerShell{}
    49  	ics := mockedICS(sh.exec)
    50  	_, err := ics.getPublicInterfaceName()
    51  	assert.EqualError(t, err, "failed to parse interface ID: strconv.Atoi: parsing \"\": invalid syntax")
    52  }
    53  
    54  func Test_getPublicInterfaceName(t *testing.T) {
    55  	sh := mockPowerShell{commands: map[string]mockShellResult{
    56  		"Get-WmiObject -Class Win32_IP4RouteTable | where { $_.destination -eq '0.0.0.0' -and $_.mask -eq '0.0.0.0'} | foreach { $_.InterfaceIndex }": {[]byte("1234567890"), nil},
    57  	}}
    58  	ics := mockedICS(sh.exec)
    59  	_, err := ics.getPublicInterfaceName()
    60  	assert.EqualError(t, err, "interface not found")
    61  }
    62  
    63  func Test_errorGettingServiceStartTypeOnEnable(t *testing.T) {
    64  	sh := mockPowerShell{commands: map[string]mockShellResult{
    65  		"Get-Service RemoteAccess | foreach { $_.StartType }": {nil, errors.New("expected error")},
    66  	}}
    67  
    68  	ics := mockedICS(sh.exec)
    69  	err := ics.Enable()
    70  	assert.EqualError(t, err, "failed to Enable RemoteAccess service: failed to get RemoteAccess service startup type: expected error")
    71  }
    72  
    73  func Test_errorSettingServiceStartTypeOnEnable(t *testing.T) {
    74  	sh := mockPowerShell{commands: map[string]mockShellResult{
    75  		"Set-Service -Name RemoteAccess -StartupType automatic": {nil, errors.New("expected error")},
    76  	}}
    77  
    78  	ics := mockedICS(sh.exec)
    79  	err := ics.Enable()
    80  	assert.EqualError(t, err, "failed to Enable RemoteAccess service: failed to set RemoteAccess service startup type to automatic: expected error")
    81  }
    82  
    83  func Test_errorStartingServiceOnEnable(t *testing.T) {
    84  	sh := mockPowerShell{commands: map[string]mockShellResult{
    85  		"Start-Service -Name RemoteAccess": {nil, errors.New("expected error")},
    86  	}}
    87  
    88  	ics := mockedICS(sh.exec)
    89  	err := ics.Enable()
    90  	assert.EqualError(t, err, "failed to Enable RemoteAccess service: failed to start RemoteAccess service: expected error")
    91  }
    92  
    93  func Test_errorGettingPublicInterfaceOnEnable(t *testing.T) {
    94  	sh := mockPowerShell{commands: map[string]mockShellResult{
    95  		"Get-WmiObject -Class Win32_IP4RouteTable | where { $_.destination -eq '0.0.0.0' -and $_.mask -eq '0.0.0.0'} | foreach { $_.InterfaceIndex }": {nil, errors.New("expected error")},
    96  	}}
    97  
    98  	ics := mockedICS(sh.exec)
    99  	err := ics.Enable()
   100  	assert.EqualError(t, err, "failed to get public interface name: failed to get interface from the default route: expected error")
   101  }
   102  
   103  func Test_errorApplyingSharingConfigOnEnable(t *testing.T) {
   104  	ifaces, _ := net.Interfaces()
   105  	iface := ifaces[0]
   106  
   107  	sh := mockPowerShell{commands: map[string]mockShellResult{
   108  		"Get-WmiObject -Class Win32_IP4RouteTable | where { $_.destination -eq '0.0.0.0' -and $_.mask -eq '0.0.0.0'} | foreach { $_.InterfaceIndex }": {[]byte(strconv.Itoa(iface.Index)), nil},
   109  
   110  		`regsvr32 /s hnetcfg.dll;
   111  		$netShare = New-Object -ComObject HNetCfg.HNetShare;
   112  		$c = $netShare.EnumEveryConnection |? { $netShare.NetConnectionProps.Invoke($_).Name -eq "` + iface.Name + `" };
   113  		$config = $netShare.INetSharingConfigurationForINetConnection.Invoke($c);$config.EnableSharing(0)`: {nil, errors.New("expected error")},
   114  	}}
   115  
   116  	ics := mockedICS(sh.exec)
   117  	err := ics.Enable()
   118  	assert.EqualError(t, err, "failed to enable internet connection sharing: expected error")
   119  }
   120  
   121  func Test_Enable(t *testing.T) {
   122  	ifaces, _ := net.Interfaces()
   123  	iface := ifaces[0]
   124  
   125  	sh := mockPowerShell{commands: map[string]mockShellResult{
   126  		"Get-WmiObject -Class Win32_IP4RouteTable | where { $_.destination -eq '0.0.0.0' -and $_.mask -eq '0.0.0.0'} | foreach { $_.InterfaceIndex }": {[]byte(strconv.Itoa(iface.Index)), nil},
   127  	}}
   128  
   129  	ics := mockedICS(sh.exec)
   130  	err := ics.Enable()
   131  	assert.NoError(t, err)
   132  }
   133  
   134  func Test_AddDel(t *testing.T) {
   135  	sh := mockPowerShell{commands: map[string]mockShellResult{
   136  		`Get-WmiObject Win32_NetworkAdapter | Where-Object {$_.ServiceName -eq "tap0901"} | foreach { $_.NetConnectionID }`: {[]byte("myst0"), nil},
   137  	}}
   138  
   139  	ics := mockedICS(sh.exec)
   140  	_, vpnNetwork, _ := net.ParseCIDR("127.0.0.1/24")
   141  	_, err := ics.Setup(Options{
   142  		VPNNetwork:    *vpnNetwork,
   143  		ProviderExtIP: net.ParseIP("8.8.8.8"),
   144  	})
   145  	assert.NoError(t, err)
   146  
   147  	err = ics.Del(nil)
   148  	assert.NoError(t, err)
   149  }
   150  
   151  func Test_errorInterfaceOnAdd(t *testing.T) {
   152  	sh := mockPowerShell{commands: map[string]mockShellResult{}}
   153  
   154  	ics := mockedICS(sh.exec)
   155  	_, vpnNetwork, _ := net.ParseCIDR("8.8.8.8/24")
   156  	_, err := ics.Setup(Options{
   157  		VPNNetwork:    *vpnNetwork,
   158  		ProviderExtIP: net.ParseIP("8.8.8.8"),
   159  	})
   160  	assert.EqualError(t, err, "failed to find suitable interface: interface not found")
   161  }
   162  
   163  func Test_errorRevertStartupTypeOnDisable(t *testing.T) {
   164  	ifaces, _ := net.Interfaces()
   165  	iface := ifaces[0]
   166  
   167  	sh := mockPowerShell{commands: map[string]mockShellResult{
   168  		"Get-WmiObject -Class Win32_IP4RouteTable | where { $_.destination -eq '0.0.0.0' -and $_.mask -eq '0.0.0.0'} | foreach { $_.InterfaceIndex }": {[]byte(strconv.Itoa(iface.Index)), nil},
   169  		"Set-Service -Name RemoteAccess -StartupType testStatus": {nil, errors.New("expected error")},
   170  	}}
   171  
   172  	ics := mockedICS(sh.exec)
   173  	ics.remoteAccessStatus = "testStatus"
   174  	err := ics.Disable()
   175  
   176  	assert.EqualError(t, err, "failed to revert RemoteAccess service startup type: expected error")
   177  }
   178  
   179  func Test_errorGettingPublicInterfaceOnDisable(t *testing.T) {
   180  	sh := mockPowerShell{commands: map[string]mockShellResult{
   181  		"Get-WmiObject -Class Win32_IP4RouteTable | where { $_.destination -eq '0.0.0.0' -and $_.mask -eq '0.0.0.0'} | foreach { $_.InterfaceIndex }": {nil, errors.New("expected error")},
   182  	}}
   183  
   184  	ics := mockedICS(sh.exec)
   185  	err := ics.Disable()
   186  
   187  	assert.EqualError(t, err, "failed to get public interface name: failed to get interface from the default route: expected error")
   188  }
   189  
   190  func Test_Disable(t *testing.T) {
   191  	ifaces, _ := net.Interfaces()
   192  	iface := ifaces[0]
   193  
   194  	sh := mockPowerShell{commands: map[string]mockShellResult{
   195  		"Get-WmiObject -Class Win32_IP4RouteTable | where { $_.destination -eq '0.0.0.0' -and $_.mask -eq '0.0.0.0'} | foreach { $_.InterfaceIndex }": {[]byte(strconv.Itoa(iface.Index)), nil},
   196  	}}
   197  
   198  	ics := mockedICS(sh.exec)
   199  	err := ics.Disable()
   200  
   201  	assert.NoError(t, err)
   202  }
   203  
   204  type mockShellResult struct {
   205  	output []byte
   206  	err    error
   207  }
   208  
   209  type mockPowerShell struct {
   210  	err      error
   211  	commands map[string]mockShellResult
   212  }
   213  
   214  func (sh *mockPowerShell) exec(cmd string) ([]byte, error) {
   215  	if c, ok := sh.commands[cmd]; ok {
   216  		return c.output, c.err
   217  	}
   218  	return nil, sh.err
   219  }
   220  
   221  func mockICSConfig(_map map[string]string) (map[string]string, error) {
   222  	return nil, nil
   223  }