To avoid security issues, you must approve old UDS Version access.
'
- #
- # if QtGui.QMessageBox.warning(None, 'ACCESS Warning', errorString, QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) == QtGui.QMessageBox.No:
- # raise Exception('Server not approved. Access denied.')
-
- six.exec_(script, globals(), {'parent': self, 'sp': params})
-
- except RetryException as e:
- self.ui.info.setText(six.text_type(e) + ', retrying access...')
- # Retry operation in ten seconds
- QtCore.QTimer.singleShot(10000, self.getTransportData)
-
- except Exception as e:
- #logger.exception('Got exception executing script:')
- self.showError(e)
-
- def endScript(self):
- # After running script, wait for stuff
- try:
- tools.waitForTasks()
- except Exception:
- pass
-
- try:
- tools.unlinkFiles()
- except Exception:
- pass
-
- try:
- tools.execBeforeExit()
- except Exception:
- pass
-
- self.closeWindow()
-
- def start(self):
- '''
- Starts proccess by requesting version info
- '''
- self.ui.info.setText('Initializing...')
- QtCore.QTimer.singleShot(100, self.getVersion)
-
-
-def done(data):
- QtGui.QMessageBox.critical(None, 'Notice', six.text_type(data.data), QtGui.QMessageBox.Ok)
- sys.exit(0)
-
-# Ask user to approve endpoint
-def approveHost(hostName, parentWindow=None):
- settings = QtCore.QSettings()
- settings.beginGroup('endpoints')
-
- approved = settings.value(hostName, False).toBool()
-
- errorString = 'Only approve UDS servers that you trust to avoid security issues.
'
-
- if approved or QtGui.QMessageBox.warning(parentWindow, 'ACCESS Warning', errorString, QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) == QtGui.QMessageBox.Yes:
- settings.setValue(hostName, True)
- approved = True
-
- settings.endGroup()
- return approved
-
-if __name__ == "__main__":
- logger.debug('Initializing connector')
- # Initialize app
- app = QtGui.QApplication(sys.argv)
-
- # Set several info for settings
- QtCore.QCoreApplication.setOrganizationName('Virtual Cable S.L.U.')
- QtCore.QCoreApplication.setApplicationName('UDS Connector')
-
- if 'darwin' not in sys.platform:
- logger.debug('Mac OS *NOT* Detected')
- app.setStyle('plastique')
-
- if six.PY3 is False:
- logger.debug('Fixing threaded execution of commands')
- import threading
- threading._DummyThread._Thread__stop = lambda x: 42 # type: ignore pylint: disable=protected-access
-
- # First parameter must be url
- try:
- uri = sys.argv[1]
-
- if uri == '--test':
- sys.exit(0)
-
- logger.debug('URI: %s', uri)
- if uri[:6] != 'uds://' and uri[:7] != 'udss://':
- raise Exception()
-
- ssl = uri[3] == 's'
- host, UDSClient.ticket, UDSClient.scrambler = uri.split('//')[1].split('/') # type: ignore
- logger.debug('ssl:%s, host:%s, ticket:%s, scrambler:%s', ssl, host, UDSClient.ticket, UDSClient.scrambler)
- except Exception:
- logger.debug('Detected execution without valid URI, exiting')
- QtGui.QMessageBox.critical(None, 'Notice', 'UDS Client Version {}'.format(VERSION), QtGui.QMessageBox.Ok)
- sys.exit(1)
-
- # Setup REST api endpoint
- RestRequest.restApiUrl = '{}://{}/rest/client'.format(['http', 'https'][ssl], host)
- logger.debug('Setting request URL to %s', RestRequest.restApiUrl)
- # RestRequest.restApiUrl = 'https://172.27.0.1/rest/client'
-
- try:
- logger.debug('Starting execution')
-
- # Approbe before going on
- if approveHost(host) is False:
- raise Exception('Host {} was not approved'.format(host))
-
- win = UDSClient()
- win.show()
-
- win.start()
-
- exitVal = app.exec_()
- logger.debug('Execution finished correctly')
-
- except Exception as e:
- logger.exception('Got an exception executing client:')
- exitVal = 128
- QtGui.QMessageBox.critical(None, 'Error', six.text_type(e), QtGui.QMessageBox.Ok)
-
- logger.debug('Exiting')
- sys.exit(exitVal)
diff --git a/client/full/src/UDSResources.qrc b/client/full/src/UDSResources.qrc
deleted file mode 100644
index 175cfa76..00000000
--- a/client/full/src/UDSResources.qrc
+++ /dev/null
@@ -1,6 +0,0 @@
-
-# https://github.com/paramiko/paramiko/blob/master/demos/forward.py
-
-from __future__ import unicode_literals
-
-from binascii import hexlify
-import threading
-import random
-import time
-import select
-
-import paramiko
-import six
-
-from .log import logger
-
-if six.PY2:
- import SocketServer as socketserver # pylint: disable=import-error
-else:
- import socketserver
-
-class CheckfingerPrints(paramiko.MissingHostKeyPolicy):
- def __init__(self, fingerPrints):
- super(CheckfingerPrints, self).__init__()
- self.fingerPrints = fingerPrints
-
- def missing_host_key(self, client, hostname, key):
- if self.fingerPrints:
- remotefingerPrints = hexlify(key.get_fingerprint()).decode().lower()
- logger.debug('Checking keys {} against {}'.format(remotefingerPrints, self.fingerPrints))
- if remotefingerPrints not in self.fingerPrints.split(','):
- logger.error("Server {!r} has invalid fingerPrints. ({} vs {})".format(hostname, remotefingerPrints, self.fingerPrints))
- raise paramiko.SSHException(
- "Server {!r} has invalid fingerPrints".format(hostname)
- )
-
-
-class ForwardServer(socketserver.ThreadingTCPServer):
- daemon_threads = True
- allow_reuse_address = True
-
-
-class Handler(socketserver.BaseRequestHandler):
-
- def handle(self):
- self.thread.currentConnections += 1
-
- try:
- chan = self.ssh_transport.open_channel('direct-tcpip',
- (self.chain_host, self.chain_port),
- self.request.getpeername())
- except Exception as e:
- logger.exception('Incoming request to %s:%d failed: %s', self.chain_host, self.chain_port, repr(e))
- return
- if chan is None:
- logger.error('Incoming request to %s:%d was rejected by the SSH server.', self.chain_host, self.chain_port)
- return
-
- logger.debug('Connected! Tunnel open %r -> %r -> %r', self.request.getpeername(), chan.getpeername(), (self.chain_host, self.chain_port))
- try:
- while self.event.is_set() is False:
- r, _w, _x = select.select([self.request, chan], [], [], 1) # pylint: disable=unused-variable
-
- if self.request in r:
- data = self.request.recv(1024)
- if not data:
- break
- chan.send(data)
- if chan in r:
- data = chan.recv(1024)
- if not data:
- break
- self.request.send(data)
- except Exception:
- pass
-
- try:
- peername = self.request.getpeername()
- chan.close()
- self.request.close()
- logger.debug('Tunnel closed from %r', peername,)
- except Exception:
- pass
-
- self.thread.currentConnections -= 1
-
- if self.thread.stoppable is True and self.thread.currentConnections == 0:
- self.thread.stop()
-
-
-class ForwardThread(threading.Thread):
- status = 0 # Connecting
-
- def __init__(self, server, port, username, password, localPort, redirectHost, redirectPort, waitTime, fingerPrints):
- threading.Thread.__init__(self)
- self.client = None
- self.fs = None
-
- self.server = server
- self.port = int(port)
- self.username = username
- self.password = password
-
- self.localPort = int(localPort)
- self.redirectHost = redirectHost
- self.redirectPort = redirectPort
-
- self.waitTime = waitTime
-
- self.fingerPrints = fingerPrints
-
- self.stopEvent = threading.Event()
-
- self.timer = None
- self.currentConnections = 0
- self.stoppable = False
- self.client = None
-
- def clone(self, redirectHost, redirectPort, localPort=None):
- if localPort is None:
- localPort = random.randrange(33000, 52000)
-
- ft = ForwardThread(self.server, self.port, self.username, self.password, localPort, redirectHost, redirectPort, self.waitTime, self.fingerPrints)
- ft.client = self.client
- self.client.useCount += 1 # One more using this client
- ft.start()
-
- while ft.status == 0:
- time.sleep(0.1)
-
- return (ft, localPort)
-
-
- def _timerFnc(self):
- self.timer = None
- logger.debug('Timer fnc: %s', self.currentConnections)
- self.stoppable = True
- if self.currentConnections <= 0:
- self.stop()
-
- def run(self):
- if self.client is None:
- try:
- self.client = paramiko.SSHClient()
- self.client.useCount = 1 # Custom added variable, to keep track on when to close tunnel
- # self.client.load_system_host_keys()
- self.client.set_missing_host_key_policy(CheckfingerPrints(self.fingerPrints))
-
- logger.debug('Connecting to ssh host %s:%d ...', self.server, self.port)
-
- self.client.connect(self.server, self.port, username=self.username, password=self.password, timeout=5)
- except Exception:
- logger.exception('Exception connecting: ')
- self.status = 2 # Error
- return
-
- class SubHandler(Handler):
- chain_host = self.redirectHost
- chain_port = self.redirectPort
- ssh_transport = self.client.get_transport()
- event = self.stopEvent
- thread = self
-
- logger.debug('Wait Time: %s', self.waitTime)
- self.timer = threading.Timer(self.waitTime, self._timerFnc)
- self.timer.start()
-
- self.status = 1 # Ok, listening
-
- self.fs = ForwardServer(('', self.localPort), SubHandler)
- self.fs.serve_forever()
-
- def stop(self):
- try:
- if self.timer:
- self.timer.cancel()
-
- self.stopEvent.set()
- self.fs.shutdown()
-
- if self.client is not None:
- self.client.useCount -= 1
- if self.client.useCount == 0:
- self.client.close()
- self.client = None # Clean up
- except Exception:
- logger.exception('Exception stopping')
-
-
-def forward(server, port, username, password, redirectHost, redirectPort, localPort=None, waitTime=10, fingerPrints=None):
- '''
- Instantiates an ssh connection to server:port
- Returns the Thread created and the local redirected port as a list: (thread, port)
- '''
- port, redirectPort = int(port), int(redirectPort)
-
- if localPort is None:
- localPort = random.randrange(33000, 52000)
-
- logger.debug('Connecting to %s:%s using %s/%s redirecting to %s:%s, listening on 127.0.0.1:%s',
- server, port, username, password, redirectHost, redirectPort, localPort)
-
- ft = ForwardThread(server, port, username, password, localPort, redirectHost, redirectPort, waitTime, fingerPrints)
-
- ft.start()
-
- while ft.status == 0:
- time.sleep(0.1)
-
- return (ft, localPort)
diff --git a/client/full/src/uds/log.py b/client/full/src/uds/log.py
deleted file mode 100644
index 4c4446c4..00000000
--- a/client/full/src/uds/log.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2014 Virtual Cable S.L.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-#
-# * Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-# * Neither the name of Virtual Cable S.L. nor the names of its contributors
-# may be used to endorse or promote products derived from this software
-# without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-'''
-@author: Adolfo Gómez, dkmaster at dkmon dot com
-'''
-from __future__ import unicode_literals
-
-import logging
-import os
-import sys
-import tempfile
-
-if sys.platform.startswith('linux'):
- from os.path import expanduser # pylint: disable=ungrouped-imports
- logFile = expanduser('~/udsclient.log')
-else:
- logFile = os.path.join(tempfile.gettempdir(), b'udsclient.log')
-
-try:
- logging.basicConfig(
- filename=logFile,
- filemode='a',
- format='%(levelname)s %(asctime)s %(message)s',
- level=logging.INFO
- )
-except Exception:
- logging.basicConfig(format='%(levelname)s %(asctime)s %(message)s', level=logging.INFO)
-
-logger = logging.getLogger('udsclient')
diff --git a/client/full/src/uds/osDetector.py b/client/full/src/uds/osDetector.py
deleted file mode 100644
index aa29d390..00000000
--- a/client/full/src/uds/osDetector.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# -*- coding: utf-8 -*-
-
-#
-# Copyright (c) 2017 Virtual Cable S.L.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-#
-# * Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-# * Neither the name of Virtual Cable S.L. nor the names of its contributors
-# may be used to endorse or promote products derived from this software
-# without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-'''
-@author: Adolfo Gómez, dkmaster at dkmon dot com
-'''
-from __future__ import unicode_literals
-
-import sys
-
-LINUX = 'Linux'
-WINDOWS = 'Windows'
-MAC_OS_X = 'Mac os x'
-
-def getOs():
- if sys.platform.startswith('linux'):
- return LINUX
- if sys.platform.startswith('win'):
- return WINDOWS
- if sys.platform.startswith('darwin'):
- return MAC_OS_X
- return 'other'
diff --git a/client/full/src/uds/rest.py b/client/full/src/uds/rest.py
deleted file mode 100644
index 3789a984..00000000
--- a/client/full/src/uds/rest.py
+++ /dev/null
@@ -1,123 +0,0 @@
-# -*- coding: utf-8 -*-
-
-#
-# Copyright (c) 2017 Virtual Cable S.L.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-#
-# * Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-# * Neither the name of Virtual Cable S.L. nor the names of its contributors
-# may be used to endorse or promote products derived from this software
-# without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-'''
-@author: Adolfo Gómez, dkmaster at dkmon dot com
-'''
-# pylint: disable=c-extension-no-member,no-name-in-module
-from __future__ import unicode_literals
-
-import json
-import urllib
-
-import six
-
-from PyQt4.QtCore import pyqtSignal, pyqtSlot
-from PyQt4.QtCore import QObject, QUrl, QSettings
-from PyQt4.QtCore import Qt
-from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply, QSslCertificate
-from PyQt4.QtGui import QMessageBox
-
-from . import osDetector
-
-from . import VERSION
-
-
-
-class RestRequest(QObject):
-
- restApiUrl = '' #
-
- done = pyqtSignal(dict, name='done')
-
- def __init__(self, url, parentWindow, done, params=None): # parent not used
- super(RestRequest, self).__init__()
- # private
- self._manager = QNetworkAccessManager()
- if params is not None:
- url += '?' + '&'.join('{}={}'.format(k, urllib.quote(six.text_type(v).encode('utf8'))) for k, v in params.iteritems())
-
- self.url = QUrl(RestRequest.restApiUrl + url)
-
- # connect asynchronous result, when a request finishes
- self._manager.finished.connect(self._finished)
- self._manager.sslErrors.connect(self._sslError)
- self._parentWindow = parentWindow
-
- self.done.connect(done, Qt.QueuedConnection)
-
- # private slot, no need to declare as slot
- @pyqtSlot(QNetworkReply)
- def _finished(self, reply):
- '''
- Handle signal 'finished'. A network request has finished.
- '''
- try:
- if reply.error() != QNetworkReply.NoError:
- raise Exception(reply.errorString())
- data = six.text_type(reply.readAll())
- data = json.loads(data)
- except Exception as e:
- data = {
- 'result': None,
- 'error': six.text_type(e)
- }
-
- self.done.emit(data)
-
- reply.deleteLater() # schedule for delete from main event loop
-
- @pyqtSlot(QNetworkReply, list)
- def _sslError(self, reply, errors):
- # reply.ignoreSslErrors()
-
- settings = QSettings()
- settings.beginGroup('ssl')
- cert = errors[0].certificate()
- digest = six.text_type(cert.digest().toHex())
-
- approved = settings.value(digest, False).toBool()
-
- errorString = 'Please, accept the certificate for {}
'.format(cert.subjectInfo(QSslCertificate.CommonName))
-
- # for err in errors:
- # errorString += '' + err.errorString() + ''
-
- # errorString += ''
-
- if approved or QMessageBox.warning(self._parentWindow, 'SSL Warning', errorString, QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes:
- settings.setValue(digest, True)
- reply.ignoreSslErrors()
-
- settings.endGroup()
-
- def get(self):
- request = QNetworkRequest(self.url)
- request.setRawHeader('User-Agent', osDetector.getOs() + " - UDS Connector " + VERSION)
- self._manager.get(request)
diff --git a/client/full/src/uds/tools.py b/client/full/src/uds/tools.py
deleted file mode 100644
index 5c4b93dd..00000000
--- a/client/full/src/uds/tools.py
+++ /dev/null
@@ -1,205 +0,0 @@
-# -*- coding: utf-8 -*-
-
-#
-# Copyright (c) 2015 Virtual Cable S.L.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-#
-# * Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-# * Neither the name of Virtual Cable S.L. nor the names of its contributors
-# may be used to endorse or promote products derived from this software
-# without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-'''
-@author: Adolfo Gómez, dkmaster at dkmon dot com
-'''
-from __future__ import unicode_literals
-
-from base64 import b64decode
-
-import tempfile
-import string
-import random
-import os
-import socket
-import stat
-import sys
-import time
-
-import six
-
-from .log import logger
-
-_unlinkFiles = []
-_tasksToWait = []
-_execBeforeExit = []
-
-sys_fs_enc = sys.getfilesystemencoding() or 'mbcs'
-
-# Public key for scripts
-PUBLIC_KEY = '''-----BEGIN PUBLIC KEY-----
-MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuNURlGjBpqbglkTTg2lh
-dU5qPbg9Q+RofoDDucGfrbY0pjB9ULgWXUetUWDZhFG241tNeKw+aYFTEorK5P+g
-ud7h9KfyJ6huhzln9eyDu3k+kjKUIB1PLtA3lZLZnBx7nmrHRody1u5lRaLVplsb
-FmcnptwYD+3jtJ2eK9ih935DYAkYS4vJFi2FO+npUQdYBZHPG/KwXLjP4oGOuZp0
-pCTLiCXWGjqh2GWsTECby2upGS/ZNZ1r4Ymp4V2A6DZnN0C0xenHIY34FWYahbXF
-ZGdr4DFBPdYde5Rb5aVKJQc/pWK0CV7LK6Krx0/PFc7OGg7ItdEuC7GSfPNV/ANt
-5BEQNF5w2nUUsyN8ziOrNih+z6fWQujAAUZfpCCeV9ekbwXGhbRtdNkbAryE5vH6
-eCE0iZ+cFsk72VScwLRiOhGNelMQ7mIMotNck3a0P15eaGJVE2JV0M/ag/Cnk0Lp
-wI1uJQRAVqz9ZAwvF2SxM45vnrBn6TqqxbKnHCeiwstLDYG4fIhBwFxP3iMH9EqV
-2+QXqdJW/wLenFjmXfxrjTRr+z9aYMIdtIkSpADIlbaJyTtuQpEdWnrlDS2b1IGd
-Okbm65EebVzOxfje+8dRq9Uqwip8f/qmzFsIIsx3wPSvkKawFwb0G5h2HX5oJrk0
-nVgtClKcDDlSaBsO875WDR0CAwEAAQ==
------END PUBLIC KEY-----'''
-
-
-def saveTempFile(content, filename=None):
- if filename is None:
- filename = ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(16))
- filename = filename + '.uds'
-
- if 'win32' in sys.platform:
- logger.info('Fixing for win32')
- filename = filename.encode(sys_fs_enc)
-
- filename = os.path.join(tempfile.gettempdir(), filename)
-
- with open(filename, 'w') as f:
- f.write(content)
-
- logger.info('Returning filename')
- return filename
-
-
-def readTempFile(filename):
- if 'win32' in sys.platform:
- filename = filename.encode('utf-8')
-
- filename = os.path.join(tempfile.gettempdir(), filename)
- try:
- with open(filename, 'r') as f:
- return f.read()
- except Exception:
- return None
-
-
-def testServer(host, port, timeOut=4):
- try:
- sock = socket.create_connection((host, int(port)), timeOut)
- sock.close()
- except Exception:
- return False
- return True
-
-
-def findApp(appName, extraPath=None):
- if 'win32' in sys.platform and isinstance(appName, six.text_type):
- appName = appName.encode(sys_fs_enc)
- searchPath = os.environ['PATH'].split(os.pathsep)
- if extraPath is not None:
- searchPath += list(extraPath)
-
- for path in searchPath:
- fileName = os.path.join(path, appName)
- if os.path.isfile(fileName) and (os.stat(fileName).st_mode & stat.S_IXUSR) != 0:
- return fileName
- return None
-
-
-def getHostName():
- '''
- Returns current host name
- In fact, it's a wrapper for socket.gethostname()
- '''
- hostname = socket.gethostname()
- if 'win32' in sys.platform:
- hostname = hostname.decode(sys_fs_enc)
-
- hostname = six.text_type(hostname)
- logger.info('Hostname: %s', hostname)
- return hostname
-
-# Queing operations (to be executed before exit)
-
-
-def addFileToUnlink(filename):
- '''
- Adds a file to the wait-and-unlink list
- '''
- _unlinkFiles.append(filename)
-
-
-def unlinkFiles():
- '''
- Removes all wait-and-unlink files
- '''
- if _unlinkFiles:
- time.sleep(5) # Wait 5 seconds before deleting anything
-
- for f in _unlinkFiles:
- try:
- os.unlink(f)
- except Exception:
- pass
-
-
-def addTaskToWait(taks):
- _tasksToWait.append(taks)
-
-
-def waitForTasks():
- for t in _tasksToWait:
- try:
- if hasattr(t, 'join'):
- t.join()
- elif hasattr(t, 'wait'):
- t.wait()
- except Exception:
- pass
-
-
-def addExecBeforeExit(fnc):
- _execBeforeExit.append(fnc)
-
-
-def execBeforeExit():
- for fnc in _execBeforeExit:
- fnc.__call__()
-
-
-def verifySignature(script, signature):
- '''
- Verifies with a public key from whom the data came that it was indeed
- signed by their private key
- param: public_key_loc Path to public key
- param: signature String signature to be verified
- return: Boolean. True if the signature is valid; False otherwise.
- '''
- # For signature checking
- from Crypto.PublicKey import RSA
- from Crypto.Signature import PKCS1_v1_5
- from Crypto.Hash import SHA256
-
- rsakey = RSA.importKey(PUBLIC_KEY)
- signer = PKCS1_v1_5.new(rsakey)
- digest = SHA256.new(script) # Script is "binary string" here
- if signer.verify(digest, b64decode(signature)):
- return True
- return False
diff --git a/client/full/src/uds/tunnel.py b/client/full/src/uds/tunnel.py
deleted file mode 100644
index 55102c24..00000000
--- a/client/full/src/uds/tunnel.py
+++ /dev/null
@@ -1,249 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2021 Virtual Cable S.L.U.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-#
-# * Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-# * Neither the name of Virtual Cable S.L.U. nor the names of its contributors
-# may be used to endorse or promote products derived from this software
-# without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-'''
-@author: Adolfo Gómez, dkmaster at dkmon dot com
-'''
-from __future__ import unicode_literals
-
-import socket
-import ssl
-import threading
-import time
-import random
-import select
-import logging
-
-import six
-
-if six.PY2:
- import SocketServer as socketserver # pylint: disable=import-error
-else:
- import socketserver # pylint: disable=import-error
-
-HANDSHAKE_V1 = b'\x5AMGB\xA5\x01\x00'
-BUFFER_SIZE = 1024 * 16 # Max buffer length
-DEBUG = True
-LISTEN_ADDRESS = '0.0.0.0' if DEBUG else '127.0.0.1'
-
-# ForwarServer states
-TUNNEL_LISTENING, TUNNEL_OPENING, TUNNEL_PROCESSING, TUNNEL_ERROR = 0, 1, 2, 3
-
-logger = logging.getLogger(__name__)
-
-
-class ForwardServer(socketserver.ThreadingTCPServer):
- daemon_threads = True
- allow_reuse_address = True
-
- def __init__(
- self,
- remote,
- ticket,
- timeout,
- local_port,
- check_certificate,
- ):
-
- local_port = local_port or random.randrange(33000, 53000)
-
- socketserver.ThreadingTCPServer.__init__(
- self,
- server_address=(LISTEN_ADDRESS, local_port),
- RequestHandlerClass=Handler
- )
- self.remote = remote
- self.ticket = ticket
- # Negative values for timeout, means "accept always connections"
- # "but if no connection is stablished on timeout (positive)"
- # "stop the listener"
- self.timeout = int(time.time()) + timeout if timeout > 0 else 0
- self.check_certificate = check_certificate
- self.stop_flag = threading.Event() # False initial
- self.current_connections = 0
-
- self.status = TUNNEL_LISTENING
- self.can_stop = False
-
- timeout = abs(timeout) or 60
- self.timer = threading.Timer(
- abs(timeout), ForwardServer.__checkStarted, args=(self,)
- )
- self.timer.start()
-
- def stop(self):
- if not self.stop_flag.is_set():
- logger.debug('Stopping servers')
- self.stop_flag.set()
- if self.timer:
- self.timer.cancel()
- self.timer = None
- self.shutdown()
-
- def connect(self):
- with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as rsocket:
- logger.info('CONNECT to %s', self.remote)
-
- rsocket.connect(self.remote)
-
- context = ssl.create_default_context()
-
- # Do not "recompress" data, use only "base protocol" compression
- context.options |= ssl.OP_NO_COMPRESSION
-
- # If ignore remote certificate
- if self.check_certificate is False:
- context.check_hostname = False
- context.verify_mode = ssl.CERT_NONE
- logger.warning('Certificate checking is disabled!')
-
- return context.wrap_socket(rsocket, server_hostname=self.remote[0])
-
- def check(self):
- if self.status == TUNNEL_ERROR:
- return False
-
- try:
- with self.connect() as ssl_socket:
- ssl_socket.sendall(HANDSHAKE_V1 + b'TEST')
- resp = ssl_socket.recv(2)
- if resp != b'OK':
- raise Exception({'Invalid tunnelresponse: {resp}'})
- return True
- except Exception as e:
- logger.error(
- 'Error connecting to tunnel server %s: %s', self.server_address, e
- )
- return False
-
- @property
- def stoppable(self):
- logger.debug('Is stoppable: %s', self.can_stop)
- return self.can_stop or (self.timeout != 0 and int(time.time()) > self.timeout)
-
- @staticmethod
- def __checkStarted(fs):
- logger.debug('New connection limit reached')
- fs.timer = None
- fs.can_stop = True
- if fs.current_connections <= 0:
- fs.stop()
-
-
-class Handler(socketserver.BaseRequestHandler):
- # server: ForwardServer
- def handle(self):
- self.server.status = TUNNEL_OPENING
-
- # If server processing is over time
- if self.server.stoppable:
- self.server.status = TUNNEL_ERROR
- logger.info('Rejected timedout connection')
- self.request.close() # End connection without processing it
- return
-
- self.server.current_connections += 1
-
- # Open remote connection
- try:
- logger.debug('Ticket %s', self.server.ticket)
- with self.server.connect() as ssl_socket:
- # Send handhshake + command + ticket
- ssl_socket.sendall(HANDSHAKE_V1 + b'OPEN' + self.server.ticket.encode())
- # Check response is OK
- data = ssl_socket.recv(2)
- if data != b'OK':
- data += ssl_socket.recv(128)
- raise Exception(
- 'Error received: {}'.format(data.decode(errors="ignore"))
- ) # Notify error
-
- # All is fine, now we can tunnel data
- self.process(remote=ssl_socket)
- except Exception as e:
- logger.error('Error connecting to %s', self.server.remote)
- self.server.status = TUNNEL_ERROR
- self.server.stop()
- finally:
- self.server.current_connections -= 1
-
- if self.server.current_connections <= 0 and self.server.stoppable:
- self.server.stop()
-
- # Processes data forwarding
- def process(self, remote):
- self.server.status = TUNNEL_PROCESSING
- logger.debug('Processing tunnel with ticket %s', self.server.ticket)
- # Process data until stop requested or connection closed
- try:
- while not self.server.stop_flag.is_set():
- r, _w, _x = select.select([self.request, remote], [], [], 1.0)
- if self.request in r:
- data = self.request.recv(BUFFER_SIZE)
- if not data:
- break
- remote.sendall(data)
- if remote in r:
- data = remote.recv(BUFFER_SIZE)
- if not data:
- break
- self.request.sendall(data)
- logger.debug('Finished tunnel with ticekt %s', self.server.ticket)
- except Exception as e:
- pass
-
-
-def _run(server):
- logger.debug(
- 'Starting forwarder: %s -> %s, timeout: %d',
- server.server_address,
- server.remote,
- server.timeout,
- )
- server.serve_forever()
- logger.debug('Stoped forwarder %s -> %s', server.server_address, server.remote)
-
-
-def forward(
- remote,
- ticket,
- timeout=0,
- local_port=0,
- check_certificate=True,
- ):
-
- fs = ForwardServer(
- remote=remote,
- ticket=ticket,
- timeout=timeout,
- local_port=local_port,
- check_certificate=check_certificate,
- )
- # Starts a new thread
- threading.Thread(target=_run, args=(fs,)).start()
-
- return fs
diff --git a/client/full/src/update.sh b/client/full/src/update.sh
deleted file mode 100755
index 1429c873..00000000
--- a/client/full/src/update.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-
-
-function process {
- for a in *.ui; do
- pyuic4 $a -o `basename $a .ui`.py -x
- done
-}
-
-pyrcc4 -py3 UDSResources.qrc -o UDSResources_rc.py
-
-
-# process current directory ui's
-process
-
diff --git a/client/thin/.project b/client/thin/.project
deleted file mode 100644
index 42e0d976..00000000
--- a/client/thin/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
- UDSClient-Thin
-
-
-
-
-
- org.python.pydev.PyDevBuilder
-
-
-
-
-
- org.python.pydev.pythonNature
-
-
diff --git a/client/thin/.pydevproject b/client/thin/.pydevproject
deleted file mode 100644
index fd93aec4..00000000
--- a/client/thin/.pydevproject
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
- /${PROJECT_DIR_NAME}/src
-
-
-
- python 2.7
-
- system-2.7
-
-
diff --git a/client/thin/src/UDSClient.py b/client/thin/src/UDSClient.py
deleted file mode 100644
index 0966a826..00000000
--- a/client/thin/src/UDSClient.py
+++ /dev/null
@@ -1,174 +0,0 @@
-# -*- coding: utf-8 -*-
-
-#
-# Copyright (c) 2017 Virtual Cable S.L.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-#
-# * Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-# * Neither the name of Virtual Cable S.L. nor the names of its contributors
-# may be used to endorse or promote products derived from this software
-# without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-'''
-@author: Adolfo Gómez, dkmaster at dkmon dot com
-'''
-from __future__ import unicode_literals
-import sys
-import json
-
-import six
-
-from uds import ui
-from uds.rest import RestRequest, RetryException
-from uds.forward import forward # pylint: disable=unused-import
-from uds import VERSION
-from uds.log import logger # @UnresolvedImport
-from uds import tools
-
-
-# Server before this version uses "unsigned" scripts
-OLD_METHOD_VERSION = '2.4.0'
-
-def approveHost(hostName):
- from os.path import expanduser
- hostsFile = expanduser('~/.udsclient.hosts')
-
- try:
- with open(hostsFile, 'r') as f:
- approvedHosts = f.read().splitlines()
- except Exception:
- approvedHosts = []
-
- hostName = hostName.lower()
-
- if hostName in approvedHosts:
- return True
-
- errorString = 'The server {} must be approved:\n'.format(hostName)
- errorString += 'Only approve UDS servers that you trust to avoid security issues.'
-
- approved = ui.question("ACCESS Warning", errorString)
-
- if approved:
- approvedHosts.append(hostName)
- logger.debug('Host was approved, saving to approvedHosts file')
- try:
- with open(hostsFile, 'w') as f:
- f.write('\n'.join(approvedHosts))
- except Exception:
- logger.warning('Got exception writing to %s', hostsFile)
-
- return approved
-
-
-def getWithRetry(api, url, parameters=None):
- while True:
- try:
- return api.get(url, parameters)
- except RetryException as e:
- if ui.question('Service not available', 'Error {}.\nPlease, wait a minute and press "OK" to retry, or "CANCEL" to abort'.format(e)) is True:
- continue
- raise Exception('Cancelled by user')
-
-
-if __name__ == "__main__":
- logger.debug('Initializing connector')
-
- if six.PY3 is False:
- logger.debug('Fixing threaded execution of commands')
- import threading
- threading._DummyThread._Thread__stop = lambda x: 42 # type: ignore, pylint:disable=protected-access
-
- # First parameter must be url
- try:
- uri = sys.argv[1]
-
- if uri == '--test':
- sys.exit(0)
-
- logger.debug('URI: %s', uri)
- if uri[:6] != 'uds://' and uri[:7] != 'udss://':
- raise Exception()
-
- ssl = uri[3] == 's'
- host, ticket, scrambler = uri.split('//')[1].split('/')
- logger.debug('ssl: %s, host:%s, ticket:%s, scrambler:%s', ssl, host, ticket, scrambler)
-
- except Exception:
- logger.debug('Detected execution without valid URI, exiting')
- ui.message('UDS Client', 'UDS Client Version {}'.format(VERSION))
- sys.exit(1)
-
- rest = RestRequest(host, ssl)
- logger.debug('Setting request URL to %s', rest.restApiUrl)
-
- # Main requests part
- # First, get version
- try:
- res = getWithRetry(rest, '')
-
- logger.debug('Got information %s', res)
- requiredVersion = res['requiredVersion']
-
- if requiredVersion > VERSION:
- ui.message("New UDS Client available", "A new uds version is needed in order to access this version of UDS.\nPlease, download and install it")
- sys.exit(1)
-
- res = getWithRetry(rest, '/{}/{}'.format(ticket, scrambler), parameters={'hostname': tools.getHostName(), 'version': VERSION})
-
- params = None
-
- if requiredVersion <= OLD_METHOD_VERSION:
- script = res.decode('base64').decode('bz2')
- else:
- # We have three elements on result:
- # * Script
- # * Signature
- # * Script data
- # We test that the Script has correct signature, and them execute it with the parameters
- script, signature, params = res['script'].decode('base64').decode('bz2'), res['signature'], json.loads(res['params'].decode('base64').decode('bz2'))
- if tools.verifySignature(script, signature) is False:
- logger.error('Signature is invalid')
-
- raise Exception('Invalid UDS code signature. Please, report to administrator')
-
- logger.debug('Script: %s', script)
- six.exec_(script, globals(), {'parent': None, 'sp': params})
- except Exception as e:
- error = 'ERROR: {}'.format(e)
- logger.error(error)
- ui.message('Error', error)
- sys.exit(2)
-
- # Finalize
- try:
- tools.waitForTasks()
- except Exception:
- pass
-
- try:
- tools.unlinkFiles()
- except Exception:
- pass
-
- try:
- tools.execBeforeExit()
- except Exception:
- pass
diff --git a/client/thin/src/uds/__init__.py b/client/thin/src/uds/__init__.py
deleted file mode 120000
index 6337f314..00000000
--- a/client/thin/src/uds/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-../../../full/src/uds/__init__.py
\ No newline at end of file
diff --git a/client/thin/src/uds/forward.py b/client/thin/src/uds/forward.py
deleted file mode 120000
index 8c8edf3c..00000000
--- a/client/thin/src/uds/forward.py
+++ /dev/null
@@ -1 +0,0 @@
-../../../full/src/uds/forward.py
\ No newline at end of file
diff --git a/client/thin/src/uds/log.py b/client/thin/src/uds/log.py
deleted file mode 120000
index 88d1c914..00000000
--- a/client/thin/src/uds/log.py
+++ /dev/null
@@ -1 +0,0 @@
-../../../full/src/uds/log.py
\ No newline at end of file
diff --git a/client/thin/src/uds/osDetector.py b/client/thin/src/uds/osDetector.py
deleted file mode 120000
index de893d19..00000000
--- a/client/thin/src/uds/osDetector.py
+++ /dev/null
@@ -1 +0,0 @@
-../../../full/src/uds/osDetector.py
\ No newline at end of file
diff --git a/client/thin/src/uds/rest.py b/client/thin/src/uds/rest.py
deleted file mode 100644
index 944715d3..00000000
--- a/client/thin/src/uds/rest.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# -*- coding: utf-8 -*-
-
-#
-# Copyright (c) 2015 Virtual Cable S.L.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-#
-# * Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-# * Neither the name of Virtual Cable S.L. nor the names of its contributors
-# may be used to endorse or promote products derived from this software
-# without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-'''
-@author: Adolfo Gómez, dkmaster at dkmon dot com
-'''
-from __future__ import unicode_literals
-
-import requests
-from . import VERSION
-
-import json
-import six
-import osDetector
-
-from .log import logger
-
-
-class RetryException(Exception):
- pass
-
-
-class RestRequest(object):
-
- restApiUrl = ''
-
- def __init__(self, host, ssl=True): # parent not used
- super(RestRequest, self).__init__()
-
- self.host = host
- self.ssl = ssl
- self.restApiUrl = '{}://{}/rest/client'.format(['http', 'https'][ssl], host)
-
- def get(self, url, params=None):
- url = self.restApiUrl + url
- if params is not None:
- url += '?' + '&'.join('{}={}'.format(k, six.moves.urllib.parse.quote(six.text_type(v).encode('utf8'))) for k, v in params.iteritems()) # @UndefinedVariable
-
- logger.debug('Requesting %s', url)
-
- try:
- r = requests.get(url, headers={'Content-type': 'application/json', 'User-Agent': osDetector.getOs() + " - UDS Connector " + VERSION}, verify=False)
- except requests.exceptions.ConnectionError:
- raise Exception('Error connecting to UDS Server at {}'.format(self.restApiUrl[0:-11]))
-
- if r.ok:
- logger.debug('Request was OK. %s', r.text)
- data = json.loads(r.text)
- if not 'error' in data:
- return data['result']
- # Has error
- if data.get('retryable', '0') == '1':
- raise RetryException(data['error'])
-
- raise Exception(data['error'])
-
- logger.error('Error requesting %s: %s, %s', url, r.code, r.text)
- raise Exception('Error {}: {}'.format(r.code, r.text))
diff --git a/client/thin/src/uds/tools.py b/client/thin/src/uds/tools.py
deleted file mode 120000
index c05c13f1..00000000
--- a/client/thin/src/uds/tools.py
+++ /dev/null
@@ -1 +0,0 @@
-../../../full/src/uds/tools.py
\ No newline at end of file
diff --git a/client/thin/src/uds/ui/__init__.py b/client/thin/src/uds/ui/__init__.py
deleted file mode 100644
index 5877eae6..00000000
--- a/client/thin/src/uds/ui/__init__.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# -*- coding: utf-8 -*-
-
-#
-# Copyright (c) 2017 Virtual Cable S.L.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-#
-# * Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-# * Neither the name of Virtual Cable S.L. nor the names of its contributors
-# may be used to endorse or promote products derived from this software
-# without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-'''
-@author: Adolfo Gómez, dkmaster at dkmon dot com
-'''
-from __future__ import unicode_literals
-
-try:
- import gtkui as theUI
-except Exception:
- import consoleui as theUI # @Reimport
-
-def message(title, message):
- theUI.message(title, message)
-
-def question(title, message):
- return theUI.question(title, message)
-
diff --git a/client/thin/src/uds/ui/browser.py b/client/thin/src/uds/ui/browser.py
deleted file mode 100644
index 3af71683..00000000
--- a/client/thin/src/uds/ui/browser.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# -*- coding: utf-8 -*-
-
-#
-# Copyright (c) 2017 Virtual Cable S.L.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-#
-# * Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-# * Neither the name of Virtual Cable S.L. nor the names of its contributors
-# may be used to endorse or promote products derived from this software
-# without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-'''
-@author: Adolfo Gómez, dkmaster at dkmon dot com
-'''
-from __future__ import unicode_literals
-import random
-import os
-import tempfile
-import string
-import webbrowser
-
-TEMPLATE = '''
-
- {title}
-
-
- {title}
- {message}
-
-
-'''
-
-def _htmlFilename():
- return os.path.join(tempfile.gettempdir(), ''.join([random.choice(string.ascii_lowercase) for i in range(22)]) + '.html')
-
-def message(title, message):
- filename = _htmlFilename()
- with open(filename, 'w') as f:
- f.write(TEMPLATE.format(title=title, message=message))
-
- webbrowser.open('file://' + filename, new=0, autoraise=False)
diff --git a/client/thin/src/uds/ui/consoleui.py b/client/thin/src/uds/ui/consoleui.py
deleted file mode 100644
index 9660db64..00000000
--- a/client/thin/src/uds/ui/consoleui.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# -*- coding: utf-8 -*-
-
-#
-# Copyright (c) 2017 Virtual Cable S.L.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-#
-# * Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-# * Neither the name of Virtual Cable S.L. nor the names of its contributors
-# may be used to endorse or promote products derived from this software
-# without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-'''
-@author: Adolfo Gómez, dkmaster at dkmon dot com
-'''
-from __future__ import unicode_literals
-import sys
-import time
-from uds.log import logger
-
-counter = 0
-
-def message(title, message):
- sys.stderr.write("** {} **\n {}\n".format(title, message))
-
-def question(title, message):
- global counter
- if counter > 100: # 5 minutes
- return False
- counter += 1
- sys.stderr.write("** {} **\n{}\nReturning YES in 3 seconds. (counter is {})\n".format(title, message, counter))
- time.sleep(3) # Wait 3 seconds before returning
- return True
diff --git a/client/thin/src/uds/ui/gtkui.py b/client/thin/src/uds/ui/gtkui.py
deleted file mode 100644
index 60c82573..00000000
--- a/client/thin/src/uds/ui/gtkui.py
+++ /dev/null
@@ -1,143 +0,0 @@
-# -*- coding: utf-8 -*-
-
-#
-# Copyright (c) 2017 Virtual Cable S.L.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-#
-# * Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-# * Neither the name of Virtual Cable S.L. nor the names of its contributors
-# may be used to endorse or promote products derived from this software
-# without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-'''
-@author: Adolfo Gómez, dkmaster at dkmon dot com
-'''
-from __future__ import unicode_literals
-
-import re
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-import gobject
-
-LINE_LEN = 65
-
-class Dialog():
- def __init__(self, title, message, timeout=-1, withCancel=True):
- self.title = title
- self.message = message
- self.timeout = timeout
- self.withCancel = withCancel
-
- self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
- self.window.set_position(gtk.WIN_POS_CENTER)
- # self.window.set_size_request(320, 200)
- self.window.set_title(self.title)
- self.create_widgets()
- self.connect_signals()
- self.window.show_all()
-
- self.window.connect("destroy", self.destroy)
-
- # Setup "auto OK" timer
- if timeout != -1:
- self.timerId = gobject.timeout_add(self.timeout * 1000, self.callback_timer)
- else:
- self.timerId = -1
-
- self.result = False
-
- gtk.main()
-
- @property
- def adapted_message(self):
- msg = ''
- for l in re.sub(r'
]*>', '', self.message).replace('
', '\n').split('\n'):
- words = []
- length = 0
- for word in l.split(' '):
- if length + len(word) >= LINE_LEN:
- msg += ' '.join(words) + '\n'
- words = []
- length = 0
- length += len(word) + 1
- words.append(word)
- msg += ' '.join(words) + '\n'
- return msg
-
- def create_widgets(self):
- self.vbox = gtk.VBox(spacing=10)
- self.vbox.set_size_request(490, -1)
-
- self.messageLabel = gtk.Label()
- # Fix message markup
- # self.message = re.sub(r']*>', '', self.message).replace('
', '\n' )
-
- # Set as simple markup
- self.messageLabel.set_markup('\n' + self.adapted_message + '\n')
- self.messageLabel.set_alignment(xalign=0.5, yalign=1)
-
- self.hbox = gtk.HBox(spacing=10)
- self.button_ok = gtk.Button("OK")
- self.hbox.pack_start(self.button_ok)
-
- if self.withCancel:
- self.button_cancel = gtk.Button("Cancel")
- self.hbox.pack_start(self.button_cancel)
-
- self.vbox.pack_start(self.messageLabel)
- self.vbox.pack_start(self.hbox)
-
- self.window.add(self.vbox)
-
- def connect_signals(self):
- self.button_ok.connect("clicked", self.callback_ok)
- if self.withCancel:
- self.button_cancel.connect("clicked", self.callback_cancel)
-
- def destroy(self, widget, data=None):
- self.setResult(False)
-
- def setResult(self, val):
- if self.timerId != -1:
- gobject.source_remove(self.timerId)
- self.timerId = -1
-
- self.result = val
- self.window.hide()
- gtk.main_quit()
-
-
- def callback_ok(self, widget, callback_data=None):
- self.setResult(True)
-
- def callback_cancel(self, widget, callback_data=None):
- self.setResult(False)
-
- def callback_timer(self):
- self.setResult(True)
-
-def message(title, message):
- Dialog(title, message, withCancel=False)
-
-def question(title, message):
- dlg = Dialog(title, message, timeout=30, withCancel=True)
- return dlg.result
diff --git a/client/thin/src/udsclient b/client/thin/src/udsclient
deleted file mode 100644
index 7ccc303e..00000000
--- a/client/thin/src/udsclient
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-
-cd /lib/UDSClient
-exec python UDSClient.pyc $@
diff --git a/client/thin/thinstation/README.txt b/client/thin/thinstation/README.txt
deleted file mode 100644
index 43134a47..00000000
--- a/client/thin/thinstation/README.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-Steps:
-1.- If building from repository, full copy (recursive) the "src" folder of "client/thin" (from openuds project) inside the "udsclient" folder here (so we will have an client/thin/udsclient/src folder, with the source code of thin client). If building from the .tar.gz, simply ignore this step
-2.- Copy the folder "udsclient" to /build/packages inside the thinstation build environment
-3.- enter the chroot of thinstation
-4.- go to the udsclient folder (/build/packages/udsclient)
-5.- Execute "build.sh"
-6.- Edit the file /build/build.conf, and add this line:
- package udsclient
-7.- Execute the build process
-
-Ready!!!
diff --git a/client/thin/thinstation/udsclient/.dna b/client/thin/thinstation/udsclient/.dna
deleted file mode 100644
index e69de29b..00000000
diff --git a/client/thin/thinstation/udsclient/.gitignore b/client/thin/thinstation/udsclient/.gitignore
deleted file mode 100644
index 2741c5fa..00000000
--- a/client/thin/thinstation/udsclient/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-lib
-src
diff --git a/client/thin/thinstation/udsclient/UDSClient.desktop b/client/thin/thinstation/udsclient/UDSClient.desktop
deleted file mode 100644
index 7173bfe9..00000000
--- a/client/thin/thinstation/udsclient/UDSClient.desktop
+++ /dev/null
@@ -1,11 +0,0 @@
-[Desktop Entry]
-Name=UDSClient
-Comment=UDS Helper
-Keywords=uds;client;vdi;
-Exec=/bin/udsclient %u
-Icon=help-browser
-StartupNotify=true
-Terminal=false
-Type=Application
-Categories=Utility;
-MimeType=x-scheme-handler/uds;x-scheme-handler/udss;
diff --git a/client/thin/thinstation/udsclient/bin/udsclient b/client/thin/thinstation/udsclient/bin/udsclient
deleted file mode 100755
index 7ccc303e..00000000
--- a/client/thin/thinstation/udsclient/bin/udsclient
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-
-cd /lib/UDSClient
-exec python UDSClient.pyc $@
diff --git a/client/thin/thinstation/udsclient/build.sh b/client/thin/thinstation/udsclient/build.sh
deleted file mode 100755
index ecc4ab71..00000000
--- a/client/thin/thinstation/udsclient/build.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/sh
-pip install paramiko requests six pycrypto
-rm -rf lib
-mkdir -p lib/python2.7/site-packages
-for a in requests paramiko pyasn1 cryptography packaging idna asn1crypto six enum ipaddress cffi Crypto; do cp -r /usr/lib/python2.7/site-packages/$a* lib/python2.7/site-packages/; done
-cp src/udsclient bin
-chmod 755 bin/udsclient
-mkdir lib/UDSClient
-cp src/UDSClient.py lib/UDSClient
-chmod 755 lib/UDSClient/UDSClient.py
-cp -r src/uds lib/UDSClient
-mkdir lib/applications
-cp UDSClient.desktop lib/applications
diff --git a/client/thin/thinstation/udsclient/dependencies b/client/thin/thinstation/udsclient/dependencies
deleted file mode 100644
index dc497e7e..00000000
--- a/client/thin/thinstation/udsclient/dependencies
+++ /dev/null
@@ -1,5 +0,0 @@
-base
-#add your own dependancies to this file, base should always be included.
-python
-pygtk
-freerdp
diff --git a/client/thin/thinstation/udsclient/etc/cmd/README b/client/thin/thinstation/udsclient/etc/cmd/README
deleted file mode 100644
index 0c1a73e6..00000000
--- a/client/thin/thinstation/udsclient/etc/cmd/README
+++ /dev/null
@@ -1,15 +0,0 @@
-In here you place the commands to start your application if using the scripts
-
-/etc/thinstation.packages
-or /etc/thinstation.console
-
-see examples for for information
-
-
-possible types are
-
-example.global (this is always needed)
-example.menu
-example.console
-example.window
-example.fullscreen
diff --git a/client/thin/thinstation/udsclient/etc/cmd/example.fullscreen b/client/thin/thinstation/udsclient/etc/cmd/example.fullscreen
deleted file mode 100755
index 405431e8..00000000
--- a/client/thin/thinstation/udsclient/etc/cmd/example.fullscreen
+++ /dev/null
@@ -1 +0,0 @@
-CMD_FULLSCREEN="example -FULLSCREEN"
diff --git a/client/thin/thinstation/udsclient/etc/cmd/example.global b/client/thin/thinstation/udsclient/etc/cmd/example.global
deleted file mode 100755
index 11283739..00000000
--- a/client/thin/thinstation/udsclient/etc/cmd/example.global
+++ /dev/null
@@ -1 +0,0 @@
-CMD_GLOBAL="example -startapp"
diff --git a/client/thin/thinstation/udsclient/etc/console/README b/client/thin/thinstation/udsclient/etc/console/README
deleted file mode 100644
index 915032b1..00000000
--- a/client/thin/thinstation/udsclient/etc/console/README
+++ /dev/null
@@ -1 +0,0 @@
-Place a 0 length file in here as the same name as the package if your application is a Console App
diff --git a/client/thin/thinstation/udsclient/etc/init.d/your_start_up_script b/client/thin/thinstation/udsclient/etc/init.d/your_start_up_script
deleted file mode 100755
index 02f10130..00000000
--- a/client/thin/thinstation/udsclient/etc/init.d/your_start_up_script
+++ /dev/null
@@ -1,34 +0,0 @@
-#! /bin/sh
-
-. /etc/thinstation.global
-
-# note you can replace this package with a symlink to /etc/thinstation.packages
-# for GUI apps, or /etc/thinstation.console for console apps
-# if you do then you will need to create a seperate initilization script for
-# any other parameters which need to be started at bootup
-
-
-case "$1" in
-init)
- if ! pkg_initialized $PACKAGE; then
-
- # Your startup instructions go here
-
- pkg_set_init_flag $PACKAGE
- fi
- ;;
-console)
-;;
-window)
-;;
-fullscreen)
-;;
-help)
- echo "Usage: $0 init"
- ;;
- *)
- exit 1
- ;;
-esac
-
-exit 0
diff --git a/client/thin/thinstation/udsclient/etc/rc5.d/S10this_is_a_symlink_to_start_up_script b/client/thin/thinstation/udsclient/etc/rc5.d/S10this_is_a_symlink_to_start_up_script
deleted file mode 120000
index fb51a297..00000000
--- a/client/thin/thinstation/udsclient/etc/rc5.d/S10this_is_a_symlink_to_start_up_script
+++ /dev/null
@@ -1 +0,0 @@
-/etc/init.d/your_start_up_script
\ No newline at end of file