Пример #1
0
    def fail_bad_negotiation(self, reason, fields=None):
        '''sends an error and cancels everything.

if fields is None, the remote party has given us a bad cryptographic value of some kind

otherwise, list the fields we haven't implemented'''

        err = xmpp.Error(xmpp.Message(), xmpp.ERR_FEATURE_NOT_IMPLEMENTED)
        err.T.error.T.text.setData(reason)

        if fields:
            feature = xmpp.Node(xmpp.NS_FEATURE + ' feature')

            for field in fields:
                fn = xmpp.Node('field')
                fn['var'] = field
                feature.addChild(node=feature)

            err.addChild(node=feature)

        self.send(err)

        self.status = None
        self.enable_encryption = False

        # this prevents the MAC check on decryption from succeeding,
        # preventing falsified messages from going through.
        self.km_o = ''
Пример #2
0
def user_send_nickname(account, nick):
    if not gajim.connections[account].pep_supported:
        return
    item = xmpp.Node('nick', {'xmlns': xmpp.NS_NICK})
    item.addData(nick)

    gajim.connections[account].send_pb_publish('', xmpp.NS_NICK, item, '0')
Пример #3
0
def user_send_tune(account,
                   artist='',
                   title='',
                   source='',
                   track=0,
                   length=0,
                   items=None):
    if not (gajim.config.get_per('accounts', account, 'publish_tune') and \
    gajim.connections[account].pep_supported):
        return
    item = xmpp.Node('tune', {'xmlns': xmpp.NS_TUNE})
    if artist != '':
        i = item.addChild('artist')
        i.addData(artist)
    if title != '':
        i = item.addChild('title')
        i.addData(title)
    if source != '':
        i = item.addChild('source')
        i.addData(source)
    if track != 0:
        i = item.addChild('track')
        i.addData(track)
    if length != 0:
        i = item.addChild('length')
        i.addData(length)
    if items is not None:
        item.addChild(payload=items)

    gajim.connections[account].send_pb_publish('', xmpp.NS_TUNE, item, '0')
Пример #4
0
def user_send_activity(account, activity, subactivity='', message=''):
    if not gajim.connections[account].pep_supported:
        return
    item = xmpp.Node('activity', {'xmlns': xmpp.NS_ACTIVITY})
    if activity != '':
        i = item.addChild(activity)
    if subactivity != '':
        i.addChild(subactivity)
    if message != '':
        i = item.addChild('text')
        i.addData(message)

    gajim.connections[account].send_pb_publish('', xmpp.NS_ACTIVITY, item, '0')
Пример #5
0
def user_send_mood(account, mood, message=''):
    if not gajim.connections[account].pep_supported:
        return
    item = xmpp.Node('mood', {'xmlns': xmpp.NS_MOOD})
    if mood != '':
        if mood in GAJIM_MOODS:
            ns = 'http://gajim.org/moods'
        else:
            ns = None
        item.addChild(mood, namespace=ns)
    if message != '':
        i = item.addChild('text')
        i.addData(message)

    gajim.connections[account].send_pb_publish('', xmpp.NS_MOOD, item, '0')
Пример #6
0
    def on_send_button_clicked(self, w):
        '''Gather info from widgets and send it as a message.'''
        # constructing item to publish... that's atom:entry element
        item = xmpp.Node('entry', {'xmlns': 'http://www.w3.org/2005/Atom'})
        author = item.addChild('author')
        author.addChild('name', {}, [self.from_entry.get_text()])
        item.addChild('generator', {}, ['Gajim'])
        item.addChild('title', {}, [self.subject_entry.get_text()])
        item.addChild('id', {}, ['0'])

        buffer = self.contents_textview.get_buffer()
        item.addChild(
            'content', {},
            [buffer.get_text(buffer.get_start_iter(), buffer.get_end_iter())])

        # publish it to node
        gajim.connections[self.account].send_pb_publish(
            self.servicejid, self.groupid, item, '0')

        # close the window
        self.window.destroy()
Пример #7
0
    def decrypt_stanza(self, stanza):
        # delete the unencrypted explanation body, if it exists
        orig_body = stanza.getTag('body')
        if orig_body:
            stanza.delChild(orig_body)

        c = stanza.getTag(
            name='c',
            namespace='http://www.xmpp.org/extensions/xep-0200.html#ns')

        stanza.delChild(c)

        # contents of <c>, minus <mac>, minus whitespace
        macable = ''.join(
            map(str, filter(lambda x: x.getName() != 'mac', c.getChildren())))

        received_mac = base64.b64decode(c.getTagData('mac'))
        calculated_mac = self.hmac(self.km_o, macable + \
         crypto.encode_mpi_with_padding(self.c_o))

        if not calculated_mac == received_mac:
            raise exceptions.DecryptionError, 'bad signature'

        m_final = base64.b64decode(c.getTagData('data'))
        m_compressed = self.decrypt(m_final)
        plaintext = self.decompress(m_compressed)

        try:
            parsed = xmpp.Node(node='<node>' + plaintext + '</node>')
        except Exception:
            raise exceptions.DecryptionError, 'decrypted <data/> not parseable as XML'

        for child in parsed.getChildren():
            stanza.addChild(node=child)

        return stanza
Пример #8
0
    def respond_e2e_bob(self, form, negotiated, not_acceptable):
        response = xmpp.Message()
        feature = response.NT.feature
        feature.setNamespace(xmpp.NS_FEATURE)

        x = xmpp.DataForm(typ='submit')

        x.addChild(node=xmpp.DataField(name='FORM_TYPE', value='urn:xmpp:ssn'))
        x.addChild(node=xmpp.DataField(name='accept', value='true'))

        for name in negotiated:
            # some fields are internal and should not be sent
            if not name in ('send_pubkey', 'recv_pubkey'):
                x.addChild(
                    node=xmpp.DataField(name=name, value=negotiated[name]))

        self.negotiated = negotiated

        # the offset of the group we chose (need it to match up with the dhhash)
        group_order = 0
        self.modp = int(form.getField('modp').getOptions()[group_order][1])
        x.addChild(node=xmpp.DataField(name='modp', value=self.modp))

        g = dh.generators[self.modp]
        p = dh.primes[self.modp]

        self.n_o = base64.b64decode(form['my_nonce'])

        dhhashes = form.getField('dhhashes').getValues()
        self.negotiated['He'] = base64.b64decode(
            dhhashes[group_order].encode('utf8'))

        bytes = int(self.n / 8)

        self.n_s = crypto.generate_nonce()

        # n-bit random number
        self.c_o = crypto.decode_mpi(crypto.random_bytes(bytes))
        self.c_s = self.c_o ^ (2**(self.n - 1))

        self.y = crypto.srand(2**(2 * self.n - 1), p - 1)
        self.d = crypto.powmod(g, self.y, p)

        to_add = {
            'my_nonce': self.n_s,
            'dhkeys': crypto.encode_mpi(self.d),
            'counter': crypto.encode_mpi(self.c_o),
            'nonce': self.n_o
        }

        for name in to_add:
            b64ed = base64.b64encode(to_add[name])
            x.addChild(node=xmpp.DataField(name=name, value=b64ed))

        self.form_o = ''.join(
            map(lambda el: xmpp.c14n.c14n(el), form.getChildren()))
        self.form_s = ''.join(
            map(lambda el: xmpp.c14n.c14n(el), x.getChildren()))

        self.status = 'responded-e2e'

        feature.addChild(node=x)

        if not_acceptable:
            response = xmpp.Error(response, xmpp.ERR_NOT_ACCEPTABLE)

            feature = xmpp.Node(xmpp.NS_FEATURE + ' feature')

            for f in not_acceptable:
                n = xmpp.Node('field')
                n['var'] = f
                feature.addChild(node=n)

            response.T.error.addChild(node=feature)

        self.send(response)
Пример #9
0
    def verify_identity(self, form, dh_i, sigmai, i_o):
        m_o = base64.b64decode(form['mac'])
        id_o = base64.b64decode(form['identity'])

        m_o_calculated = self.hmac(self.km_o,
                                   crypto.encode_mpi(self.c_o) + id_o)

        if m_o_calculated != m_o:
            raise exceptions.NegotiationError, 'calculated m_%s differs from received m_%s' % (
                i_o, i_o)

        if i_o == 'a' and self.sas_algs == 'sas28x5':
            # we don't need to calculate this if there's a verified retained secret
            # (but we do anyways)
            self.sas = crypto.sas_28x5(m_o, self.form_s)

        if self.negotiated['recv_pubkey']:
            plaintext = self.decrypt(id_o)
            parsed = xmpp.Node(node='<node>' + plaintext + '</node>')

            if self.negotiated['recv_pubkey'] == 'hash':
                fingerprint = parsed.getTagData('fingerprint')

                # XXX find stored pubkey or terminate session
                raise 'unimplemented'
            else:
                if self.negotiated['sign_algs'] == (XmlDsig + 'rsa-sha256'):
                    keyvalue = parsed.getTag(name='RSAKeyValue',
                                             namespace=XmlDsig)

                    n, e = map(
                        lambda x: crypto.decode_mpi(
                            base64.b64decode(keyvalue.getTagData(x))),
                        ('Modulus', 'Exponent'))
                    eir_pubkey = RSA.construct((n, long(e)))

                    pubkey_o = xmpp.c14n.c14n(keyvalue)
                else:
                    # XXX DSA, etc.
                    raise 'unimplemented'

            enc_sig = parsed.getTag(name='SignatureValue',
                                    namespace=XmlDsig).getData()
            signature = (crypto.decode_mpi(base64.b64decode(enc_sig)), )
        else:
            mac_o = self.decrypt(id_o)
            pubkey_o = ''

        c7l_form = self.c7lize_mac_id(form)

        content = self.n_s + self.n_o + crypto.encode_mpi(dh_i) + pubkey_o

        if sigmai:
            self.form_o = c7l_form
            content += self.form_o
        else:
            form_o2 = c7l_form
            content += self.form_o + form_o2

        mac_o_calculated = self.hmac(self.ks_o, content)

        if self.negotiated['recv_pubkey']:
            hash = crypto.sha256(mac_o_calculated)

            if not eir_pubkey.verify(hash, signature):
                raise exceptions.NegotiationError, 'public key signature verification failed!'

        elif mac_o_calculated != mac_o:
            raise exceptions.NegotiationError, 'calculated mac_%s differs from received mac_%s' % (
                i_o, i_o)