Source code for hackthebox.vpn

"""
Examples:
    Retrieving the current VPN server::

        print(client.get_current_vpn_server())

    Switching to a given VPN server::

        req = input("What server? ")
        server = next(filter(lambda x: x.friendly_name == req), client.get_all_vpn_servers()))
        server.switch()
        server.download(path="/tmp/out.ovpn")

"""

from __future__ import annotations

import os

from . import htb
from .errors import VpnException, CannotSwitchWithActive

from typing import TYPE_CHECKING, cast

if TYPE_CHECKING:
    from .htb import HTBClient


[docs]class VPNServer(htb.HTBObject): """Class representing individual VPN servers provided by Hack The Box Attributes: friendly_name: Friendly name of the server Example: ``'US Free 1'`` current_clients: The number of currently connected clients location: The physical location of the server Example: ``'US'`` """ friendly_name: str current_clients: int location: str _detailed_func = lambda x: None # noinspection PyUnresolvedReferences def __init__(self, data: dict, client: "HTBClient", summary=False): self._client = client self.id = data["id"] self.friendly_name = data["friendly_name"] self.current_clients = data["current_clients"] self.location = data["location"] self.summary = summary def __repr__(self): return f"<VPN Server '{self.friendly_name}'>" def __str__(self): return f"{self.friendly_name}"
[docs] def switch(self) -> bool: """ Switches the client to use this VPN server Returns: Whether the switch was completed successfully """ # TODO: Throw exception on failure result = cast( dict, self._client.do_request(f"connections/servers/switch/{self.id}", post=True), ) if result["status"] is True: return True if ( result["message"] == "You must stop your active machine before switching VPN" ): raise CannotSwitchWithActive raise VpnException
[docs] def download(self, path=None, tcp=False) -> str: """ Args: path: The name of the OVPN file to download to. If none is provided, it is saved to the current directory. tcp: Download TCP instead of UDP Returns: The path of the file """ if path is None: path = os.path.join(os.getcwd(), f"{self.friendly_name}.ovpn") url = f"access/ovpnfile/{self.id}/0" if tcp: # Funky URL url += "/1" data = self._client.do_request(url, download=True) # We can't download VPN packs for servers we're not assigned to if b"You are not assigned" in data: self.switch() data = cast(bytes, self._client.do_request(url, download=True)) with open(path, "wb") as f: f.write(data) return path