from libs.platform import getAddonPath


addon = xbmcaddon.Addon("service.vpn.manager")
addon_name = addon.getAddonInfo("name")

# Get the first argument which will indicate the connection that's being dealt with
connection_order = sys.argv[1]

debugTrace("Entered connect.py with parameter " + connection_order)

# If a new connection is being validated, check everything needed is entered
vpn_provider = addon.getSetting("vpn_provider")
vpn_username = addon.getSetting("vpn_username")
vpn_password = addon.getSetting("vpn_password")
    
if xbmcvfs.exists(getUserDataPath(getVPNLocation(vpn_provider) + "/DEFAULT.txt")):
    vpn_username = "******"
    vpn_password = "******"
    
if not usesPassAuth(vpn_provider) or (not vpn_username == "" and not vpn_provider == ""):
    connectVPN(str(connection_order), "")
else:
    xbmcgui.Dialog().ok(addon_name, "Please enter a user name and password.  " + vpn_provider + " requires them for authentication.")

# Finally return to the settings screen if that's where we came from
if connection_order > 0:
    xbmc.executebuiltin("Addon.OpenSettings(service.vpn.manager)")

debugTrace("Exit connect.py")
Exemple #2
0
addon_name = addon.getAddonInfo("name")

# Get the first argument which will indicate the connection that's being dealt with
connection_order = sys.argv[1]

debugTrace("Entered connect.py with parameter " + connection_order)

# If a new connection is being validated, check everything needed is entered
vpn_provider = addon.getSetting("vpn_provider")
vpn_username = addon.getSetting("vpn_username")
vpn_password = addon.getSetting("vpn_password")

if xbmcvfs.exists(
        getUserDataPath(getVPNLocation(vpn_provider) + "/DEFAULT.txt")):
    vpn_username = "******"
    vpn_password = "******"

if not usesPassAuth(getVPNLocation(vpn_provider)) or (
        not vpn_username == "" and not vpn_provider == ""):
    connectVPN(str(connection_order), "")
else:
    xbmcgui.Dialog().ok(
        addon_name, "Please enter a user name and password.  " + vpn_provider +
        " requires them for authentication.")

# Finally return to the settings screen if that's where we came from
if connection_order > 0:
    xbmc.executebuiltin("Addon.OpenSettings(service.vpn.manager)")

debugTrace("Exit connect.py")
from libs.platform import getAddonPath


addon = xbmcaddon.Addon("service.vpn.manager")
addon_name = addon.getAddonInfo("name")

# Get the first argument which will indicate the connection that's being dealt with
connection_order = sys.argv[1]

debugTrace("Entered connect.py with parameter " + connection_order)

# If a new connection is being validated, check everything needed is entered
vpn_provider = addon.getSetting("vpn_provider")
vpn_username = addon.getSetting("vpn_username")
vpn_password = addon.getSetting("vpn_password")
    
if xbmcvfs.exists(getUserDataPath(getVPNLocation(vpn_provider) + "/DEFAULT.txt")):
    vpn_username = "******"
    vpn_password = "******"
    
if not usesPassAuth(getVPNLocation(vpn_provider)) or (not vpn_username == "" and not vpn_provider == ""):
    connectVPN(str(connection_order), "")
else:
    xbmcgui.Dialog().ok(addon_name, "Please enter a user name and password.  " + vpn_provider + " requires them for authentication.")

# Finally return to the settings screen if that's where we came from
if connection_order > 0:
    xbmc.executebuiltin("Addon.OpenSettings(service.vpn.manager)")

debugTrace("Exit connect.py")
Exemple #4
0
# Get the first argument which will indicate the connection that's being dealt with
connection_order = sys.argv[1]

debugTrace("Entered connect.py with parameter " + connection_order)

# If a new connection is being validated, check everything needed is entered
vpn_provider = addon.getSetting("vpn_provider")
vpn_username = addon.getSetting("vpn_username")
vpn_password = addon.getSetting("vpn_password")

if xbmcvfs.exists(
        getUserDataPath(getVPNLocation(vpn_provider) + "/DEFAULT.txt")):
    vpn_username = "******"
    vpn_password = "******"

if not usesPassAuth(vpn_provider) or (not vpn_username == ""
                                      and not vpn_provider == ""):
    connectVPN(str(connection_order), "")
else:
    xbmcgui.Dialog().ok(
        addon_name, "Please enter a user name and password.  " + vpn_provider +
        " requires them for authentication.")

# Finally return to the settings screen if that's where we came from
if connection_order > 0:
    defCred()
    xbmc.executebuiltin("Addon.OpenSettings(service.purevpn.monitor)")

debugTrace("Exit connect.py")
Exemple #5
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')
Exemple #6
0
				# Refresh primary vpns
                debugTrace("Update primary VPNs from settings")
                refreshPrimaryVPNs()

                # Determine if the VPN has been set up
                if primary_vpns[0] == "":
                    debugTrace("Found no VPNs, setup is invalid")
                    vpn_setup = False
                else:
                    debugTrace("Found " + str(len(primary_vpns)) + " VPNs, setup is valid")
                    vpn_setup = True
                    vpn_provider = addon.getSetting("vpn_provider_validated")
                    # If it's been set up, just check the VPN credentials file exists
                    # It can get deleted sometimes, like when reinstalling the addon
                    if usesPassAuth(getVPNLocation(vpn_provider)) and not xbmcvfs.exists(getCredentialsPath(addon)):
                        writeCredentials(addon)
                
                # Force a reboot timer check
                reboot_timer = 3600
                seconds_to_reboot_check = 0

				# Refresh filter lists
                debugTrace("Update filter lists from settings")
                refreshAddonFilterLists()

				# If the VPN is not deliberately disconnected, then connect it
                if vpn_setup and not getVPNState() == "off":
                    if getVPNState() == "started":
                        debugTrace("VPN is started on " + getVPNProfile() + " requesting " + getVPNRequestedProfile())
						# We're connected, but to the wrong VPN
if not getID() == "":

    addon = xbmcaddon.Addon(getID())
    addon_name = getName()

    # If a new connection is being validated, check everything needed is entered
    vpn_provider = addon.getSetting("vpn_provider")
    vpn_username = addon.getSetting("vpn_username")
    vpn_password = addon.getSetting("vpn_password")
        
    if xbmcvfs.exists(getUserDataPath(getVPNLocation(vpn_provider) + "/DEFAULT.txt")):
        vpn_username = "******"
        vpn_password = "******"
        
    if not usesPassAuth(getVPNLocation(vpn_provider)) or (not vpn_username == "" and not vpn_provider == ""):
        connectVPN(str(connection_order), "")
    else:
        if vpn_provider == "":
            xbmcgui.Dialog().ok(addon_name, "Please select a VPN provider and enter a user name and password.")
        else:
            xbmcgui.Dialog().ok(addon_name, "Please enter a user name and password.  " + vpn_provider + " requires them for authentication.")

    # Finally return to the settings screen if that's where we came from
    if connection_order > 0:
        command = "Addon.OpenSettings(" + getID() + ")"
        xbmc.executebuiltin(command)

else:
    errorTrace("connect.py", "VPN service is not ready")