1
0
mirror of https://github.com/dkmstr/openuds.git synced 2024-12-22 13:34:04 +03:00

merged from 2.2

This commit is contained in:
Adolfo Gómez García 2018-07-23 09:54:35 +02:00
commit e37b929adc
12 changed files with 47 additions and 36 deletions

View File

@ -219,7 +219,7 @@ class UDSClient(QtGui.QMainWindow):
QtCore.QTimer.singleShot(10000, self.getTransportData) QtCore.QTimer.singleShot(10000, self.getTransportData)
except Exception as e: except Exception as e:
logger.exception('Got exception executing script:') #logger.exception('Got exception executing script:')
self.showError(e) self.showError(e)
def endScript(self): def endScript(self):

View File

@ -46,7 +46,7 @@ logging.basicConfig(
filename=logFile, filename=logFile,
filemode='a', filemode='a',
format='%(levelname)s %(asctime)s %(message)s', format='%(levelname)s %(asctime)s %(message)s',
level=logging.DEBUG level=logging.INFO
) )
logger = logging.getLogger('udsclient') logger = logging.getLogger('udsclient')

View File

@ -38,6 +38,7 @@ from uds.models import Authenticator
from uds.models import DeployedService from uds.models import DeployedService
from uds.models import Transport from uds.models import Transport
from uds.models import TicketStore from uds.models import TicketStore
from uds.core.managers import cryptoManager
from uds.core.util.model import processUuid from uds.core.util.model import processUuid
from uds.core.util import tools from uds.core.util import tools
@ -207,7 +208,7 @@ class Tickets(Handler):
data = { data = {
'username': username, 'username': username,
'password': password, 'password': cryptoManager().encrypt(password),
'realname': realname, 'realname': realname,
'groups': groups, 'groups': groups,
'auth': auth.uuid, 'auth': auth.uuid,

View File

@ -59,7 +59,7 @@ class CacheCleaner(Job):
class TicketStoreCleaner(Job): class TicketStoreCleaner(Job):
frecuency = 3600 * 12 # every twelve hours frecuency = 60 # every minute (60 seconds)
friendly_name = 'Ticket Storage Cleaner' friendly_name = 'Ticket Storage Cleaner'
def __init__(self, environment): def __init__(self, environment):

View File

@ -35,6 +35,7 @@ from __future__ import unicode_literals
from django.http import HttpResponse from django.http import HttpResponse
from uds.models import TicketStore from uds.models import TicketStore
from uds.core.auths import auth from uds.core.auths import auth
from uds.core.managers import cryptoManager
import six import six
import logging import logging
@ -55,8 +56,11 @@ def dict2resp(dct):
def guacamole(request, tunnelId): def guacamole(request, tunnelId):
logger.debug('Received credentials request for tunnel id {0}'.format(tunnelId)) logger.debug('Received credentials request for tunnel id {0}'.format(tunnelId))
tunnelId, scrambler = tunnelId.split('.')
try: try:
val = TicketStore.get(tunnelId, invalidate=False) val = TicketStore.get(tunnelId, invalidate=False)
val['password'] = cryptoManager().xor(val['password'], scrambler)
response = dict2resp(val) response = dict2resp(val)
except Exception: except Exception:

View File

@ -25,9 +25,9 @@
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # 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 # 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. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
""" '''
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com .. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
""" '''
from __future__ import unicode_literals from __future__ import unicode_literals
@ -45,7 +45,7 @@ import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
__updated__ = '2016-09-16' __updated__ = '2018-07-19'
class TicketStore(UUIDModel): class TicketStore(UUIDModel):
@ -78,7 +78,7 @@ class TicketStore(UUIDModel):
@staticmethod @staticmethod
def generateUuid(): def generateUuid():
# more owner is this: # more secure is this:
# ''.join(random.SystemRandom().choice(string.ascii_lowercase + string.digits) for _ in range(40)) # ''.join(random.SystemRandom().choice(string.ascii_lowercase + string.digits) for _ in range(40))
return cryptoManager().randomString(40) return cryptoManager().randomString(40)
@ -91,7 +91,7 @@ class TicketStore(UUIDModel):
validator = pickle.dumps(validator) validator = pickle.dumps(validator)
data = pickle.dumps(data) data = pickle.dumps(data)
if secure: if secure:
data = cryptoManager().encrypt(data) pass
return TicketStore.objects.create(stamp=getSqlDatetime(), data=data, validator=validator, validity=validity, owner=owner).uuid return TicketStore.objects.create(stamp=getSqlDatetime(), data=data, validator=validator, validity=validity, owner=owner).uuid
@ -106,16 +106,16 @@ class TicketStore(UUIDModel):
data = pickle.dumps(data) data = pickle.dumps(data)
if secure: if secure:
data = cryptoManager().encrypt() pass
try: try:
t = TicketStore.objects.get(uuid=uuid, owner=owner) t = TicketStore.objects.get(uuid=uuid)
t.data = data t.data = pickle.dumps(data)
t.stamp = getSqlDatetime() t.stamp = getSqlDatetime()
t.validity = validity t.validity = validity
t.save() t.save()
except TicketStore.DoesNotExist: except TicketStore.DoesNotExist:
t = TicketStore.objects.create(uuid=uuid, stamp=getSqlDatetime(), data=data, validator=validator, validity=validity, owner=owner) t = TicketStore.objects.create(uuid=uuid, stamp=getSqlDatetime(), data=pickle.dumps(data), validator=validator, validity=validity)
@staticmethod @staticmethod
def get(uuid, invalidate=True, owner=None, secure=False): def get(uuid, invalidate=True, owner=None, secure=False):
@ -128,10 +128,8 @@ class TicketStore(UUIDModel):
if t.stamp + validity < now: if t.stamp + validity < now:
raise TicketStore.InvalidTicket('Not valid anymore') raise TicketStore.InvalidTicket('Not valid anymore')
if secure is True: # if secure: TODO
data = pickle.loads(cryptoManager().decrypt(t.data)) data = pickle.loads(t.data)
else:
data = pickle.loads(t.data)
# If has validator, execute it # If has validator, execute it
if t.validator is not None: if t.validator is not None:
@ -161,10 +159,13 @@ class TicketStore(UUIDModel):
@staticmethod @staticmethod
def cleanup(): def cleanup():
from datetime import timedelta
now = getSqlDatetime() now = getSqlDatetime()
cleanSince = now - datetime.timedelta(seconds=TicketStore.MAX_VALIDITY) for v in TicketStore.objects.all():
if now > v.stamp + timedelta(seconds=v.validity):
v.delete()
cleanSince = now - datetime.timedelta(seconds=TicketStore.MAX_VALIDITY)
number = TicketStore.objects.filter(stamp__lt=cleanSince).delete() number = TicketStore.objects.filter(stamp__lt=cleanSince).delete()
logger.debug('Cleaned {} tickets'.format(number))
def __unicode__(self): def __unicode__(self):
if self.validator is not None: if self.validator is not None:

View File

@ -44,6 +44,7 @@ from uds.core.transports.BaseTransport import TUNNELED_GROUP
from uds.core.transports import protocols from uds.core.transports import protocols
from uds.core.util import connection from uds.core.util import connection
from uds.core.util import OsDetector from uds.core.util import OsDetector
from uds.core.managers import cryptoManager
from uds.models import TicketStore from uds.models import TicketStore
import logging import logging
@ -192,12 +193,15 @@ class HTML5RDPTransport(Transport):
if domain != '': if domain != '':
username = domain + '\\' + username username = domain + '\\' + username
scrambler = cryptoManager().randomString(32)
passwordCrypted = cryptoManager().xor(password, scrambler)
# Build params dict # Build params dict
params = { params = {
'protocol': 'rdp', 'protocol': 'rdp',
'hostname': ip, 'hostname': ip,
'username': username, 'username': username,
'password': password, 'password': passwordCrypted,
'ignore-cert': 'true', 'ignore-cert': 'true',
'security': self.security.value, 'security': self.security.value,
'drive-path': '/share/{}'.format(user.uuid), 'drive-path': '/share/{}'.format(user.uuid),
@ -229,4 +233,5 @@ class HTML5RDPTransport(Transport):
ticket = TicketStore.create(params, validity=self.ticketValidity.num()) ticket = TicketStore.create(params, validity=self.ticketValidity.num())
return HttpResponseRedirect("{}/transport/?{}&{}".format(self.guacamoleServer.value, ticket, request.build_absolute_uri(reverse('Index')))) return HttpResponseRedirect("{}/transport/?{}.{}&{}".format(self.guacamoleServer.value, ticket, scrambler, request.build_absolute_uri(reverse('Index'))))

View File

@ -27,9 +27,9 @@
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # 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. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
""" '''
@author: Adolfo Gómez, dkmaster at dkmon dot com @author: Adolfo Gómez, dkmaster at dkmon dot com
""" '''
from __future__ import unicode_literals from __future__ import unicode_literals
from django.utils.translation import ugettext_noop as _ from django.utils.translation import ugettext_noop as _
from uds.core.managers.UserPrefsManager import CommonPrefs from uds.core.managers.UserPrefsManager import CommonPrefs
@ -44,14 +44,14 @@ logger = logging.getLogger(__name__)
READY_CACHE_TIMEOUT = 30 READY_CACHE_TIMEOUT = 30
__updated__ = '2018-05-18' __updated__ = '2018-07-19'
class RDPTransport(BaseRDPTransport): class RDPTransport(BaseRDPTransport):
""" '''
Provides access via RDP to service. Provides access via RDP to service.
This transport can use an domain. If username processed by authenticator contains '@', it will split it and left-@-part will be username, and right password This transport can use an domain. If username processed by authenticator contains '@', it will split it and left-@-part will be username, and right password
""" '''
typeName = _('RDP') typeName = _('RDP')
typeType = 'RDPTransport' typeType = 'RDPTransport'
typeDescription = _('RDP Protocol. Direct connection.') typeDescription = _('RDP Protocol. Direct connection.')
@ -104,7 +104,7 @@ class RDPTransport(BaseRDPTransport):
r.domain = domain r.domain = domain
r.redirectPrinters = self.allowPrinters.isTrue() r.redirectPrinters = self.allowPrinters.isTrue()
r.redirectSmartcards = self.allowSmartcards.isTrue() r.redirectSmartcards = self.allowSmartcards.isTrue()
r.redirectDrives = self.allowDrives.isTrue() r.redirectDrives = self.allowDrives.value
r.redirectHome = self.redirectHome.isTrue() r.redirectHome = self.redirectHome.isTrue()
r.redirectSerials = self.allowSerials.isTrue() r.redirectSerials = self.allowSerials.isTrue()
r.enableClipboard = self.allowClipboard.isTrue() r.enableClipboard = self.allowClipboard.isTrue()

View File

@ -27,9 +27,9 @@
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # 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. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
""" '''
@author: Adolfo Gómez, dkmaster at dkmon dot com @author: Adolfo Gómez, dkmaster at dkmon dot com
""" '''
from __future__ import unicode_literals from __future__ import unicode_literals
from django.utils.translation import ugettext_noop as _ from django.utils.translation import ugettext_noop as _
from uds.core.managers.UserPrefsManager import CommonPrefs from uds.core.managers.UserPrefsManager import CommonPrefs
@ -48,7 +48,7 @@ import logging
import random import random
import string import string
__updated__ = '2018-05-18' __updated__ = '2018-07-19'
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -56,10 +56,10 @@ READY_CACHE_TIMEOUT = 30
class TRDPTransport(BaseRDPTransport): class TRDPTransport(BaseRDPTransport):
""" '''
Provides access via RDP to service. Provides access via RDP to service.
This transport can use an domain. If username processed by authenticator contains '@', it will split it and left-@-part will be username, and right password This transport can use an domain. If username processed by authenticator contains '@', it will split it and left-@-part will be username, and right password
""" '''
typeName = _('RDP') typeName = _('RDP')
typeType = 'TSRDPTransport' typeType = 'TSRDPTransport'
typeDescription = _('RDP Protocol. Tunneled connection.') typeDescription = _('RDP Protocol. Tunneled connection.')
@ -132,7 +132,7 @@ class TRDPTransport(BaseRDPTransport):
r.domain = domain r.domain = domain
r.redirectPrinters = self.allowPrinters.isTrue() r.redirectPrinters = self.allowPrinters.isTrue()
r.redirectSmartcards = self.allowSmartcards.isTrue() r.redirectSmartcards = self.allowSmartcards.isTrue()
r.redirectDrives = self.allowDrives.isTrue() r.redirectDrives = self.allowDrives.value
r.redirectHome = self.redirectHome.isTrue() r.redirectHome = self.redirectHome.isTrue()
r.redirectSerials = self.allowSerials.isTrue() r.redirectSerials = self.allowSerials.isTrue()
r.enableClipboard = self.allowClipboard.isTrue() r.enableClipboard = self.allowClipboard.isTrue()

View File

@ -10,8 +10,8 @@ from uds import tools # @UnresolvedImport
import six import six
thePass = six.binary_type('{m.password}'.encode('UTF-16LE'))
try: try:
thePass = six.binary_type("""{m.password}""".encode('UTF-16LE'))
password = win32crypt.CryptProtectData(thePass, None, None, None, None, 0x01).encode('hex') password = win32crypt.CryptProtectData(thePass, None, None, None, None, 0x01).encode('hex')
except Exception: except Exception:
# Cannot encrypt for user, trying for machine # Cannot encrypt for user, trying for machine

View File

@ -21,8 +21,8 @@ if forwardThread.status == 2:
tools.addTaskToWait(forwardThread) tools.addTaskToWait(forwardThread)
thePass = six.binary_type('{m.password}'.encode('UTF-16LE'))
try: try:
thePass = six.binary_type(sp['password'].encode('UTF-16LE'))
password = win32crypt.CryptProtectData(thePass, None, None, None, None, 0x01).encode('hex') password = win32crypt.CryptProtectData(thePass, None, None, None, None, 0x01).encode('hex')
except Exception: except Exception:
# Cannot encrypt for user, trying for machine # Cannot encrypt for user, trying for machine

View File

@ -152,7 +152,7 @@ def ticketAuth(request, ticketId):
auth = data['auth'] auth = data['auth']
realname = data['realname'] realname = data['realname']
servicePool = data['servicePool'] servicePool = data['servicePool']
password = data['password'] password = cryptoManager().decrypt(data['password'])
transport = data['transport'] transport = data['transport']
except Exception: except Exception:
logger.error('Ticket stored is not valid') logger.error('Ticket stored is not valid')