def getUserDataPathWrapper(name):
    # Return the fully qualified user path and file name
    if generateVPNs():
        return "/storage/.kodi/userdata/addon_data/service.vpn.manager/" + name
    else:
        if getPlatform() == platforms.WINDOWS:
            return getUserDataPath(name).replace("\\", "\\\\")
        else:
            return getUserDataPath(name)
def getAddonPathWrapper(name):
    # Return the fully qualified add-on path and file name
    if generateVPNs():
        return "/storage/.kodi/addons/service.vpn.manager/" + name
    else:
        if getPlatform() == platforms.WINDOWS:
            return getAddonPath(True, name).replace("\\", "\\\\")
        else:
            return getAddonPath(True, name)
Beispiel #3
0
def getFriendlyProfileName(vpn_provider, ovpn_connection):
    # Make the VPN profile names more readable to the user to select from
    regex_str = getRegexPattern(vpn_provider)
    # Deal with some Windows nonsense
    if getPlatform() == platforms.WINDOWS:
        regex_str = regex_str.replace(r"/", r"\\")
    # Return friendly version of string
    match = re.search(regex_str, ovpn_connection)
    return match.group(1)
def getUserDataPathWrapper(path):
    # This function resets the VPN profiles to the standard VPN Manager install
    # location as per OpenELEC, or to the platform install location
    force_default_install = fakeConnection()
    if force_default_install:
        return "/storage/.kodi/userdata/addon_data/service.vpn.manager/" + path        
    else:
        if getPlatform() == platforms.WINDOWS:
            return getUserDataPath(path).replace("\\", "\\\\")
        else:
            return getUserDataPath(path)
def getUserDataPathWrapper(path):
    # This function resets the VPN profiles to the standard VPN Manager install
    # location as per OpenELEC, or to the platform install location
    force_default_install = fakeConnection()
    if force_default_install:
        return "/storage/.kodi/userdata/addon_data/service.vpn.manager/" + path
    else:
        if getPlatform() == platforms.WINDOWS:
            return getUserDataPath(path).replace("\\", "\\\\")
        else:
            return getUserDataPath(path)
def getUpParam(provider):
    ext = "sh"
    if getPlatform() == platforms.WINDOWS:
        ext = "bat"
    filename = getUserDataPathWrapper(getVPNLocation(provider) + "/up." + ext)
    if xbmcvfs.exists(filename): return "up " + filename
    filename = getAddonPathWrapper(getVPNLocation(provider) + "/up." + ext)
    if xbmcvfs.exists(filename): return "up " + filename
    if xbmcaddon.Addon("service.vpn.manager").getSetting(
            "use_default_up_down") == "true":
        filename = getAddonPathWrapper("up." + ext)
        if xbmcvfs.exists(filename): return "up " + filename
    return ""
Beispiel #7
0
def getFriendlyProfileList(vpn_provider, ovpn_connections):
    # Munge a ovpn full path name is something more friendly
    
    connections = []
    regex_str = getRegexPattern(vpn_provider)
    # Deal with some Windows nonsense
    if getPlatform() == platforms.WINDOWS:
        regex_str = regex_str.replace(r"/", r"\\")
    # Produce a compiled pattern and interate around the list of connections
    pattern = re.compile(regex_str)
    for connection in ovpn_connections:
        connections.append(pattern.search(connection).group(1))        
    return connections
def writeDefaultUpFile():
    p = getPlatform()
    if p == platforms.LINUX or p == platforms.RPI:
        infoTrace("vpnproviders.py", "Writing default up script")
        up = open(getAddonPath(True, "up.sh"), 'w')
        up.write("#!/bin/bash\n")
        up.write("iptables -F\n")
        up.write(
            "iptables -A INPUT -i tun0 -m state --state ESTABLISHED,RELATED -j ACCEPT\n"
        )
        up.write("iptables -A INPUT -i tun0 -j DROP\n")
        up.close()
        command = "chmod +x " + getAddonPath(True, "up.sh")
        if useSudo(): command = "sudo " + command
        infoTrace("vpnproviders.py", "Fixing default up.sh " + command)
        os.system(command)
def getBestPathWrapper(name):
    # This function will return the path to the user version of a given file
    # if it exists, otherwise it'll return the path the default add-on version

    # This is just about resetting the ovpn documents if neccesary
    if generateVPNs():
        return "/storage/.kodi/addons/service.vpn.manager/" + path
    else:
        filename = getUserDataPath(name)
        if not xbmcvfs.exists(filename):
            filename = getAddonPath(True, name)
        else:
            infoTrace("vpnprovider.py", "Using userdata override " + filename)
        if getPlatform() == platforms.WINDOWS:
            return filename.replace("\\", "\\\\")
        else:
            return filename
def getSeparatorOutput():
    if getPlatform() == platforms.WINDOWS:
        # Need to double escape Windows as we output this as another slash gets striped as it gets read back in again
        return "\\\\"
    else:
        return "/"
def getAddonPathWrapper(name):
    # Return the fully qualified add-on path and file name
    if getPlatform() == platforms.WINDOWS:
        return getAddonPath(True, name).replace("\\", "\\\\")
    else:
        return getAddonPath(True, name)
Beispiel #12
0
# Get the arguments passed in
base_url = sys.argv[0]
addon_handle = int(sys.argv[1])
args = sys.argv[2].split("?", )
action = ""
params = ""
# If an argument has been passed in, the first character will be a ?, so the first list element is empty
inc = 0
for token in args:
    if inc == 1 : action = token
    if inc > 1 : params = params + token
    inc = inc + 1  

# Don't seem to need to do this on *nix platforms as the filename will be different
if getPlatform() == platforms.WINDOWS: params = params.replace("/", "\\")

debugTrace("Parsed arguments to action=" + action + " params=" + params)

    
def topLevel():
    # Build the top level menu with URL callbacks to this plugin
    debugTrace("Displaying the top level menu")
    url = base_url + "?settings"
    li = xbmcgui.ListItem("Add-on Settings", iconImage=getIconPath()+"settings.png")
    xbmcplugin.addDirectoryItem(handle=addon_handle, url=url, listitem=li)
    url = base_url + "?display"
    li = xbmcgui.ListItem("Display VPN status", iconImage=getIconPath()+"display.png")
    xbmcplugin.addDirectoryItem(handle=addon_handle, url=url, listitem=li)
    if addon.getSetting("vpn_system_menu_item") == "true":
        url = base_url + "?system"
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:
        template_path = getTemplateFile(vpn_provider)
        debugTrace("Opening template file " + template_path)
        template_file = open(template_path, 'r')
        template = template_file.readlines()
        template_file.close()
    except Exception as e:
        errorTrace("vpnproviders.py",
                   "Couldn't open the template file for " + vpn_provider)
        errorTrace("vpnproviders.py", str(e))
        return False

    # Open a translate file
    try:
        debugTrace("Opening translate file for " + vpn_provider)
        translate_file = open(
            getAddonPath(True, vpn_provider + "/TRANSLATE.txt"), 'w')
        debugTrace("Opened translate file for " + vpn_provider)
    except Exception as e:
        errorTrace("vpnproviders.py",
                   "Couldn't open the translate file for " + vpn_provider)
        errorTrace("vpnproviders.py", str(e))
        return False

    if getPlatform() == platforms.WINDOWS and addon.getSetting(
            "block_outside_dns") == "true":
        template.append("block-outside-dns")

    if addon.getSetting("force_ping") == "true":
        template.append("ping #PINGSPEED")
        template.append("ping-exit #PINGEXIT")
        template.append("ping-timer-rem")

    if addon.getSetting("up_down_script") == "true":
        template.append("script-security 2")
        template.append(getUpParam(vpn_provider))
        template.append(getDownParam(vpn_provider))

    # 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 Exception as e:
        errorTrace(
            "vpnproviders.py", "Couldn't open the locations file for " +
            vpn_provider + "\n" + locations_name)
        errorTrace("vpnproviders.py", str(e))
        translate_file.close()
        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"
            crl_pem = "crl.pem"
            dh_parm = "dh.pem"
            user1 = ""
            user2 = ""
            user_key = getUserDataPathWrapper(vpn_provider + "/" +
                                              getKeyName(vpn_provider, geo))
            user_cert = getUserDataPathWrapper(vpn_provider + "/" +
                                               getCertName(vpn_provider, geo))
            user_pass = getUserDataPathWrapper(
                vpn_provider + "/" + getKeyPassName(vpn_provider, geo))
            remove_flags = ""
            if proto == "udp":
                ping_speed = "5"
                ping_exit = "30"
            else:
                ping_speed = "10"
                ping_exit = "60"

            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 "#USERPASS" in pair[0]: user_pass = pair[1].strip()
                    if "#CRLVERIFY" in pair[0]: crl_pem = pair[1].strip()
                    if "#DH" in pair[0]: dh_parm = pair[1].strip()
                    if "#USER1" in pair[0]: user1 = pair[1].strip()
                    if "#USER2" in pair[0]: user2 = pair[1].strip()
                    if "#PINGSPEED" in pair[0]: ping_speed = pair[1].strip()
                    if "#PINGEXIT" in pair[0]: ping_exit = 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 Exception as e:
            errorTrace(
                "vpnproviders.py", "Location file for " + vpn_provider +
                " invalid on line\n" + location)
            errorTrace("vpnproviders.py", str(e))
            translate_file.close()
            return False

        try:
            ovpn_file = open(
                getAddonPath(True, vpn_provider + "/" + geo + ".ovpn"), 'w')
            translate_location = geo
            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 i == 0: translate_server = server
                        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
                    if i > 1:
                        translate_server = translate_server + " & " + str(
                            i - 1) + " more"
                    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)
                # Pass is always generated by the add-on so will be in the addon directory
                if "#PASS" in output_line:
                    output_line = output_line.replace(
                        "#PASS",
                        getAddonPathWrapper(vpn_provider + "/" + "pass.txt"))
                # These flags are files that can be over ridden in the user data directory
                if "#CERT" in output_line:
                    output_line = output_line.replace(
                        "#CERT",
                        getBestPathWrapper(vpn_provider + "/" + ca_cert))
                if "#TLSKEY" in output_line:
                    output_line = output_line.replace(
                        "#TLSKEY",
                        getBestPathWrapper(vpn_provider + "/" + ta_key))
                if "#CRLVERIFY" in output_line:
                    output_line = output_line.replace(
                        "#CRLVERIFY",
                        getBestPathWrapper(vpn_provider + "/" + crl_pem))
                if "#DH" in output_line:
                    output_line = output_line.replace(
                        "#DH",
                        getBestPathWrapper(vpn_provider + "/" + dh_parm))
                # User files are managed by the add-on so will be in the user directory (set above)
                output_line = output_line.replace("#USERKEY", user_key)
                output_line = output_line.replace("#USERCERT", user_cert)
                output_line = output_line.replace("#USERPASS", user_pass)
                # Path is the add-on path, not the user directory
                if "#PATH" in output_line:
                    output_line = output_line.replace(
                        "#PATH", getAddonPathWrapper(vpn_provider + "/"))
                output_line = output_line.replace("#USER1", user1)
                output_line = output_line.replace("#USER2", user2)
                output_line = output_line.replace("#PINGSPEED", ping_speed)
                output_line = output_line.replace("#PINGEXIT", ping_exit)
                # 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)
            translate_file.write(translate_location + "," + translate_server +
                                 " (" + proto.upper() + ")\n")
        except Exception as e:
            errorTrace(
                "vpnproviders.py", "Can't write a location file for " +
                vpn_provider + " failed on line\n" + location)
            errorTrace("vpnproviders.py", str(e))
            translate_file.close()
            return False

    # Write the location to server translation file
    translate_file.close()

    # Flag that the files have been generated
    writeGeneratedFile(vpn_provider)

    return True
Beispiel #14
0
    reboot_timer = 0
    seconds_to_reboot_check = 0
    reboot_time = ""
    reboot_day = ""
    last_file_check_time = 0
    
    last_cycle = ""
    delay = 5
    connection_errors = 0
    stop = False

    vpn_setup = True
    vpn_provider = ""
    playing = False
    
    infoTrace("service.py", "Starting VPN monitor service, platform is " + str(getPlatform()) + ", version is " + addon.getAddonInfo("version"))
    infoTrace("service.py", "Kodi build is " + xbmc.getInfoLabel('System.BuildVersion'))
    
    while not monitor.abortRequested():

        if stopRequested() or stop:
            if not stop:
				# Acknowledge that we've stopped so that the config can do things
				# Also shorten the delay so that we can be more responsive and kill any cycle attempt
                debugTrace("Service received a stop request")
                ackStop()                
                stop = True
                delay = 2
                clearVPNCycle()
            elif startRequested():
                debugTrace("Service received a start request")
def getAddonPathWrapper(name):
    # Return the fully qualified add-on path and file name
    if getPlatform() == platforms.WINDOWS:
        return getAddonPath(True, name).replace("\\", "\\\\")
    else:
        return getAddonPath(True, name)
Beispiel #16
0
    # Retry time in seconds
    connection_retry_time = 3600
    timer = 0
    cycle_timer = 0
    last_cycle = ""
    delay = 5
    connection_errors = 0
    stop = False

    vpn_setup = True
    vpn_provider = ""
    playing = False

    infoTrace(
        "service.py", "Starting VPN monitor service, platform is " +
        str(getPlatform()) + ", version is " + addon.getAddonInfo("version"))
    infoTrace("service.py",
              "Kodi build is " + xbmc.getInfoLabel('System.BuildVersion'))

    while not monitor.abortRequested():

        if stopRequested() or stop:
            if not stop:
                # Acknowledge that we've stopped so that the config can do things
                # Also shorten the delay so that we can be more responsive and kill any cycle attempt
                debugTrace("Service received a stop request")
                ackStop()
                stop = True
                delay = 2
                clearVPNCycle()
            elif startRequested():
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)

    # Open a translate file
    try:
        debugTrace("Opening translate file for " + vpn_provider)
        translate_file = open(
            getAddonPath(True, vpn_provider + "/TRANSLATE.txt"), 'w')
        debugTrace("Opened translate file for " + vpn_provider)
    except Exception as e:
        errorTrace("vpnproviders.py",
                   "Couldn't open the translate file for " + vpn_provider)
        errorTrace("vpnproviders.py", str(e))
        return False

    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:connection.rfind(".ovpn")]
            translate_location = name
            translate_server = ""
            server_count = 0

            found_up = False
            found_down = False
            found_script_sec = False
            found_block_dns = False
            found_ping = False
            proto = "udp"

            # Update the necessary values in the ovpn file
            for line in lines:

                line = line.strip(' \t\n\r')

                # 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")

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

                # Update user cert and key
                if not isUserDefined(vpn_provider) and usesUserKeys(
                        vpn_provider):
                    if line.startswith("cert "):
                        line = "cert " + getUserDataPathWrapper(
                            vpn_provider + "/" +
                            getCertName(vpn_provider, name))
                    if line.startswith("key "):
                        line = "key " + getUserDataPathWrapper(
                            vpn_provider + "/" +
                            getKeyName(vpn_provider, name))

                # Update key password (if there is one)
                if not isUserDefined(vpn_provider) or usesKeyPass(
                        vpn_provider):
                    if line.startswith("askpass"):
                        line = "askpass " + getUserDataPathWrapper(
                            vpn_provider + "/" + getKeyPass(vpn_provider))

                # 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

                if line.startswith("up "):
                    found_up = True
                if line.startswith("down "):
                    found_down = True
                if line.startswith("script-security "):
                    found_script_sec = True
                if line.startswith("block-outside-dns"):
                    found_block_dns = True

                if line.startswith("ping"):
                    found_ping = True

                f.write(line + "\n")

            if not found_block_dns and getPlatform(
            ) == platforms.WINDOWS and addon.getSetting(
                    "block_outside_dns") == "true":
                f.write("block-outside-dns\n")

            if addon.getSetting("up_down_script") == "true":
                if not found_script_sec: f.write("script-security 2\n")
                if not found_up: f.write(getUpParam(vpn_provider) + "\n")
                if not found_down: f.write(getDownParam(vpn_provider) + "\n")

            if not found_ping and addon.getSetting("force_ping") == "true":
                if proto == "tcp":
                    f.write("ping 10\n")
                    f.write("ping-exit 60\n")
                else:
                    f.write("ping 5\n")
                    f.write("ping-exit 30\n")
                f.write("ping-timer-rem\n")

            f.close()

            if server_count > 1:
                translate_server = translate_server + " & " + str(
                    server_count - 1) + " more"
            translate_file.write(translate_location + "," + translate_server +
                                 " (" + proto.upper() + ")\n")

        except Exception as e:
            errorTrace("vpnproviders.py", "Failed to update ovpn file")
            errorTrace("vpnproviders.py", str(e))
            translate_file.close()
            return False

    # Write the location to server translation file
    translate_file.close()

    # Flag that the files have been generated
    writeGeneratedFile(vpn_provider)

    return True
Beispiel #18
0
# Get the arguments passed in
base_url = sys.argv[0]
addon_handle = int(sys.argv[1])
args = sys.argv[2].split("?", )
action = ""
params = ""
# If an argument has been passed in, the first character will be a ?, so the first list element is empty
inc = 0
for token in args:
    if inc == 1: action = token
    if inc > 1: params = params + token
    inc = inc + 1

# Don't seem to need to do this on *nix platforms as the filename will be different
if getPlatform() == platforms.WINDOWS: params = params.replace("/", "\\")

debugTrace("Parsed arguments to action=" + action + " params=" + params)


def topLevel():
    # Build the top level menu with URL callbacks to this plugin
    debugTrace("Displaying the top level menu")
    url = base_url + "?settings"
    li = xbmcgui.ListItem("Add-on Settings",
                          iconImage=getIconPath() + "settings.png")
    xbmcplugin.addDirectoryItem(handle=addon_handle, url=url, listitem=li)
    url = base_url + "?display"
    li = xbmcgui.ListItem("Display VPN status",
                          iconImage=getIconPath() + "display.png")
    xbmcplugin.addDirectoryItem(handle=addon_handle, url=url, listitem=li)
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:connection.rfind(".ovpn")]

            if getPlatform() == platforms.WINDOWS and addon.getSetting(
                    "block_outside_dns") == "true":
                lines.append("block-outside-dns")

            # 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