Exemplo n.º 1
0
    def default(self, obj):
        """
            A useful JSON encoder for development, as it dumps CCP objects.
        """
        if isinstance(obj, blue.MarshalStream):
            return machobase.Loads(obj)
        if isinstance(obj, MachoAddress) or isinstance(obj, MachoPacket):
            return obj.__getstate__()
        if isinstance(obj, blue.DBRow):
            item = {}
            for key in obj.__columns__:
                item[key] = obj[key]

            return item
        if isinstance(obj, Rowset):
            return [r for r in obj]
        if isinstance(obj, Row):
            item = {}
            for key in obj.header:
                item[key] = obj[key]

            return item
        if isinstance(obj, SparseRowset):
            items = []
            for item in obj:
                items.append(self.default(item))

            return items
        if isinstance(obj, KeyVal):
            return obj.__dict__
        if isinstance(obj, UserError):
            return dict({'error': obj.msg}, **obj.dict)
        print obj, 'cannot be encoded and has', dir(obj)
        return json.JSONEncoder.default(self, obj)
Exemplo n.º 2
0
    def Authenticate(self, username, password, token):
        """
        The client-side of the client authentication protocol. 'token' is an SSO auth token or None,
        """
        timer = Enter('machoNet::GPS::Authenticate')
        try:
            message = (
                localization.GetByLabel(
                    '/Carbon/GPS/ConnectionTimeoutNoCompatibilityHandshake'),
                'HANDSHAKE_TIMEOUT_FAILEDSERVERINITIATECOMPATIBILITYHANDSHAKE')
            response = macho.Loads(
                self.ApplyWithTimeout(self.UnEncryptedRead, (),
                                      message=message))
            insecresp = {
                'macho_version': response[1],
                'cluster_usercount': response[2],
                'boot_version': response[3],
                'boot_build': response[4],
                'update_info': response[6]
            }
            if '@' in response[5]:
                insecresp['boot_codename'], insecresp[
                    'boot_region'] = response[5].split('@')
            else:
                insecresp['boot_codename'], insecresp[
                    'boot_region'] = response[5], ''
            if str(boot.region) != insecresp['boot_region']:
                log.general.Log(
                    'Handshake Failed - Insecure Boot Region Mismatch (common.ini:region) - Server: %s  - Client: %s'
                    % (insecresp['boot_region'], str(boot.region)), log.LGERR)
                self.Close(
                    localization.GetByLabel('/Carbon/GPS/IncompatibleRegion'),
                    'HANDSHAKE_INCOMPATIBLEREGION')
                raise GPSTransportClosed(
                    localization.GetByLabel('/Carbon/GPS/IncompatibleRegion'),
                    'HANDSHAKE_INCOMPATIBLEREGION',
                    machoVersion=response[1],
                    version=response[3],
                    build=response[4],
                    codename=insecresp['boot_codename'],
                    region=insecresp['boot_region'],
                    loggedOnUserCount=response[2])
            if str(boot.codename) != insecresp['boot_codename']:
                log.general.Log(
                    'Handshake Failed - Insecure Boot Code Name Mismatch  (common.ini:codename) - Server: %s - Client: %s'
                    % (insecresp['boot_codename'], str(boot.codename)),
                    log.LGERR)
                self.Close(
                    localization.GetByLabel('/Carbon/GPS/IncompatibleRelease'),
                    'HANDSHAKE_INCOMPATIBLERELEASE')
                raise GPSTransportClosed(
                    localization.GetByLabel('/Carbon/GPS/IncompatibleRelease'),
                    'HANDSHAKE_INCOMPATIBLERELEASE',
                    machoVersion=response[1],
                    version=response[3],
                    build=response[4],
                    codename=insecresp['boot_codename'],
                    region=insecresp['boot_region'],
                    loggedOnUserCount=response[2])
            if boot.version != response[3]:
                log.general.Log(
                    'Handshake Failed - Insecure Boot Version Mismatch (common.ini:version) - Server: %s - Client: %s'
                    % (response[3], boot.version), log.LGERR)
                self.Close(
                    localization.GetByLabel('/Carbon/GPS/IncompatibleVersion'),
                    'HANDSHAKE_INCOMPATIBLEVERSION')
                raise GPSTransportClosed(
                    localization.GetByLabel('/Carbon/GPS/IncompatibleVersion'),
                    'HANDSHAKE_INCOMPATIBLEVERSION',
                    machoVersion=response[1],
                    version=response[3],
                    build=response[4],
                    codename=insecresp['boot_codename'],
                    region=insecresp['boot_region'],
                    loggedOnUserCount=response[2])
            if macho.version != response[1]:
                log.general.Log(
                    'Handshake Failed - Insecure Macho Version Mismatch - Server: %s - Client: %s'
                    % (response[1], macho.version), log.LGERR)
                self.Close(
                    localization.GetByLabel(
                        '/Carbon/GPS/IncompatibleProtocol'),
                    'HANDSHAKE_INCOMPATIBLEPROTOCOL')
                raise GPSTransportClosed(localization.GetByLabel(
                    '/Carbon/GPS/IncompatibleProtocol'),
                                         'HANDSHAKE_INCOMPATIBLEPROTOCOL',
                                         machoVersion=response[1],
                                         version=response[3],
                                         build=response[4],
                                         codename=insecresp['boot_codename'],
                                         region=insecresp['boot_region'],
                                         loggedOnUserCount=response[2])
            if boot.build < response[4]:
                log.general.Log(
                    'Handshake Failed - Insecure Boot Build Mismatch (common.ini:build) - Server: %s - Client: %s'
                    % (response[4], boot.build), log.LGERR)
                self.Close(
                    localization.GetByLabel('/Carbon/GPS/IncompatibleBuild'),
                    'HANDSHAKE_INCOMPATIBLEBUILD')
                raise GPSTransportClosed(
                    localization.GetByLabel('/Carbon/GPS/IncompatibleBuild'),
                    'HANDSHAKE_INCOMPATIBLEBUILD',
                    machoVersion=response[1],
                    version=response[3],
                    build=response[4],
                    codename=insecresp['boot_codename'],
                    region=insecresp['boot_region'],
                    loggedOnUserCount=response[2])
            request = (170472, macho.version, 0, boot.version, boot.build,
                       str(boot.codename) + '@' + str(boot.region))
            self.UnEncryptedWrite(macho.Dumps(request))
            if username:
                self.UnEncryptedWrite(
                    macho.Dumps((None, 'VK',
                                 Crypto.CryptoHash(util.CaseFold(username)))))
            if username is None:
                self.UnEncryptedWrite(macho.Dumps((None, 'QC')))
                message = (localization.GetByLabel(
                    '/Carbon/GPS/ConnectionTimeoutNoCompatibilityHandshake'
                ), 'HANDSHAKE_TIMEOUT_FAILEDSERVERINITIATECOMPATIBILITYHANDSHAKE'
                           )
                logonQueuePosition = macho.Loads(
                    self.ApplyWithTimeout(self.UnEncryptedRead, (),
                                          message=message))
                sm.GetService('machoNet').SetLogonQueuePosition(
                    logonQueuePosition)
                return insecresp
            log.general.Log('LLV Initializing Crypto Context', log.LGINFO)
            request = self.cryptoContext.Initialize()
            if type(request) != types.DictType:
                log.general.Log('LLV Crypto Init Context failure: ' + request,
                                log.LGERR)
                self.Close('Crypto Initialization Failure')
                raise GPSTransportClosed(
                    localization.GetByLabel('/Carbon/GPS/IncompatibleBuild'),
                    'HANDSHAKE_INCOMPATIBLEBUILD',
                    loggedOnUserCount=response[2])
            log.general.Log('LLV Sending Encrypted Session Key', log.LGINFO)
            self.UnEncryptedWrite(
                macho.Dumps((getattr(macho, 'publicKeyVersion',
                                     'placebo'), request)))
            message = (localization.GetByLabel(
                '/Carbon/GPS/ConnectionTimeoutClientNotCompatible'),
                       'HANDSHAKE_TIMEOUT_CLIENTCOMPATIBILITYHANDSHAKE')
            macho.Loads(
                self.ApplyWithTimeout(self.UnEncryptedRead, (),
                                      message=message))
            log.general.Log('LLV Generating Secure Client Handshake',
                            log.LGINFO)
            affiliateID = 0
            try:
                aidfile = blue.ResFile()
                if aidfile.Open('res:/aid.txt'):
                    affiliateID = int(str(aidfile.Read()))
                else:
                    log.general.Log(
                        'No aid.txt file present in res directory.',
                        log.LGINFO)
            except StandardError:
                log.general.Log(
                    'No affiliate ID present, or failed to read aid.txt',
                    log.LGERR)
                sys.exc_clear()

            dict = {
                'macho_version': macho.version,
                'boot_version': boot.version,
                'boot_build': boot.build,
                'boot_codename': str(boot.codename),
                'boot_region': str(boot.region),
                'user_name': username,
                'user_password': None,
                'user_password_hash': macho.PasswordHash(username, password),
                'user_languageid': prefs.GetValue('languageID', 'EN'),
                'user_affiliateid': affiliateID,
                'user_sso_token': token
            }
            clientChallenge = Crypto.GetRandomBytes(
                self.handShakePaddingLength)
            log.general.Log('LLV Writing Secure Client Handshake', log.LGINFO)
            self.EncryptedWrite(macho.Dumps((clientChallenge, dict)))
            log.general.Log('LLV Reading password version', log.LGINFO)
            message = (localization.GetByLabel(
                '/Carbon/GPS/ConnectionTimeoutServerTimeout'),
                       'HANDSHAKE_TIMEOUT_SERVERSECUREHANDSHAKE')
            passwordVersion = macho.Loads(
                self.ApplyWithTimeout(self.EncryptedRead, (), message=message))
            if passwordVersion == 1:
                dict['user_password'] = password
                dict['user_password_hash'] = None
                log.general.Log(
                    'LLV Writing Secure Client Handshake (Attempt 2)',
                    log.LGINFO)
                self.EncryptedWrite(macho.Dumps((clientChallenge, dict)))
            log.general.Log('LLV Reading Crypted Server Handshake', log.LGINFO)
            message = (localization.GetByLabel(
                '/Carbon/GPS/ConnectionTimeoutServerTimeout'),
                       'HANDSHAKE_TIMEOUT_SERVERSECUREHANDSHAKE')
            serverChallenge, signedFunc, context, response = macho.Loads(
                self.ApplyWithTimeout(self.EncryptedRead, (), message=message))
            log.general.Log('LLV Verifying Response Hash', log.LGINFO)
            if response['challenge_responsehash'] != Crypto.CryptoHash(
                    clientChallenge):
                self.Close(
                    "Server response signature incorrect, the server's crypto hash wasn't correct"
                )
                raise GPSTransportClosed(
                    "Server response signature incorrect, the server's crypto hash wasn't correct",
                    loggedOnUserCount=response[2])
            if response.get('user_logonqueueposition', 0) >= 2:
                sm.GetService('machoNet').SetLogonQueuePosition(
                    response['user_logonqueueposition'])
                raise UserError(
                    'AutLogonFailureTotalUsers',
                    {'position': response['user_logonqueueposition']})
            try:
                sm.GetService('machoNet').UpdateGlobalConfig(
                    response.get('config_vals', {}))
            except:
                log.LogException()

            outputBuffer, funcResult = self.__Execute(signedFunc, context)
            log.general.Log('LLV Writing Secure Challenge-Response',
                            log.LGINFO)
            self.EncryptedWrite(
                macho.Dumps((Crypto.CryptoHash(serverChallenge), outputBuffer,
                             funcResult)))
            log.general.Log('LLV Reading Ack to Challenge-Response',
                            log.LGINFO)
            message = (localization.GetByLabel(
                '/Carbon/GPS/ConnectionTimeoutChallengeFailure'),
                       'HANDSHAKE_TIMEOUT_SERVERRESPONSETOCLIENTCHALLENGE')
            crAck = macho.Loads(
                self.ApplyWithTimeout(self.EncryptedRead, (), message=message))
            if not crAck:
                self.Close("Server didn't ACK our Challenge-Response")
                raise GPSTransportClosed(localization.GetByLabel(
                    '/Carbon/GPS/ChallengeResponseNotAcknowledged'),
                                         loggedOnUserCount=response[2])
            response.update(crAck)
            if 'live_updates' in response:
                live_updates = response['live_updates']
                del response['live_updates']
                for theUpdate in live_updates:
                    sm.ScatterEvent('OnLiveClientUpdate', theUpdate.code)

            log.general.Log('LLV Succeeded', log.LGINFO)
            self.handShake = response
            return response
        finally:
            Leave(timer)
Exemplo n.º 3
0
    def HandleClientAuthentication(self, loggedOnUserCount, transportID,
                                   counter, sessionID, eveInVIP):
        """
        The (proxy) server-side of the client authentication protocol. 'loggedOnUserCouunt' is the number
        of users logged into entire cluster, 'transportID' ID of connecting transport, 'sessionID' is the
        transport's (fresh, new) sessionID, 'counter' the number of times the transport has entered the
        authentication protocol before this call.
        """
        timer = Enter('machoNet::GPS::HandleClientAuthentication')
        try:
            try:
                updateInfo = sm.GetService('machoNet').GetValidClientCodeHash()
            except:
                log.general.Log('Clienthash info not available', log.LGINFO)
                updateInfo = const.responseUnknown

            response = (170472, macho.version,
                        loggedOnUserCount, boot.version, boot.build,
                        str(boot.codename) + '@' + str(boot.region),
                        updateInfo)
            self.UnEncryptedWrite(macho.Dumps(response))
            message = (localization.GetByLabel(
                '/Carbon/GPS/ConnectionTimeoutClientNotCompatible'),
                       'HANDSHAKE_TIMEOUT_CLIENTCOMPATIBILITYHANDSHAKE')
            handshakeTimeout = prefs.GetValue(
                'GpsCompatibilityHandshakeTimeout',
                120) * (10 if counter else 1)
            log.general.Log(
                'GPS[%d]: HandleClientAuthentication waiting for handshake (timeout=%ds, counter=%d)'
                % (transportID, handshakeTimeout, counter), log.LGINFO)
            response = macho.Loads(
                self.ApplyWithTimeout(self.UnEncryptedRead, (),
                                      message=message,
                                      timeout=handshakeTimeout))
            if '@' in response[5]:
                codename, region = response[5].split('@')
            else:
                codename, region = response[5], ''
            if str(boot.region) != region:
                if boot.role == 'client':
                    log.general.Log(
                        'Handshake Failed - Insecure Region Code Mismatch (common.ini:region) - Server: %s  - Client: %s'
                        % (region, str(boot.region)), log.LGERR)
                self.Close(
                    localization.GetByLabel('/Carbon/GPS/IncompatibleRegion'),
                    'HANDSHAKE_INCOMPATIBLEREGION')
                return 'ERR'
            if str(boot.codename) != codename:
                log.general.Log(
                    'Handshake Failed - Insecure Boot Code Name Mismatch (common.ini:codename) - Server: %s - Client: %s'
                    % (codename, str(boot.codename)), log.LGERR)
                self.Close(
                    localization.GetByLabel('/Carbon/GPS/IncompatibleRelease'),
                    'HANDSHAKE_INCOMPATIBLERELEASE')
                return 'ERR'
            if boot.version != response[3]:
                log.general.Log(
                    'Handshake Failed - Insecure Boot Version Mismatch (common.ini:version) - Server: %s - Client: %s'
                    % (response[3], boot.version), log.LGERR)
                self.Close(
                    localization.GetByLabel('/Carbon/GPS/IncompatibleVersion'),
                    'HANDSHAKE_INCOMPATIBLEVERSION')
                return 'ERR'
            if macho.version != response[1]:
                log.general.Log(
                    'Handshake Failed - Insecure Macho Version Mismatch - Server: %s - Client: %s'
                    % (response[1], macho.version), log.LGERR)
                self.Close(
                    localization.GetByLabel(
                        '/Carbon/GPS/IncompatibleProtocol'),
                    'HANDSHAKE_INCOMPATIBLEPROTOCOL')
                return 'ERR'
            if boot.build > response[4]:
                log.general.Log(
                    'Handshake Failed - Insecure Boot Build Mismatch (common.ini:build) - Server: %s - Client: %s'
                    % (response[4], boot.build), log.LGERR)
                self.Close(
                    localization.GetByLabel('/Carbon/GPS/IncompatibleBuild'),
                    'HANDSHAKE_INCOMPATIBLEBUILD')
                return 'ERR'
            log.general.Log(
                'LLV Reading Client Crypto Context OR VIP Key OR Queue Check',
                log.LGINFO)
            vipKey = None
            message = (localization.GetByLabel(
                '/Carbon/GPS/ConnectionTimeoutNoCompatibilityHandshake'),
                       'HANDSHAKE_TIMEOUT_CLIENTSECUREHANDSHAKE')
            clientCryptoContextPacket = macho.Loads(
                self.ApplyWithTimeout(self.UnEncryptedRead, (),
                                      message=message))
            if clientCryptoContextPacket[
                    0] is None and clientCryptoContextPacket[1] == 'VK':
                vipKey = clientCryptoContextPacket[2]
            if clientCryptoContextPacket[
                    0] is None and clientCryptoContextPacket[1] == 'VK':
                log.general.Log(
                    'LLV Reading Client Crypto Context OR Queue Check',
                    log.LGINFO)
                message = (localization.GetByLabel(
                    '/Carbon/GPS/ConnectionTimeoutNoCompatibilityHandshake'),
                           'HANDSHAKE_TIMEOUT_CLIENTSECUREHANDSHAKE')
                clientCryptoContextPacket = macho.Loads(
                    self.ApplyWithTimeout(self.UnEncryptedRead, (),
                                          message=message))
            if counter == 0:
                sm.GetService('machoNet').PutTransportInLogonQueue(transportID)
            logonQueuePosition = sm.GetService(
                'machoNet').GetLogonQueuePosition(transportID, vipKey)
            if clientCryptoContextPacket[
                    0] is None and clientCryptoContextPacket[1] == 'QC':
                if eveInVIP:
                    self.Close(
                        localization.GetByLabel(
                            '/Carbon/GPS/NotAcceptingConnections'),
                        'ACL_NOTACCEPTING')
                    return 'OK'
                log.general.Log('Logon Queue Position Query - Complete',
                                log.LGINFO)
                self.UnEncryptedWrite(macho.Dumps(logonQueuePosition))
                return 'OK'
            log.general.Log('LLV Reading Client Crypto Context', log.LGINFO)
            keyVersion, request = clientCryptoContextPacket
            if keyVersion != getattr(macho, 'publicKeyVersion', 'placebo'):
                log.general.Log(
                    'Handshake Failed - Public Key Mismatch - Public Key Version is %s but should be %s'
                    % (keyVersion, getattr(macho, 'publicKeyVersion',
                                           'placebo')), log.LGERR)
                self.Close(
                    localization.GetByLabel(
                        '/Carbon/GPS/IncompatiblePublicKey'),
                    'HANDSHAKE_INCOMPATIBLEPUBLICKEY')
                return 'ERR'
            log.general.Log('LLV Initializing Crypto Context', log.LGINFO)
            request = self.cryptoContext.Initialize(request)
            if type(request) != types.DictType:
                self.Close('Handshake Failed - ' + request)
                return 'ERR'
            self.UnEncryptedWrite(macho.Dumps('OK CC'))
            passwordVersion = 0
            userName = None
            passwordVersionOK = False
            passwordVersionAttempteRemaining = 2
            while not passwordVersionOK:
                if passwordVersionAttempteRemaining < 1:
                    self.Close('Password version handshake failure')
                    return 'ERR'
                passwordVersionAttempteRemaining -= 1
                log.general.Log('LLV Reading Secure Client Handshake',
                                log.LGINFO)
                message = (localization.GetByLabel(
                    '/Carbon/GPS/ConnectionTimeoutNoCompatibilityHandshake'),
                           'HANDSHAKE_TIMEOUT_CLIENTSECUREHANDSHAKE')
                clientChallenge, request2 = macho.Loads(
                    self.ApplyWithTimeout(self.EncryptedRead, (),
                                          message=message))
                request.update(request2)
                log.general.Log('LLV Verifying Secure Client Handshake',
                                log.LGINFO)
                for k in self.__mandatory_fields__:
                    if k not in request:
                        self.Close('Handshake corrupt, missing %s' % k)
                        return 'ERR'

                if passwordVersion == 0 or userName != request['user_name']:
                    passwordVersion = 2
                    userName = request['user_name']
                if passwordVersionAttempteRemaining == 1:
                    log.general.Log('LLV Writing password version', log.LGINFO)
                    self.EncryptedWrite(macho.Dumps(passwordVersion))
                if passwordVersion == 1:
                    if request['user_password'] is not None:
                        passwordVersionOK = True
                else:
                    passwordVersionOK = True

            log.general.Log('LLV Performing Version Check', log.LGINFO)
            if str(boot.region) != request['boot_region']:
                log.general.Log(
                    'Handshake Failed - Boot Region Mismatch - Boot Region is %s but should be %s'
                    % (request['boot.region'], str(boot.region)), log.LGERR)
                self.Close(
                    localization.GetByLabel('/Carbon/GPS/IncompatibleRegion'),
                    'HANDSHAKE_INCOMPATIBLEREGION')
                return 'ERR'
            if str(boot.codename) != request['boot_codename']:
                log.general.Log(
                    'Handshake Failed - Boot Code Name Mismatch - Boot Code Name is %s but should be %s'
                    % (request['boot.codeName'], str(boot.codename)),
                    log.LGERR)
                self.Close(
                    localization.GetByLabel('/Carbon/GPS/IncompatibleRelease'),
                    'HANDSHAKE_INCOMPATIBLERELEASE')
                return 'ERR'
            if boot.version != request['boot_version']:
                log.general.Log(
                    'Handshake Failed - Boot Version Mismatch - Boot Version is %s but should be %s'
                    % (request['boot.version'], boot.version), log.LGERR)
                self.Close(
                    localization.GetByLabel('/Carbon/GPS/IncompatibleVersion'),
                    'HANDSHAKE_INCOMPATIBLEVERSION')
                return 'ERR'
            if macho.version != request['macho_version']:
                log.general.Log(
                    'Handshake Failed - Macho Version Mismatch - Macho Version is %s but should be %s'
                    % (request['macho.version'], macho.version), log.LGERR)
                self.Close(
                    localization.GetByLabel(
                        '/Carbon/GPS/IncompatibleProtocol'),
                    'HANDSHAKE_INCOMPATIBLEPROTOCOL')
                return 'ERR'
            if boot.build > request['boot_build']:
                log.general.Log(
                    'Handshake Failed - Boot Build Mismatch - Boot Build is %s but should be at least %s'
                    % (request['boot.build'], boot.build), log.LGERR)
                self.Close(
                    localization.GetByLabel('/Carbon/GPS/IncompatibleBuild'),
                    'HANDSHAKE_INCOMPATIBLEBUILD')
                return 'ERR'
            if len(clientChallenge) != self.handShakePaddingLength:
                self.Close(
                    localization.GetByLabel(
                        '/Carbon/GPS/IncorrentHandshakePadding',
                        current=len(clientChallenge),
                        expected=self.handShakePaddingLength))
                return 'ERR'
            handShakeHash = Crypto.CryptoHash(clientChallenge)
            try:
                globalConfig = sm.GetService('machoNet').GetGlobalConfig()
            except:
                log.LogException()
                globalConfig = {}

            log.general.Log('LLV Generating Server Challenge', log.LGINFO)
            dict = {
                'challenge_responsehash': handShakeHash,
                'macho_version': macho.version,
                'boot_version': boot.version,
                'boot_build': boot.build,
                'boot_codename': str(boot.codename),
                'boot_region': str(boot.region),
                'cluster_usercount': loggedOnUserCount,
                'proxy_nodeid': sm.GetService('machoNet').GetNodeID(),
                'user_logonqueueposition': logonQueuePosition,
                'config_vals': globalConfig
            }
            serverChallenge = Crypto.GetRandomBytes(
                self.handShakePaddingLength)
            log.general.Log('LLV Crypting Server Challenge', log.LGINFO)
            import handshake
            code = marshal.dumps(handshake.GetHandshakeFunc())
            ch = (serverChallenge, Crypto.Sign(code), {}, dict)
            log.general.Log('LLV Writing Server Challenge', log.LGINFO)
            self.EncryptedWrite(macho.Dumps(ch))
            if not request['user_name'] or not (
                    request['user_password'] or
                    request['user_password_hash']) or logonQueuePosition > 1:
                return 'OK'
            if vipKey and vipKey != Crypto.CryptoHash(
                    util.CaseFold(request['user_name'] or '')):
                self.Close(
                    localization.GetByLabel(
                        '/Carbon/GPS/HandshakeFailedVIPKey'))
                return 'ERR'
            log.general.Log('LLV Reading Client Challenge-Response',
                            log.LGINFO)
            message = (localization.GetByLabel(
                '/Carbon/GPS/ConnectionTimeoutClientTimeout'),
                       'HANDSHAKE_TIMEOUT_CLIENTRESPONSETOSERVERCHALLENGE')
            challengeResponse, funcOutput, funcResult = macho.Loads(
                self.ApplyWithTimeout(self.EncryptedRead, (), message=message))
            if challengeResponse != Crypto.CryptoHash(serverChallenge):
                self.Close(
                    localization.GetByLabel(
                        '/Carbon/GPS/HandshakeFailedHashMismatch'))
                return 'ERR'
            verification = handshake.Verify(funcOutput, funcResult, request)
            if verification is not None:
                self.Close(
                    localization.GetByLabel(
                        '/Carbon/GPS/HandshakeFailedVerificationFailure',
                        verification=verification),
                    'HANDSHAKE_FAILEDVERIFICATION')
                return 'ERR'
            request['handshakefunc_output'] = funcOutput
            request['handshakefunc_result'] = funcResult
            try:
                authenticationResult = sm.GetService('machoNet').Authenticate(
                    self, request, sessionID)
                request.update(authenticationResult)
            except UserRejectedByVIP:
                if not sm.GetService('machoNet').IsClusterShuttingDown():
                    log.general.Log(
                        "Handshake Failed - VIP Check - The cluster is running in VIP mode, and you're not kewl",
                        log.LGINFO)
                self.Close(
                    localization.GetByLabel(
                        '/Carbon/GPS/NotAcceptingConnections'),
                    'ACL_NOTACCEPTING')
                return 'OK'
            except UserError as e:
                self.Close(e.msg, e.msg, e.dict)
                return 'ERR'
            except RuntimeError as e:
                self.Close(e.msg, e.msg, e.dict)
                return 'ERR'
            except Exception:
                log.LogException('Handshake Failed - Server Failure')
                self.Close(
                    localization.GetByLabel(
                        '/Carbon/GPS/HandshakeFailedServerFailure'))
                return 'ERR'

            authenticationResult['live_updates'] = sm.GetService(
                'liveUpdateMgr').GetLiveUpdates(request)
            authenticationResult['client_hash'] = sm.GetService(
                'machoNet').GetValidClientCodeHash()
            log.general.Log('LLV Writing Server Challenge-Response-Ack',
                            log.LGINFO)
            self.EncryptedWrite(macho.Dumps(authenticationResult))
            log.general.Log('LLV Succeeded', log.LGINFO)
            self.handShake = request
            return request
        finally:
            Leave(timer)
Exemplo n.º 4
0
    def Read(self):
        self.currentReaders += 1
        try:
            thePickle = self.transport.Read()
        finally:
            self.currentReaders -= 1

        if getattr(self, 'userID', None) and len(thePickle) > 100000:
            self.machoNet.LogWarn(
                'Read a ', len(thePickle),
                ' byte packet (before decompression) from userID=',
                getattr(self, 'userID',
                        'non-user'), ' on address ', self.transport.address)
        elif len(thePickle) > 5000000:
            self.machoNet.LogWarn(
                'Read a ', len(thePickle),
                ' byte packet (before decompression) from userID=',
                getattr(self, 'userID',
                        'non-user'), ' on address ', self.transport.address)
        if thePickle[0] not in '}~':
            before = len(thePickle)
            try:
                with bluepy.Timer(
                        'machoNet::MachoTransport::Read::DeCompress'):
                    thePickle = zlib.decompress(thePickle)
            except zlib.error as e:
                raise RuntimeError('Decompression Failure: ' + strx(e))

            after = len(thePickle)
            if after <= before:
                self.machoNet.LogError('Decompress shrank data from ', before,
                                       ' to ', after, ' bytes')
            else:
                self.machoNet.decompressedBytes.Add(after - before)
        if getattr(self, 'userID', None) and len(thePickle) > 100000:
            self.machoNet.LogWarn(
                'Read a ', len(thePickle),
                ' byte packet (after decompression, if appropriate) from userID=',
                getattr(self, 'userID',
                        'non-user'), ' on address ', self.transport.address)
        elif len(thePickle) > 5000000:
            self.machoNet.LogWarn(
                'Read a ', len(thePickle),
                ' byte packet (after decompression, if appropriate) from userID=',
                getattr(self, 'userID',
                        'non-user'), ' on address ', self.transport.address)
        if self.clientID:
            self.machoNet.dataReceived.Add(len(thePickle))
        else:
            self.machoNet.dataReceived.AddFrom(self.nodeID, len(thePickle))
        try:
            message = macho.Loads(thePickle)
        except GPSTransportClosed as e:
            self.transport.Close(**e.GetCloseArgs())
            raise
        except StandardError:
            if self.transportName == 'tcp:packet:client':
                self._LogPotentialAttackAndClose(thePickle)
            raise

        message.SetPickle(thePickle)
        if macho.mode == 'client' and message.source.addressType == const.ADDRESS_TYPE_NODE and message.destination.addressType == const.ADDRESS_TYPE_BROADCAST:
            message.oob['sn'] = self.machoNet.notifySequenceIDByNodeID[
                message.source.nodeID]
            self.machoNet.notifySequenceIDByNodeID[message.source.nodeID] += 1
        if self.transportName == 'tcp:packet:client':
            message.source = MachoAddress(clientID=self.clientID,
                                          callID=message.source.callID)
            if message.contextKey is not None or message.applicationID is not None or message.languageID is not None:
                self._LogPotentialAttackAndClose(thePickle)
                raise StandardError(
                    'Packet containing contextKey received on a client transport. Hack?'
                )
        if hasattr(self, 'userID'):
            message.userID = self.userID
        if message.command != const.cluster.MACHONETMSG_TYPE_MOVEMENTNOTIFICATION or MACHONET_LOGMOVEMENT:
            self.LogInfo('Read: ', message)
        if macho.mode == 'proxy':
            for objectID, refID in message.oob.get('OID-', {}).iteritems():
                s = self.sessions.get(self.clientID, None)
                if s is None:
                    s = self.sessions.get(self.nodeID, None)
                if s is not None:
                    s.UnregisterMachoObject(objectID, refID)

        if macho.mode == 'server':
            ls = localstorage.GetLocalStorage()
            ls['applicationID'] = message.applicationID
            ls['languageID'] = message.languageID
        return message