Example #1
0
def req_for_ovpn_file(server_id, user_protocol):
    """
	Makes a request to ProtonVPN servers and returns with a OVPN template "file", returns False otherwise.
	"""

    url = f"https://api.protonmail.ch/vpn/config?Platform={OS_PLATFORM}&LogicalID={server_id}&Protocol={user_protocol}"

    try:
        log.info("Fetched request from ProtonVPN.")
        return requests.get(url, headers=(PROTON_HEADERS))
    except:
        log.critical("Unable to fetch request from ProtonVPN.")
        return False
Example #2
0
def copy_credentials():
    cmds = [
        f"mkdir /opt/{PROJECT_NAME}/",
        f"cp {USER_CRED_FILE} /opt/{PROJECT_NAME}/"
    ]
    try:
        if (not os.path.isdir("/opt/" + PROJECT_NAME + "/")):
            for cmd in cmds:
                subprocess.run(["sudo", "bash", "-c", cmd])
        else:
            subprocess.run(["sudo", "bash", "-c", cmds[1]])

        print("Copied credentials")
        log.info(f"Credentials were copied to: \"/opt/{PROJECT_NAME}\"")
        return True
    except:
        print("Unable to copy credentials")
        log.critical(f"Unable to copy credentials to: \"/opt/{PROJECT_NAME}\"")
        return False
Example #3
0
def generate_ovpn_for_boot(server_req):

    original_req = server_req.text
    start_index = original_req.find("auth-user-pass")
    modified_request = original_req[:start_index +
                                    14] + " /opt/" + PROJECT_NAME + "/" + USER_CRED_FILE.split(
                                        "/")[-1] + original_req[start_index +
                                                                14:]
    ovpn_file_created = False
    append_to_file = "cat > /etc/openvpn/client/" + OVPN_FILE.split(
        "/")[-1].split(".")[0] + ".conf <<EOF " + modified_request + "\nEOF"

    try:
        output = subprocess.run(["sudo", "bash", "-c", append_to_file],
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
        log.debug(f"Injection comand output: {output}")
        ovpn_file_created = True
    except:
        print("Unable to create configuration file in /openvpn/client/")
        log.critical(f"Could not generate/modify openVPN file.")
        return False

    print("Created new file in /openvpn/client/")
    log.info(f"\"Start on boot\" path to credentials injected.")

    if ovpn_file_created and walk_to_file(
            "/opt/", USER_CRED_FILE, in_dirs=True):
        log.critical(
            f"OVPN file for boot was NOT generated in: \"/etc/openvpn/client/\""
        )
        return False

    if not copy_credentials():
        return False

    filename = OVPN_FILE.split("/")[-1].split(".")[0]
    log.info(
        f"OVPN file for boot was generated: \"/etc/openvpn/client/{filename}\""
    )
    return True
	def openvpn_disconnect(self):
		openvpn_PID = self.check_for_running_ovpn_process()
		is_connected = False
		
		print("Disconnecting from vpn server...")
		log.info(f"PID is: {'NONE' if not openvpn_PID else openvpn_PID}")

		if not openvpn_PID:
			print("Unable to disconnect, no OpenVPN process was found.")
			log.warning("Could not find any OpenVPN processes.")
			return False

		try:
			is_connected = get_ip_info()
		except:
			is_connected = False
		
		log.info(f"Tested for internet connection: \"{is_connected}\"")

		if not manage_dns(action_type="restore"):
			log.critical("Unable to restore DNS prior to disconnecting from VPN, restarting NetworkManager might be needed.")
			
		if not manage_ipv6(action_type="restore"):
			log.warning("Unable to enable IPV6 prior to disconnecting from VPN.")

		# if not manage_killswitch(action_type="restore"):
		# 	return False

		output = subprocess.run(["sudo","kill", "-9", openvpn_PID], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
		# SIGTERM - Terminate opevVPN, ref: https://www.poftut.com/what-is-linux-sigterm-signal-and-difference-with-sigkill/
		if output.returncode != 0:
			print("Unable to disconnecto from VPN.")
			log.critical(f"Unable to disconnecto from VPN, \"{output}\"")
			return False

		log.info("Disconnected from VPN.")
		print("You are disconnected from VPN.")
		return True
	def start_on_boot_manager(self, action):
		enabled_on_boot = True
		#load user preferences
		try:
			user_pref = self.user_manager.read_user_data()
		except:
			print("Profile was not initialized.")
			log.warning("User profile was not initialized.")
			return False

		if action == "enable":
			success_msg = "\"Launch on boot\" service enabled."
			fail_msg = "Cant enable \"launch on boot\" service."

			self.server_manager.cache_servers()
			server_collection = []

			user_inp_country = input("Which country do you want to start on boot ? ").strip().upper()
			server_list_file = user_inp_country+SERVER_FILE_TYPE

			#load country configurations
			try:
				with open(os.path.join(CACHE_FOLDER, server_list_file)) as file:
					server_list = json.load(file)
			except TypeError:
				print("Servers are not cached.")
				log.warning("Servers are not cached.") 
				return False

			print("Server name|\tServer Load|\tFeatures|\tTier")
			for server in server_list['serverList']:
				if server_list['serverList'][server]['tier'] <= user_pref['tier']:
					server_collection.append(server_list['serverList'][server])
					print(
						server_list['serverList'][server]['name']+"|\t\t\t"+str(server_list['serverList'][server]['load'])+"|\t"+
						str(server_list['serverList'][server]['features'])+"|\t\t"+str(server_list['serverList'][server]['tier'])
					)
			
			if len(server_collection) == 0:
				print("No servers were found")
				return False

			user_selected_server = int(input("Which server to connecto on boot: "))
			selected_server = [server for server in server_collection if str(user_selected_server) in server['name']][0]
			
			user_pref['on_boot_server_id'] = selected_server['id']
			user_pref['on_boot_server_name'] = selected_server['name']
			user_pref['on_boot_protocol'] = user_pref['protocol']
			
			server_req = req_for_ovpn_file(selected_server['id'], user_pref['protocol'])

			if not server_req:
				return False

			if not generate_ovpn_for_boot(server_req):
				return False
		elif action == "kill":
			openvpn_PID = self.check_for_running_ovpn_process()
			if not openvpn_PID:
				print("Not PID was found")
				log.debug("Attempted to kill \"openvpn start on boot\" process, none found.")
				return False

			output = subprocess.run(["sudo","kill", "-9", openvpn_PID], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
			# SIGTERM - Terminate opevVPN, ref: https://www.poftut.com/what-is-linux-sigterm-signal-and-difference-with-sigkill/
			if output.returncode != 0:
				print(f"Unable to kill PID {openvpn_PID}.")
				log.critical(f"Unable to disconnecto from VPN, \"{output}\"")
				return False

			self.restart_network_manager()
			return True
		elif action == "disable":
			success_msg = "\"Launch on boot\" service is disabled."
			fail_msg = "Cant disable service \"launch on boot\"."
			enabled_on_boot = False
			#here it should kill all openvpn processes and disable service daemon
		elif action == "restart":
			success_msg = "\"Launch on boot\" service was restarted."
			fail_msg = "Cant restart service \"launch on boot\"."

		try:
			output = subprocess.run(["sudo", "systemctl", action, ON_BOOT_PROCESS_NAME], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
			log.debug(f"Start on boot log: {output}")
		except:
			print("\n"+fail_msg+"\n")
			log.critical("Something went wrong, could not enable \"start on boot\"")
			return False

		if not delete_folder_recursive(CACHE_FOLDER):
			log.debug("Unable to delete cache folder recursively.")

		print("\n"+success_msg+"\n")
		user_pref['on_boot_enabled'] = enabled_on_boot

		if not edit_file(USER_PREF_FILE, json.dumps(user_pref, indent=2), append=False):
			log.debug("Unable to save on boot preferences.")

		log.info(f"Start on boot created: \"{output.stdout.decode()}\"")
	def openvpn_connect(self, protocol=False):
		openvpn_PID = self.check_for_running_ovpn_process()
		pre_vpn_conn_ip = False
		port_types = {"udp": 1194, "tcp": 443}

		if openvpn_PID:
			print("Unable to connect, a OpenVPN process is already running.")
			log.info("Unable to connect, a OpenVPN process is already running.")
			return False

		try:
			pre_vpn_conn_ip, pre_vpn_conn_isp = get_ip_info()
		except:
			pre_vpn_conn_ip = False
			pre_vpn_conn_isp = False

		log.info(f"Tested for internet connection: \"{pre_vpn_conn_ip}\"")

		if not pre_vpn_conn_ip:
			print("There is no internet connection.")
			log.warning("Unable to connect, check your internet connection.")
		
		print("Connecting to vpn server...")

		if not protocol:
			protocol = "udp"

		# Needs to be worked on, new way to connect to VPN, might help with killswitch
		with open(OVPN_LOG_FILE, "w+") as log_file:
			subprocess.Popen(
				[	"sudo",
					"openvpn",
					"--config", OVPN_FILE,
					"--auth-user-pass", USER_CRED_FILE
				],
				stdout=log_file, stderr=log_file
			)

		with open(OVPN_LOG_FILE, "r") as log_file:
			while True:
				content = log_file.read()
				log_file.seek(0)
				if "Initialization Sequence Completed" in content:
					print("VPN established")
					#change DNS
					dns_dhcp_regex = re.compile(
						r"(dhcp-option DNS )"
						r"(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"
					)
					dns_dhcp = dns_dhcp_regex.search(content)
					log.debug(f"DNS___RESULT: {dns_dhcp}")
					if dns_dhcp:
						dns_server = dns_dhcp.group(2)
						manage_dns(action_type="custom", dns_addr=dns_server)
					else:
						print("Could not apply custom DNS.")
						log.critical(f"Could not apply custom DNS: {dns_dhcp}")

					if not manage_ipv6(action_type="disable"):
						return False
					# if not manage_killswitch(action_type="enable", protocol=protocol, port=port_types[protocol]):
					# 	return False
					# compare old IP with new IP, if they are different the connection has succeded
					
					log.debug("Connected to the VPN.")
					return True
				elif "AUTH_FAILED" in content:
					print("Authentication failed")
					break