Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Windows support #102

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft

Conversation

michkot
Copy link

@michkot michkot commented Nov 25, 2021

Closes #41

TODOs:

__main__.py : make the "if WINDOWS" checks nicer; somehow fix fork support (multiprocessing? struggling soo far); maybe enhance the tool with DNS NRPT support - it would be nice for INC split configurations

win.py : maybe move the transformation between IPvXAddresses and PS argument here?

powershell.py : do smarter support for PS detection (PS7 is called pwsh.exe); add comment regarding the "we keep a hidden powershell running in the background and feed him commands over STDIN; interlaving them with echo NULL; and reading the JSON-serialized responses back over STDOUT, delimted by NULL" idea; improve error handling if possible (without risking deadlock by reading just STDIN and not STDOUT) -- probably parse the output of each command separately from its "echo $?" status check

The idea is looking for collabolators and testers.
credits for original windows-port attempt go to https://github.com/bersbersbers
class NrptProvider:
@abstractmethod
def add_nrtp(self, namespace, servers):
"""NRPT Rule addition.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it NRPT or NRTP? And what is it?

@@ -72,10 +72,14 @@ def __init__(self, path):
if not os.access(path, os.R_OK | os.W_OK):
raise OSError('Cannot read/write {}'.format(path))

@abstractmethod
def lock_hosts_file(self, hostf):
"""Lock the hosts file."""
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this method abstract, rather than using the POSIX implementation (fcntl.flock(hostf, fctnl.LOCK_EX)?

Comment on lines +7 to +19
class PythonOsProcessProvider(ProcessProvider):
def kill(self, pid, signal=SIGTERM):
os.kill(pid, signal)

def pid(self):
return os.getpid()

def is_alive(self, pid):
try:
os.kill(pid, 0)
return True
except ProcessLookupError:
return False
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about put this in generic.py, rather than creating a new portable.py? (And let's just call it OsProcessProvider rather than add the seemingly-redundant Python to the name.)


def do_connect(env, args):
global providers
global platform
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this. platform is already a global, imported with from sys import platform

Comment on lines +225 to +228
# erase all addresses (needed on Windows to clean-up the adapter)
# TODO: also cleanup DNS?
# TODO: also cleanup routes?
providers.route.remove_address(env.tundev)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of removing the preexisting addresses from the VPN adapter when connecting?

From OpenConnect development, we already know that if another (down) adapter is using the same address… we have to clean it up before we can assign it to the VPN adapter. In v9.0, we'll do this automatically: https://gitlab.com/openconnect/openconnect/-/blob/master/tun-win32.c#L228

But I don't know what issue is being solved by removing the previously assigned addresses when connecting. 🤷‍♂️

@@ -387,6 +419,8 @@ def parse_env(environ=os.environ):
raise AssertionError("IPv4 network (INTERNAL_IP4_{{NETADDR,NETMASK}}) {ad}/{nm} does not match INTERNAL_IP4_NETMASKLEN={nml} (implies /{nmi})".format(
ad=orig_netaddr, nm=env.netmask, nml=env.netmasklen, nmi=env.network.netmask))
assert env.network.netmask == env.netmask
# first/lowest IP-addr in the range should be internal GW (seen in Windows vpnc-script.js)
env.via = next(env.network.hosts())
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://gitlab.com/openconnect/vpnc-scripts/-/commit/b3dec790951444d5e5f5c6659ca8b51569207b03 🤔

  1. This won't work if env.network is /32. n=ipaddress.ip_network('192.168.12.25/32'); next(n.hosts())StopIteration.
  2. If env.network isn't /32, then in order to match vpnc-script-win.js, it should be the second host IP address, not the first.

How about this?

from itertools import islice

lowest_hosts = islice(env.network.hosts(), 0, 2)
env.via = lowest_hosts[1] if len(lowest_hosts) == 2 else env.network.network_address

Comment on lines +557 to +578
def initGlobalProviders():
global providers

if "provider" in globals():
return

# Set platform-specific providers
providers = slurpy()
for pn, pv in get_default_providers().items():
try:
if isinstance(pv, Exception):
raise pv
providers[pn] = pv()
except Exception as e:
print("WARNING: Couldn't configure {} provider: {}".format(pn, e), file=stderr)

def main(args=None, environ=os.environ):
global providers

try:
p, args, env = parse_args_and_env(args, environ)

# Set platform-specific providers
providers = slurpy()
for pn, pv in get_default_providers().items():
try:
if isinstance(pv, Exception):
raise pv
providers[pn] = pv()
except Exception as e:
print("WARNING: Couldn't configure {} provider: {}".format(pn, e), file=stderr)

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why this is being changed.

@jpfleischer jpfleischer mentioned this pull request Jan 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Windows support
2 participants