コード例 #1
0
 def got_cancel(self, message):
     i = toint(message[1:5])
     if i >= self.torrent.numpieces:
         self.fatal_error("Piece index out of range")
         return
     if self.upload:
         self.upload.got_cancel(i, toint(message[5:9]), toint(message[9:]))
コード例 #2
0
 def got_piece(self, message):
     i = toint(message[1:5])
     if i >= self.torrent.numpieces:
         self.fatal_error("Piece index out of range")
         return
     if self.download.got_piece(i, toint(message[5:9]), message[9:]):
         for ep in self.torrent.active_streams:
             ep.send_have(i)
コード例 #3
0
 def _read_messages(self):
     yield 4
     l = toint(self._message)
     yield l
     action = self._message
     yield 4
     l = toint(self._message)
     yield l
     data = self._message
     self.callback(action, data)
コード例 #4
0
 def got_have(self, message):
     i = toint(message[1:])
     if i >= self.torrent.numpieces:
         log.error("Piece index out of range")
         self.fatal_error()
         return
     self.download.got_have(i)
コード例 #5
0
 def got_partial(self, message):
     p_remain = toint(message[1:5])
     self.partial_recv += message[5:]
     if len(self.partial_recv) > self.neighbor.config['max_message_length']:
         log.error("Received message longer than max length")
         return
     if len(message[5:]) == p_remain:
         self.got_message(self.partial_recv)
         self.partial_recv = ''
コード例 #6
0
ファイル: NeighborLink.py プロジェクト: Miserlou/Anomos
 def _read_messages(self):
     """ Read messages off the line and relay or process them
         depending on connection type """
     while True:
         yield 2 # Stream ID
         stream = toint(self._message)
         handler = self.get_stream_handler(stream)
         self._message = ''
         yield 4   # Message Length
         l = toint(self._message)
         if l > self.config['max_message_length']:
             log.warning("Received message longer than max length")
         #    return
         self._message = ''
         yield l # Payload
         if handler == self:
             # Grab the stream ID to initialize the received stream
             self.incoming_stream_id = stream
         handler.got_message(self._message)
         self._message = ''
コード例 #7
0
ファイル: NeighborLink.py プロジェクト: self20/Anomos
 def _read_messages(self):
     """ Read messages off the line and relay or process them
         depending on connection type """
     while True:
         yield 2  # Stream ID
         stream = toint(self._message)
         handler = self.get_stream_handler(stream)
         self._message = ''
         yield 4  # Message Length
         l = toint(self._message)
         if l > self.config['max_message_length']:
             log.warning("Received message longer than max length")
         #    return
         self._message = ''
         yield l  # Payload
         if handler == self:
             # Grab the stream ID to initialize the received stream
             self.incoming_stream_id = stream
         handler.got_message(self._message)
         self._message = ''
コード例 #8
0
class Certificate:
    def __init__(self, loc=None, secure=False, tracker=False):
        self.secure = secure
        self.tracker = tracker
        if None in (global_cryptodir, global_randfile):
            raise CryptoError('Crypto not initialized, call initCrypto first')
        self.keyfile = os.path.join(global_cryptodir, '%s-key.pem' % (loc))
        self.certfile = os.path.join(global_cryptodir, '%s-cert.pem' % (loc))

        if not (os.path.exists(self.certfile)
                and os.path.exists(self.keyfile)):
            if self.tracker:
                hostname = self._gethostname()
            else:
                hostname = 'localhost'
            self._create(hostname=hostname)
        else:
            self._load()

    def _gethostname(self):
        from socket import gethostname
        hostname = gethostname()
        tmpname = raw_input("Please enter the tracker's hostname " \
                        "for the SSL certificate (default: %s): " % hostname)
        if tmpname.strip(" "):
            hostname = tmpname
        return hostname

    def _load(self):
        """Attempts to load the certificate and key from self.certfile and self.keyfile,
           Generates the certificate and key if they don't exist"""
        if not self.secure:
            self.rsakey = RSA.load_key(self.keyfile,
                                       m2util.no_passphrase_callback)
        else:
            # Allow 3 attempts before quitting
            i = 0
            while i < 3:
                try:
                    self.rsakey = RSA.load_key(self.keyfile)
                    break
                except RSA.RSAError:
                    i += 1
            else:
                log.warning("\nInvalid password entered, exiting.")
                sys.exit()
        self.cert = X509.load_cert(self.certfile)

    @Anomos.Crypto.use_rand_file
    def _create(self, hostname='localhost'):
        # Make the RSA key
        self.rsakey = RSA.gen_key(2048, m2.RSA_F4)
        if self.secure:
            # Save the key, AES256-CBC encrypted
            self.rsakey.save_key(self.keyfile, 'aes_256_cbc')
        else:
            # Save the key unencrypted.
            self.rsakey.save_key(self.keyfile,
                                 None,
                                 callback=m2util.no_passphrase_callback)
        # Make the public key
        pkey = EVP.PKey()
        pkey.assign_rsa(self.rsakey, 0)
        # Generate the certificate
        self.cert = X509.X509()
        self.cert.set_serial_number(long(bttime()))
        self.cert.set_version(0x2)
        self.cert.set_pubkey(pkey)
        # Set the name on the certificate
        name = X509.X509_Name()
        name.CN = hostname
        self.cert.set_subject(name)
        self.cert.set_issuer(name)
        # Set the period of time the cert is valid for (5 years from issue)
        notBefore = m2.x509_get_not_before(self.cert.x509)
        notAfter = m2.x509_get_not_after(self.cert.x509)
        m2.x509_gmtime_adj(notBefore, 0)
        m2.x509_gmtime_adj(notAfter, 60 * 60 * 24 * 365 * 5)
        # Sign the certificate
        self.cert.sign(pkey, 'sha1')
        # Save it
        self.cert.save_pem(self.certfile)

    def get_ctx(self,
                allow_unknown_ca=False,
                req_peer_cert=True,
                session=None):
        ctx = SSL.Context("sslv23")
        # Set certificate and private key
        m2.ssl_ctx_use_x509(ctx.ctx, self.cert.x509)
        m2.ssl_ctx_use_rsa_privkey(ctx.ctx, self.rsakey.rsa)
        if not m2.ssl_ctx_check_privkey(ctx.ctx):
            raise CryptoError('public/private key mismatch')
        # Ciphers/Options
        ctx.set_cipher_list(CIPHER_SET)
        ctx.set_options(CTX_OPTIONS)
        # CA settings
        cloc = os.path.join(global_certpath, 'cacert.root.pem')
        if ctx.load_verify_locations(cafile=cloc) != 1:
            log.error("Problem loading CA certificates")
            raise CryptoError('CA certificates not loaded')
        # Verification
        cb = mk_verify_cb(allow_unknown_ca=allow_unknown_ca)
        CTX_V_FLAGS = SSL.verify_peer
        if req_peer_cert:
            CTX_V_FLAGS |= SSL.verify_fail_if_no_peer_cert
        ctx.set_verify(CTX_V_FLAGS, 3, cb)
        # Session
        if session:
            ctx.set_session_id_ctx(session)
        return ctx

    def fingerprint(self):
        md = EVP.MessageDigest("sha1")
        md.update(self.rsakey.pub()[1])
        return b2a_hex(md.digest())

    def decrypt(self, data):
        """
        Decrypts data encrypted with this public key

        @param data: The data, padding and all, to be decrypted
        @type data: string

        @raise CryptoError: Priv. decrypt fail or Bad Checksum

        @return: tuple (decrypted message, padding) if returnpad is true, string otherwise
        @rtype: tuple
        """
        rsa_keysize_B = len(self.rsakey) / 8
        # Decrypt the session key and IV with our private key
        try:
            tmpsk = self.rsakey.private_decrypt(data[:rsa_keysize_B],
                                                RSA.pkcs1_oaep_padding)
        except RSA.RSAError, e:
            raise CryptoError("A decryption error occurred: %s" % str(e))
        sk = tmpsk[:32]  # Session Key
        iv = tmpsk[32:]  # IV
        sessionkey = Anomos.Crypto.AESKey(sk, iv)
        # Decrypt the rest of the message with the session key
        content = sessionkey.decrypt(data[rsa_keysize_B:])
        msglen = content[:4]  # first 4 bytes
        msglen_int = toint(msglen)
        pos = 4
        message = content[pos:pos + msglen_int]  # next msglen_int bytes
        pos += msglen_int
        givenchksum = content[pos:pos + 20]  # next 20 bytes
        pos += 20
        md = EVP.MessageDigest("sha1")
        md.update(msglen + message)
        mychksum = md.digest()
        if givenchksum != mychksum:
            raise CryptoError(
                "Bad Checksum - Data may have been tampered with")
        return (message, content[pos:])