Ejemplo n.º 1
0
def genovpnFiles(vpn_provider):
    if not ovpnFilesAvailable(getVPNLocation(vpn_provider)):

        # Fetch the list of locations available.  If there are multiple, the user can select
        locations = getLocationFiles(getVPNLocation(vpn_provider))            
        default_label = "Default"
        i = 0            
        for location in locations:
            locations[i] = location[location.index("LOCATIONS")+10:location.index(".txt")]
            if locations[i] == "" : locations[i] = default_label
            i = i + 1
        selected_profile = ""
        if len(locations) == 0: errorTrace("vpnproviders.py", "No LOCATIONS.txt files found in VPN directory.  Cannot generate ovpn files.")
        if len(locations) > 1:
            selected_location = xbmcgui.Dialog().select("Select connections profile", locations)
            selected_profile = locations[selected_location]
            if selected_profile == default_label : selected_profile = ""
        
        addon = xbmcaddon.Addon()
        addon.setSetting("vpn_locations_list", selected_profile)

        # Delete any old files in other directories
        debugTrace("Deleting all generated ovpn files")
        removeGeneratedFiles()
        # Generate new ones
        try:
            provider_gen = fixOVPNFiles(getVPNLocation(vpn_provider), selected_profile)
        except:
            errorTrace("Couldn't generate new .ovpn files")
            provider_gen = False
        xbmc.sleep(500)
        return provider_gen
    else:
        return True
Ejemplo n.º 2
0
def getShellfireMessages(vpn_provider, last_time, last_id):
    # Return any message ID and message available from the provider
    
    # Never return a message for a paid account unless a last_time of 0 is being used to force it
    if getAccountType() > 0 and not last_time == 0: return "", ""
    
    # Fetch any available deal
    rc, api_data = sendAPI("?action=getAvailablePricingDeal", "Retrieving messages", "", False)
    # Adding 'Success' to the end of this line will return a test message
    # Check the call worked and that it was successful.  If there's no message, a bad response is returned
    if not rc: return "", ""
    if not api_data["status"] == "success": return "", ""

    try:
        # Extract and format the message
        id = api_data["data"]["pricingDealId"]
        message = api_data["data"]["name"] + " - " + api_data["data"]["description"] + " - Only available until "
        ts = int(api_data["data"]["validUntil"])
        message = message + time.strftime("%b %d", time.gmtime(ts))
        message = message + " - " + api_data["data"]["url"]
        
        # Don't return a message if the same message was displayed < 1 week ago 
        if (not last_time == 0) and (last_time + 604800 > now()) and last_id == id:
            return "", ""
            
    except Exception as e:
        errorTrace("alternativeShellfire.py", "Couldn't format message returned")
        errorTrace("alternativeShellfire.py", "JSON received is \n" + json.dumps(api_data, indent=4))
        return "", ""
    
    return id, message
Ejemplo n.º 3
0
def copySystemdFiles():
    # Delete any existing openvpn.service and copy openvpn service file to config directory
    service_source = getAddonPath(True, "openvpn.service")
    service_dest = getSystemdPath("system.d/openvpn.service")
    debugTrace("Copying openvpn.service " + service_source + " to " +
               service_dest)
    if not fakeSystemd():
        if xbmcvfs.exists(service_dest): xbmcvfs.delete(service_dest)
        xbmcvfs.copy(service_source, service_dest)
        if not xbmcvfs.exists(service_dest):
            raise IOError('Failed to copy service ' + service_source + " to " +
                          service_dest)

    # Delete any existing openvpn.config and copy first VPN to openvpn.config
    config_source = sudo_setting = xbmcaddon.Addon(
        getID()).getSetting("1_vpn_validated")
    if service_source == "":
        errorTrace("vpnplatform.py", "Nothing has been validated")
    config_dest = getSystemdPath("openvpn.config")
    debugTrace("Copying openvpn.config " + config_source + " to " +
               config_dest)
    if not fakeSystemd():
        if xbmcvfs.exists(config_dest): xbmcvfs.delete(config_dest)
        xbmcvfs.copy(config_source, config_dest)
        if not xbmcvfs.exists(config_dest):
            raise IOError('Failed to copy service ovpn ' + config_source +
                          " to " + config_dest)
Ejemplo n.º 4
0
def getTokenNordVPN():
    # Return a token that can be used on API calls
    token, renew, expiry, _ = getTokens()

    # If the expiry time is passed, renew the token
    if expiry.isdigit() and int(expiry) < now():
        if renewNordVPN(renew):
            token, _, _, _ = getTokens()
            return token
        else:
            # Force an authenticate to happen
            token = ""

    # The authentication call is made during connection validation, which will validate everything and fetch
    # the tokens.  If a reboot happens and the tokens disappear, then we need to force an authenticate again
    if token == "":
        addon = xbmcaddon.Addon(getID())
        if authenticateNordVPN(addon.getSetting("vpn_provider_validated"),
                               addon.getSetting("vpn_username_validated"),
                               addon.getSetting("vpn_password_validated")):
            token, _, _, _ = getTokens()
            return token
        else:
            errorTrace("alternativeNord.py",
                       "Couldn't authenticate or renew the user ID")
            resetTokens()
            raise RuntimeError("Couldn't get a user ID token")

    debugTrace("Using existing user ID token")
    return token
Ejemplo n.º 5
0
def getVPNConnectionStatus():
    # Open the openvpn output file and parse it for known phrases
    # Return 'connected', 'auth failed', 'network failed', 'error' or ''

    if fakeConnection(): return connection_status.UNKNOWN

    # **** ADD MORE PLATFORMS HERE ****
    # Might not need to mess with this too much if the log output from openvpn is the same
    
    p = getPlatform()
    if p == platforms.LINUX or p == platforms.RPI:
        path = getVPNLogFilePath()
        state = connection_status.UNKNOWN
        if xbmcvfs.exists(path):
            debugTrace("Reading log file")
            log = open(path,'r')
            lines = log.readlines()
            for line in lines:
                if "Initialization Sequence Completed" in line:
                    state = connection_status.CONNECTED
                    break
                if "AUTH_FAILED" in line:
                    state = connection_status.AUTH_FAILED
                if "TLS Error" in line:
                    state = connection_status.NETWORK_FAILED
                if "Connection timed out" in line:
                    state = connection_status.TIMEOUT
            log.close()
            # Haven't found what's expected so return an empty stream
            if not state == connection_status.UNKNOWN: debugTrace("VPN connection status is " + str(state))
            return state
        else:
            errorTrace("platform.py", "Tried to get VPN connection status but log file didn't exist")
            return connection_status.ERROR
Ejemplo n.º 6
0
def getIPInfo(addon):
    # Based this code on a routine in the VPN for OPENELEC plugin
    # Generate request to find out where this IP is based
    # Return ip info source, ip, location, isp
    source = addon.getSetting("ip_info_source")
    if not source in getIPSources():
        addon.setSetting("ip_info_source", getIPSources()[0])
        source == getIPSources()[0]

    debugTrace("Getting IP info from " + source)
    retry = 0
    while retry < 5:
        ip, country, region, city, isp = getIPInfoFrom(source)

        if ip == "no info":
            debugTrace("No location information was returned for IP using " + source)
            # Got a response but couldn't format it.  No point retrying
            return source, "no info", "unknown", "unknown"
        elif ip == "error":
            errorTrace("common.py", "Something bad happened when trying to get a response from iplocation.net " + isp)
            # Didn't get a valid response so want to retry three times in case service was busy
            if retry == 2 : return source + " (not available)", "unknown", "unknown", "unknown"
            xbmc.sleep(3000)            
        else:
            # Worked, exit loop
            break
        retry = retry + 1
        
    location = ""
    if not (region == "-" or region == "Not Available"): location = region
    if not (country == "-" or country == "Not Available"):
        if not location == "": location = location + ", "
        location = location + country

    return source, ip, location, isp
Ejemplo n.º 7
0
def deleteTestFile():
    try:
        if xbmcvfs.exists(getTestFilePath()):
            xbmcvfs.delete(getTestFilePath())
    except Exception as e:
        errorTrace("vpnplatform.py", "Couldn't delete test file")
        errorTrace("vpnplatform.py", str(e))
Ejemplo n.º 8
0
def getVPNConnectionStatus():
    # Open the openvpn output file and parse it for known phrases
    # Return 'connected', 'auth failed', 'network failed', 'error' or ''

    if fakeConnection(): return connection_status.UNKNOWN

    # **** ADD MORE PLATFORMS HERE ****
    # Might not need to mess with this too much if the log output from different platform openvpns are the same

    p = getPlatform()
    if p == platforms.LINUX or p == platforms.RPI or p == platforms.WINDOWS:
        path = getVPNLogFilePath()
        state = connection_status.UNKNOWN
        if xbmcvfs.exists(path):
            debugTrace("Reading log file")
            log = open(path, 'r')
            lines = log.readlines()
            for line in lines:
                if "Initialization Sequence Completed" in line:
                    state = connection_status.CONNECTED
                    break
                if "AUTH_FAILED" in line:
                    state = connection_status.AUTH_FAILED
                if "private key password verification failed" in line:
                    state = connection_status.AUTH_FAILED
                if "TLS Error" in line:
                    state = connection_status.NETWORK_FAILED
                if "Connection timed out" in line:
                    state = connection_status.TIMEOUT
                if "Inactivity timeout" in line:
                    state = connection_status.TIMEOUT
                if "Error opening configuration file" in line:
                    state = connection_status.FILE_ERROR
                if p == platforms.WINDOWS and "ROUTE" in line and "Access is denied" in line:
                    # This is a Windows, not running Kodi as administrator error
                    state = connection_status.ACCESS_DENIED
                    break
                if p == platforms.WINDOWS and "FlushIpNetTable" in line and "Access is denied" in line:
                    # This is a Windows, not running Kodi as administrator error
                    state = connection_status.ACCESS_DENIED
                    break
                #if "ERROR: Linux route" in line:
                # state = connection_status.ROUTE_FAILED
                # This tests for a Linux route failure, only it's commented out as
                # it can legitimately fail if the route already exists.  If it fails
                # for other reasons, I can't tell the different just yet.
                # break
            log.close()
            # Haven't found what's expected so return an empty stream
            if not state == connection_status.UNKNOWN:
                debugTrace("VPN connection status is " + str(state))
            return state
        else:
            errorTrace(
                "vpnplatform.py",
                "Tried to get VPN connection status but log file didn't exist")
            return connection_status.ERROR
Ejemplo n.º 9
0
def checkVPNCommand(addon):
    # Issue the openvpn command and see if the output is a bunch of commands
    if not fakeConnection():
        p = getPlatform()
        # Issue the openvpn command, expecting to get the options screen back
        if p == platforms.RPI or p == platforms.LINUX:
            # Issue Linux command
            command = getOpenVPNPath() + " > " + getVPNLogFilePath() + " &"
            if useSudo(): command = "sudo " + command
            infoTrace("platform.py", "Testing openvpn with : " + command)
            os.system(command)
        elif p == platforms.WINDOWS:
            # Issue Windows command
            command = getOpenVPNPath()
            args = shlex.split(command)
            outfile = open(getVPNLogFilePath(), 'w')
            proc = subprocess.Popen(args,
                                    stdout=outfile,
                                    creationflags=subprocess.SW_HIDE,
                                    shell=True)

        # **** ADD MORE PLATFORMS HERE ****

        # Waiting for the log file to appear
        xbmc.sleep(1000)
        i = 0
        while not xbmcvfs.exists(getVPNLogFilePath()) and i < 10:
            xbmc.sleep(1000)
            i = i + 1
        # If the log file appears, check it's what we expect
        if xbmcvfs.exists(getVPNLogFilePath()):
            log_file = open(getVPNLogFilePath(), 'r')
            log_file_lines = log_file.readlines()
            log_file.close()
            i = 0
            # Look for a phrase we'd expect to see if the call
            # worked and the list of options was displayed
            for line in log_file_lines:
                if "General Options" in line:
                    return True
                i = i + 1
            # Write the log file in case there's something in it
            errorTrace("platform.py", "Ran openvpn command and it failed")
            writeVPNLog()
        else:
            errorTrace("platform.py",
                       "Ran openvpn command and VPN log didn't appear")

        # Display an error message
        dialog_msg = "The OpenVPN executable isn't working.  Check the log, then from a command line prompt type 'openvpn' and fix any problems reported\n"
        xbmcgui.Dialog().ok(addon.getAddonInfo("name"), dialog_msg)
        return False

    else:
        return True
Ejemplo n.º 10
0
def getipstack(json_data):
    try:
        ip = json_data["ip"]
        country = json_data["country_name"]
        region = json_data["region_name"]
        city = json_data["city"]       
        return ip, country, region, city, "Unknown"
    except Exception as e:
        errorTrace("ipinfo.py", "Couldn't parse JSON data " + str(json_data))
        errorTrace("ipinfo.py", str(e))
        return None, None, None, None, None 
Ejemplo n.º 11
0
def updateVPNFiles(vpn_provider):
    # If the OVPN files aren't generated then they need to be updated with location info    
    
    infoTrace("vpnproviders.py", "Updating VPN profiles for " + vpn_provider)
    # Get the list of VPN profile files        
    ovpn_connections = getProfileList(vpn_provider)

    # See if there's a port override going on
    addon = xbmcaddon.Addon("service.vpn.manager")
    if addon.getSetting("default_udp") == "true":
        portUDP = ""
    else:
        portUDP = addon.getSetting("alternative_udp_port")
        
    if addon.getSetting("default_tcp") == "true":
        portTCP = ""
    else:
        portTCP = addon.getSetting("alternative_tcp_port")
    
    for connection in ovpn_connections:
        try:
            f = open(connection, 'r+')
            debugTrace("Processing file " + connection)
            lines = f.readlines()
            f.seek(0)
            f.truncate()
            # Update the necessary values in the ovpn file
            for line in lines:
                
                if "auth-user-pass" in line:
                    line = "auth-user-pass " + getAddonPathWrapper(vpn_provider + "/" + "pass.txt\n")

                if "remote " in line:
                    port = ""
                    for newline in lines:
                        if "proto " in newline:
                            if "tcp" in newline and not portTCP == "": port = portTCP
                            if "udp" in newline and not portUDP == "": port = portUDP
                    if not port == "":
                        tokens = line.split()
                        line = "remote " + tokens[1] + " " + port + "\n"
                           
                f.write(line)
            f.close()
        except:
            errorTrace("profileupdate.py", "Failed to update ovpn file")
            return False

    # Write a file to indicate successful update of the ovpn files
    ovpn_file = open(getAddonPath(True, vpn_provider + "/GENERATED.txt"), 'w')
    ovpn_file.close()
            
    return True    
    
Ejemplo n.º 12
0
def getipinfo(json_data):
    try:
        ip = json_data["ip"]
        country = json_data["country"]
        region = json_data["region"]
        city = json_data["city"]
        isp = json_data["org"]        
        return ip, country, region, city, isp
    except Exception as e:
        errorTrace("ipinfo.py", "Couldn't parse JSON data " + str(json_data))
        errorTrace("ipinfo.py", str(e))
        return None, None, None, None, None               
Ejemplo n.º 13
0
def writeVPNLog():
    # Write the openvpn output log to the error file
    try:
        log_file = open(getVPNLogFilePath(), 'r')
        log_output = log_file.readlines()
        log_file.close()
        infoTrace("platform.py", "VPN log file start >>>")
        for line in log_output:
            print line
        infoTrace("platform.py", "<<< VPN log file end")
    except:
        errorTrace("platform.py", "Couldn't write VPN error log")
Ejemplo n.º 14
0
def writeVPNLog():
    # Write the openvpn output log to the error file
    try:
        log_file = open(getVPNLogFilePath(), "r")
        log_output = log_file.readlines()
        log_file.close()
        infoTrace("platform.py", "VPN log file start >>>")
        for line in log_output:
            print line
        infoTrace("platform.py", "<<< VPN log file end")
    except:
        errorTrace("platform.py", "Couldn't write VPN error log")
Ejemplo n.º 15
0
def fakeItTillYouMakeIt(fake):
    try:
        if fake:
            if not fakeConnection():
                f = open(getUserDataPath(fake_name),'w')
                f.close()
        else:
            if fakeConnection():
                xbmcvfs.delete(getUserDataPath(fake_name))
    except Exception as e:
        errorTrace("vpnplatform.py", "fakeItTillYouMakeIt " + str(fake) + " failed")
        errorTrace("vpnplatform.py", str(e))
Ejemplo n.º 16
0
def checkVPNCommand(addon):
    # Issue the openvpn command and see if the output is a bunch of commands
    if not fakeConnection():
        p = getPlatform()
        # Issue the openvpn command, expecting to get the options screen back
        if p == platforms.RPI or p == platforms.LINUX:
            # Issue Linux command
            command = getOpenVPNPath() + " > " + getVPNLogFilePath() + " &"
            if useSudo():
                command = "sudo " + command
            infoTrace("platform.py", "Testing openvpn with : " + command)
            os.system(command)
        elif p == platforms.WINDOWS:
            # Issue Windows command
            command = getOpenVPNPath()
            args = shlex.split(command)
            outfile = open(getVPNLogFilePath(), "w")
            proc = subprocess.Popen(args, stdout=outfile, creationflags=subprocess.SW_HIDE, shell=True)

        # **** ADD MORE PLATFORMS HERE ****

        # Waiting for the log file to appear
        xbmc.sleep(1000)
        i = 0
        while not xbmcvfs.exists(getVPNLogFilePath()) and i < 10:
            xbmc.sleep(1000)
            i = i + 1
        # If the log file appears, check it's what we expect
        if xbmcvfs.exists(getVPNLogFilePath()):
            log_file = open(getVPNLogFilePath(), "r")
            log_file_lines = log_file.readlines()
            log_file.close()
            i = 0
            # Look for a phrase we'd expect to see if the call
            # worked and the list of options was displayed
            for line in log_file_lines:
                if "General Options" in line:
                    return True
                i = i + 1
            # Write the log file in case there's something in it
            errorTrace("platform.py", "Ran openvpn command and it failed")
            writeVPNLog()
        else:
            errorTrace("platform.py", "Ran openvpn command and VPN log didn't appear")

        # Display an error message
        dialog_msg = "The OpenVPN executable isn't working.  Check the log, then from a command line prompt type 'openvpn' and fix any problems reported\n"
        xbmcgui.Dialog().ok(addon.getAddonInfo("name"), dialog_msg)
        return False

    else:
        return True
Ejemplo n.º 17
0
def writeTestFile():
    # Write the command test output to the error file
    try:
        log_file = open(getTestFilePath(), 'r')
        log_output = log_file.readlines()
        log_file.close()
        infoTrace("vpnplatform.py", "Command test file start >>>")
        for line in log_output:
            infoPrint(line)
        infoTrace("vpnplatform.py", "<<< Command test file end")
    except Exception as e:
        errorTrace("vpnplatform.py", "Couldn't write test file")
        errorTrace("vpnplatform.py", str(e))
Ejemplo n.º 18
0
def startService():
    # Routine for config to call to request that service starts.  Can time out if there's no response
    # Check to see if service is not already running (shouldn't be...)
    if not xbmcgui.Window(10000).getProperty("VPN_Manager_Service_Control") == "stopped": return True
    
    debugTrace("Requesting service restarts")
    # Update start property and wait for service to respond or timeout
    xbmcgui.Window(10000).setProperty("VPN_Manager_Service_Control", "start")
    for i in range (0, 30):
        xbmc.sleep(1000)
        if xbmcgui.Window(10000).getProperty("VPN_Manager_Service_Control") == "started": return True
    # No response in 30 seconds, service is probably dead
    errorTrace("common.py", "Couldn't communicate with VPN monitor service, didn't acknowledge a start")
    return False
Ejemplo n.º 19
0
def stopService():
    # Routine for config to call to request service stops and waits until that happens
    # Check to see if the service has stopped previously
    if xbmcgui.Window(10000).getProperty("VPN_Manager_Service_Control") == "stopped": return True
    
    debugTrace("Requesting service stops")
    # Update start property and wait for service to respond or timeout
    xbmcgui.Window(10000).setProperty("VPN_Manager_Service_Control", "stop")
    for i in range (0, 30):
        xbmc.sleep(1000)
        if xbmcgui.Window(10000).getProperty("VPN_Manager_Service_Control") == "stopped": return True
    # Haven't had a response in 30 seconds which is badness
    errorTrace("common.py", "Couldn't communicate with VPN monitor service, didn't acknowledge a stop")
    return False
Ejemplo n.º 20
0
def recordAction(action):
    log = getActionLogName(False)
    old_log = getActionLogName(True)
    addon = xbmcaddon.Addon("service.zomboided.tools")
    if addon.getSetting("enable_action_log") == "true":
        try:
            if xbmcvfs.exists(log):
                st = xbmcvfs.Stat(log)
                size = st.st_size()
                if size > 1024000:  # Limit log files to 1MB...this allow for ~10000 entries
                    debugTrace("Action log size is " + str(size) +
                               ", starting new action log")
                    if xbmcvfs.exists(old_log):
                        xbmcvfs.delete(old_log)
                    xbmcvfs.rename(log, old_log)
        except Exception as e:
            errorTrace("common.py", "Couldn't manage existing action log file")
            errorTrace("common.py", str(e))

        try:
            log_file = open(log, 'a+')
            time = datetime.datetime.fromtimestamp(now())
            log_file.write(str(time) + " " + action + "\n")
            log_file.close()
        except Exception as e:
            errorTrace("common.py", "Couldn't record action")
            errorTrace("common.py", str(e))
Ejemplo n.º 21
0
def writeKeyPass(key_pass_name, password):
    # Return the password being used for a given key file
    try:
        if xbmcvfs.exists(key_pass_name):
            xbmcvfs.delete(key_pass_name)
        debugTrace("Writing key password file " + key_pass_name)
        pass_file = open(key_pass_name, 'w')
        pass_file.write(password)
        pass_file.close()
        return True
    except Exception as e:
        errorTrace("vpnproviders.py",
                   "Failed to write key password file to userdata")
        errorTrace("vpnproviders.py", str(e))
        return False
Ejemplo n.º 22
0
def popupSysBox():
    if not getID() == "":
        addon = xbmcaddon.Addon(getID())
        dialog_text_l = ""
        dialog_text_r = ""
        data_left = getSystemData(addon, True, True, False, False)
        data_right = getSystemData(addon, False, False, False, True)
        for line in data_left:
            if line.startswith("[B]") and not dialog_text_l == "": dialog_text_l = dialog_text_l + "\n"
            dialog_text_l = dialog_text_l + line + "\n"
        for line in data_right:
            if line.startswith("[B]") and not dialog_text_r == "": dialog_text_r = dialog_text_r + "\n"
            dialog_text_r = dialog_text_r + line + "\n"    
        showInfoBox("System Information", dialog_text_l, dialog_text_r)
    else:
        errorTrace("sysbox.py", "VPN service is not ready")
Ejemplo n.º 23
0
def clearUserData():
    # Deleting everything here, but not deleting 'DEFAULT.txt' as 
    # any existing user and password info will get deleted
    path = getUserDataPath("UserDefined" + "/*.*")
    debugTrace("Deleting contents of User Defined directory" + path)
    files = glob.glob(path)
    try:
        for file in files:
            if not file.endswith("DEFAULT.txt") and xbmcvfs.exists(file): 
                debugTrace("Deleting " + file)
                xbmcvfs.delete(file)
    except Exception as e:
        errorTrace("userdefined.py", "Couldn't clear the UserDefined directory")
        errorTrace("userdefined.py", str(e))
        return False
    return True
Ejemplo n.º 24
0
def writeCert(vpn_provider, cert_name, content):
    # Write out the certificate represented by the content
    filename = getAddonPath(True, vpn_provider + "/" + cert_name)
    try:
        line = ""
        debugTrace("Writing certificate " + cert_name)
        output = open(filename, 'w')
        # Output the content line by line
        for line in content:       
            output.write(line)
        output.close()
        return True
    except Exception as e:
        errorTrace("alternativeShellfire`.py", "Couldn't write certificate " + filename)
        errorTrace("alternativeShellfire.py", str(e))
        return False
Ejemplo n.º 25
0
def copyKeyAndCert(vpn_provider, ovpn_name, user_key, user_cert):
    # Copy the user key and cert to the userdata directory
    key_dest = getUserDataPath(vpn_provider + "/" + getKeyName(vpn_provider, ovpn_name))
    key_source = user_key
    cert_dest = getUserDataPath(vpn_provider + "/" + getCertName(vpn_provider, ovpn_name))
    cert_source = user_cert
    try:
        debugTrace("Copying key " + key_source + " to " + key_dest)
        if xbmcvfs.exists(key_dest): xbmcvfs.delete(key_dest)
        xbmcvfs.copy(key_source, key_dest)
        debugTrace("Copying cert " + cert_source + " to " + cert_dest)
        if xbmcvfs.exists(cert_dest): xbmcvfs.delete(cert_dest)
        xbmcvfs.copy(cert_source, cert_dest)
        return True
    except:
        errorTrace("vpnproviders.py", "Failed to copy user key or cert file to userdata")
        return False
Ejemplo n.º 26
0
def getVPNConnectionStatus():
    # Open the openvpn output file and parse it for known phrases
    # Return 'connected', 'auth failed', 'network failed', 'error' or ''

    if fakeConnection():
        return connection_status.UNKNOWN

    # **** ADD MORE PLATFORMS HERE ****
    # Might not need to mess with this too much if the log output from different platform openvpns are the same

    p = getPlatform()
    if p == platforms.LINUX or p == platforms.RPI or p == platforms.WINDOWS:
        path = getVPNLogFilePath()
        state = connection_status.UNKNOWN
        if xbmcvfs.exists(path):
            debugTrace("Reading log file")
            log = open(path, "r")
            lines = log.readlines()
            for line in lines:
                if "Initialization Sequence Completed" in line:
                    state = connection_status.CONNECTED
                    break
                if "AUTH_FAILED" in line:
                    state = connection_status.AUTH_FAILED
                if "TLS Error" in line:
                    state = connection_status.NETWORK_FAILED
                if "Connection timed out" in line:
                    state = connection_status.TIMEOUT
                if p == platforms.WINDOWS and "ROUTE" in line and "Access is denied" in line:
                    # This is a Windows, not running Kodi as administrator error
                    state = connection_status.ACCESS_DENIED
                    break
                # if "ERROR: Linux route" in line:
                # state = connection_status.ROUTE_FAILED
                # This tests for a Linux route failure, only it's commented out as
                # it can legitimately fail if the route already exists.  If it fails
                # for other reasons, I can't tell the different just yet.
                # break
            log.close()
            # Haven't found what's expected so return an empty stream
            if not state == connection_status.UNKNOWN:
                debugTrace("VPN connection status is " + str(state))
            return state
        else:
            errorTrace("platform.py", "Tried to get VPN connection status but log file didn't exist")
            return connection_status.ERROR
def writeCert(vpn_provider, cert_name, content):
    # Write out the certificate represented by the content
    filename = getAddonPath(True, vpn_provider + "/" + cert_name)
    try:
        line = ""
        debugTrace("Writing certificate " + cert_name)
        output = open(filename, 'w')
        # Output the content line by line
        for line in content:
            output.write(line)
        output.close()
        return True
    except Exception as e:
        errorTrace("alternativeShellfire`.py",
                   "Couldn't write certificate " + filename)
        errorTrace("alternativeShellfire.py", str(e))
        return False
Ejemplo n.º 28
0
def writeVPNLog():
    # Write the openvpn output log to the error file
    try:
        if xbmcvfs.exists(getVPNLogFilePath()):
            log_file = open(getVPNLogFilePath(), 'r')
            log_output = log_file.readlines()
            log_file.close()
            infoTrace("vpnplatform.py", "VPN log file start >>>")
            for line in log_output:
                line = line.strip("\n")
                infoPrint(line)
            infoTrace("vpnplatform.py", "<<< VPN log file end")
        else:
            infoTrace("vpnplatform.py", "No VPN log file exists to write")
    except Exception as e:
        errorTrace("vpnplatform.py", "Couldn't write VPN error log")
        errorTrace("vpnplatform.py", str(e))
Ejemplo n.º 29
0
def writeVPNConfiguration(ovpn):
    # Write the openvpn configuration to the error file
    try:
        if xbmcvfs.exists(ovpn):
            ovpn_file = open(ovpn, 'r')
            ovpn_output = ovpn_file.readlines()
            ovpn_file.close()
            infoTrace("vpnplatform.py", "VPN configuration " + ovpn + " start >>>")
            for line in ovpn_output:
                line = line.strip("\n")
                infoPrint(line)
            infoTrace("vpnplatform.py", "<<< VPN configuration file end")
        else:
            infoTrace("vpnplatform.py", "No VPN configuration " + ovpn + " exists to write")
    except Exception as e:
        errorTrace("vpnplatform.py", "Couldn't write VPN error log")
        errorTrace("vpnplatform.py", str(e))
Ejemplo n.º 30
0
def copyKeyAndCert(vpn_provider, ovpn_name, user_key, user_cert):
    # Copy the user key and cert to the userdata directory
    key_dest = getUserDataPath(vpn_provider + "/" + getKeyName(vpn_provider, ovpn_name))
    key_source = user_key
    cert_dest = getUserDataPath(vpn_provider + "/" + getCertName(vpn_provider, ovpn_name))
    cert_source = user_cert
    try:
        debugTrace("Copying key " + key_source + " to " + key_dest)
        if xbmcvfs.exists(key_dest): xbmcvfs.delete(key_dest)
        xbmcvfs.copy(key_source, key_dest)
        debugTrace("Copying cert " + cert_source + " to " + cert_dest)
        if xbmcvfs.exists(cert_dest): xbmcvfs.delete(cert_dest)
        xbmcvfs.copy(cert_source, cert_dest)
        return True
    except:
        errorTrace("vpnproviders.py", "Failed to copy user key or cert file to userdata")
        return False
Ejemplo n.º 31
0
def updateVPNFiles(vpn_provider):
    # If the OVPN files aren't generated then they need to be updated with location info    
    
    infoTrace("vpnproviders.py", "Updating VPN profiles for " + vpn_provider)
    # Get the list of VPN profile files        
    ovpn_connections = getProfileList(vpn_provider)

    # Set ports as default
    portUDP = ""
    portTCP = ""
    
    for connection in ovpn_connections:
        try:
            f = open(connection, 'r+')
            debugTrace("Processing file " + connection)
            lines = f.readlines()
            f.seek(0)
            f.truncate()
            # Update the necessary values in the ovpn file
            for line in lines:
                
                if "auth-user-pass" in line:
                    line = "auth-user-pass " + getAddonPathWrapper(vpn_provider + "/" + "pass.txt\n")

                if "remote " in line:
                    port = ""
                    for newline in lines:
                        if "proto " in newline:
                            if "tcp" in newline and not portTCP == "": port = portTCP
                            if "udp" in newline and not portUDP == "": port = portUDP
                    if not port == "":
                        tokens = line.split()
                        line = "remote " + tokens[1] + " " + port + "\n"
                           
                f.write(line)
            f.close()
        except:
            errorTrace("profileupdate.py", "Failed to update ovpn file")
            return False

    # Write a file to indicate successful update of the ovpn files
    ovpn_file = open(getAddonPath(True, vpn_provider + "/GENERATED.txt"), 'w')
    ovpn_file.close()
            
    return True    
Ejemplo n.º 32
0
def writeCredentials(addon): 
   
    # Write the credentials file        
    try:
        credentials_path = getCredentialsPath(addon)
        debugTrace("Writing VPN credentials file to " + credentials_path)
        credentials = open(credentials_path,'w')
        credentials.truncate()
        credentials.close()
        credentials = open(credentials_path,'a')
        credentials.write(addon.getSetting("vpn_username")+"\n")
        credentials.write(addon.getSetting("vpn_password")+"\n")
        credentials.close()
    except:
        errorTrace("common.py", "Couldn't create credentials file " + credentials_path)
        return False
    xbmc.sleep(500)
    return True
Ejemplo n.º 33
0
def getServices():
    # Get the list of services
    rc, api_data = sendAPI("?action=getAllVpnDetails", "Retrieving list of services", "", True)
    if not rc: return None
  
    # Extract and return the list of service levels the user is entitled to
    try:
        services = []
        service_list = ""
        for item in api_data["data"]:
            services.append(item["eAccountType"] +";" + str(item["iVpnId"]))
            service_list = service_list + item["eAccountType"] + ", (" + str(item["iVpnId"]) + ") "
        debugTrace("Found services " + service_list)
        return services
    except Exception as e:
        errorTrace("alternativeShellfire.py", "Couldn't parse the data that came back when listing the serice levels")
        errorTrace("alternativeShellfire.py", str(e))
        return None
Ejemplo n.º 34
0
def checkPidofCommand(addon):
    # Disable this for now as kodi.bin may not exist on all systems
    return True
    # Only necessary with Linux, sees if pidof is installed/working
    p = getPlatform()
    if p == platforms.RPI or p == platforms.LINUX:
        # Issue Linux command
        command = getPidofPath() + " kodi.bin > " + getTestFilePath(
        ) + " 2>&1 &"
        if useSudo(): command = "sudo " + command
        infoTrace("vpnplatform.py", "Testing pidof with : " + command)
        os.system(command)
    else:
        return True

    # Waiting for the log file to appear
    xbmc.sleep(1000)
    i = 0
    while not xbmcvfs.exists(getTestFilePath()) and i < 10:
        xbmc.sleep(1000)
        i = i + 1
    # If the log file appears, check it's what we expect
    if xbmcvfs.exists(getTestFilePath()):
        log_file = open(getTestFilePath(), 'r')
        log_file_lines = log_file.readlines()
        log_file.close()
        # If this worked, the first line should be a number
        for line in log_file_lines:
            line = line.strip()
            if line.isdigit():
                deleteTestFile()
                return True
        # Write the log file in case there's something in it
        errorTrace("vpnplatform.py", "Ran pidof command and it failed")
        writeTestFile()
        dialog_msg = "The command 'pidof' is required to run this add-on.  Please install it and ensure it's available on the command path."
    else:
        errorTrace("vpnplatform.py",
                   "Ran pidof command and the log didn't appear")
        dialog_msg = "The 'pidof' command isn't writing out a response.  Try changing the Kodi log directory setting in Settings-Debug menu and retry."

    # Display an error message
    xbmcgui.Dialog().ok(addon.getAddonInfo("name"), dialog_msg)
    return False
Ejemplo n.º 35
0
def copyUserDefinedFiles():    
    # Copy everything in the user directory to the addon directory
    infoTrace("vpnproviders.py", "Copying user defined files from userdata directory")
    source_path = getUserDataPath((user_def_str)+"/")
    dest_path = getAddonPath(True, user_def_str + "/")
    # Get the list of connection profiles and another list of strings to abuse for the selection screen    
    try:
        files = getUserDataList(user_def_str, "*")
        if len(files) == 0:
            errorTrace("vpnproviders.py", "No User Defined files available to copy from " + source_path)
            return False
        for file in files:
            name = file[file.rfind(getSeparator())+1:]
            dest_file = dest_path + getSeparator() + name
            xbmcvfs.copy(file, dest_file)
        return True
    except:
        errorTrace("vpnproviders.py", "Error copying files from " + source_path + " to " + dest_path)
        return False
Ejemplo n.º 36
0
def copyUserDefinedFiles():    
    # Copy everything in the user directory to the addon directory
    infoTrace("vpnproviders.py", "Copying user defined files from userdata directory")
    source_path = getUserDataPath((user_def_str)+"/")
    dest_path = getAddonPath(True, user_def_str + "/")
    # Get the list of connection profiles and another list of strings to abuse for the selection screen    
    try:
        files = getUserDataList(user_def_str, "*")
        if len(files) == 0:
            errorTrace("vpnproviders.py", "No User Defined files available to copy from " + source_path)
            return False
        for file in files:
            name = file[file.rfind(getSeparator())+1:]
            dest_file = dest_path + getSeparator() + name
            xbmcvfs.copy(file, dest_file)
        return True
    except:
        errorTrace("vpnproviders.py", "Error copying files from " + source_path + " to " + dest_path)
        return False
Ejemplo n.º 37
0
def checkKillallCommand(addon):
    # Only necessary with Linux, sees if killall is installed/working
    p = getPlatform()
    if p == platforms.RPI or p == platforms.LINUX:
        # Issue Linux command
        command = getKillallPath() + " vpnmanagertest > " + getTestFilePath(
        ) + " 2>&1 &"
        if useSudo(): command = "sudo " + command
        infoTrace("vpnplatform.py", "Testing killall with : " + command)
        os.system(command)
    else:
        return True

    # Waiting for the log file to appear
    xbmc.sleep(1000)
    i = 0
    while not xbmcvfs.exists(getTestFilePath()) and i < 10:
        xbmc.sleep(1000)
        i = i + 1
    # If the log file appears, check it's what we expect
    if xbmcvfs.exists(getTestFilePath()):
        log_file = open(getTestFilePath(), 'r')
        log_file_lines = log_file.readlines()
        log_file.close()
        # Look for a phrase we'd expect to see if the call
        # worked and a killall error message was displayed
        for line in log_file_lines:
            if "vpnmanagertest" in line:
                deleteTestFile()
                return True
        # Write the log file in case there's something in it
        errorTrace("vpnplatform.py", "Ran killall command and it failed")
        writeTestFile()
        dialog_msg = "The command 'killall' is required to run this add-on.  Please install it and ensure it's available on the command path."
    else:
        errorTrace("vpnplatform.py",
                   "Ran killall command and the log didn't appear")
        dialog_msg = "The 'killall' command isn't writing out a response.  Try changing the Kodi log directory setting in Settings-Debug menu and retry."

    # Display an error message
    xbmcgui.Dialog().ok(addon.getAddonInfo("name"), dialog_msg)
    return False
Ejemplo n.º 38
0
def isVPNTaskRunning():
    # Return True if the VPN task is still running, or the VPN connection is still active
    # Return False if the VPN task is no longer running and the connection is not active

    if fakeConnection():
        return True

    p = getPlatform()
    if p == platforms.LINUX or p == platforms.RPI:
        try:
            command = "pidof openvpn"
            if useSudo():
                command = "sudo " + command
            debugTrace("(Linux) Checking VPN task with " + command)
            pid = os.system(command)
            # This horrible call returns 0 if it finds a process, it's not returning the PID number
            if pid == 0:
                return True
            return False
        except:
            errorTrace("platform.py", "VPN task list failed")
            return False
    if p == platforms.WINDOWS:
        try:
            command = 'tasklist /FI "IMAGENAME eq OPENVPN.EXE"'
            debugTrace("(Windows) Checking VPN task with " + command)
            args = shlex.split(command)
            out = subprocess.check_output(args, creationflags=subprocess.SW_HIDE, shell=True).strip()
            if "openvpn.exe" in out:
                return True
            else:
                return False
        except:
            errorTrace("platform.py", "VPN task list failed")
            return False

    # **** ADD MORE PLATFORMS HERE ****

    return False
Ejemplo n.º 39
0
def makeButtonsFile():
    # Use the buttons template to build a file to run at boot to check for a button press and run some commands
    addon = xbmcaddon.Addon("service.zomboided.tools")
    template_filename = xbmc.translatePath(
        "special://home/addons/service.zomboided.tools/BUTTONS.txt")
    python_filename = getButtonsPythonName()
    # Read the template file in
    try:
        if xbmcvfs.exists(template_filename):
            template_file = open(template_filename, 'r')
            template = template_file.readlines()
            template_file.close()
            i = 0
            for line in template:
                if "#GPIOBUTTON" in line:
                    template[i] = line.replace(
                        "#GPIOBUTTON", addon.getSetting("button_gpio_number"))
                if "#GPIOLED" in line:
                    template[i] = line.replace(
                        "#GPIOLED", addon.getSetting("led_gpio_number"))
                if "#OSCOMMANDS" in line:
                    commands = ""
                    for j in range(1, 10):
                        cmd = addon.getSetting("button_command_" + str(j))
                        if not cmd == "":
                            if not j == 1: commands = commands + "    "
                            commands = commands + 'os.system("' + cmd + '")\n'
                        else:
                            break
                    template[i] = line.replace("#OSCOMMANDS", commands)
                i += 1
    except Exception as e:
        errorTrace("common.py", "Couldn't read the buttons template file")
        errorTrace("common.py", str(e))
        return False

    # Write a new button file
    debugTrace("Writing an updated python button file")
    try:
        output = open(python_filename, 'w')
        for line in template:
            output.write(line)
        output.close()
        return True
    except Exception as e:
        errorTrace("common.py", "Couldn't write the new python buttons file")
        errorTrace("common.py", str(e))
        return False
Ejemplo n.º 40
0
def isVPNTaskRunning():
    # Return True if the VPN task is still running, or the VPN connection is still active
    # Return False if the VPN task is no longer running and the connection is not active

    if fakeConnection(): return True

    p = getPlatform()
    if p == platforms.LINUX or p == platforms.RPI:
        try:
            command = "pidof openvpn"
            if useSudo(): command = "sudo " + command
            debugTrace("(Linux) Checking VPN task with " + command)
            pid = os.system(command)
            # This horrible call returns 0 if it finds a process, it's not returning the PID number
            if pid == 0: return True
            return False
        except:
            errorTrace("platform.py", "VPN task list failed")
            return False
    if p == platforms.WINDOWS:
        try:
            command = 'tasklist /FI "IMAGENAME eq OPENVPN.EXE"'
            debugTrace("(Windows) Checking VPN task with " + command)
            args = shlex.split(command)
            out = subprocess.check_output(args,
                                          creationflags=subprocess.SW_HIDE,
                                          shell=True).strip()
            if "openvpn.exe" in out:
                return True
            else:
                return False
        except:
            errorTrace("platform.py", "VPN task list failed")
            return False

    # **** ADD MORE PLATFORMS HERE ****

    return False
def getServices():
    # Get the list of services
    rc, api_data = sendAPI("?action=getAllVpnDetails",
                           "Retrieving list of services", "", True)
    if not rc: return None

    # Extract and return the list of service levels the user is entitled to
    try:
        services = []
        service_list = ""
        for item in api_data["data"]:
            services.append(item["eAccountType"] + ";" + str(item["iVpnId"]))
            service_list = service_list + item["eAccountType"] + ", (" + str(
                item["iVpnId"]) + ") "
        debugTrace("Found services " + service_list)
        return services
    except Exception as e:
        errorTrace(
            "alternativeShellfire.py",
            "Couldn't parse the data that came back when listing the serice levels"
        )
        errorTrace("alternativeShellfire.py", str(e))
        return none
Ejemplo n.º 42
0
def copyLog():

    addon = xbmcaddon.Addon("service.zomboided.tools")
    addon_name = addon.getAddonInfo("name")

    # Copy the log file
    log_path = ""
    dest_path = ""
    try:
        log_path = xbmc.translatePath("special://logpath/kodi.log")
        start_dir = ""
        dest_folder = xbmcgui.Dialog().browse(
            0, "Select folder to copy log file into", "files", "", False,
            False, start_dir, False)
        dest_path = "kodi " + datetime.datetime.now().strftime(
            "%y-%m-%d %H-%M-%S") + ".log"
        dest_path = dest_folder + dest_path.replace(" ", "_")
        debugTrace("Copying " + log_path + " to " + dest_path)
        addon = xbmcaddon.Addon("service.zomboided.tools")
        infoTrace(
            "managefiles.py", "Copying log file to " + dest_path +
            ".  Using version " + addon.getSetting("version_number"))
        xbmcvfs.copy(log_path, dest_path)
        if not xbmcvfs.exists(dest_path):
            raise IOError('Failed to copy log ' + log_path + " to " +
                          dest_path)
        dialog_message = "Copied log file to:\n" + dest_path
    except:
        errorTrace("managefiles.py",
                   "Failed to copy log from " + log_path + " to " + dest_path)
        if xbmcvfs.exists(log_path):
            dialog_message = "Error copying log, try copying it to a different location."
        else:
            dialog_messsage = "Could not find the kodi.log file."
        errorTrace("managefiles.py",
                   dialog_message + " " + log_path + ", " + dest_path)
    xbmcgui.Dialog().ok("Log Copy", dialog_message)
Ejemplo n.º 43
0
def getNordVPNLocationsCommon(vpn_provider, exclude_used, friendly):
    # Return a list of all of the locations or location .ovpn files
    addon = xbmcaddon.Addon(getID())
    # Get the list of used, validated location file names
    used = []
    if exclude_used:
        # Adjust the 11 below to change conn_max
        for i in range(1, 11):
            s = addon.getSetting(str(i) + "_vpn_validated_friendly")
            if not s == "": used.append(s)

    filename = getAddonPath(True, vpn_provider + "/" + NORD_LOCATIONS)
    # If the list of countries doesn't exist (this can happen after a reinstall)
    # then go and do the pre-fetch first.  Otherwise this shouldn't be necessary
    try:
        if not xbmcvfs.exists(filename):
            getNordVPNPreFetch(vpn_provider)
    except Exception as e:
        errorTrace(
            "alternativeNord.py",
            "Couldn't download the list of countries for " + vpn_provider +
            " from " + filename)
        errorTrace("alternativeNord.py", str(e))
        return []

    # Read the locations file and generate the location file name, excluding any that are used
    try:

        locations_file = open(filename, 'r')
        locations = locations_file.readlines()
        locations_file.close()
        return_locations = []
        for l in locations:
            country, id = l.split(",")
            if not exclude_used or not country in used:
                if friendly:
                    return_locations.append(country)
                else:
                    return_locations.append(
                        getNordVPNLocationName(vpn_provider, country))
        return return_locations
    except Exception as e:
        errorTrace(
            "alternativeNord.py", "Couldn't read the list of countries for " +
            vpn_provider + " from " + filename)
        errorTrace("alternativeNord.py", str(e))
        return []
Ejemplo n.º 44
0
def getButtonCommands():
    # Use button activated commands from a userdata file instead of entering them
    addon = xbmcaddon.Addon("service.zomboided.tools")
    filename = xbmc.translatePath(
        "special://userdata/addon_data/service.zomboided.tools/COMMANDS.txt")

    # This will just warn the user on the settings screen we're using a file instead
    if xbmcvfs.exists(filename):
        addon.setSetting("button_override", "true")
    else:
        addon.setSetting("button_override", "false")

    if addon.getSetting("button_enabled") == "true":
        # Check if there's a bunch of commands in userdata to use instead
        try:
            if xbmcvfs.exists(filename):
                # Read the commands file and update settings
                commands_file = open(filename, 'r')
                commands = commands_file.readlines()
                commands_file.close()
                i = 1
                for command in commands:
                    command = command.strip(' \t\n\r')
                    # Ignore lines beginning with a #
                    if not command.startswith("#"):
                        addon.setSetting("button_command_" + str(i), command)
                        i += 1
                    if i == 11: break
                # Clear out any old commands
                for j in range(i, 10):
                    addon.setSetting("button_command_" + str(j), "")
        except Exception as e:
            errorTrace(
                "common.py",
                "Couldn't use the userdata COMMANDS.txt file to populate the settings"
            )
            errorTrace("common.py", str(e))
Ejemplo n.º 45
0
def getVPNConnectionStatus():
    # Open the openvpn output file and parse it for known phrases
    # Return 'connected', 'auth failed', 'network failed', 'error' or ''

    if fakeConnection(): return connection_status.UNKNOWN

    # **** ADD MORE PLATFORMS HERE ****
    # Might not need to mess with this too much if the log output from openvpn is the same

    p = getPlatform()
    if p == platforms.LINUX or p == platforms.RPI:
        path = getVPNLogFilePath()
        state = connection_status.UNKNOWN
        if xbmcvfs.exists(path):
            debugTrace("Reading log file")
            log = open(path, 'r')
            lines = log.readlines()
            for line in lines:
                if "Initialization Sequence Completed" in line:
                    state = connection_status.CONNECTED
                    break
                if "AUTH_FAILED" in line:
                    state = connection_status.AUTH_FAILED
                if "TLS Error" in line:
                    state = connection_status.NETWORK_FAILED
                if "Connection timed out" in line:
                    state = connection_status.TIMEOUT
            log.close()
            # Haven't found what's expected so return an empty stream
            if not state == connection_status.UNKNOWN:
                debugTrace("VPN connection status is " + str(state))
            return state
        else:
            errorTrace(
                "platform.py",
                "Tried to get VPN connection status but log file didn't exist")
            return connection_status.ERROR
Ejemplo n.º 46
0
            # This forces a connection validation after something stops playing
            if player.isPlaying():
                playing = True
            if playing and not player.isPlaying():
                playing = False
                timer = connection_retry_time + 1
                                        
			# This just checks the connection is still good every hour, providing the player is not busy
            if vpn_setup and not player.isPlaying() and timer > connection_retry_time:
                addon = xbmcaddon.Addon()
                if addon.getSetting("vpn_reconnect") == "true":
                    debugTrace("Reconnect timer triggered, checking connection")
                    if not isVPNConnected() and not (getVPNState() == "off"):
                        # Don't know why we're disconnected, but reconnect to the last known VPN
                        errorTrace("service.py", "VPN monitor service detected VPN connection " + getVPNProfile() + " is not running when it should be")
                        writeVPNLog()
                        if getVPNRequestedProfile() == "":
                            setVPNRequestedProfile(getVPNProfile())
                            setVPNRequestedProfileFriendly(getVPNProfileFriendly())
                        setVPNProfile("")
                        setVPNProfileFriendly("")
                        reconnect_vpn = True
                    timer = 0

            # Check to see if it's time for a reboot (providing we need to, and nothing is playing)
            if (not player.isPlaying()) and reboot_timer >= seconds_to_reboot_check:
                addon = xbmcaddon.Addon()
                reboot_timer = 0
                # Assume the next check is in an hour
                seconds_to_reboot_check = 3600
Ejemplo n.º 47
0
 if not getVPNRequestedProfile() == "":
     progress.close()
     xbmcgui.Dialog().ok(addon_name, "Connection to VPN being attempted and will be aborted.  Try again in a few seconds.")
     setAPICommand("Disconnect")
     success = False
 
 if success:
     # Stop the VPN monitor
     xbmc.sleep(100)
     progress.update(0, progress_title, "Pausing VPN monitor...")
     xbmc.sleep(100)
         
     if not stopService():
         progress.close()
         # Display error result in an ok dialog
         errorTrace("resetVPN.py", "VPN monitor service is not running, can't reset VPNs")
         xbmcgui.Dialog().ok(progress_title, "Error, Service not running. Check log and re-enable.")
         success = False
 
 # Disconnect and reset all connections
 if success:
     progress.update(20, progress_title, "VPN monitor paused")
     xbmc.sleep(DIALOG_SPEED)
     progress.update(40, progress_title, "Stopping any active VPN connection...")
     xbmc.sleep(100)
     resetVPNConnections(addon)
     # Reset any validated values
     addon.setSetting("vpn_provider_validated", "")
     addon.setSetting("vpn_username_validated", "")
     addon.setSetting("vpn_password_validated", "")
 
Ejemplo n.º 48
0
def updateVPNFiles(vpn_provider):
    # If the OVPN files aren't generated then they need to be updated with location info    
    
    infoTrace("vpnproviders.py", "Updating VPN profiles for " + vpn_provider)
    # Get the list of VPN profile files        
    ovpn_connections = getAddonList(vpn_provider, "*.ovpn")

    # See if there's a port override going on
    addon = xbmcaddon.Addon("service.vpn.manager")
    if addon.getSetting("default_udp") == "true":
        portUDP = ""
    else:
        portUDP = addon.getSetting("alternative_udp_port")
        
    if addon.getSetting("default_tcp") == "true":
        portTCP = ""
    else:
        portTCP = addon.getSetting("alternative_tcp_port")

    # Get the logging level
    verb_value = addon.getSetting("openvpn_verb")
    if verb_value == "":
        verb_value = "1"
        addon.setSetting("openvpn_verb", verb_value)
        
    for connection in ovpn_connections:
        try:
            f = open(connection, 'r+')
            debugTrace("Processing file " + connection)
            lines = f.readlines()
            f.seek(0)
            f.truncate()
            # Get the profile friendly name in case we need to generate key/cert names
            name = connection[connection.rfind(getSeparator())+1:]
            # Update the necessary values in the ovpn file
            for line in lines:
                
                # Update path to pass.txt
                if not isUserDefined(vpn_provider) or addon.getSetting("user_def_credentials") == "true":
                    if line.startswith("auth-user-pass"):
                        line = "auth-user-pass " + getAddonPathWrapper(vpn_provider + "/" + "pass.txt\n")

                # Update port numbers
                if line.startswith("remote "):
                    port = ""
                    for newline in lines:
                        if "proto " in newline:
                            if "tcp" in newline and not portTCP == "": port = portTCP
                            if "udp" in newline and not portUDP == "": port = portUDP
                    if not port == "":
                        tokens = line.split()
                        line = "remote " + tokens[1] + " " + port + "\n"

                # Update user cert and key                
                if usesUserKeys(vpn_provider):
                    if line.startswith("cert "):
                        line = "cert " + getUserDataPathWrapper(vpn_provider + "/" + getCertName(vpn_provider, name) + "\n")
                    if line.startswith("key "):
                        line = "key " + getUserDataPathWrapper(vpn_provider + "/" + getKeyName(vpn_provider, name) + "\n")
                
                # For user defined profile we need to replace any path tags with the addon dir path
                if isUserDefined(vpn_provider):
                    line = line.replace("#PATH", getAddonPathWrapper(vpn_provider))
                
                # Set the logging level
                if line.startswith("verb "):
                    line = "verb " + verb_value + "\n"
    
                f.write(line)
            f.close()
        except:
            errorTrace("vpnproviders.py", "Failed to update ovpn file")
            return False

    # Flag that the files have been generated            
    writeGeneratedFile(vpn_provider)
            
    return True    
Ejemplo n.º 49
0
def connectVPN(connection_order, vpn_profile):

    # Don't know where this was called from so using plugin name to get addon handle
    addon = xbmcaddon.Addon("service.vpn.manager")
    addon_name = addon.getAddonInfo("name")

    # If we've not arrived here though the addon (because we've used the add-on setting
    # on the option menu), we want to surpress running the wizard as there's no need.
    addon.setSetting("vpn_wizard_run", "true")

    # Check openvpn installed and runs
    if not addon.getSetting("checked_openvpn") == "true":        
        if checkVPNInstall(addon): addon.setSetting("checked_openvpn", "true")
        else: return

    if not addon.getSetting("ran_openvpn") == "true":
        stopVPN()    
        if checkVPNCommand(addon): addon.setSetting("ran_openvpn", "true")
        else: return
    
    # The VPN protocol can be blank if this is a new run and the wizard is being used.
    # Force it to UDP as that's the most optimal and let them change in the settings.
    vpn_protocol = addon.getSetting("vpn_protocol")
    if vpn_protocol == "":
        addon.setSetting("vpn_protocol", "UDP")
        vpn_protocol = "UDP"
    
    # Do some stuff to set up text used in dialog windows
    connection_title = ""
    
    # Adjust strings below if changing number of conn_max
    if connection_order == "0" : connection_title = ""
    if connection_order == "1" : connection_title = " first"
    if connection_order == "2" : connection_title = " second"
    if connection_order == "3" : connection_title = " third"
    if connection_order == "4" : connection_title = " fourth"
    if connection_order == "5" : connection_title = " fifth"
    if connection_order == "6" : connection_title = " sixth"
    if connection_order == "7" : connection_title = " seventh"
    if connection_order == "8" : connection_title = " eighth"
    if connection_order == "9" : connection_title = " ninth"
    if connection_order == "10" : connection_title = " tenth"
    
    state = ""
    
    forceCycleLock()
    
    # Display a progress dialog box (put this on the screen quickly before doing other stuff)
    progress = xbmcgui.DialogProgress()
    progress_title = "Connecting to" + connection_title + " VPN."
    progress.create(addon_name,progress_title) 

    debugTrace(progress_title)
        
    # Pause the monitor service
    progress_message = "Pausing VPN monitor."
    progress.update(1, progress_title, progress_message)
    if not stopService():
        progress.close()
        # Display error result in an ok dialog
        errorTrace("common.py", "VPN monitor service is not running, can't start VPN")
        xbmcgui.Dialog().ok(progress_title, "Error, Service not running.\nCheck log and re-enable.")
        return

    if not progress.iscanceled():
        progress_message = "VPN monitor paused."
        debugTrace(progress_message)
        progress.update(5, progress_title, progress_message)
        xbmc.sleep(500)
        
    # Stop any active VPN connection
    if not progress.iscanceled():
        progress_message = "Stopping any active VPN connection."    
        progress.update(6, progress_title, progress_message)
        stopVPNConnection()

    if not progress.iscanceled():
        progress_message = "Disconnected from VPN."
        progress.update(10, progress_title, progress_message)
        xbmc.sleep(500)
        
    # Install the VPN provider    
    existing_connection = ""
    if not progress.iscanceled():
    
        vpn_provider = addon.getSetting("vpn_provider")
    
        # This is some code to copy the user name from a default file rather than use the user entered values.
        # It exists to help development where swapping between providers constantly is tedious.
        default_path = getUserDataPath(getVPNLocation(vpn_provider) + "/DEFAULT.txt")
        if connection_order == "1" and xbmcvfs.exists(default_path):
            default_file = open(default_path, 'r')
            default = default_file.readlines()
            default_file.close()
            default_value = default[0].strip(' \t\n\r')
            addon.setSetting("vpn_username", default_value)
            default_value = default[1].strip(' \t\n\r')
            addon.setSetting("vpn_password", default_value)  

        # Reset the username/password if it's not being used
        if not usesPassAuth(vpn_provider):
            addon.setSetting("vpn_username", "")
            addon.setSetting("vpn_password", "")  
                
        vpn_username = addon.getSetting("vpn_username")
        vpn_password = addon.getSetting("vpn_password")
        
        # Reset the setting indicating we've a good configuration for just this connection
        if not connection_order == "0":
            existing_connection = addon.getSetting(connection_order + "_vpn_validated")
            addon.setSetting(connection_order + "_vpn_validated", "")
            addon.setSetting(connection_order + "_vpn_validated_friendly", "")
        last_provider = addon.getSetting("vpn_provider_validated")
        last_credentials = addon.getSetting("vpn_username_validated") + " " + addon.getSetting("vpn_password_validated")
        if last_provider == "" : last_provider = "?"
        
        # Provider or credentials we've used previously have changed so we need to reset all validated connections
        vpn_credentials = vpn_username + " " + vpn_password
        if not last_provider == vpn_provider:
            last_credentials = "?"
        if not last_credentials == vpn_credentials:
            debugTrace("Credentials have changed since last time lthrough so need to revalidate")
            resetVPNConfig(addon, 1)   
    
    # Generate or fix the OVPN files if we've not done this previously
    provider_gen = True
    if not progress.iscanceled():
        if not ovpnFilesAvailable(getVPNLocation(vpn_provider)):

            # Fetch the list of locations available.  If there are multiple, the user can select
            locations = getLocationFiles(getVPNLocation(vpn_provider))            
            default_label = "Default"
            i = 0            
            for location in locations:
                locations[i] = location[location.index("LOCATIONS")+10:location.index(".txt")]
                if locations[i] == "" : locations[i] = default_label
                i = i + 1
            selected_profile = ""
            if len(locations) == 0: errorTrace("common.py", "No LOCATIONS.txt files found in VPN directory.  Cannot generate ovpn files.")
            if len(locations) > 1:
                selected_location = xbmcgui.Dialog().select("Select connections profile", locations)
                selected_profile = locations[selected_location]
                if selected_profile == default_label : selected_profile = ""
            
            addon.setSetting("vpn_locations_list", selected_profile)
            progress_message = "Setting up VPN provider " + vpn_provider + "."
            progress.update(11, progress_title, progress_message)
            # Delete any old files in other directories
            debugTrace("Deleting all generated ovpn files")
            removeGeneratedFiles()
            # Generate new ones
            try:
                provider_gen = fixOVPNFiles(getVPNLocation(vpn_provider), selected_profile)
            except:
                errorTrace("Couldn't generate new .ovpn files")
                provider_gen = False
            xbmc.sleep(500)

    if provider_gen:
        if not progress.iscanceled():
            progress_message = "Using VPN provider " + vpn_provider
            progress.update(15, progress_title, progress_message)
            xbmc.sleep(500)
                            
        # Set up user credentials file
        if not progress.iscanceled() and usesPassAuth(vpn_provider):
            credentials_path = getCredentialsPath(addon)
            debugTrace("Attempting to use the credentials in " + credentials_path)
            if (not last_credentials == vpn_credentials) or (not xbmcvfs.exists(credentials_path)) or (not connectionValidated(addon)):
                progress_message = "Configuring authentication settings for user " + vpn_username + "."
                progress.update(16, progress_title, progress_message)
                provider_gen = writeCredentials(addon)

    got_keys = True
    keys_copied = True
    cancel_attempt = False
    cancel_clear = False
    if provider_gen:
        ovpn_name = ""
        if not progress.iscanceled():
            if usesPassAuth(vpn_provider):
                progress_message = "Using authentication settings for user " + vpn_username + "."
            else:
                progress_message = "User authentication not used with " + vpn_provider + "."
            progress.update(19, progress_title, progress_message)
            xbmc.sleep(500)

        # Display the list of connections
        if not progress.iscanceled():

            if not connection_order == "0":
                debugTrace("Displaying list of connections")
                all_connections = getProfileList(vpn_provider)
                ovpn_connections = getFilteredProfileList(all_connections, vpn_protocol, addon)
                ovpn_connections.sort()
                connections = getFriendlyProfileList(vpn_provider, ovpn_connections)
                
                if len(connections) > 0:
                    if existing_connection == "":
                        cancel_text = "[I]Cancel connection attempt[/I]"
                    else:
                        cancel_text = "[I]Cancel connection attempt and clear connection[/I]"
                        cancel_clear = True
                    connections.append(cancel_text)
                    selected_connection = xbmcgui.Dialog().select("Select " + connection_title + " VPN profile", connections)                  
                
                    # Based on the value selected, get the path name to the ovpn file
                    ovpn_name = connections[selected_connection]
                    if ovpn_name == cancel_text:
                        ovpn_name = ""
                        cancel_attempt = True
                    else:
                        ovpn_connection = ovpn_connections[selected_connection]
            else:
                ovpn_name = getFriendlyProfileName(vpn_provider, vpn_profile)
                ovpn_connection = vpn_profile

        if not progress.iscanceled() and not ovpn_name == "":
            # Fetch the key from the user if one is needed
            if usesUserKeys(getVPNLocation(vpn_provider)):                
                # If a key already exists, skip asking for it
                if not (gotKeys(getVPNLocation(vpn_provider), ovpn_name)):
                    # Stick out a helpful message if this is first time through
                    if not gotKeys(getVPNLocation(vpn_provider), ""):
                        xbmcgui.Dialog().ok(addon_name, vpn_provider + " provides unique key and certificate files to authenticate, typically called [I]client.key and client.crt[/I] or [I]user.key and user.crt[/I].  Make these files available on an accessable drive or USB key.")                
                    # Get the last directory browsed to avoid starting from the top
                    start_dir = xbmcgui.Window(10000).getProperty("VPN_Manager_User_Directory")
                    if usesSingleKey(getVPNLocation(vpn_provider)): select_title = "Select the user key file to use for all connections"
                    else: select_title = "Select the user key file to use for this individual connection"
                    key_file = xbmcgui.Dialog().browse(1, select_title, "files", ".key", False, False, start_dir, False)
                    if key_file.endswith(".key"):
                        start_dir = os.path.dirname(key_file) + getSeparator()
                        if usesSingleKey(getVPNLocation(vpn_provider)): select_title = "Select the user certificate file to use for all connections"
                        else: select_title = "Select the user certificate file to use for this individual connection"
                        crt_file = xbmcgui.Dialog().browse(1, select_title, "files", ".crt", False, False, start_dir, False)                    
                        if crt_file.endswith(".crt"):
                            start_dir = os.path.dirname(crt_file) + getSeparator()
                            xbmcgui.Window(10000).setProperty("VPN_Manager_User_Directory", start_dir)
                            keys_copied = copyKeyAndCert(getVPNLocation(vpn_provider), ovpn_name, key_file, crt_file)
                            got_keys = keys_copied
                        else:
                            got_keys = False
                    else:
                        got_keys = False

        # Try and connect to the VPN provider using the entered credentials        
        if not progress.iscanceled() and not ovpn_name == "" and got_keys:    
            progress_message = "Connecting using profile " + ovpn_name + "."
            debugTrace(progress_message)
            
            # Start the connection and wait a second before starting to check the state
            startVPN(ovpn_connection)
            
            i = 0
            # Bad network takes over a minute to spot so loop for a bit longer (each loop is 2 seconds)
            loop_max = 38
            if fakeConnection(): loop_max = 2
            percent = 20
            while i <= loop_max:
                progress.update(percent, progress_title, progress_message)
                xbmc.sleep(2000)
                state = getVPNConnectionStatus()
                if not (state == connection_status.UNKNOWN or state == connection_status.TIMEOUT) : break
                if progress.iscanceled(): break
                i = i + 1
                percent = percent + 2

    # Mess with the state to make it look as if we've connected to a VPN
    if fakeConnection() and not progress.iscanceled() and provider_gen and not ovpn_name == "" and got_keys: state = connection_status.CONNECTED
    
    # Determine what happened during the connection attempt        
    if state == connection_status.CONNECTED :
        # Success, VPN connected! Display an updated progress window whilst we work out where we're connected to
        progress_message = "Connected, restarting VPN monitor."
        progress.update(97, progress_title, progress_message)
        # Set the final message to indicate success
        progress_message = "Connected, VPN monitor restarted."
        _, ip, country, isp = getIPInfo(addon)
        dialog_message = "Connected to a VPN in " + country + ".\nUsing profile " + ovpn_name + ".\nExternal IP address is " + ip + ".\nService Provider is " + isp + "."
        infoTrace("common.py", dialog_message)
        if ifDebug(): writeVPNLog()
        # Store that setup has been validated and the credentials used
        setVPNProfile(ovpn_connection)
        setVPNProfileFriendly(ovpn_name)
        if not connection_order == "0":
            addon.setSetting("vpn_provider_validated", vpn_provider)
            addon.setSetting("vpn_username_validated", vpn_username)
            addon.setSetting("vpn_password_validated", vpn_password)
            addon.setSetting(connection_order + "_vpn_validated", ovpn_connection)
            addon.setSetting(connection_order + "_vpn_validated_friendly", ovpn_name)
        setVPNState("started")
        setVPNRequestedProfile("")
        setVPNRequestedProfileFriendly("")
        setVPNLastConnectedProfile("")
        setVPNLastConnectedProfileFriendly("")
        setConnectionErrorCount(0)
        # Indicate to the service that it should update its settings
        updateService()        
    elif progress.iscanceled() or cancel_attempt:
        # User pressed cancel.  Don't change any of the settings as we've no idea how far we got
        # down the path of installing the VPN, configuring the credentials or selecting the connection
        # We're assuming here that if the VPN or user ID has been changed, then the connections are invalid
        # already.  If the cancel happens during the connection validation, we can just use the existing one.
        # Set the final message to indicate user cancelled operation
        progress_message = "Cancelling connection attempt, restarting VPN monitor."
        progress.update(97, progress_title, progress_message)
        # Set the final message to indicate cancellation
        progress_message = "Cancelling connection attempt, VPN monitor restarted."
        # Restore the previous connection info 
        dialog_message = "Cancelled connection attempt.\n"
        if not connection_order == "0":
            if not isVPNConnected():
                if cancel_clear:
                    dialog_message = dialog_message + "This connection has been removed from the list of valid connections."
                else:
                    dialog_message = dialog_message + "This connection has not been validated."
                resetVPNConfig(addon, int(connection_order))
        else:
            dialog_message = dialog_message + "Please reconnect."
        
        # Don't know how far we got, if we were trying to connect and then got cancelled,
        # there might still be an instance of openvpn running we need to kill
        stopVPN()
    else:
        # An error occurred, The current connection is already invalidated.  The VPN credentials might 
        # be ok, but if they need re-entering, the user must update them which will force a reset.  
        progress_message = "Error connecting to VPN, restarting VPN monitor."
        progress.update(97, progress_title, progress_message)
        xbmc.sleep(500)
        # Set the final message to show an error occurred
        progress_message = "Error connecting to VPN, VPN monitor restarted."
        # First set of errors happened prior to trying to connect
        if not provider_gen:
            dialog_message = "Error creating OVPN or credentials file for provider.\nCheck log to determine cause of failure."
        elif not got_keys:
            if not keys_copied:
                dialog_message = "Failed to copy supplied user key and cert files.\nCheck log and retry."
            else:
                dialog_message = "User key and certificate files are required, but were not provided.  Locate the files and try again."
        elif ovpn_name == "":
            dialog_message = "No unused VPN profiles were available for " + vpn_protocol + " protocol.\nChange VPN provider settings."
        else:
            # This second set of errors happened because we tried to connect and failed
            if state == connection_status.AUTH_FAILED: 
                dialog_message = "Error connecting to VPN, authentication failed.\nCheck your username and password."
                credentials_path = getCredentialsPath(addon)
                if not connection_order == "0":
                    addon.setSetting("vpn_username_validated", "")
                    addon.setSetting("vpn_password_validated", "")
            elif state == connection_status.NETWORK_FAILED: 
                dialog_message = "Error connecting to VPN, could not estabilish connection.\nCheck your username, password and network connectivity and retry."
            elif state == connection_status.TIMEOUT:
                dialog_message = "Error connecting to VPN, connection has timed out.\nTry using a different VPN profile or retry."
            else:
                dialog_message = "Error connecting to VPN, something unexpected happened.\nRetry to check openvpn operation and then check log."
                addon.setSetting("ran_openvpn", "false")
            
            # Output what when wrong with the VPN to the log
            writeVPNLog()

        if not connection_order == "0" :
            resetVPNConfig(addon, int(connection_order))
        
        errorTrace("common.py", dialog_message)

        # The VPN might be having a spaz still so we want to ensure it's stopped
        stopVPN()

    # Restart service
    if not startService():
        progress.close()
        errorTrace("common.py", "VPN monitor service is not running, VPN has started")
        dialog_message = "Error, Service not running.\nCheck log and reboot."        
    else:
        # Close out the final progress dialog
        progress.update(100, progress_title, progress_message)
        xbmc.sleep(500)
        progress.close()
    
    freeCycleLock()

    # Display connection result in an ok dialog
    xbmcgui.Dialog().ok(progress_title, dialog_message)
    
    # Refresh the screen if this is not being done on settings screen
    if connection_order == "0" : xbmc.executebuiltin('Container.Refresh')
Ejemplo n.º 50
0
            show_filters = False
        elif filters[i] == id_reset:
            # Delete all of the filters
            if len(filters) > 5:
                del filters[0:len(filters)-5]
        elif filters[i] == id_single:
            # Ask user for window ID
            new_filter = editSingle("")
            if not new_filter == "": filters.insert(len(filters)-5, new_filter)
        elif filters[i] == id_range:
            # Ask user for range of window IDs
            new_filter = editRange("")
            if not new_filter == "": filters.insert(len(filters)-5, new_filter)
        else:
            # Edit or delete an existing filter
            if not xbmcgui.Dialog().yesno(addon_name, "Edit or delete window ID filter " + filters[i] + "?", nolabel="Edit", yeslabel="Delete"):
                if "-" in filters[i]:
                    new_filter = editRange(filters[i])
                else:
                    new_filter = editSingle(filters[i])
                if not new_filter == "": filters.insert(len(filters)-5, new_filter)
            else:
                del filters[i]

    command = "Addon.OpenSettings(" + getID() + ")"
    xbmc.executebuiltin(command)   
else:
    errorTrace("windowfilter.py", "VPN service is not ready")
    
debugTrace("-- Exit windowfilter.py --")
Ejemplo n.º 51
0
def generateOVPNFiles(vpn_provider, alternative_locations_name):
    # Generate the OVPN files for a VPN provider using the template and update with location info
    
    infoTrace("vpnproviders.py", "Generating OVPN files for " + vpn_provider + " using list " + alternative_locations_name)

    # See if there's a port override going on
    addon = xbmcaddon.Addon("service.vpn.manager")
    if addon.getSetting("default_udp") == "true":
        portUDP = ""
    else:
        portUDP = addon.getSetting("alternative_udp_port")
        
    if addon.getSetting("default_tcp") == "true":
        portTCP = ""
    else:
        portTCP = addon.getSetting("alternative_tcp_port")

    # Get the logging level
    verb_value = addon.getSetting("openvpn_verb")
    if verb_value == "":
        verb_value = "1"
        addon.setSetting("openvpn_verb", verb_value)
        
    # Load ovpn template
    try:
        debugTrace("Opening template file for " + vpn_provider)
        template_file = open(getAddonPath(True, vpn_provider + "/TEMPLATE.txt"), 'r')
        debugTrace("Opened template file for " + vpn_provider)
        template = template_file.readlines()
        template_file.close()
    except:
        errorTrace("vpnproviders.py", "Couldn't open the template file for " + vpn_provider)
        return False
    
    # Load locations file
    if not alternative_locations_name == "":
        if alternative_locations_name == "User":
            locations_name = getUserDataPath(vpn_provider + "/LOCATIONS.txt")
        else:
            locations_name = getAddonPath(True, vpn_provider + "/LOCATIONS " + alternative_locations_name + ".txt")
    else:
        locations_name = getAddonPath(True, vpn_provider + "/LOCATIONS.txt")

    try:
        debugTrace("Opening locations file for " + vpn_provider + "\n" + locations_name)
        locations_file = open(locations_name, 'r')
        debugTrace("Opened locations file for " + vpn_provider)
        locations = locations_file.readlines()
        locations_file.close()
    except:
        errorTrace("vpnproviders.py", "Couldn't open the locations file for " + vpn_provider + "\n" + locations_name)
        return False

    # For each location, generate an OVPN file using the template
    for location in locations:
        try:
            location_values = location.split(",")
            geo = location_values[0]
            servers = location_values[1].split()
            proto = location_values[2]
            ports = (location_values[3].strip(' \t\n\r')).split()
            port = ""

            # Initialise the set of values that can be modified by the location file tuples
            ca_cert = "ca.crt"
            ta_key = "ta.key"
            user_key = getUserDataPathWrapper(vpn_provider + "/" + getKeyName(vpn_provider, geo))
            user_cert = getUserDataPathWrapper(vpn_provider + "/" + getCertName(vpn_provider, geo))
            remove_flags = ""
            
            if len(location_values) > 4: 
                # The final location value is a list of multiple x=y declarations.
                # These need to be parsed out and modified.
                modifier_tuples = (location_values[4].strip(' \t\n\r')).split()
                # Loop through all of the values splitting them into name value pairs
                for modifier in modifier_tuples:
                    pair = modifier.split("=")
                    if "#CERT" in pair[0]: ca_cert = pair[1].strip()
                    if "#REMOVE" in pair[0]: remove_flags = pair[1].strip()
                    if "#TLSKEY" in pair[0]: ta_key = pair[1].strip()
                    if "#USERKEY" in pair[0]: user_key = pair[1].strip()
                    if "#USERCERT" in pair[0]: user_cert = pair[1].strip()
            if proto == "udp" and not portUDP == "": port = portUDP
            if proto == "tcp" and not portTCP == "": port = portTCP
            if port == "" and len(ports) == 1: port = ports[0]
        except:
            errorTrace("vpnproviders.py", "Location file for " + vpn_provider + " invalid on line\n" + location)
            return False
            
        try:
            ovpn_file = open(getAddonPath(True, vpn_provider + "/" + geo + ".ovpn"), 'w')
            if proto == "tcp":
                servprot = "tcp-client"
            else:
                servprot = proto

            # Do a replace on the tags in the template with data from the location file
            for line in template:
                output_line = line.strip(' \t\n\r')
                # Must check to see if there's a remove tag on the line before looking for other tags
                if "#REMOVE" in output_line:
                    if output_line[output_line.index("#REMOVE")+7] in remove_flags:
                        # Remove the line if it's a flag this location doesn't care about
                        output_line = ""
                    else:
                        # Delete the tag if this location doesn't want this line removed
                        output_line = output_line.replace("#REMOVE" + output_line[output_line.index("#REMOVE")+7], "")
                output_line = output_line.replace("#PROTO", proto)
                output_line = output_line.replace("#SERVPROT", servprot)
                # If there are multiple servers then we'll need to duplicate the server
                # line (which starts with 'remote ') and fix the server.  The rest of the
                # code will deal with the port which is the same for all lines (although
                # this assumption might not be true for all VPN providers...)
                if output_line.startswith("remote "):
                    server_template = output_line
                    server_lines = ""
                    i = 0
                    for server in servers:
                        if not server_lines == "" : server_lines = server_lines + "\n"
                        server_lines = server_lines + server_template.replace("#SERVER", server)
                        if port == "":
                            server_lines = server_lines.replace("#PORT", ports[i])
                        i = i + 1
                    output_line = server_lines
                # There might be other places we use server and port, so still the do the replace
                output_line = output_line.replace("#SERVER", servers[0])
                output_line = output_line.replace("#PORT", port)
                output_line = output_line.replace("#PASS", getAddonPathWrapper(vpn_provider + "/" + "pass.txt"))
                output_line = output_line.replace("#CERT", getAddonPathWrapper(vpn_provider + "/" + ca_cert))
                output_line = output_line.replace("#TLSKEY", getAddonPathWrapper(vpn_provider + "/" + ta_key))
                output_line = output_line.replace("#CRLVERIFY", getAddonPathWrapper(vpn_provider + "/" + "crl.pem"))
                output_line = output_line.replace("#USERKEY", user_key)
                output_line = output_line.replace("#USERCERT", user_cert)
                # Overwrite the verb value with the one in the settings
                if output_line.startswith("verb "):
                    output_line = "verb " + verb_value
                # This is a little hack to remove a tag that doesn't work with TCP but is needed for UDP
                # Could do this with a #REMOVE, but doing it here is less error prone.
                if "explicit-exit-notify" in line and proto == "tcp": output_line = ""
                if not output_line == "" : ovpn_file.write(output_line + "\n")
            ovpn_file.close()
            debugTrace("Wrote location " + geo + " " + proto)
        except:
            errorTrace("vpnproviders.py", "Can't write a location file for " + vpn_provider + " failed on line\n" + location)
            return False
    
    # Flag that the files have been generated
    writeGeneratedFile(vpn_provider)

    return True
Ejemplo n.º 52
0
                title = "Connected - " + getVPNProfileFriendly()
                connections.insert(0, disconnect_text)
            else:
                title = "Disconnected"
                connections.insert(0, disconnected_text)
            
            connections.append(cancel_text)

            i = xbmcgui.Dialog().select(title, connections)
            if connections[i] == disconnect_text or connections[i] == disconnected_text:
                setAPICommand("Disconnect")
            elif not connections[i] == cancel_text:
                if getVPNProfile() == location_connections[i-1] and (allowReconnection(vpn_provider) or addon.getSetting("allow_cycle_reconnect") == "true"):
                    setAPICommand("Reconnect")
                else:
                    if isAlternative(vpn_provider) and addon.getSetting("table_display_type") == "All connections":
                        _, connection, user_text, ignore = getAlternativeLocation(vpn_provider, connections[i], 0, True)
                        if not ignore and not user_text == "":
                            xbmcgui.Dialog().ok(addon_name, user_text)
                    else:
                        connection = location_connections[i-1]
                    if not connection == "":
                        setAPICommand(connection)
            freeCycleLock()
    else:
        xbmcgui.Dialog().notification(addon_name, "VPN is not set up and authenticated.", xbmcgui.NOTIFICATION_ERROR, 10000, True)
else:
    errorTrace("table.py", "VPN service is not ready")
    
debugTrace("-- Exit table.py --")
Ejemplo n.º 53
0
        setAPICommand("Restart")
    elif lcommand == "reconnect":
        setAPICommand("Reconnect")
    elif lcommand == "getip":
        setAPICommand("GetIP")
    elif lcommand.startswith("connect"): 
        connection = command[8:].strip(' \t\n\r')
        if connection.isdigit():
            c = int(connection)
            addon = xbmcaddon.Addon(getID())
            # Adjust the 11 below to change conn_max
            if c > 0 and c < 11:
                connection = addon.getSetting(str(c) + "_vpn_validated")
                if not connection == "":
                    setAPICommand(connection)
                else:
                    errorTrace("api.py", "Connection requested, " + str(c) + " has not been validated")
            else:
                errorTrace("api.py", "Invalid connection, " + str(c) + " requested")
        else:
            if xbmcvfs.exists(connection):
                setAPICommand(connection)
            else:
                errorTrace("api.py", "Requested connection, " + connection + " does not exist")
    else:
        errorTrace("api.py", "Unrecognised command: " + command)
else:
    errorTrace("api.py", "VPN service is not ready")
    
debugTrace("-- Exit api.py --")
Ejemplo n.º 54
0
def sendAPI(command, command_text, api_data, check_response):
    # Common routine to send an API command
    try:
        response = ""
        rc = True
        rest_url = REQUEST_URL + command
        
        auth_token,_,_,_ = getTokens()
        # Login again if the token is blank and the command is not login anyway
        if auth_token == "" and not "=login" in command:
            debugTrace("Logging in again because auth token not valid")
            addon = xbmcaddon.Addon(getID())
            rc = authenticateShellfire(addon.getSetting("vpn_provider"), addon.getSetting("vpn_username"), addon.getSetting("vpn_password"))
            auth_token,_,_,_ = getTokens()
            if auth_token == "" or not rc:
                raise Exception(command_text + " was not authorized")
        
        if ifHTTPTrace(): infoTrace("alternativeShellfire.py", command_text + " " + rest_url)     
        else: debugTrace(command_text)
        
        req = urllib2.Request(rest_url, api_data, REQUEST_HEADERS)
        if not auth_token == "": req.add_header("x-authorization-token", auth_token)
        t_before = now()
        response = urllib2.urlopen(req)
        api_data = json.load(response)   
        t_after = now()    
        response.close()

        # Trace if the command took a long time
        if ifJSONTrace(): infoTrace("alternativeShellfire.py", "JSON received is \n" + json.dumps(api_data, indent=4))
        if t_after - t_before > TIME_WARN: infoTrace("alternativeShellfire.py", command_text + " took " + str(t_after - t_before) + " seconds")
        
        # Check the response and fail if it's bad
        if check_response:
            if not api_data["status"] == "success":
                raise Exception(command_text + " returned bad response, " + api_data["status"])
        
    except urllib2.HTTPError as e:
        errorTrace("alternativeShellfire.py", command_text + " failed")
        errorTrace("alternativeShellfire.py", "API call was " + rest_url)
        if not api_data == "": errorTrace("alternativeShellfire.py", "Data returned was \n" + json.dumps(api_data, indent=4))
        errorTrace("alternativeShellfire.py", "Response was " + str(e.code) + " " + e.reason)
        errorTrace("alternativeShellfire.py", e.read())
        rc = False
    except Exception as e:
        errorTrace("alternativeShellfire.py", command_text + " failed")
        errorTrace("alternativeShellfire.py", "API call was " + rest_url)
        if not api_data == "": errorTrace("alternativeShellfire.py", "Data returned was \n" + json.dumps(api_data, indent=4))
        errorTrace("alternativeShellfire.py", "Response was " + str(type(e)) + " " + str(e))
        rc = False
    
    return rc, api_data
Ejemplo n.º 55
0
    dest_path = ""
    try:
        log_path = getLogPath()
        start_dir = ""
        dest_folder = xbmcgui.Dialog().browse(0, "Select folder to copy log file into", "files", "", False, False, start_dir, False)
        dest_path = "kodi " + datetime.datetime.now().strftime("%y-%m-%d %H-%M-%S") + ".log"
        dest_path = dest_folder + dest_path.replace(" ", "_")
        # Write VPN log to log before copying
        writeVPNLog()
        debugTrace("Copying " + log_path + " to " + dest_path)
        addon = xbmcaddon.Addon("service.vpn.manager")
        infoTrace("managefiles.py", "Copying log file to " + dest_path + ".  Using version " + addon.getSetting("version_number"))
        xbmcvfs.copy(log_path, dest_path)
        dialog_message = "Copied log file to:\n" + dest_path
    except:
        errorTrace("Failed to copy log from " + log_path + " to " + dest_path)
        if xbmcvfs.exists(log_path):
            dialog_message = "Error copying log, try copying it to a different location."
        else:
            dialog_messsage = "Could not find the kodi.log file."
        errorTrace("managefiles.py", dialog_message + " " + log_path + ", " + dest_path)
    xbmcgui.Dialog().ok("Log Copy", dialog_message)


# Delete the user key and cert files        
elif action == "user":
    if addon.getSetting("1_vpn_validated") == "" or xbmcgui.Dialog().yesno(addon_name, "Deleting key and certificate files will reset all VPN connections.  Connections must be re-validated before use.\nContinue?"):

        # Reset the connection before we do anything else
        if isVPNConnected(): resetVPNConnections(addon)
    
Ejemplo n.º 56
0
def getShellfirePreFetch(vpn_provider):
    # Fetch and store location info
    filename = getAddonPath(True, vpn_provider + "/" + SHELLFIRE_LOCATIONS)
    if xbmcvfs.exists(filename):
        try:
            st = xbmcvfs.Stat(filename)
            create_time = int(st.st_ctime())
            t = now()
            # Fetch again if this is more than a day old otherwise use what there is
            if create_time + 86400 < t:
                debugTrace("Create time of " + filename + " is " + str(create_time) + " time now is " + str(t) + ", fetching location data again")
            else:
                debugTrace("Create time of " + filename + " is " + str(create_time) + " time now is " + str(t) + ", using existing data")
                # Less than a day old, so using the existing file
                return True
        except Exception as e:
            errorTrace("alternativeShellfire.py", "List of countries exist but couldn't get the time stamp for " + filename)
            errorTrace("alternativeShellfire.py", str(e))
            return False

    # Download the list of locations
    error = True
    try:
        response = ""
        api_data = ""
        rest_url = "https://www.shellfire.de/webservice/serverlist.php"
        
        if ifHTTPTrace(): infoTrace("alternativeShellfire.py", "Downloading list of locations using " + rest_url)
        else: debugTrace("Downloading list of locations")
        
        # This is not a JSON call, a header and servers are returned in a ; separated list
        req = urllib2.Request(rest_url, "", REQUEST_HEADERS)
        t_before = now()
        response = urllib2.urlopen(req)
        api_data = response.read()
        t_after = now()    
        response.close()

        if ifJSONTrace(): infoTrace("alternativeShellfire.py", "Text received is \n" + api_data)
        if t_after - t_before > TIME_WARN: infoTrace("alternativeShellfire.py", "Retrieving list of locations took " + str(t_after - t_before) + " seconds")
        
    except urllib2.HTTPError as e:
        errorTrace("alternativeShellfire.py", "Couldn't retrieve the list of locations")
        errorTrace("alternativeShellfire.py", "API call was " + rest_url)
        if not api_data == "": errorTrace("alternativeShellfire.py", "Data returned was \n" + api_data)
        errorTrace("alternativeShellfire.py", "Response was " + str(e.code) + " " + e.reason)
        errorTrace("alternativeShellfire.py", e.read())
        return False
    except Exception as e:
        errorTrace("alternativeShellfire.py", "Couldn't retrieve the list of locations")
        errorTrace("alternativeShellfire.py", "API call was " + rest_url)
        if not api_data == "": errorTrace("alternativeShellfire.py", "Data returned was \n" + api_data)
        errorTrace("alternativeShellfire.py", "Response was " + str(type(e)) + " " + str(e))
        return False
            
    # The first line has the headers, so find the position of the information that's interesting
    api_table = api_data.split("\n") 
    headers = api_table[0].split(";")
    id_pos = headers.index("iVpnServerId")
    country_pos = headers.index("Country")
    city_pos = headers.index("sCity")
    host_pos = headers.index("sHost")
    type_pos = headers.index("eServerType")    
    debugTrace("Header decoded.  ID is " + str(id_pos) + ", Country is " + str(country_pos) + ", City is " + str(city_pos) + ", Host is " + str(host_pos) + ", Type is " + str(type_pos))
    api_table[0] = ""
    
    try:
        line = ""
        cleaned_data = []
        debugTrace("Parsing the text and extracting the country, server and type")
        for line in api_table:       
            server_data = line.split(";")
            # Avoid parsing empty lines, or lines where there's not enough data
            if len(server_data) > 5:
                cleaned_data.append(server_data[country_pos] + " - " + server_data[city_pos] + " (S" + server_data[id_pos] + ")," + server_data[host_pos] + "," + server_data[type_pos] + "," + server_data[id_pos] + "\n")
    except Exception as e:
        errorTrace("alternativeShellfire`.py", "Couldn't parse the list of locations for " + vpn_provider)
        if not server_data == "": errorTrace("alternativeShellfire.py", "Processing line " + line)
        errorTrace("alternativeShellfire.py", str(e))
        return False
        
    # Sort the locations alphabetically
    cleaned_data.sort()    
        
    try:
        line = ""
        debugTrace("Parsing the text and writing the list of locations")
        output = open(filename, 'w')
        # Parse the data and create list containing the stuff we care about
        for line in cleaned_data:       
            output.write(line)
        output.close()
        return True
    except Exception as e:
        errorTrace("alternativeShellfire`.py", "Couldn't write the list of locations for " + vpn_provider + " to " + filename)
        if not server_data == "": errorTrace("alternativeShellfire.py", "Processing server " + line)
        errorTrace("alternativeShellfire.py", str(e))

    # Delete the location file if the was a problem creating it.  This will force a download next time through
    try:
        if xbmcvfs.exists(filename): 
            errorTrace("alternativeShellfire.py", "Deleting location file " + filename + " to clean up after previous error")
            xbmcvfs.delete(filename)
    except Exception as e:
        errorTrace("alternativeShellfire.py", "Couldn't delete the location file " + filename)
        errorTrace("alternativeShellfire.py", str(e))
    return False
Ejemplo n.º 57
0
def getShellfireLocation(vpn_provider, location, server_count, just_name):
    # Return the friendly and .ovpn name
    addon = xbmcaddon.Addon(getID())
    # Just return if this is a title that's been passed in
    if location.startswith(TITLE_START): return "", "", "Select a location or server", True
    # Remove all of the tagging
    # There's some escaping of the UPGRADE_END characters when passed in via the add-on menu
    # This is why the command below searches for the end of the upgrade and strips it
    location = location.replace(UPGRADE_START, "")
    if "I]" in location: location = location[:(location.index("I]")-2)]
    location = location.strip(" ")
    
    filename = getAddonPath(True, vpn_provider + "/" + SHELLFIRE_LOCATIONS)
    try:
        if not xbmcvfs.exists(filename):
            getShellfirePreFetch(vpn_provider)
    except Exception as e:
        errorTrace("alternativeShellfire.py", "Couldn't download the list of locations for " + vpn_provider + " from " + filename)
        errorTrace("alternativeShellfire.py", str(e))
        return "", "", "", False
           
    try:
        # Read the locations from the file and list by account type
        locations_file = open(filename, 'r')
        locations = locations_file.readlines()
        locations_file.close()
        for l in locations:
            if location in l:
                country, server, type, server_id = l.split(",")
                server_id = server_id.strip(" \n")
                break
        # Return an upgrade message if this server is not available to the user
        if ACCOUNT_TYPES.index(type) > ACCOUNT_TYPES.index(getAccountType()):
            _, message = getShellfireMessages(vpn_provider, 0, "")
            if message == "": message = "Get access to servers in over 30 countries with unlimited speed at shellfire.net/kodi"
            return "", "", "Upgrade to use this [B]" + type + "[/B] location.\n" + message, False
        
        # Generate the file name from the location
        location_filename = getShellfireLocationName(vpn_provider, country)
        
        if just_name: return location, location_filename, "", False
        
    except Exception as e:
        errorTrace("alternativeShellfire.py", "Couldn't read the list of locations for " + vpn_provider + " from " + filename)
        errorTrace("alternativeShellfire.py", str(e))
        return "", "", "", False
        
    # Set the selected server for the VPN being used
    try:
        setShellfireServer(getAccountID(), server_id)
        
        # Set the protocol.  If it's "UDP and TCP", choose UDP
        proto = addon.getSetting("vpn_protocol")
        if "UDP" in proto: proto = "UDP"
        if not setShellfireProtocol(getAccountID(), proto):
           raise Exception("Couldn't set the protocol") 
        
        # Get the parameters associated with this server and put them in a file
        if not getShellfireOvpn(getAccountID(), vpn_provider, country):
            raise Exception("Couldn't create an OVPN file") 
        
        # Get the certs associated with this server and put them in a file
        if not getShellfireCerts(getAccountID(), vpn_provider, country):
            raise Exception("Couldn't create the certificates") 

        return country, location_filename, "", False
    except Exception as e:
        errorTrace("alternativeShellfire.py", "Couldn't read the list of locations for " + vpn_provider + " from " + filename)
        errorTrace("alternativeShellfire.py", str(e))
        return "", "", "", False
Ejemplo n.º 58
0
def getShellfireLocationsCommon(vpn_provider, exclude_used, friendly, servers):
    # Return a list of all of the locations
    addon = xbmcaddon.Addon(getID())
    # Get the list of used, validated location file names
    used = []
    if exclude_used:
        # Adjust the 11 below to change conn_max
        for i in range(1, 11):
            s = addon.getSetting(str(i) + "_vpn_validated_friendly")
            if not s == "" : used.append(s)

    filename = getAddonPath(True, vpn_provider + "/" + SHELLFIRE_LOCATIONS)
    # If the list of locations doesn't exist (this can happen after a reinstall)
    # then go and do the pre-fetch first.  Otherwise this shouldn't be necessary
    try:
        if not xbmcvfs.exists(filename):
            getShellfirePreFetch(vpn_provider)
    except Exception as e:
        errorTrace("alternativeShellfire.py", "Couldn't download the list of locations for " + vpn_provider + " from " + filename)
        errorTrace("alternativeShellfire.py", str(e))
        return [] 

    try:
        service = ACCOUNT_TYPES.index(getAccountType())
    except Exception as e:
        errorTrace("alternativeShellfire.py", "Don't have an account for " + vpn_provider)
        errorTrace("alternativeShellfire.py", str(e))
        return []
        
    try:
            
        # Read the locations from the file and list by account type
        locations_file = open(filename, 'r')
        locations = locations_file.readlines()
        locations_file.close()
        return_locations = []
        
        # List the free servers
        return_locations.append(TITLE_START + "Free Locations" + TITLE_END)
        for l in locations:
            country, server, type, server_id = l.split(",")
            server_id = server_id.strip(" \n")    
            if type == ACCOUNT_TYPES[0]:
                if not exclude_used or not country in used:
                    if friendly:
                        return_locations.append(SERVER_START + country + SERVER_END)
                    elif servers:
                        return_locations.append(SERVER_START + server + SERVER_END)
                    else:
                        return_locations.append(type + getShellfireLocationName(vpn_provider, country))

        # List the paid servers
        return_locations.append(TITLE_START + "Paid Locations" + TITLE_END)
        for l in locations:
            country, server, type, server_id = l.split(",")
            server_id = server_id.strip(" \n")
            if not type == ACCOUNT_TYPES[0]:
                if ACCOUNT_TYPES.index(type) > service:
                    start = UPGRADE_START
                    end = UPGRADE_END
                else:
                    start = SERVER_START
                    end = SERVER_END
                if not exclude_used or not country in used:
                    if friendly:
                        return_locations.append(start + country + end)
                    elif servers:
                        return_locations.append(start + server + end)
                    else:
                        return_locations.append(type + getShellfireLocationName(vpn_provider, country))

        return return_locations    
    except Exception as e:
        errorTrace("alternativeShellfire.py", "Couldn't read the list of locations for " + vpn_provider + " from " + filename)
        errorTrace("alternativeShellfire.py", str(e))
        return []
        
    return []
Ejemplo n.º 59
0
def disconnectVPN():
    # Don't know where this was called from so using plugin name to get addon handle
    addon = xbmcaddon.Addon("service.vpn.manager")
    addon_name = addon.getAddonInfo("name")

    debugTrace("Disconnecting the VPN")
    
    forceCycleLock()
    
    # Show a progress box before executing stop
    progress = xbmcgui.DialogProgress()
    progress_title = "Disconnecting from VPN."
    progress.create(addon_name,progress_title)
    
    # Pause the monitor service
    progress_message = "Pausing VPN monitor."
    progress.update(1, progress_title, progress_message)
    if not stopService():
        progress.close()
        # Display error in an ok dialog, user will need to do something...
        errorTrace("common.py", "VPN monitor service is not running, can't stop VPN")
        xbmcgui.Dialog().ok(progress_title, "Error, Service not running.\nCheck log and reboot.")
        freeCycleLock()
        return
    
    xbmc.sleep(500)
    
    progress_message = "Stopping any active VPN connection."
    progress.update(1, progress_title, progress_message)
    
    # Kill the VPN connection if the user hasn't gotten bored waiting
    if not progress.iscanceled():
        stopVPNConnection()
        xbmc.sleep(500)    
        progress_message = "Disconnected from VPN, restarting VPN monitor"
        setVPNLastConnectedProfile("")
        setVPNLastConnectedProfileFriendly("")
        setVPNState("off")
    else:
        progress_message = "Disconnect cancelled, restarting VPN monitor"
        
    # Restart service
    if not startService():
        progress.close()
        errorTrace("common.py", "VPN monitor service is not running, VPN has stopped")
        dialog_message = "Error, Service not running.\nCheck log and reboot."        
    else:
        # Close out the final progress dialog
        progress.update(100, progress_title, progress_message)
        xbmc.sleep(500)
        progress.close()
    
        # Update screen and display result in an ok dialog
        xbmc.executebuiltin('Container.Refresh')
        _, ip, country, isp = getIPInfo(addon)       
        dialog_message = "Disconnected from VPN.\nNetwork location is " + country + ".\nExternal IP address is " + ip + ".\nService Provider is " + isp
        
        infoTrace("common.py", "Disconnected from the VPN")

    freeCycleLock()
    
    xbmcgui.Dialog().ok(addon_name, dialog_message)
Ejemplo n.º 60
0
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#    This module assists with the import of a user defined VPN provider

import xbmc
from libs.utility import debugTrace, errorTrace, infoTrace, newPrint, getID
from libs.userdefined import importWizard

debugTrace("Entered import.py")

if not getID() == "":     
    importWizard()        

    # Return to the settings screen
    command = "Addon.OpenSettings(" + getID() + ")"
    xbmc.executebuiltin(command)
else:
    errorTrace("import.py", "VPN service is not ready")

debugTrace("Exit import.py")