コード例 #1
0
            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)
    
        # Select the provider
        provider_list = []
        for provider in providers:
            if usesUserKeys(provider):
                provider_list.append(getVPNDisplay(provider))
        provider_list.sort()
        index = xbmcgui.Dialog().select("Select VPN provider", provider_list)
        provider_display = provider_list[index]
        provider = getVPNLocation(provider_display)
        # Get the key/cert pairs for that provider and offer up for deletion
        user_keys = getUserKeys(provider)
        user_certs = getUserCerts(provider)
        if len(user_keys) > 0 or len(user_certs) > 0:
            still_deleting = True
            while still_deleting:
                if len(user_keys) > 0 or len(user_certs) > 0:
                
                    # Build a list of things to display.  We should always have pairs, but if
                    # something didn't copy or the user has messed with the dir this will cope
コード例 #2
0
        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 disconnect and reset all VPN connections. Connections must be re-validated before use. Continue?"
        ):

            # Disconnect so that live files are not being modified
            if isVPNConnected(): resetVPNConnections(addon)

            # Select the provider
            provider_list = []
            for provider in providers:
                if usesUserKeys(provider):
                    provider_list.append(getVPNDisplay(provider))
            provider_list.sort()
            index = xbmcgui.Dialog().select("Select VPN provider",
                                            provider_list)
            provider_display = provider_list[index]
            provider = getVPNLocation(provider_display)
            # Get the key/cert pairs for that provider and offer up for deletion
            user_keys = getUserKeys(provider)
            user_certs = getUserCerts(provider)
            if len(user_keys) > 0 or len(user_certs) > 0:
                still_deleting = True
                while still_deleting:
                    if len(user_keys) > 0 or len(user_certs) > 0:

                        # Build a list of things to display.  We should always have pairs, but if
コード例 #3
0
ファイル: common.py プロジェクト: Stevie-Bs/repository.xvbmc
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')