Example #1
0
    def sign(self, keypairs):
        print_error("tx.sign(), keypairs:", keypairs)

        for i, txin in enumerate(self.inputs):

            # if the input is multisig, parse redeem script
            redeem_script = txin.get('redeemScript')
            num, redeem_pubkeys = parse_redeemScript(redeem_script) if redeem_script else (1, [txin.get('redeemPubkey')])

            # add pubkeys
            txin["pubkeys"] = redeem_pubkeys
            # get list of already existing signatures
            signatures = txin.get("signatures",{})
            # continue if this txin is complete
            if len(signatures) == num:
                continue

            for_sig = Hash(self.tx_for_sig(i).decode('hex'))
            for pubkey in redeem_pubkeys:
                if pubkey in keypairs.keys():
                    # add signature
                    sec = keypairs[pubkey]
                    pkey = regenerate_key(sec)
                    secexp = pkey.secret
                    private_key = ecdsa.SigningKey.from_secret_exponent( secexp, curve = SECP256k1 )
                    public_key = private_key.get_verifying_key()
                    sig = private_key.sign_digest_deterministic( for_sig, hashfunc=hashlib.sha256, sigencode = ecdsa.util.sigencode_der )
                    assert public_key.verify_digest( sig, for_sig, sigdecode = ecdsa.util.sigdecode_der)
                    self.add_signature(i, pubkey, sig.encode('hex'))


        print_error("is_complete", self.is_complete())
        self.raw = self.serialize( self.inputs, self.outputs )
Example #2
0
    def send(self, messages, callback):

        sub = []
        for message in messages:
            m, v = message
            if m[-10:] == '.subscribe':
                sub.append(message)

        if sub:
            with self.lock:
                if self.subscriptions.get(callback) is None: 
                    self.subscriptions[callback] = []
                for message in sub:
                    if message not in self.subscriptions[callback]:
                        self.subscriptions[callback].append(message)

        if not self.is_connected: 
            print_error("interface: trying to send while not connected")
            return

        if self.protocol in 'st':
            with self.lock:
                out = self.send_tcp(messages, callback)
        else:
            # do not use lock, http is synchronous
            out = self.send_http(messages, callback)

        return out
Example #3
0
 def new_blockchain_height(self, blockchain_height, i):
     if self.is_connected():
         if self.server_is_lagging():
             print_error( "Server is lagging", blockchain_height, self.get_server_height())
             if self.config.get('auto_cycle'):
                 self.set_server(i.server)
     self.notify('updated')
Example #4
0
    def run(self):
        threading.Thread(target=self.reading_thread).start()
        while self.is_running():
            try:
                r = self.response_queue.get(timeout=0.1)
            except Queue.Empty:
                continue
            id = r.get('id')
            if id is None:
                method = r.get('method')
                params = r.get('params')
            else:
                ws, amount, rr = self.sub_ws[id]
                method = rr.get('method')
                params = rr.get('params')

            result = r.get('result')

            if method == 'blockchain.address.subscribe':
                util.print_error('response', r)
                if result is not None:
                    request = {'method':'blockchain.address.get_balance', 'params':params, 'id':self.counter}
                    self.server.send_request(self, request)
                    self.sub_ws[self.counter] = ws, amount, request
                    self.counter += 1

            if r.get('method') == 'blockchain.address.get_balance':
                util.print_error('response', r)
                if not ws.closed:
                    if sum(result.values()) >=amount:
                        ws.sendMessage(unicode('paid'))

        self.server.remove_client(self)
Example #5
0
    def process_request(self, request):
        method = request['method']
        params = request['params']
        _id = request['id']

        if method.startswith('network.'):
            out = {'id':_id}
            try:
                f = getattr(self, method[8:])
            except AttributeError:
                out['error'] = "unknown method"
            try:
                out['result'] = f(*params)
            except BaseException as e:
                out['error'] = str(e)
                print_error("network error", str(e))

            self.response_queue.put(out)
            return

        if method == 'blockchain.address.subscribe':
            addr = params[0]
            if addr in self.addresses:
                self.response_queue.put({'id':_id, 'result':self.addresses[addr]}) 
                return

        self.interface.send_request(request)
Example #6
0
    def get_socket(self):
        if self.use_ssl:
            cert_path = os.path.join( self.config.path, 'certs', self.host)
            if not os.path.exists(cert_path):
                is_new = True
                s = self.get_simple_socket()
                if s is None:
                    return
                # try with CA first
                try:
                    s = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_SSLv23, cert_reqs=ssl.CERT_REQUIRED, ca_certs=ca_path, do_handshake_on_connect=True)
                except ssl.SSLError, e:
                    s = None
                if s and self.check_host_name(s.getpeercert(), self.host):
                    print_error("SSL certificate signed by CA:", self.host)
                    return s

                # get server certificate.
                # Do not use ssl.get_server_certificate because it does not work with proxy
                s = self.get_simple_socket()
                try:
                    s = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_SSLv23, cert_reqs=ssl.CERT_NONE, ca_certs=None)
                except ssl.SSLError, e:
                    print_error("SSL error retrieving SSL certificate:", self.host, e)
                    return

                dercert = s.getpeercert(True)
                s.close()
                cert = ssl.DER_cert_to_PEM_cert(dercert)
                # workaround android bug
                cert = re.sub("([^\n])-----END CERTIFICATE-----","\\1\n-----END CERTIFICATE-----",cert)
                temporary_path = cert_path + '.temp'
                with open(temporary_path,"w") as f:
                    f.write(cert)
Example #7
0
 def sign(self, keypairs):
     for i, txin in enumerate(self.inputs()):
         num = txin['num_sig']
         for x_pubkey in txin['x_pubkeys']:
             signatures = filter(None, txin['signatures'])
             if len(signatures) == num:
                 # txin is complete
                 break
             if x_pubkey in keypairs.keys():
                 print_error("adding signature for", x_pubkey)
                 # add pubkey to txin
                 txin = self._inputs[i]
                 x_pubkeys = txin['x_pubkeys']
                 ii = x_pubkeys.index(x_pubkey)
                 sec = keypairs[x_pubkey]
                 pubkey = public_key_from_private_key(sec)
                 txin['x_pubkeys'][ii] = pubkey
                 txin['pubkeys'][ii] = pubkey
                 self._inputs[i] = txin
                 # add signature
                 for_sig = Hash(self.tx_for_sig(i).decode('hex'))
                 pkey = regenerate_key(sec)
                 secexp = pkey.secret
                 private_key = bitcoin.MySigningKey.from_secret_exponent( secexp, curve = SECP256k1 )
                 public_key = private_key.get_verifying_key()
                 sig = private_key.sign_digest_deterministic( for_sig, hashfunc=hashlib.sha256, sigencode = ecdsa.util.sigencode_der )
                 assert public_key.verify_digest( sig, for_sig, sigdecode = ecdsa.util.sigdecode_der)
                 txin['signatures'][ii] = sig.encode('hex')
                 self._inputs[i] = txin
     print_error("is_complete", self.is_complete())
     self.raw = self.serialize()
Example #8
0
    def run(self):
        self.network.start(self.network_queue)
        while self.is_running():
            try:
                response = self.network_queue.get(timeout=0.1)
            except Queue.Empty:
                continue
            if self.debug:
                print_error("<--", response)
            response_id = response.get('id')
            if response_id:
                with self.lock:
                    client_id, client = self.requests.pop(response_id)
                response['id'] = client_id
                client.response_queue.put(response)
            else:
                # notification
                m = response.get('method')
                v = response.get('params')
                for client in self.clients:
                    if repr((m, v)) in client.subscriptions:
                        client.response_queue.put(response)

        self.network.stop()
        print_error("server exiting")
Example #9
0
    def verify_chunk(self, index, hexdata):
        data = hexdata.decode('hex')
        height = index*1920
        num = len(data)/80

        if index == 0:
            previous_hash = ("0"*64)
        else:
            prev_header = self.read_header(index*1920-1)
            if prev_header is None: raise
            previous_hash = self.hash_header(prev_header)

        if height < 43847:
            bits, target = self.get_target(index)

        for i in xrange(num):
            height = index*1920 + i
            raw_header = data[i*80:(i+1)*80]
            header = self.header_from_string(raw_header)
            _hash = self.pow_hash_header(header)
            if height >= 43847:
                bits, target = self.get_target(height, data=data)
            assert previous_hash == header.get('prev_block_hash')
            assert bits == header.get('bits')
            assert int('0x'+_hash,16) < target

            print_error( 'verified height ', str(height))
            previous_header = header
            previous_hash = self.hash_header(header)

        self.save_chunk(index, data)
        print_error("validated chunk %d"%height)
Example #10
0
def daemon_loop(server):
    s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    daemon_socket = os.path.join(server.config.path, DAEMON_SOCKET)
    if os.path.exists(daemon_socket):
        os.remove(daemon_socket)
    daemon_timeout = server.config.get('daemon_timeout', None)
    s.bind(daemon_socket)
    s.listen(5)
    s.settimeout(1)
    t = time.time()
    while server.running:
        try:
            connection, address = s.accept()
        except socket.timeout:
            if daemon_timeout is None:
                continue
            if not server.clients:
                if time.time() - t > daemon_timeout:
                    print_error("Daemon timeout")
                    break
            else:
                t = time.time()
            continue
        t = time.time()
        client = ClientThread(server, connection)
        client.start()
    server.stop()
    # sleep so that other threads can terminate cleanly
    time.sleep(0.5)
    print_error("Daemon exiting")
Example #11
0
    def get_chain(self, interface, final_header):

        header = final_header
        chain = [ final_header ]
        requested_header = False
        queue = Queue.Queue()
        height = header.get('block_height')

        while self.is_running():

            if requested_header:
                header = self.retrieve_header(interface, queue)
                if not header: return
                chain = [ header ] + chain
                requested_header = False

            height = header.get('block_height')
            previous_header = self.read_header(height -1)
            if not previous_header:
                self.request_header(interface, height - 1, queue)
                requested_header = True
                continue

            # verify that it connects to my chain
            prev_hash = self.hash_header(previous_header)
            if prev_hash != header.get('prev_block_hash'):
                print_error("reorg")
                self.request_header(interface, height - 1, queue)
                requested_header = True
                continue

            else:
                # the chain is complete
                return chain
Example #12
0
    def retrieve_header(self, i, queue):
        timeout = 1
        while True:
            try:
                ir = queue.get(timeout=timeout)
                timeout = 1
            except Queue.Empty:
                print_error('timeout', timeout)
                if timeout < 32:
                    timeout *= 2
                continue

            if not ir:
                continue

            i, r = ir

            if r.get('error'):
                print_error('Verifier received an error:', r)
                continue

            # 3. handle response
            method = r['method']
            params = r['params']
            result = r['result']

            if method == 'blockchain.block.get_header':
                return result
Example #13
0
    def verify_chunk(self, index, hexdata):
        data = hexdata.decode('hex')
        height = index
        num = len(data)/88

        if index == 0:
            previous_hash = ("0"*64)
        else:
            prev_header = self.read_header(index-1)
            if prev_header is None: raise
            previous_hash = self.hash_header(prev_header)

        bits, target = self.get_target(index)

        for i in range(num):
            height = index + i
            raw_header = data[i*88:(i+1)*88]
            header = self.header_from_string(raw_header)
            _hash = self.hash_header(header)
            assert previous_hash == header.get('prev_block_hash')
            #assert bits == header.get('bits')
            #assert int('0x'+_hash,16) < target # Cant do bits for memorycoin yet

            previous_header = header
            previous_hash = _hash

        self.save_chunk(index, data)
        print_error("validated chunk %d"%height)
Example #14
0
    def sign(self, keypairs):
        print_error("tx.sign(), keypairs:", keypairs)

        for i, txin in enumerate(self.inputs):

            # continue if this txin is complete
            signatures = filter(lambda x: x is not None, txin['signatures'])
            num = txin['num_sig']
            if len(signatures) == num:
                continue

            redeem_pubkeys = txin['pubkeys']
            for_sig = Hash(self.tx_for_sig(i).decode('hex'))
            for pubkey in redeem_pubkeys:
                if pubkey in keypairs.keys():
                    # add signature
                    sec = keypairs[pubkey]
                    pkey = regenerate_key(sec)
                    secexp = pkey.secret
                    private_key = ecdsa.SigningKey.from_secret_exponent( secexp, curve = SECP256k1 )
                    public_key = private_key.get_verifying_key()
                    sig = private_key.sign_digest_deterministic( for_sig, hashfunc=hashlib.sha256, sigencode = ecdsa.util.sigencode_der )
                    assert public_key.verify_digest( sig, for_sig, sigdecode = ecdsa.util.sigdecode_der)
                    self.add_signature(i, pubkey, sig.encode('hex'))


        print_error("is_complete", self.is_complete())
        self.raw = self.serialize( self.inputs, self.outputs )
Example #15
0
    def verify_header(self, header):
        # add header to the blockchain file
        # if there is a reorg, push it in a stack

        height = header.get('block_height')

        prev_header = self.read_header(height -1)
        if not prev_header:
            # return False to request previous header
            return False

        prev_hash = self.hash_header(prev_header)
        bits, target = self.get_target(height/2016)
        _hash = self.hash_header(header)
        try:
            assert prev_hash == header.get('prev_block_hash')
            assert bits == header.get('bits')
            assert eval('0x'+_hash) < target
        except:
            # this can be caused by a reorg.
            print_error("verify header failed"+ repr(header))
            verifier.undo_verifications()

            # return False to request previous header.
            return False

        self.save_header(header)
        print_error("verify header:", _hash, height)
        return True
Example #16
0
    def get_chunks(self, i, header, height):
        requested_chunks = []
        min_index = (self.local_height + 1)/2016
        max_index = (height + 1)/2016
        for n in range(min_index, max_index + 1):
            print_error( "requesting chunk", n )
            i.send([ ('blockchain.block.get_chunk',[n])], 'get_header')
            requested_chunks.append(n)
            break

        while requested_chunks:
            try:
                r = i.get_response('get_header',timeout=1)
            except Queue.Empty:
                continue
            if not r: continue

            if r.get('error'):
                print_error('Verifier received an error:', r)
                continue

            # 3. handle response
            method = r['method']
            params = r['params']
            result = r['result']

            if method == 'blockchain.block.get_chunk':
                index = params[0]
                self.verify_chunk(index, result)
                requested_chunks.remove(index)
Example #17
0
    def set_parameters(self, host, port, protocol, proxy, auto_connect):
        proxy_str = interface.serialize_proxy(proxy)
        server_str = ':'.join([ host, port, protocol ])
        self.config.set_key('auto_cycle', auto_connect, True)
        self.config.set_key("proxy", proxy_str, True)
        self.config.set_key("protocol", protocol, True)
        self.config.set_key("server", server_str, True)

        if self.proxy != proxy_str or self.protocol != protocol:
            print_error('restarting network')
            self.proxy = proxy_str
            self.protocol = protocol
            for i in self.interfaces.values(): i.stop()
            if auto_connect:
                #self.interface = None
                return

        if auto_connect:
            if not self.interface.is_connected:
                self.switch_to_random_interface()
            else:
                if self.server_is_lagging():
                    self.stop_interface()
        else:
            self.set_server(server_str)
Example #18
0
    def verify_chunk(self, index, hexdata):
        data = hexdata.decode('hex')
        height = index*2016
        num = len(data)/80
        print_error("validating headers %d"%height)

        if index == 0:  
            previous_hash = ("0"*64)
        else:
            prev_header = self.read_header(index*2016-1)
            if prev_header is None: raise
            previous_hash = self.hash_header(prev_header)

        bits, target = self.get_target(index)

        for i in range(num):
            height = index*2016 + i
            raw_header = data[i*80:(i+1)*80]
            header = self.header_from_string(raw_header)
            _hash = self.hash_header(header)
            assert previous_hash == header.get('prev_block_hash')
            assert bits == header.get('bits')
            assert eval('0x'+_hash) < target

            previous_header = header
            previous_hash = _hash 

        self.save_chunk(index, data)
Example #19
0
def verify_message(address, signature, message):
    try:
        EC_KEY.verify_message(address, signature, message)
        return True
    except Exception as e:
        print_error("Verification error: {0}".format(e))
        return False
Example #20
0
def daemon_loop(server):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    daemon_port = server.config.get('daemon_port', DAEMON_PORT)
    daemon_timeout = server.config.get('daemon_timeout', 5*60)
    s.bind(('localhost', daemon_port))
    s.listen(5)
    s.settimeout(1)
    t = time.time()
    while server.running:
        try:
            connection, address = s.accept()
        except socket.timeout:
            if not server.clients:
                if time.time() - t > daemon_timeout:
                    print_error("Daemon timeout")
                    break
            else:
                t = time.time()
            continue
        t = time.time()
        client = ClientThread(server, connection)
        client.start()
    server.stop()
    # sleep so that other threads can terminate cleanly
    time.sleep(0.5)
    print_error("Daemon exiting")
Example #21
0
    def run(self):
        self.blockchain.start()

        with self.lock:
            self.running = True

        while self.is_running():
            try:
                i = self.queue.get(timeout = 30 if self.interfaces else 3)
            except Queue.Empty:
                if len(self.interfaces) < NUM_SERVERS:
                    self.start_random_interface()
                continue

            if i.is_connected:
                self.add_recent_server(i)
                i.send([ ('blockchain.headers.subscribe',[])], self.on_header)
                if i == self.interface:
                    print_error('sending subscriptions to', self.interface.server)
                    self.send_subscriptions()
                    self.trigger_callback('connected')
            else:
                self.disconnected_servers.append(i.server)
                self.interfaces.pop(i.server)
                if i.server in self.heights:
                    self.heights.pop(i.server)
                if i == self.interface:
                    self.interface = None
                    self.trigger_callback('disconnected')

            if self.interface is None and self.config.get('auto_cycle'):
                self.switch_to_random_interface()
Example #22
0
    def run(self):
        self.start_tcp()
        self.change_status()
        if not self.is_connected:
            return

        t = 0
        while self.is_connected:
            # ping the server with server.version
            if time.time() - t > 60:
                if self.is_ping:
                    print_error("ping timeout", self.server)
                    self.is_connected = False
                    break
                else:
                    self.send_request({'method':'server.version', 'params':[ELECTRUM_VERSION, PROTOCOL_VERSION]})
                    self.is_ping = True
                    t = time.time()
            try:
                response = self.pipe.get()
            except util.timeout:
                continue
            if response is None:
                self.is_connected = False
                break
            self.process_response(response)

        self.change_status()
        print_error("closing connection:", self.server)
Example #23
0
 def update_signatures(self, raw):
     """Add new signatures to a transaction"""
     d = deserialize(raw)
     for i, txin in enumerate(self.inputs()):
         sigs1 = txin.get('signatures')
         sigs2 = d['inputs'][i].get('signatures')
         for sig in sigs2:
             if sig in sigs1:
                 continue
             for_sig = Hash(self.tx_for_sig(i).decode('hex'))
             # der to string
             order = ecdsa.ecdsa.generator_secp256k1.order()
             r, s = ecdsa.util.sigdecode_der(sig.decode('hex'), order)
             sig_string = ecdsa.util.sigencode_string(r, s, order)
             pubkeys = txin.get('pubkeys')
             compressed = True
             for recid in range(4):
                 public_key = MyVerifyingKey.from_signature(sig_string, recid, for_sig, curve = SECP256k1)
                 pubkey = point_to_ser(public_key.pubkey.point, compressed).encode('hex')
                 if pubkey in pubkeys:
                     public_key.verify_digest(sig_string, for_sig, sigdecode = ecdsa.util.sigdecode_string)
                     j = pubkeys.index(pubkey)
                     print_error("adding sig", i, j, pubkey, sig)
                     self._inputs[i]['signatures'][j] = sig
                     self._inputs[i]['x_pubkeys'][j] = pubkey
                     break
     # redo raw
     self.raw = self.serialize()
Example #24
0
def load_certificates():
    try:
        ca_f = open(ca_path, "r")
    except Exception:
        print "ERROR: Could not open %s" % ca_path
        print "ca-bundle.crt file should be placed in ~/.electrum/ca/ca-bundle.crt"
        print "Documentation on how to download or create the file here: http://curl.haxx.se/docs/caextract.html"
        print "Payment will continue with manual verification."
        return False
    c = ""
    for line in ca_f:
        if line == "-----BEGIN CERTIFICATE-----\n":
            c = line
        else:
            c += line
        if line == "-----END CERTIFICATE-----\n":
            x = x509.X509()
            try:
                x.parse(c)
            except Exception as e:
                util.print_error("cannot parse cert:", e)
            ca_list[x.getFingerprint()] = x
    ca_f.close()
    util.print_error("%d certificates" % len(ca_list))
    return True
Example #25
0
    def __init__(self, options={}):

        # system conf, readonly
        self.system_config = {}
        if options.get('portable') == False:
            self.read_system_config()

        # user conf, writeable
        self.user_dir = user_dir()
        self.user_config = {}
        if options.get('portable') == False:
            self.read_user_config()

        # command-line options
        self.options_config = options

        self.wallet_config = {}
        self.wallet_file_exists = False
        self.init_path(self.options_config.get('wallet_path'))
        print_error( "path", self.path )
        if self.path:
            self.read_wallet_config(self.path)

        # portable wallet: use the same directory for wallet and headers file
        if options.get('portable'):
            self.wallet_config['blockchain_headers_path'] = os.path.dirname(self.path)
Example #26
0
    def send(self, messages, callback):
        """return the ids of the requests that we sent"""

        # detect subscriptions
        sub = []
        for message in messages:
            m, v = message
            if m[-10:] == '.subscribe':
                sub.append(message)
        if sub:
            with self.lock:
                if self.subscriptions.get(callback) is None: 
                    self.subscriptions[callback] = []
                for message in sub:
                    if message not in self.subscriptions[callback]:
                        self.subscriptions[callback].append(message)

        with self.lock:
            requests = []
            ids = []
            for m in messages:
                method, params = m 
                request = {'id': self.message_id, 'method': method, 'params': params}
                self.unanswered_requests[self.message_id] = method, params, callback
                ids.append(self.message_id)
                requests.append(request)
                if self.debug: 
                    print_error("-->", request)
                self.message_id += 1

            self.pipe.send_all(requests)
            return ids
Example #27
0
 def server_is_lagging(self):
     h = self.get_server_height()
     if not h:
         print_error('no height for main interface')
         return False
     lag = self.get_local_height() - self.get_server_height()
     return lag > 1
Example #28
0
    def process_pending_sends(self):
        # Requests needs connectivity.  If we don't have an interface,
        # we cannot process them.
        if not self.interface:
            return

        with self.lock:
            sends = self.pending_sends
            self.pending_sends = []

        for messages, callback in sends:
            for method, params in messages:
                r = None
                if method.endswith('.subscribe'):
                    k = self.get_index(method, params)
                    # add callback to list
                    l = self.subscriptions.get(k, [])
                    if callback not in l:
                        l.append(callback)
                    self.subscriptions[k] = l
                    # check cached response for subscriptions
                    r = self.sub_cache.get(k)
                if r is not None:
                    util.print_error("cache hit", k)
                    callback(r)
                else:
                    message_id = self.queue_request(method, params)
                    self.unanswered_requests[message_id] = method, params, callback
Example #29
0
 def add_client(self, client):
     for key in ['status', 'banner', 'updated', 'servers', 'interfaces']:
         value = self.network.get_status_value(key)
         client.response_queue.put({'method':'network.status', 'params':[key, value]})
     with self.lock:
         self.clients.append(client)
         print_error("new client:", len(self.clients))
Example #30
0
 def send_tcp(self, messages, callback):
     """return the ids of the requests that we sent"""
     out = ''
     ids = []
     for m in messages:
         method, params = m 
         request = json.dumps( { 'id':self.message_id, 'method':method, 'params':params } )
         self.unanswered_requests[self.message_id] = method, params, callback
         ids.append(self.message_id)
         if self.debug:
             print "-->", request
         self.message_id += 1
         out += request + '\n'
     while out:
         try:
             sent = self.s.send( out )
             out = out[sent:]
         except socket.error,e:
             if e[0] in (errno.EWOULDBLOCK,errno.EAGAIN):
                 print_error( "EAGAIN: retrying")
                 time.sleep(0.1)
                 continue
             else:
                 traceback.print_exc(file=sys.stdout)
                 # this happens when we get disconnected
                 print_error( "Not connected, cannot send" )
                 return None
Example #31
0
    def execute(self, printer):
        # currently we fetch top buzzfeed articles (don't judge me, they are a good laugh)
        params = {'country': 'de', 'pageSize': self.count}
        r = requests.get(
            News.API_ENDPOINT,
            params=params,
            headers={'Authorization': 'Bearer ' + config.NEWSAPI_KEY})

        util.print_header(printer, 'Nachrichten')

        if r.status_code != 200:
            print("Error: Couldn't fetch news articles (request failed)")
            util.print_error(printer)
            return

        try:
            json = r.json()
        except ValueError as e:
            print(e)
            print(
                "Error: Couldn't fetch headlines (invalid or missing response content)"
            )
            util.print_error(printer)
            return

        try:
            articles = [_Article(**current)
                        for current in json['articles']][0:self.count]
        except KeyError as e:
            print(e)
            print(
                "Error: Couldn't fetch headlines (unexpected response format)")
            util.print_error(printer)
            return

        for a in articles:
            # print the source
            printer.underlineOn()
            printer.write(a.source_name + '\n')
            printer.underlineOff()
            # print the headline
            printer.write(a.title + '\n')
            printer.feed(1)
            # TODO: implement QR-Code generation

        printer.feed(1)
Example #32
0
def evaluate_scan(pred_file, gt_file, confusion):
    try:
        pred_ids = util_3d.load_ids(pred_file)
    except:
        util.print_error('unable to load ' + pred_file + ': ' + str(e))
    try:
        gt_ids = util_3d.load_ids(gt_file)
    except:
        util.print_error('unable to load ' + gt_file + ': ' + str(e))
    # sanity checks
    if not pred_ids.shape == gt_ids.shape:
        util.print_error('%s: number of predicted values does not match number of vertices' % pred_file, user_fault=True)
    for (gt_val,pred_val) in izip(gt_ids.flatten(),pred_ids.flatten()):
        if gt_val not in VALID_CLASS_IDS:
            continue
        if pred_val not in VALID_CLASS_IDS:
            pred_val = UNKNOWN_ID
        confusion[gt_val][pred_val] += 1
def visualize(pred_file, mesh_file, output_file):
    if not output_file.endswith('.ply'):
        util.print_error('output file must be a .ply file')
    colors = util.create_color_palette()
    num_colors = len(colors)
    ids = util_3d.load_ids(pred_file)
    with open(mesh_file, 'rb') as f:
        plydata = PlyData.read(f)
        num_verts = plydata['vertex'].count
        if num_verts != len(ids):
            util.print_error('#predicted labels = ' + str(len(ids)) + 'vs #mesh vertices = ' + str(num_verts))
        # *_vh_clean_2.ply has colors already
        for i in range(num_verts):
            if ids[i] >= num_colors:
                util.print_error('found predicted label ' + str(ids[i]) + ' not in nyu40 label set')
            color = colors[ids[i]]
            plydata['vertex']['red'][i] = color[0]
            plydata['vertex']['green'][i] = color[1]
            plydata['vertex']['blue'][i] = color[2]
    plydata.write(output_file)
Example #34
0
def read_instance_prediction_file(filename, pred_path):
    lines = open(filename).read().splitlines()
    instance_info = {}
    abs_pred_path = os.path.abspath(pred_path)
    for line in lines:
        parts = line.split(' ')
        if len(parts) != 3:
            util.print_error('invalid instance prediction file. Expected (per line): [rel path prediction] [label id prediction] [confidence prediction]')
        if os.path.isabs(parts[0]):
            util.print_error('invalid instance prediction file. First entry in line must be a relative path')
        mask_file = os.path.join(os.path.dirname(filename), parts[0])
        mask_file = os.path.abspath(mask_file)
        # check that mask_file lives inside prediction path
        if os.path.commonprefix([mask_file, abs_pred_path]) != abs_pred_path:
            util.print_error('predicted mask {} in prediction text file {} points outside of prediction path.'.format(mask_file,filename))

        info            = {}
        info["label_id"] = int(float(parts[1]))
        info["conf"]    = float(parts[2])
        instance_info[mask_file]  = info
    return instance_info
Example #35
0
def validate_single_rule(config_id: str, rule_index: int, rule: Dict[str, Any]) -> bool:
    rule_id_err_msg = f'(rule id: {rule.get("id", MISSING_RULE_ID)})'
    if not set(rule.keys()).issuperset(YAML_MUST_HAVE_KEYS):
        print_error(
            f"{config_id} is missing keys at rule {rule_index+1} {rule_id_err_msg}, must have: {YAML_MUST_HAVE_KEYS}"
        )
        return False
    if not set(rule.keys()).issubset(YAML_ALL_VALID_RULE_KEYS):
        print_error(
            f"{config_id} has invalid rule key at rule {rule_index+1} {rule_id_err_msg}, can only have: {YAML_ALL_VALID_RULE_KEYS}"
        )
        return False
    try:
        _ = build_boolean_expression(rule)
    except InvalidRuleSchema as ex:
        print_error(
            f"{config_id}: inside rule {rule_index+1} {rule_id_err_msg}, pattern fields can't look like this: {ex}"
        )
        return False

    return True
Example #36
0
    def sign(self, keypairs):
        print_error("tx.sign(), keypairs:", keypairs)
        for i, txin in enumerate(self.inputs):
            signatures = filter(None, txin['signatures'])
            num = txin['num_sig']
            if len(signatures) == num:
                # continue if this txin is complete
                continue

            for x_pubkey in txin['x_pubkeys']:
                if x_pubkey in keypairs.keys():
                    print_error("adding signature for", x_pubkey)
                    # add pubkey to txin
                    txin = self.inputs[i]
                    x_pubkeys = txin['x_pubkeys']
                    ii = x_pubkeys.index(x_pubkey)
                    sec = keypairs[x_pubkey]
                    pubkey = public_key_from_private_key(sec)
                    txin['x_pubkeys'][ii] = pubkey
                    txin['pubkeys'][ii] = pubkey
                    self.inputs[i] = txin
                    # add signature
                    # signature for input skips nTime
                    for_sig = Hash(self.tx_for_sig(i).decode('hex'))
                    pkey = regenerate_key(sec)
                    secexp = pkey.secret
                    private_key = ecdsa.SigningKey.from_secret_exponent(
                        secexp, curve=SECP256k1)
                    public_key = private_key.get_verifying_key()
                    sig = private_key.sign_digest_deterministic(
                        for_sig,
                        hashfunc=hashlib.sha256,
                        sigencode=ecdsa.util.sigencode_der)
                    assert public_key.verify_digest(
                        sig, for_sig, sigdecode=ecdsa.util.sigdecode_der)
                    txin['signatures'][ii] = sig.encode('hex')
                    self.inputs[i] = txin

        print_error("is_complete", self.is_complete())
        self.raw = self.serialize()
Example #37
0
    def run(self):
        self.init_headers_file()
        self.set_local_height()
        self.print_error("%d blocks"%self.local_height)

        while self.is_running():
            try:
                result = self.queue.get(timeout=0.1)
            except Queue.Empty:
                continue
            if not result:
                continue
            i, header = result
            if not header:
                continue
            height = header.get('block_height')
            if height <= self.local_height:
                continue
            if height > self.local_height + 50:
                if not self.get_and_verify_chunks(i, header, height):
                    continue
            if height > self.local_height:
                # get missing parts from interface (until it connects to my chain)
                chain = self.get_chain( i, header )
                # skip that server if the result is not consistent
                if not chain:
                    print_error('e')
                    continue
                # verify the chain
                if self.verify_chain( chain ):
                    print_error("height:", height, i.server)
                    for header in chain:
                        self.save_header(header)
                else:
                    print_error("error", i.server)
                    # todo: dismiss that server
                    continue
            self.network.new_blockchain_height(height, i)

        self.print_error("stopped")
Example #38
0
    def run(self):
        self.s = self.get_socket()
        if self.s:
            self.s.settimeout(60)
            self.is_connected = True
            print_error("connected to", self.host, self.port)
            self.pipe = util.SocketPipe(self.s)

        self.change_status()
        if not self.is_connected:
            return

        t = 0
        while self.is_connected:
            # ping the server with server.version
            if time.time() - t > 60:
                if self.is_ping:
                    print_error("ping timeout", self.server)
                    self.is_connected = False
                    break
                else:
                    self.send_request({
                        'method':
                        'server.version',
                        'params': [ELECTRUM_VERSION, PROTOCOL_VERSION]
                    })
                    self.is_ping = True
                    t = time.time()
            try:
                response = self.pipe.get()
            except util.timeout:
                continue
            if response is None:
                self.is_connected = False
                break
            self.process_response(response)

        self.change_status()
        print_error("closing connection:", self.server)
    def verify_header(self, header):
        # add header to the blockchain file
        # if there is a reorg, push it in a stack

        height = header.get('block_height')

        prev_header = self.read_header(height -1)
        if not prev_header:
            # return False to request previous header
            return False

        prev_hash = self.hash_header(prev_header)
        bits, target = self.get_target(height/2016)
        _hash = self.hash_header(header)
        try:
            assert prev_hash == header.get('prev_block_hash')
            assert bits == header.get('bits')
            assert eval('0x'+_hash) < target
        except:
            # this can be caused by a reorg.
            print_error("verify header failed"+ repr(header))
            # undo verifications
            with self.lock:
                items = self.verified_tx.items()[:]
            for tx_hash, item in items:
                tx_height, timestamp, pos = item
                if tx_height >= height:
                    print_error("redoing", tx_hash)
                    with self.lock:
                        self.verified_tx.pop(tx_hash)
                        if tx_hash in self.merkle_roots:
                            self.merkle_roots.pop(tx_hash)
            # return False to request previous header.
            return False

        self.save_header(header)
        print_error("verify header:", _hash, height)
        return True
Example #40
0
    def verify_chain(self, chain):
        first_header = chain[0]
        first_height = first_header.get('block_height')

        # get preceding headers to use in KGW
        prev_chain = [
            self.read_header(x)
            for x in range(first_height - self.cache_kgw_size, first_height)
        ]
        prev_header = prev_chain[-1]

        chain_target = self.kgw.get_chain_target(prev_chain, chain)

        for i, header in enumerate(chain):
            height = header.get('block_height')
            prev_hash = self.hash_header(prev_header)
            bits, target = chain_target[i]

            if prev_hash != header.get('prev_block_hash'):
                print_error("height %d: prev_hash mismatch" % height)
                return False

            if bits != header.get('bits'):
                print_error("height %d: bits mismatch %u vs %u" %
                            (height, bits, header.get('bits')))
                return False

            if height <= self.kgw.last_pow_block:
                _hash = self.pow_hash_header(header)

                if int('0x' + _hash, 16) >= target:
                    print_error("height %d: PoW hash >= target" % height)
                    return False

            prev_header = header

        return True
Example #41
0
    def get_and_verify_chunks(self, i, header, height):
        requested_chunks = []
        queue = Queue.Queue()
        min_index = (self.local_height + 1) / 2016
        max_index = (height + 1) / 2016

        for n in range(min_index, max_index + 1):
            i.send([('blockchain.block.get_chunk', [n])],
                   lambda i, r: queue.put(r))
            requested_chunks.append(n)

        print_error("requested chunks:", requested_chunks)

        while requested_chunks:
            try:
                r = queue.get(timeout=1)
            except Queue.Empty:
                continue
            if not r: continue

            if r.get('error'):
                print_error('Verifier received an error:', r)
                continue

            # 3. handle response
            params = r['params']
            result = r['result']

            index = params[0]
            try:
                self.verify_chunk(index, result)
            except Exception:
                print_error('Verify chunk failed!!')
                return False
            requested_chunks.remove(index)

        return True
Example #42
0
def attempt_key_import(keyid, key_fullpath):
    """Ask user to import key."""
    global IMPORTED
    print(SEPT)
    ig = InputGetter(
        '\nDo you want to attempt to import keyid {}: (y/N) '.format(keyid))
    import_key_answer = ig.get_answer()
    if import_key_answer in [None, False]:
        return False
    with cli_gpg_ctx() as ctx:
        err, _ = ctx.import_key(keyid)
        if err is not None:
            util.print_error(err.strerror)
            return False
        err, key_content = ctx.export_key(keyid)
        if err is not None:
            util.print_error(err.strerror)
            return False
        util.write_out(key_fullpath, key_content)
        print('\n')
        util.print_success('Public key id: {} was imported'.format(keyid))
        err, content = ctx.display_keyinfo(key_fullpath)
        if err is not None:
            util.print_error(
                'Unable to parse {}, will be removed'.format(key_fullpath))
            os.unlink(key_fullpath)
            return False
        print("\n", content)
        ig = InputGetter(message='\nDo you want to keep this key: (Y/n) ',
                         default='y')
        if ig.get_answer() is True:
            IMPORTED = content
            return True
        else:
            os.unlink(key_fullpath)
    return False
Example #43
0
def parse_scriptSig(d, bytes):
    try:
        decoded = [x for x in script_GetOp(bytes)]
    except Exception:
        # coinbase transactions raise an exception
        print_error("cannot find address in input script", bytes.encode('hex'))
        return

    # payto_pubkey
    match = [opcodes.OP_PUSHDATA4]
    if match_decoded(decoded, match):
        sig = decoded[0][1].encode('hex')
        d['address'] = "(pubkey)"
        d['signatures'] = [sig]
        d['num_sig'] = 1
        d['x_pubkeys'] = ["(pubkey)"]
        d['pubkeys'] = ["(pubkey)"]
        return

    # non-generated TxIn transactions push a signature
    # (seventy-something bytes) and then their public key
    # (65 bytes) onto the stack:
    match = [opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4]
    if match_decoded(decoded, match):
        sig = decoded[0][1].encode('hex')
        x_pubkey = decoded[1][1].encode('hex')
        try:
            signatures = parse_sig([sig])
            pubkey, address = parse_xpub(x_pubkey)
        except:
            import traceback
            traceback.print_exc(file=sys.stdout)
            print_error("cannot find address in input script",
                        bytes.encode('hex'))
            return
        d['signatures'] = signatures
        d['x_pubkeys'] = [x_pubkey]
        d['num_sig'] = 1
        d['pubkeys'] = [pubkey]
        d['address'] = address
        return

    # p2sh transaction, m of n
    match = [opcodes.OP_0] + [opcodes.OP_PUSHDATA4] * (len(decoded) - 1)
    if not match_decoded(decoded, match):
        print_error("cannot find address in input script", bytes.encode('hex'))
        return
    x_sig = [x[1].encode('hex') for x in decoded[1:-1]]
    dec2 = [x for x in script_GetOp(decoded[-1][1])]
    m = dec2[0][0] - opcodes.OP_1 + 1
    n = dec2[-2][0] - opcodes.OP_1 + 1
    op_m = opcodes.OP_1 + m - 1
    op_n = opcodes.OP_1 + n - 1
    match_multisig = [op_m] + [opcodes.OP_PUSHDATA4] * n + [
        op_n, opcodes.OP_CHECKMULTISIG
    ]
    if not match_decoded(dec2, match_multisig):
        print_error("cannot find address in input script", bytes.encode('hex'))
        return
    x_pubkeys = map(lambda x: x[1].encode('hex'), dec2[1:-2])
    pubkeys = [parse_xpub(x)[0]
               for x in x_pubkeys]  # xpub, addr = parse_xpub()
    redeemScript = Transaction.multisig_script(pubkeys, m)
    # write result in d
    d['num_sig'] = m
    d['signatures'] = parse_sig(x_sig)
    d['x_pubkeys'] = x_pubkeys
    d['pubkeys'] = pubkeys
    d['redeemScript'] = redeemScript
    d['address'] = hash_160_to_bc_address(hash_160(redeemScript.decode('hex')),
                                          30)
Example #44
0
 def print_error(self, *msg):
     util.print_error("[blockchain]", *msg)
Example #45
0
 def request_header(self, i, h, queue):
     print_error("requesting header %d from %s" % (h, i.server))
     i.send([('blockchain.block.get_header', [h])], lambda i, r: queue.put(
         (i, r)))
Example #46
0
def parse_scriptSig(d, bytes):
    try:
        decoded = [x for x in script_GetOp(bytes)]
    except Exception:
        # coinbase transactions raise an exception
        print_error("cannot find address in input script", bytes.encode('hex'))
        return

    match = [opcodes.OP_PUSHDATA4]
    if match_decoded(decoded, match):
        item = decoded[0][1]
        if item[0] == chr(0):
            redeemScript = item.encode('hex')
            d['address'] = bitcoin.hash160_to_p2sh(
                bitcoin.hash_160(redeemScript.decode('hex')))
            d['type'] = 'p2wpkh-p2sh'
            d['redeemScript'] = redeemScript
            d['x_pubkeys'] = ["(witness)"]
            d['pubkeys'] = ["(witness)"]
            d['signatures'] = ['(witness)']
            d['num_sig'] = 1
        else:
            # payto_pubkey
            d['type'] = 'p2pk'
            d['address'] = "(pubkey)"
            d['signatures'] = [item.encode('hex')]
            d['num_sig'] = 1
            d['x_pubkeys'] = ["(pubkey)"]
            d['pubkeys'] = ["(pubkey)"]
        return

    # non-generated TxIn transactions push a signature
    # (seventy-something bytes) and then their public key
    # (65 bytes) onto the stack:
    match = [opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4]
    if match_decoded(decoded, match):
        sig = decoded[0][1].encode('hex')
        x_pubkey = decoded[1][1].encode('hex')
        try:
            signatures = parse_sig([sig])
            pubkey, address = xpubkey_to_address(x_pubkey)
        except BaseException:
            print_error("cannot find address in input script",
                        bytes.encode('hex'))
            return
        d['type'] = 'p2pkh'
        d['signatures'] = signatures
        d['x_pubkeys'] = [x_pubkey]
        d['num_sig'] = 1
        d['pubkeys'] = [pubkey]
        d['address'] = address
        return

    # p2sh transaction, m of n
    match = [opcodes.OP_0] + [opcodes.OP_PUSHDATA4] * (len(decoded) - 1)
    if not match_decoded(decoded, match):
        print_error("cannot find address in input script", bytes.encode('hex'))
        return
    x_sig = [x[1].encode('hex') for x in decoded[1:-1]]
    dec2 = [x for x in script_GetOp(decoded[-1][1])]
    m = dec2[0][0] - opcodes.OP_1 + 1
    n = dec2[-2][0] - opcodes.OP_1 + 1
    op_m = opcodes.OP_1 + m - 1
    op_n = opcodes.OP_1 + n - 1
    match_multisig = [op_m] + [opcodes.OP_PUSHDATA4] * n + [
        op_n, opcodes.OP_CHECKMULTISIG
    ]
    if not match_decoded(dec2, match_multisig):
        print_error("cannot find address in input script", bytes.encode('hex'))
        return
    x_pubkeys = map(lambda x: x[1].encode('hex'), dec2[1:-2])
    pubkeys = [safe_parse_pubkey(x) for x in x_pubkeys]
    redeemScript = multisig_script(pubkeys, m)
    # write result in d
    d['type'] = 'p2sh'
    d['num_sig'] = m
    d['signatures'] = parse_sig(x_sig)
    d['x_pubkeys'] = x_pubkeys
    d['pubkeys'] = pubkeys
    d['redeemScript'] = redeemScript
    d['address'] = hash160_to_p2sh(hash_160(redeemScript.decode('hex')))
Example #47
0
 def __init__(self, lang=None):
     lang = lang or 'en'
     print_error('language', lang)
     filename = filenames.get(lang[0:2], 'english.txt')
     self.wordlist = load_wordlist(filename)
     print_error("wordlist has %d words" % len(self.wordlist))
Example #48
0
def parse_scriptSig(d, bytes):
    try:
        decoded = [x for x in script_GetOp(bytes)]
    except Exception:
        # coinbase transactions raise an exception
        print_error("cannot find address in input script", bytes.encode('hex'))
        return

    # payto_pubkey
    match = [opcodes.OP_PUSHDATA4]
    if match_decoded(decoded, match):
        sig = decoded[0][1].encode('hex')
        d['address'] = "(pubkey)"
        d['signatures'] = [sig]
        d['num_sig'] = 1
        d['x_pubkeys'] = ["(pubkey)"]
        d['pubkeys'] = ["(pubkey)"]
        return

    # non-generated TxIn transactions push a signature
    # (seventy-something bytes) and then their public key
    # (65 bytes) onto the stack:
    match = [opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4]
    if match_decoded(decoded, match):
        sig = decoded[0][1].encode('hex')
        x_pubkey = decoded[1][1].encode('hex')
        try:
            signatures = parse_sig([sig])
            pubkey = parse_xpub(x_pubkey)
        except:
            import traceback
            traceback.print_exc(file=sys.stdout)
            print_error("cannot find address in input script",
                        bytes.encode('hex'))
            return
        d['signatures'] = signatures
        d['x_pubkeys'] = [x_pubkey]
        d['num_sig'] = 1
        d['pubkeys'] = [pubkey]
        d['address'] = public_key_to_bc_address(pubkey.decode('hex'))
        return

    # p2sh transaction, 2 of n
    match = [opcodes.OP_0]
    while len(match) < len(decoded):
        match.append(opcodes.OP_PUSHDATA4)

    if not match_decoded(decoded, match):
        print_error("cannot find address in input script", bytes.encode('hex'))
        return

    x_sig = map(lambda x: x[1].encode('hex'), decoded[1:-1])
    d['signatures'] = parse_sig(x_sig)
    d['num_sig'] = 2

    dec2 = [x for x in script_GetOp(decoded[-1][1])]
    match_2of2 = [
        opcodes.OP_2, opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4, opcodes.OP_2,
        opcodes.OP_CHECKMULTISIG
    ]
    match_2of3 = [
        opcodes.OP_2, opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4,
        opcodes.OP_PUSHDATA4, opcodes.OP_3, opcodes.OP_CHECKMULTISIG
    ]
    if match_decoded(dec2, match_2of2):
        x_pubkeys = [dec2[1][1].encode('hex'), dec2[2][1].encode('hex')]
    elif match_decoded(dec2, match_2of3):
        x_pubkeys = [
            dec2[1][1].encode('hex'), dec2[2][1].encode('hex'),
            dec2[3][1].encode('hex')
        ]
    else:
        print_error("cannot find address in input script", bytes.encode('hex'))
        return

    d['x_pubkeys'] = x_pubkeys
    pubkeys = map(parse_xpub, x_pubkeys)
    d['pubkeys'] = pubkeys
    redeemScript = Transaction.multisig_script(pubkeys, 2)
    d['redeemScript'] = redeemScript
    d['address'] = hash_160_to_bc_address(hash_160(redeemScript.decode('hex')),
                                          5)
Example #49
0
 def handleConnected(self):
     util.print_error("connected", self.address)
Example #50
0
    def send_http(self, messages, callback):
        import urllib2, json, time, cookielib
        print_error("send_http", messages)

        if self.proxy:
            socks.setdefaultproxy(self.proxy_mode, self.proxy["host"],
                                  int(self.proxy["port"]))
            socks.wrapmodule(urllib2)

        cj = cookielib.CookieJar()
        opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
        urllib2.install_opener(opener)

        t1 = time.time()

        data = []
        ids = []
        for m in messages:
            method, params = m
            if type(params) != type([]): params = [params]
            data.append({
                'method': method,
                'id': self.message_id,
                'params': params
            })
            self.unanswered_requests[
                self.message_id] = method, params, callback
            ids.append(self.message_id)
            self.message_id += 1

        if data:
            data_json = json.dumps(data)
        else:
            # poll with GET
            data_json = None

        headers = {'content-type': 'application/json'}
        if self.session_id:
            headers['cookie'] = 'SESSION=%s' % self.session_id

        try:
            req = urllib2.Request(self.connection_msg, data_json, headers)
            response_stream = urllib2.urlopen(req, timeout=DEFAULT_TIMEOUT)
        except Exception:
            return

        for index, cookie in enumerate(cj):
            if cookie.name == 'SESSION':
                self.session_id = cookie.value

        response = response_stream.read()
        self.bytes_received += len(response)
        if response:
            response = json.loads(response)
            if type(response) is not type([]):
                self.queue_json_response(response)
            else:
                for item in response:
                    self.queue_json_response(item)

        if response:
            self.poll_interval = 1
        else:
            if self.poll_interval < 15:
                self.poll_interval += 1
        #print self.poll_interval, response

        self.rtime = time.time() - t1
        self.is_connected = True
        return ids
Example #51
0
    def queue_json_response(self, c):

        # uncomment to debug
        if self.debug:
            print_error("<--", c)

        msg_id = c.get('id')
        error = c.get('error')

        if error:
            print_error("received error:", c)
            if msg_id is not None:
                with self.lock:
                    method, params, callback = self.unanswered_requests.pop(
                        msg_id)
                callback(
                    self, {
                        'method': method,
                        'params': params,
                        'error': error,
                        'id': msg_id
                    })

            return

        if msg_id is not None:
            with self.lock:
                method, params, callback = self.unanswered_requests.pop(msg_id)
            result = c.get('result')

        else:
            # notification
            method = c.get('method')
            params = c.get('params')

            if method == 'blockchain.numblocks.subscribe':
                result = params[0]
                params = []

            elif method == 'blockchain.headers.subscribe':
                result = params[0]
                params = []

            elif method == 'blockchain.address.subscribe':
                addr = params[0]
                result = params[1]
                params = [addr]

            with self.lock:
                for k, v in self.subscriptions.items():
                    if (method, params) in v:
                        callback = k
                        break
                else:
                    print_error("received unexpected notification", method,
                                params)
                    print_error(self.subscriptions)
                    return

        callback(self, {
            'method': method,
            'params': params,
            'result': result,
            'id': msg_id
        })
Example #52
0
                        os.unlink(rej)
                    os.rename(temporary_path, rej)
                else:
                    if cert_has_expired(cert_path):
                        print_error("certificate has expired:", cert_path)
                        os.unlink(cert_path)
                    else:
                        print_msg("wrong certificate", self.host)
                return
            except Exception:
                print_error("wrap_socket failed", self.host)
                traceback.print_exc(file=sys.stdout)
                return

            if is_new:
                print_error("saving certificate for", self.host)
                os.rename(temporary_path, cert_path)

        s.settimeout(60)
        self.s = s
        self.is_connected = True
        print_error("connected to", self.host, self.port)

    def run_tcp(self):
        try:
            #if self.use_ssl: self.s.do_handshake()
            out = ''
            while self.is_connected:
                try:
                    timeout = False
                    msg = self.s.recv(1024)
Example #53
0
    def run(self):
        while self.is_running():
            try:
                i, response = self.queue.get(timeout=0.1)
            except Queue.Empty:

                if len(self.interfaces) + len(
                        self.pending_servers) < self.num_server:
                    self.start_random_interface()
                if not self.interfaces:
                    if time.time(
                    ) - self.disconnected_time > DISCONNECTED_RETRY_INTERVAL:
                        print_error('network: retrying connections')
                        self.disconnected_servers = set([])
                        self.disconnected_time = time.time()
                continue

            if response is not None:
                self.process_response(i, response)
                continue

            # if response is None it is a notification about the interface
            if i.server in self.pending_servers:
                self.pending_servers.remove(i.server)

            if i.is_connected:
                self.add_interface(i)
                self.add_recent_server(i)
                i.send_request({
                    'method': 'blockchain.headers.subscribe',
                    'params': []
                })
                if i == self.interface:
                    print_error('sending subscriptions to',
                                self.interface.server)
                    self.send_subscriptions()
                    self.set_status('connected')
            else:
                self.disconnected_servers.add(i.server)
                if i.server in self.interfaces:
                    self.remove_interface(i)
                if i.server in self.heights:
                    self.heights.pop(i.server)
                if i == self.interface:
                    self.set_status('disconnected')

            if not self.interface.is_connected:
                if self.config.get('auto_cycle'):
                    self.switch_to_random_interface()
                else:
                    if self.default_server not in self.disconnected_servers:
                        print_error("restarting main interface")
                        if self.default_server in self.interfaces.keys():
                            self.switch_to_interface(
                                self.interfaces[self.default_server])
                        else:
                            self.interface = self.start_interface(
                                self.default_server)

        print_error("Network: Stopping interfaces")
        for i in self.interfaces.values():
            i.stop()
Example #54
0
 def stop(self):
     print_error("stopping network")
     with self.lock:
         self.running = False
Example #55
0
        if s is None:
            return

        s.settimeout(2)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)

        if self.use_ssl:
            try:
                s = ssl.wrap_socket(
                    s,
                    ssl_version=ssl.PROTOCOL_SSLv3,
                    cert_reqs=ssl.CERT_REQUIRED,
                    ca_certs=(temporary_path if is_new else cert_path),
                    do_handshake_on_connect=True)
            except ssl.SSLError, e:
                print_error("SSL error:", self.host, e)
                if e.errno != 1:
                    return
                if is_new:
                    rej = cert_path + '.rej'
                    if os.path.exists(rej):
                        os.unlink(rej)
                    os.rename(temporary_path, rej)
                else:
                    with open(cert_path) as f:
                        cert = f.read()
                    try:
                        x = x509.X509()
                        x.parse(cert)
                        x.slow_parse()
                    except:
Example #56
0
    def start_tcp(self):

        self.connection_msg = self.host + ':%d' % self.port

        if self.proxy is not None:

            socks.setdefaultproxy(self.proxy_mode, self.proxy["host"],
                                  int(self.proxy["port"]))
            socket.socket = socks.socksocket

            # prevent dns leaks, see http://stackoverflow.com/questions/13184205/dns-over-proxy
            def getaddrinfo(*args):
                return [(socket.AF_INET, socket.SOCK_STREAM, 6, '', (args[0],
                                                                     args[1]))]

            socket.getaddrinfo = getaddrinfo

        if self.use_ssl:
            cert_path = os.path.join(self.config.path, 'certs', self.host)

            if not os.path.exists(cert_path):
                is_new = True
                # get server certificate.
                # Do not use ssl.get_server_certificate because it does not work with proxy
                try:
                    l = socket.getaddrinfo(self.host, self.port,
                                           socket.AF_UNSPEC,
                                           socket.SOCK_STREAM)
                except socket.gaierror:
                    print_error("error: cannot resolve", self.host)
                    return

                for res in l:
                    try:
                        s = socket.socket(res[0], socket.SOCK_STREAM)
                        s.connect(res[4])
                    except:
                        s = None
                        continue

                    try:
                        s = ssl.wrap_socket(s,
                                            ssl_version=ssl.PROTOCOL_SSLv3,
                                            cert_reqs=ssl.CERT_NONE,
                                            ca_certs=None)
                    except ssl.SSLError, e:
                        print_error("SSL error retrieving SSL certificate:",
                                    self.host, e)
                        s = None

                    break

                if s is None:
                    return

                dercert = s.getpeercert(True)
                s.close()
                cert = ssl.DER_cert_to_PEM_cert(dercert)
                # workaround android bug
                cert = re.sub("([^\n])-----END CERTIFICATE-----",
                              "\\1\n-----END CERTIFICATE-----", cert)
                temporary_path = cert_path + '.temp'
                with open(temporary_path, "w") as f:
                    f.write(cert)

            else:
                is_new = False
Example #57
0
 def handleMessage(self):
     assert self.data[0:3] == 'id:'
     util.print_error("message received", self.data)
     request_id = self.data[3:]
     request_queue.put((self, request_id))
Example #58
0
class Interface(threading.Thread):
    def __init__(self, server, config=None):

        threading.Thread.__init__(self)
        self.daemon = True
        self.config = config if config is not None else SimpleConfig()
        self.connect_event = threading.Event()

        self.subscriptions = {}
        self.lock = threading.Lock()

        self.rtime = 0
        self.bytes_received = 0
        self.is_connected = False
        self.poll_interval = 1

        self.debug = False  # dump network messages. can be changed at runtime using the console

        #json
        self.message_id = 0
        self.unanswered_requests = {}
        self.pending_transactions_for_notifications = []

        # parse server
        self.server = server
        try:
            host, port, protocol = self.server.split(':')
            port = int(port)
        except Exception:
            self.server = None
            return

        if protocol not in 'ghst':
            raise Exception('Unknown protocol: %s' % protocol)

        self.host = host
        self.port = port
        self.protocol = protocol
        self.use_ssl = (protocol in 'sg')
        self.proxy = self.parse_proxy_options(self.config.get('proxy'))
        if self.proxy:
            self.proxy_mode = proxy_modes.index(self.proxy["mode"]) + 1

    def queue_json_response(self, c):

        # uncomment to debug
        if self.debug:
            print_error("<--", c)

        msg_id = c.get('id')
        error = c.get('error')

        if error:
            print_error("received error:", c)
            if msg_id is not None:
                with self.lock:
                    method, params, callback = self.unanswered_requests.pop(
                        msg_id)
                callback(
                    self, {
                        'method': method,
                        'params': params,
                        'error': error,
                        'id': msg_id
                    })

            return

        if msg_id is not None:
            with self.lock:
                method, params, callback = self.unanswered_requests.pop(msg_id)
            result = c.get('result')

        else:
            # notification
            method = c.get('method')
            params = c.get('params')

            if method == 'blockchain.numblocks.subscribe':
                result = params[0]
                params = []

            elif method == 'blockchain.headers.subscribe':
                result = params[0]
                params = []

            elif method == 'blockchain.address.subscribe':
                addr = params[0]
                result = params[1]
                params = [addr]

            with self.lock:
                for k, v in self.subscriptions.items():
                    if (method, params) in v:
                        callback = k
                        break
                else:
                    print_error("received unexpected notification", method,
                                params)
                    print_error(self.subscriptions)
                    return

        callback(self, {
            'method': method,
            'params': params,
            'result': result,
            'id': msg_id
        })

    def on_version(self, i, result):
        self.server_version = result

    def start_http(self):
        self.session_id = None
        self.is_connected = True
        self.connection_msg = ('https' if self.use_ssl else
                               'http') + '://%s:%d' % (self.host, self.port)
        try:
            self.poll()
        except Exception:
            print_error("http init session failed")
            self.is_connected = False
            return

        if self.session_id:
            print_error('http session:', self.session_id)
            self.is_connected = True
        else:
            self.is_connected = False

    def run_http(self):
        self.is_connected = True
        while self.is_connected:
            try:
                if self.session_id:
                    self.poll()
                time.sleep(self.poll_interval)
            except socket.gaierror:
                break
            except socket.error:
                break
            except Exception:
                traceback.print_exc(file=sys.stdout)
                break

        self.is_connected = False

    def poll(self):
        self.send([], None)

    def send_http(self, messages, callback):
        import urllib2, json, time, cookielib
        print_error("send_http", messages)

        if self.proxy:
            socks.setdefaultproxy(self.proxy_mode, self.proxy["host"],
                                  int(self.proxy["port"]))
            socks.wrapmodule(urllib2)

        cj = cookielib.CookieJar()
        opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
        urllib2.install_opener(opener)

        t1 = time.time()

        data = []
        ids = []
        for m in messages:
            method, params = m
            if type(params) != type([]): params = [params]
            data.append({
                'method': method,
                'id': self.message_id,
                'params': params
            })
            self.unanswered_requests[
                self.message_id] = method, params, callback
            ids.append(self.message_id)
            self.message_id += 1

        if data:
            data_json = json.dumps(data)
        else:
            # poll with GET
            data_json = None

        headers = {'content-type': 'application/json'}
        if self.session_id:
            headers['cookie'] = 'SESSION=%s' % self.session_id

        try:
            req = urllib2.Request(self.connection_msg, data_json, headers)
            response_stream = urllib2.urlopen(req, timeout=DEFAULT_TIMEOUT)
        except Exception:
            return

        for index, cookie in enumerate(cj):
            if cookie.name == 'SESSION':
                self.session_id = cookie.value

        response = response_stream.read()
        self.bytes_received += len(response)
        if response:
            response = json.loads(response)
            if type(response) is not type([]):
                self.queue_json_response(response)
            else:
                for item in response:
                    self.queue_json_response(item)

        if response:
            self.poll_interval = 1
        else:
            if self.poll_interval < 15:
                self.poll_interval += 1
        #print self.poll_interval, response

        self.rtime = time.time() - t1
        self.is_connected = True
        return ids

    def start_tcp(self):

        self.connection_msg = self.host + ':%d' % self.port

        if self.proxy is not None:

            socks.setdefaultproxy(self.proxy_mode, self.proxy["host"],
                                  int(self.proxy["port"]))
            socket.socket = socks.socksocket

            # prevent dns leaks, see http://stackoverflow.com/questions/13184205/dns-over-proxy
            def getaddrinfo(*args):
                return [(socket.AF_INET, socket.SOCK_STREAM, 6, '', (args[0],
                                                                     args[1]))]

            socket.getaddrinfo = getaddrinfo

        if self.use_ssl:
            cert_path = os.path.join(self.config.path, 'certs', self.host)

            if not os.path.exists(cert_path):
                is_new = True
                # get server certificate.
                # Do not use ssl.get_server_certificate because it does not work with proxy
                try:
                    l = socket.getaddrinfo(self.host, self.port,
                                           socket.AF_UNSPEC,
                                           socket.SOCK_STREAM)
                except socket.gaierror:
                    print_error("error: cannot resolve", self.host)
                    return

                for res in l:
                    try:
                        s = socket.socket(res[0], socket.SOCK_STREAM)
                        s.connect(res[4])
                    except:
                        s = None
                        continue

                    try:
                        s = ssl.wrap_socket(s,
                                            ssl_version=ssl.PROTOCOL_SSLv3,
                                            cert_reqs=ssl.CERT_NONE,
                                            ca_certs=None)
                    except ssl.SSLError, e:
                        print_error("SSL error retrieving SSL certificate:",
                                    self.host, e)
                        s = None

                    break

                if s is None:
                    return

                dercert = s.getpeercert(True)
                s.close()
                cert = ssl.DER_cert_to_PEM_cert(dercert)
                # workaround android bug
                cert = re.sub("([^\n])-----END CERTIFICATE-----",
                              "\\1\n-----END CERTIFICATE-----", cert)
                temporary_path = cert_path + '.temp'
                with open(temporary_path, "w") as f:
                    f.write(cert)

            else:
                is_new = False

        try:
            addrinfo = socket.getaddrinfo(self.host, self.port,
                                          socket.AF_UNSPEC, socket.SOCK_STREAM)
        except socket.gaierror:
            print_error("error: cannot resolve", self.host)
            return

        for res in addrinfo:
            try:
                s = socket.socket(res[0], socket.SOCK_STREAM)
                s.settimeout(2)
                s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
                s.connect(res[4])
            except:
                s = None
                continue
            break

        if s is None:
            print_error("failed to connect", self.host, self.port)
            return

        if self.use_ssl:
            try:
                s = ssl.wrap_socket(
                    s,
                    ssl_version=ssl.PROTOCOL_SSLv3,
                    cert_reqs=ssl.CERT_REQUIRED,
                    ca_certs=(temporary_path if is_new else cert_path),
                    do_handshake_on_connect=True)
            except ssl.SSLError, e:
                print_error("SSL error:", self.host, e)
                if e.errno != 1:
                    return
                if is_new:
                    rej = cert_path + '.rej'
                    if os.path.exists(rej):
                        os.unlink(rej)
                    os.rename(temporary_path, rej)
                else:
                    if cert_has_expired(cert_path):
                        print_error("certificate has expired:", cert_path)
                        os.unlink(cert_path)
                    else:
                        print_msg("wrong certificate", self.host)
                return
            except Exception:
                print_error("wrap_socket failed", self.host)
                traceback.print_exc(file=sys.stdout)
                return
Example #59
0
 def handleClose(self):
     util.print_error("closed", self.address)
Example #60
0
    def sign(self, private_keys):
        import deserialize

        for i in range(len(self.inputs)):
            txin = self.inputs[i]
            tx_for_sig = self.serialize(self.inputs, self.outputs, for_sig=i)

            if txin.get('redeemScript'):
                # 1 parse the redeem script
                num, redeem_pubkeys = deserialize.parse_redeemScript(
                    txin.get('redeemScript'))
                self.inputs[i]["pubkeys"] = redeem_pubkeys

                # build list of public/private keys
                keypairs = {}
                for sec in private_keys.values():
                    compressed = is_compressed(sec)
                    pkey = regenerate_key(sec)
                    pubkey = GetPubKey(pkey.pubkey, compressed)
                    keypairs[pubkey.encode('hex')] = sec

                # list of already existing signatures
                signatures = txin.get("signatures", [])
                print_error("signatures", signatures)

                for pubkey in redeem_pubkeys:
                    public_key = ecdsa.VerifyingKey.from_string(
                        pubkey[2:].decode('hex'), curve=SECP256k1)
                    for s in signatures:
                        try:
                            public_key.verify_digest(
                                s.decode('hex')[:-1],
                                Hash(tx_for_sig.decode('hex')),
                                sigdecode=ecdsa.util.sigdecode_der)
                            break
                        except ecdsa.keys.BadSignatureError:
                            continue
                    else:
                        # check if we have a key corresponding to the redeem script
                        if pubkey in keypairs.keys():
                            # add signature
                            sec = keypairs[pubkey]
                            compressed = is_compressed(sec)
                            pkey = regenerate_key(sec)
                            secexp = pkey.secret
                            private_key = ecdsa.SigningKey.from_secret_exponent(
                                secexp, curve=SECP256k1)
                            public_key = private_key.get_verifying_key()
                            sig = private_key.sign_digest(
                                Hash(tx_for_sig.decode('hex')),
                                sigencode=ecdsa.util.sigencode_der)
                            assert public_key.verify_digest(
                                sig,
                                Hash(tx_for_sig.decode('hex')),
                                sigdecode=ecdsa.util.sigdecode_der)
                            signatures.append(sig.encode('hex'))

                # for p2sh, pubkeysig is a tuple (may be incomplete)
                self.inputs[i]["signatures"] = signatures
                print_error("signatures", signatures)
                self.is_complete = len(signatures) == num

            else:
                sec = private_keys[txin['address']]
                compressed = is_compressed(sec)
                pkey = regenerate_key(sec)
                secexp = pkey.secret

                private_key = ecdsa.SigningKey.from_secret_exponent(
                    secexp, curve=SECP256k1)
                public_key = private_key.get_verifying_key()
                pkey = EC_KEY(secexp)
                pubkey = GetPubKey(pkey.pubkey, compressed)
                sig = private_key.sign_digest(
                    Hash(tx_for_sig.decode('hex')),
                    sigencode=ecdsa.util.sigencode_der)
                assert public_key.verify_digest(
                    sig,
                    Hash(tx_for_sig.decode('hex')),
                    sigdecode=ecdsa.util.sigdecode_der)

                self.inputs[i]["pubkeysig"] = [(pubkey, sig)]
                self.is_complete = True

        self.raw = self.serialize(self.inputs, self.outputs)