Beispiel #1
0
    def disable(self, url, server):
        resp = baseconv.decodeNameValue(server)
        tif = int(resp['tif'], 16)

        client  = "ver=1\r\n"
        client += "cmd=disable\r\n"
        client += "idk=%s\r\n" % self.enc.getPublicKey(url.getDomain())
        client = baseconv.encode(client)

        ids = self.enc.sign(client + server)

        url = URLParser(url.scheme + "://" + url.netloc + resp['qry'])
        success, data = self._post_form(url, "client=%s&server=%s&ids=%s" % (client, server, ids))
        logging.debug("client")
        for param in baseconv.decode(client).rstrip('\r\n').split('\r\n'):
            logging.debug('  %r', param)
        logging.debug("server")
        for param in baseconv.decode(server).rstrip('\r\n').split('\r\n'):
            logging.debug('  %r', param)
        logging.debug('  ids    %r', ids)

        if success:
            resp = baseconv.decodeNameValue(data)
            logging.debug("resp %r", resp)

            tif = int(resp['tif'], 16)
            if tif & 0x10 == 0x10:
                return False, "0x10 Function(s) not supported"

            if tif & 0x08 == 0x08:
                return True, "0x08 SQRL disabled"
        return False, data
Beispiel #2
0
    def _check_signature(self, idk, client, server, ids):
        verifying_key = ed25519.VerifyingKey(baseconv.decode(idk))

        try:
            verifying_key.verify(baseconv.decode(ids), str(client + server))
            return True
        except ed25519.BadSignatureError:
            return False
Beispiel #3
0
    def ident(self, url, server):
        resp = baseconv.decodeNameValue(server)
        tif = int(resp['tif'], 16)

        client  = "ver=1\r\n"
        client += "cmd=ident\r\n"
        client += "idk=%s\r\n" % self.enc.getPublicKey(url.getDomain())
        if self.cps:
            client += "opt=cps\r\n"
        if tif & 0x01 == 0x00:
            client += "suk=dMRXbs49XNmVUhsKzta7ESD-cP2QlnxkSaORsswOAj4\r\n" # TODO: ehhh...
            client += "vuk=q13E_hd5CR0WE0A9ZD8571te0Ul47YfsDCWpETuCGcI\r\n" # TODO: ehhh...
        client = baseconv.encode(client)

        ids = self.enc.sign(client + server)

        url = URLParser(url.scheme + "://" + url.netloc + resp['qry'])
        success, data = self._post_form(url, "client=%s&server=%s&ids=%s" % (client, server, ids))
        logging.debug("client")
        for param in baseconv.decode(client).rstrip('\r\n').split('\r\n'):
            logging.debug('  %r', param)
        logging.debug("server")
        for param in baseconv.decode(server).rstrip('\r\n').split('\r\n'):
            logging.debug('  %r', param)
        logging.debug('  ids    %r', ids)

        if success:
            resp = baseconv.decodeNameValue(data)
            logging.debug("resp %r", resp)

            tif = int(resp['tif'], 16)
            if tif & 0x08 == 0x08:
                return False, "0x08 SQRL disabled"
            if tif & 0x10 == 0x10:
                return False, "0x10 Function(s) not supported"
            #if tif > 0x04: # TODO: Check tif failure values
            #    return False, "Tif 0x%02x" % tif

            if 'url' in resp:
                return True, resp['url']
            else:
                return True, None
        return False, data
Beispiel #4
0
    def post(self, client_str, server_str, ids, sqrl_callback):
        client_str = str(client_str) # TODO(vw): Do we want to support u'nicode' or just convert?
        server_str = str(server_str) # TODO(vw): Do we want to support u'nicode' or just convert?
        client = baseconv.decodeNameValue(client_str)
        server = baseconv.decodeNameValue(server_str)
        cmd    = self._get_value(client, 'cmd')
        idk    = self._get_value(client, 'idk')

        logging.info("cmd: %r", cmd)
        logging.debug('client:')
        for key, value in client.iteritems():
            logging.debug("  %r: %r", key, value)
        logging.debug('server:')
        for key, value in server.iteritems():
            logging.debug("  %r: %r", key, value)
        logging.debug('ids:')
        logging.debug("  %r", ids)

        tif = 0
        tif ^= 4 # TODO: Check if IP matches
        session_id = None

        if not self._check_signature(idk, client_str, server_str, ids):
            logging.warn("signature failed")
            tif ^= 80 # We always included a session_id, so something has gone wrong
        elif cmd == 'query':
            session_id = self._get_url_nut(baseconv.decode(server_str))
            if sqrl_callback.id_found(idk):
                tif ^= 1
        elif cmd == 'ident':
            session_id  = self._get_value(server, 'session_id')
            if not session_id:
                tif ^= 80 # We always included a session_id, so something has gone wrong
            else:
                if sqrl_callback.id_found(idk):
                    tif ^= 1
                suk = self._get_value(server, 'suk') # TODO: Can be ''
                vuk = self._get_value(server, 'vuk')
                sqrl_callback.ident(session_id, idk, suk, vuk)
        else:
            tif ^= 10 # Not supported

        new_nut = get_nut()
        server  = "ver=1\r\n"
        server += "nut=%s\r\n" % new_nut
        server += "qry=/sqrl?nut=%s\r\n" % new_nut
        server += "tif=%x\r\n" % tif
        if session_id:
            server += "session_id=%s\r\n" % session_id
        logging.debug('response')
        for param in server.split('\r\n')[:-1]:
            logging.debug('  %r', param)
        return server
Beispiel #5
0
    def query(self, url, server, automatic_retry=True):
        client  = "ver=1\r\n"
        client += "cmd=query\r\n"
        client += "idk=%s\r\n" % self.enc.getPublicKey(url.getDomain())
        if self.cps:
            client += "opt=cps\r\n"
        client = baseconv.encode(client)

        ids = self.enc.sign(client + server)

        success, data = self._post_form(url, "client=%s&server=%s&ids=%s" % (client, server, ids))
        logging.debug("client")
        for param in baseconv.decode(client).rstrip('\r\n').split('\r\n'):
            logging.debug('  %r', param)
        logging.debug("server")
        for param in baseconv.decode(server).rstrip('\r\n').split('\r\n'):
            logging.debug('  %r', param)
        logging.debug('  ids    %r', ids)

        if success:
            resp = baseconv.decodeNameValue(data)
            logging.debug("resp %r", resp)
            tif = int(resp['tif'], 16)
            if tif & 0x01 == 0x01:
                logging.info("ID match")
            if tif & 0x04 == 0x04:
                logging.info("IP matched")
            #if tif > 0x04: # TODO: Check tif failure values
            #    logging.warn("Problems with query, tif 0x%02x", tif)

            if tif & 0x20 == 0x20:
                if automatic_retry:
                    logging.debug("0x20 Transient error. Trying again")
                    url = URLParser(url.scheme + "://" + url.netloc + resp['qry'])
                    return self.query(url, data, False)
        return success, data
Beispiel #6
0
 def test_decode_unicode(self):
     self.assertEqual(baseconv.decode(u"YWJjZA"), 'abcd')
Beispiel #7
0
 def test_decode_padding_added_back(self):
     self.assertEqual(baseconv.decode("YWJjZA"), 'abcd')
     self.assertEqual(baseconv.decode("YWJjZGU"), 'abcde')
Beispiel #8
0
 def test_decode_no_padding(self):
     self.assertEqual(baseconv.decode("YWJj"), 'abc')