mirror of
https://github.com/donaldzou/WGDashboard.git
synced 2026-04-17 10:26:18 +00:00
117 lines
4.2 KiB
Python
117 lines
4.2 KiB
Python
import re, ipaddress
|
|
import subprocess
|
|
import sqlalchemy
|
|
|
|
def RegexMatch(regex, text) -> bool:
|
|
"""
|
|
Regex Match
|
|
@param regex: Regex patter
|
|
@param text: Text to match
|
|
@return: Boolean indicate if the text match the regex pattern
|
|
"""
|
|
pattern = re.compile(regex)
|
|
return pattern.search(text) is not None
|
|
|
|
def GetRemoteEndpoint() -> str:
|
|
"""
|
|
Using socket to determine default interface IP address. Thanks, @NOXICS
|
|
@return:
|
|
"""
|
|
import socket
|
|
try:
|
|
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
|
|
s.connect(("1.1.1.1", 80)) # Connecting to a public IP
|
|
wgd_remote_endpoint = s.getsockname()[0]
|
|
return str(wgd_remote_endpoint)
|
|
except (socket.error, OSError):
|
|
pass
|
|
try:
|
|
return socket.gethostbyname(socket.gethostname())
|
|
except (socket.error, OSError):
|
|
pass
|
|
return "127.0.0.1"
|
|
|
|
|
|
def StringToBoolean(value: str):
|
|
"""
|
|
Convert string boolean to boolean
|
|
@param value: Boolean value in string came from Configuration file
|
|
@return: Boolean value
|
|
"""
|
|
return (value.strip().replace(" ", "").lower() in
|
|
("yes", "true", "t", "1", 1))
|
|
|
|
def CheckAddress(ips_str: str) -> bool:
|
|
if len(ips_str) == 0:
|
|
return False
|
|
|
|
for ip in ips_str.split(','):
|
|
stripped_ip = ip.strip()
|
|
try:
|
|
# Verify the IP-address, with the strict flag as false also allows for /32 and /128
|
|
ipaddress.ip_network(stripped_ip, strict=False)
|
|
except ValueError:
|
|
return False
|
|
return True
|
|
|
|
def CheckPeerKey(peer_key: str) -> bool:
|
|
return re.match(r"^[A-Za-z0-9+/]{43}=$", peer_key)
|
|
|
|
def ValidateDNSAddress(addresses_str: str) -> tuple[bool, str | None]:
|
|
if len(addresses_str) == 0:
|
|
return False, "Got an empty list/string to check for valid DNS-addresses"
|
|
|
|
addresses = addresses_str.split(',')
|
|
for address in addresses:
|
|
stripped_address = address.strip()
|
|
|
|
if not CheckAddress(stripped_address) and not RegexMatch(r"(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z][a-z]{0,61}[a-z]", stripped_address):
|
|
return False, f"{stripped_address} does not appear to be a valid IP-address or FQDN"
|
|
|
|
return True, None
|
|
|
|
|
|
def ValidateEndpointAllowedIPs(IPs) -> tuple[bool, str] | tuple[bool, None]:
|
|
ips = IPs.replace(" ", "").split(",")
|
|
for ip in ips:
|
|
try:
|
|
ipaddress.ip_network(ip, strict=False)
|
|
except ValueError as e:
|
|
return False, str(e)
|
|
return True, None
|
|
|
|
def GenerateWireguardPublicKey(privateKey: str) -> tuple[bool, str] | tuple[bool, None]:
|
|
try:
|
|
publicKey = subprocess.check_output(f"wg pubkey", input=privateKey.encode(), shell=True,
|
|
stderr=subprocess.STDOUT)
|
|
return True, publicKey.decode().strip('\n')
|
|
except subprocess.CalledProcessError:
|
|
return False, None
|
|
|
|
def GenerateWireguardPrivateKey() -> tuple[bool, str] | tuple[bool, None]:
|
|
try:
|
|
publicKey = subprocess.check_output(f"wg genkey", shell=True,
|
|
stderr=subprocess.STDOUT)
|
|
return True, publicKey.decode().strip('\n')
|
|
except subprocess.CalledProcessError:
|
|
return False, None
|
|
|
|
def ValidatePasswordStrength(password: str) -> tuple[bool, str] | tuple[bool, None]:
|
|
# Rules:
|
|
# - Must be over 8 characters & numbers
|
|
# - Must contain at least 1 Uppercase & Lowercase letters
|
|
# - Must contain at least 1 Numbers (0-9)
|
|
# - Must contain at least 1 special characters from $&+,:;=?@#|'<>.-^*()%!~_-
|
|
if len(password) < 8:
|
|
return False, "Password must be 8 characters or more"
|
|
if not re.search(r'[a-z]', password):
|
|
return False, "Password must contain at least 1 lowercase character"
|
|
if not re.search(r'[A-Z]', password):
|
|
return False, "Password must contain at least 1 uppercase character"
|
|
if not re.search(r'\d', password):
|
|
return False, "Password must contain at least 1 number"
|
|
if not re.search(r'[$&+,:;=?@#|\'<>.\-^*()%!~_-]', password):
|
|
return False, "Password must contain at least 1 special character from $&+,:;=?@#|'<>.-^*()%!~_-"
|
|
|
|
return True, None
|