Example #1
0
def getRecipientsPreKeyList(number):

    print('Getting recipients prekey')

    #get auth data
    phone_number = config.getConfigOption('phone_number').decode('utf-8')
    password = config.getConfigOption('password').decode('utf-8')

    r = requests.get(URL_BASE + '/v1/keys/' + number + '/*',
                     headers=headers,
                     auth=(phone_number, password))

    if r.status_code == 401:
        raise ServerError(r.status_code, 'Invalid authentication credentials.')
    elif r.status_code == 404:
        raise ServerError(r.status_code, 'Unknown/unregistered number.')
    elif r.status_code == 413:
        raise ServerError(r.status_code, 'Rate limit exceeded.')
    elif r.status_code in (200, 204):

        RecipientPreKeyUtil().saveRecipientPreKey(
            number, json.loads(r.content.decode('utf-8')))

        preKeyList = createPreKeyListFromJson(r.content)

        return preKeyList
Example #2
0
def getContactIntersection(contacts):

    #get auth data
    phone_number = config.getConfigOption('phone_number').decode('utf-8')
    password = config.getConfigOption('password').decode('utf-8')

    contacts = [ '+611231231234', '+611231231235' ]
    tokens = []
    for contact in contacts:
        thash = hashlib.sha1(contact.encode('utf-8')).digest()[0:10]
        tokens.append(base64.b64encode(thash).decode('utf-8').rstrip('='))

    data = { 'contacts' : tokens }

    r = requests.put( URL_BASE + '/v1/directory/tokens',
                     headers=headers,
                     auth=(phone_number, password),
                     data=json.dumps(data) )

    if r.status_code == 400:
        raise ServerError(r.status_code, 'Badly formatted tokens.')
    if r.status_code == 401:
        raise ServerError(r.status_code, 'Invalid authentication credentials.')
    elif r.status_code == 415:
        raise ServerError(r.status_code, 'Badly formatted JSON.')
    elif r.status_code in (200, 204):
        print(r.content)
        return r.content
Example #3
0
def getContactIntersection(contacts):

    #get auth data
    phone_number = config.getConfigOption('phone_number').decode('utf-8')
    password = config.getConfigOption('password').decode('utf-8')

    contacts = ['+611231231234', '+611231231235']
    tokens = []
    for contact in contacts:
        thash = hashlib.sha1(contact.encode('utf-8')).digest()[0:10]
        tokens.append(base64.b64encode(thash).decode('utf-8').rstrip('='))

    data = {'contacts': tokens}

    r = requests.put(URL_BASE + '/v1/directory/tokens',
                     headers=headers,
                     auth=(phone_number, password),
                     data=json.dumps(data))

    if r.status_code == 400:
        raise ServerError(r.status_code, 'Badly formatted tokens.')
    if r.status_code == 401:
        raise ServerError(r.status_code, 'Invalid authentication credentials.')
    elif r.status_code == 415:
        raise ServerError(r.status_code, 'Badly formatted JSON.')
    elif r.status_code in (200, 204):
        print(r.content)
        return r.content
Example #4
0
def getRecipientsPreKeyList(number):

    print('Getting recipients prekey')

    #get auth data
    phone_number = config.getConfigOption('phone_number').decode('utf-8')
    password = config.getConfigOption('password').decode('utf-8')

    r = requests.get(URL_BASE + '/v1/keys/' + number + '/*',
                     headers=headers,
                     auth=(phone_number, password))

    if r.status_code == 401:
        raise ServerError(r.status_code, 'Invalid authentication credentials.')
    elif r.status_code == 404:
        raise ServerError(r.status_code, 'Unknown/unregistered number.')
    elif r.status_code == 413:
        raise ServerError(r.status_code, 'Rate limit exceeded.')
    elif r.status_code in (200, 204):

        RecipientPreKeyUtil().saveRecipientPreKey(number, json.loads(r.content.decode('utf-8')))

        preKeyList = createPreKeyListFromJson(r.content)

        return preKeyList
Example #5
0
def registerPreKeys():

    #get auth data
    phone_number = config.getConfigOption('phone_number').decode('utf-8')
    password = config.getConfigOption('password').decode('utf-8')

    #generate keys
    PreKeyUtil().generatePreKeys()
    PreKeyUtil().generateLastResortKey()
    IdentityKeyUtil().generateIdentityKey()

    records = PreKeyUtil().getPreKeys()

    preKeys = list()
    for preKey in records:
        preKeys.append({
            'keyId':
            preKey.keyId,
            'publicKey':
            base64.b64encode(b'\x05' + preKey.publicKey).decode("utf-8"),
            'identityKey':
            base64.b64encode(
                b'\x05' + IdentityKeyUtil().getIdentityKey()).decode("utf-8")
        })

    lastResortKey = PreKeyUtil().getLastResortKey()
    lastResortKeyDict = {
        'keyId':
        lastResortKey.keyId,
        'publicKey':
        base64.b64encode(b'\x05' + lastResortKey.publicKey).decode("utf-8"),
        'identityKey':
        base64.b64encode(b'\x05' +
                         IdentityKeyUtil().getIdentityKey()).decode("utf-8")
    }

    data = {'lastResortKey': lastResortKeyDict, 'keys': preKeys}

    r = requests.put(URL_BASE + '/v1/keys/',
                     headers=headers,
                     auth=(phone_number, password),
                     data=json.dumps(data))

    if r.status_code == 401:
        raise ServerError(r.status_code, 'Invalid authentication credentials.')
    elif r.status_code == 415:
        raise ServerError(r.status_code, 'Badly formatted JSON.')
    elif r.status_code in (200, 204):
        return
Example #6
0
def start_gcm(GUIObject):

    #get config here to prevent reading from database in a thread
    androidId = int(config.getConfigOption('gcmandroidId'))
    securityToken = int(config.getConfigOption('gcmsecurityToken'))

    threading.Thread(target=connectGCM,
                     args=(androidId,
                           securityToken, ),
                     daemon=True,
    ).start()

    threading.Thread(target=handle_queue,
                     args=(GUIObject, ),
                     daemon=True,
    ).start()
Example #7
0
def registerGCMid():

    regid = config.getConfigOption('gcmregid').decode('utf-8')
    phone_number = config.getConfigOption('phone_number').decode('utf-8')
    password = config.getConfigOption('password').decode('utf-8')

    data = {'gcmRegistrationId': regid}

    r = requests.put(URL_BASE + '/v1/accounts/gcm/',
                     headers=headers,
                     auth=(phone_number, password),
                     data=json.dumps(data))

    if r.status_code == 401:
        raise ServerError(r.status_code, 'Invalid authentication credentials.')
    elif r.status_code == 415:
        raise ServerError(r.status_code, 'Badly formatted JSON.')
    elif r.status_code in (200, 204):
        return r.content
Example #8
0
def registerPreKeys():

    #get auth data
    phone_number = config.getConfigOption('phone_number').decode('utf-8')
    password = config.getConfigOption('password').decode('utf-8')

    #generate keys
    PreKeyUtil().generatePreKeys()
    PreKeyUtil().generateLastResortKey()
    IdentityKeyUtil().generateIdentityKey()

    records = PreKeyUtil().getPreKeys()

    preKeys = list()
    for preKey in records:
        preKeys.append(
            {
                'keyId' : preKey.keyId,
                'publicKey' : base64.b64encode(b'\x05' + preKey.publicKey).decode("utf-8"),
                'identityKey' : base64.b64encode(b'\x05' + IdentityKeyUtil().getIdentityKey()).decode("utf-8")
            }
        )

    lastResortKey = PreKeyUtil().getLastResortKey()
    lastResortKeyDict = {
                'keyId' : lastResortKey.keyId,
                'publicKey' : base64.b64encode(b'\x05' + lastResortKey.publicKey).decode("utf-8"),
                'identityKey' : base64.b64encode(b'\x05' + IdentityKeyUtil().getIdentityKey()).decode("utf-8")
            }

    data = { 'lastResortKey' : lastResortKeyDict , 'keys' : preKeys}

    r = requests.put( URL_BASE + '/v1/keys/',
                     headers=headers,
                     auth=(phone_number, password),
                     data=json.dumps(data) )

    if r.status_code == 401:
        raise ServerError(r.status_code, 'Invalid authentication credentials.')
    elif r.status_code == 415:
        raise ServerError(r.status_code, 'Badly formatted JSON.')
    elif r.status_code in (200, 204):
        return
Example #9
0
def registerGCMid():

    regid = config.getConfigOption('gcmregid').decode('utf-8')
    phone_number = config.getConfigOption('phone_number').decode('utf-8')
    password = config.getConfigOption('password').decode('utf-8')

    data = { 'gcmRegistrationId' : regid }

    r = requests.put( URL_BASE + '/v1/accounts/gcm/',
                     headers=headers,
                     auth=(phone_number, password),
                     data=json.dumps(data)
                    )

    if r.status_code == 401:
        raise ServerError(r.status_code, 'Invalid authentication credentials.')
    elif r.status_code == 415:
        raise ServerError(r.status_code, 'Badly formatted JSON.')
    elif r.status_code in (200, 204):
        return r.content
Example #10
0
def start_gcm(GUIObject):

    #get config here to prevent reading from database in a thread
    androidId = int(config.getConfigOption('gcmandroidId'))
    securityToken = int(config.getConfigOption('gcmsecurityToken'))

    threading.Thread(
        target=connectGCM,
        args=(
            androidId,
            securityToken,
        ),
        daemon=True,
    ).start()

    threading.Thread(
        target=handle_queue,
        args=(GUIObject, ),
        daemon=True,
    ).start()
Example #11
0
def submitMessage(messages):
    #get auth data
    phone_number = config.getConfigOption('phone_number').decode('utf-8')
    password = config.getConfigOption('password').decode('utf-8')

    for message in messages.messages:

        data = {
                'messages': [{
                       'type': message.type,
                       'destinationDeviceId': 1,
                       'destinationRegistrationId': message.remoteRegistrationId,
                       'body': base64.b64encode(message.body).decode('utf-8'),
                       'timestamp': int(time.time())
                      }]
        }

        r = requests.put( URL_BASE + '/v1/messages/' + messages.destination,
                         headers=headers,
                         auth=(phone_number, password),
                         data=json.dumps(data) )

    if r.status_code == 401:
        raise ServerError(r.status_code, 'Invalid authentication credentials.')
    elif r.status_code == 409:
        #this error returns data
        raise ServerError(r.status_code, 'Mismatched devices.')
    elif r.status_code == 410:
        #this error returns data
        raise ServerError(r.status_code, 'Stale devices.')
    elif r.status_code == 413:
        raise ServerError(r.status_code, 'Rate limit exceeded.')
    elif r.status_code == 415:
        raise ServerError(r.status_code, 'Badly formatted JSON.')
    elif r.status_code in (200, 204):
        return r.content
Example #12
0
def submitMessage(messages):
    #get auth data
    phone_number = config.getConfigOption('phone_number').decode('utf-8')
    password = config.getConfigOption('password').decode('utf-8')

    for message in messages.messages:

        data = {
            'messages': [{
                'type': message.type,
                'destinationDeviceId': 1,
                'destinationRegistrationId': message.remoteRegistrationId,
                'body': base64.b64encode(message.body).decode('utf-8'),
                'timestamp': int(time.time())
            }]
        }

        r = requests.put(URL_BASE + '/v1/messages/' + messages.destination,
                         headers=headers,
                         auth=(phone_number, password),
                         data=json.dumps(data))

    if r.status_code == 401:
        raise ServerError(r.status_code, 'Invalid authentication credentials.')
    elif r.status_code == 409:
        #this error returns data
        raise ServerError(r.status_code, 'Mismatched devices.')
    elif r.status_code == 410:
        #this error returns data
        raise ServerError(r.status_code, 'Stale devices.')
    elif r.status_code == 413:
        raise ServerError(r.status_code, 'Rate limit exceeded.')
    elif r.status_code == 415:
        raise ServerError(r.status_code, 'Badly formatted JSON.')
    elif r.status_code in (200, 204):
        return r.content
def decryptMessage(message):
    signalingKey = config.getConfigOption("signalingKey")

    aes_key = signalingKey[0:32]
    mac_key = signalingKey[32:32+20]

    data = base64.b64decode(message)
    if data[0] != 1:
        raise "Got bad version number: " + str(data[0])

    iv = data[1:1+16]
    ciphertext = data[1+16: len(data) - 10]
    ivAndCipherText = data[1: len(data) - 10]
    mac = data[len(data) - 10: ]

    verifyMACWithVersionByte(ivAndCipherText, mac_key, mac)

    return decryptPaddedAES(ciphertext, aes_key, iv)
Example #14
0
def decryptMessage(message):
    signalingKey = config.getConfigOption("signalingKey")

    aes_key = signalingKey[0:32]
    mac_key = signalingKey[32:32 + 20]

    data = base64.b64decode(message)
    if data[0] != 1:
        raise "Got bad version number: " + str(data[0])

    iv = data[1:1 + 16]
    ciphertext = data[1 + 16:len(data) - 10]
    ivAndCipherText = data[1:len(data) - 10]
    mac = data[len(data) - 10:]

    verifyMACWithVersionByte(ivAndCipherText, mac_key, mac)

    return decryptPaddedAES(ciphertext, aes_key, iv)
Example #15
0
def unfoundKeyFallback(key):
    logger.info("Normal command not found: {}".format(key))
    if config.getConfigOption("swallow_unused_normal_keys"):
        return ""
    else:
        return key
Example #16
0
        for i in range(0, 200, 25):
            print(i)
            self.send("*" * i)

    def closed(self, code, reason=None):
        print("Closed down", code, reason)

    def received_message(self, m):
        print(m)
        if len(m) == 175:
            self.close(reason='Bye bye')


if __name__ == '__main__':
    try:
        phone_number = '%2B' + config.getConfigOption('phone_number').decode(
            'utf-8')[1:] + '.1'

        #need to do URL escaping!!
        password = config.getConfigOption('password').decode('utf-8')

        ws = DummyClient(
            'wss://textsecure-service.whispersystems.org/v1/websocket/?user='******'&password='******'http-only', 'chat'])
        ws.connect()
        ws.run_forever()
        print('here')
    except KeyboardInterrupt:
        ws.close()
Example #17
0
                yield "#" * i

        self.send(data_provider())

        for i in range(0, 200, 25):
            print(i)
            self.send("*" * i)

    def closed(self, code, reason=None):
        print("Closed down", code, reason)

    def received_message(self, m):
        print(m)
        if len(m) == 175:
            self.close(reason='Bye bye')

if __name__ == '__main__':
    try:
        phone_number = '%2B' + config.getConfigOption('phone_number').decode('utf-8')[1:] + '.1'

        #need to do URL escaping!!
        password = config.getConfigOption('password').decode('utf-8')

        ws = DummyClient('wss://textsecure-service.whispersystems.org/v1/websocket/?user='******'&password='******'http-only', 'chat'])
        ws.connect()
        ws.run_forever()
        print('here')
    except KeyboardInterrupt:
        ws.close()