URI: 
       tadded code and default cert files to handle ssl, the user can generate their own self-signed cert files but its not necessary for security - electrum-personal-server - Maximally lightweight electrum server for a single user
  HTML git clone https://git.parazyd.org/electrum-personal-server
   DIR Log
   DIR Files
   DIR Refs
   DIR README
       ---
   DIR commit 76386c21c7e1c6b766949144be00dd59036ba559
   DIR parent 471fc07f4e89b11919017c2f912301c912ba93ae
  HTML Author: chris-belcher <chris-belcher@users.noreply.github.com>
       Date:   Fri, 16 Mar 2018 13:03:30 +0000
       
       added code and default cert files to handle ssl, the user can generate their own self-signed cert files but its not necessary for security
       
       Diffstat:
         M README.md                           |      14 ++++----------
         A cert.crt                            |      19 +++++++++++++++++++
         A cert.key                            |      27 +++++++++++++++++++++++++++
         M config.cfg_sample                   |       8 +++++++-
         M server.py                           |      46 +++++++++++++++++--------------
       
       5 files changed, 82 insertions(+), 32 deletions(-)
       ---
   DIR diff --git a/README.md b/README.md
       t@@ -38,13 +38,10 @@ wallet addresses to the `[wallets]` section.
        Finally run `./server.py` on Linux or double-click `run-server.bat` on Windows.
        The first time the server is run it will import all configured addresses as
        watch-only into the Bitcoin node, and then exit giving you a chance to
       -`-rescan` if your wallet contains historical transactions.
       +rescan if your wallet contains historical transactions.
        
       -Electrum wallet must be configured to connect to the server. SSL must be
       -disabled which can be done either by `Tools` -> `Connection` -> Uncheck box
       -`Use SSL`, or starting with the command line flag `--nossl`, depending on the
       -version of Electrum. Tell Electrum to connect to the server in
       -`Tools` -> `Server`, usually `localhost` if running on the same machine.
       +Tell Electrum to connect to the server in `Tools` -> `Server`, usually
       +`localhost` if running on the same machine.
        
        Note that you can also try this with on [testnet bitcoin](https://en.bitcoin.it/wiki/Testnet).
        Electrum can be started in testnet mode with the command line flag `--testnet`.
       t@@ -64,8 +61,6 @@ tunnel.
        This project is in alpha stages as there are several essential missing
        features such as:
        
       -* The server does not support SSL so Electrum must be configured to disable it.
       -
        * Deterministic wallets and master public keys are not supported. Addresses
          must be imported individually.
        
       t@@ -90,4 +85,4 @@ I can be contacted on freenode IRC on the `#bitcoin` and `#electrum` channels.
        
        ## Media Coverage
        
       -* https://bitcoinmagazine.com/articles/electrum-personal-server-will-give-users-full-node-security-they-need/
       -\ No newline at end of file
       +* https://bitcoinmagazine.com/articles/electrum-personal-server-will-give-users-full-node-security-they-need/
   DIR diff --git a/cert.crt b/cert.crt
       t@@ -0,0 +1,19 @@
       +-----BEGIN CERTIFICATE-----
       +MIIDBjCCAe4CCQDRr9lL8wL3+jANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB
       +VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
       +cyBQdHkgTHRkMB4XDTE4MDMxMzAwMDc1OFoXDTIzMDMxMjAwMDc1OFowRTELMAkG
       +A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0
       +IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
       +ALvqB0SrsncAhIkvmkLhhE4GW0MKGQognd1Vm67gnOZ4rC2+HwF3xS1xpJDZIjRJ
       +Tump6bp4dFoyty2vsrWJzzBib3xPh6yx37cqkQkLS7mlvl5J+VaV3vefW9Jt84Me
       +hT2xH62haZ6gyAI2OItyoC57uiKGJ/4TNcXZRchc3Ee1R29q5evMjJRBG6QLfHmc
       +btsSquPwIoGxaTICNZmmZlHKct+6bBGGbJ1tJttWCeLQe//rW9KBs+Ip3heNxZpQ
       +RZgPYwxFhZg4g4nv0CmIeMCC8KBZE82P4SRjMirVZD0YH/nNYQTEGwutZZ8F0K8Z
       +pWR1/HDXLQVeF66SreRxp98CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEATELegjEF
       +03r1SWSsJ2Jhg4gLDLi3tORqHFzu3S8JECi57geZKmF7NmhJHXd0vemusX9P8IRh
       +A0B9mEU8e92k2fenqxj/t71rm+e71PBU2GwXsE5vtkX/AGmsk6KhAsbe56A3IUGK
       +JvS3HZ2JS9MmwoUI3cHB5ExBisk4YkDripA6cIkF4i9ctQbk3bzN7FhCbj9wrKBR
       +Lg48tbswQw4UUUZ70U5uW3pt9pPbDErSifBv6UMoY8A2s4RqiyXDyI/cxVFsY71A
       +c+tInksyG4KAeDo919/Y0bNjgzOCt267ApQE96j4lnGCx/KSwduWBNMng6qeTecx
       +ZOyPoABtFZcv1g==
       +-----END CERTIFICATE-----
   DIR diff --git a/cert.key b/cert.key
       t@@ -0,0 +1,27 @@
       +-----BEGIN RSA PRIVATE KEY-----
       +MIIEogIBAAKCAQEAu+oHRKuydwCEiS+aQuGETgZbQwoZCiCd3VWbruCc5nisLb4f
       +AXfFLXGkkNkiNElO6anpunh0WjK3La+ytYnPMGJvfE+HrLHftyqRCQtLuaW+Xkn5
       +VpXe959b0m3zgx6FPbEfraFpnqDIAjY4i3KgLnu6IoYn/hM1xdlFyFzcR7VHb2rl
       +68yMlEEbpAt8eZxu2xKq4/AigbFpMgI1maZmUcpy37psEYZsnW0m21YJ4tB7/+tb
       +0oGz4ineF43FmlBFmA9jDEWFmDiDie/QKYh4wILwoFkTzY/hJGMyKtVkPRgf+c1h
       +BMQbC61lnwXQrxmlZHX8cNctBV4XrpKt5HGn3wIDAQABAoIBAHjQSuH8nZ3i6FMn
       +Fr+/LAfaEFy2pkiblcNSoeg6IsYOeWxjWp3f+hZwhQRXhaUmKKUUB+BKR0wiZSDr
       +YDNVKa8K6nB61VjTd2jU5jBxYbs284C9gKAJdTOw8iEFbdU0DygNs7c3GqfQ6SZ6
       +47nL9W5NP+uoYxf4E89jFHlwMnOq3n2vW3TUIys0Op3RG40VqKEhU/XsOIjU5B7C
       +HN2wMKMol3N62t8rbX/J7PaWxR3O017kim1Xz0fSbYA+nHk6SvA2rXMdShACcBRz
       +t/DK4TzjwUL3a7P8Lvw8cfe0C6pBQD1sAcUxw4CQBcCs/PMCModJWoUmCflZZTqe
       ++WdDA9kCgYEA8yvQyVhK4xMAWzCzaRjBNpFpFJAX6XAHjMmhnOCLNe2m7SQdi5p4
       +/j65P9pjRv+nD07cv/7mrYAWXFXkLgz3WWObR4A5eWjA0gnyIHJGNa9NQ7vCWu6g
       +aQpI+hnnwShakxuQ7w9w1WKAXh0rvnWO4hOxHlr5ve7UpEN18s7uzQMCgYEAxdPu
       +b38Qb2tGUXWQOBYsJNvhdwevO8EPggP044ENJvQW0gmJuVsF/Yrua0TNrUv+ETYd
       +mgK6MhNlxR6v3STwDg/OpM+MvgBafKRX2PeBJTf6k3Yx7ykxhLNPmuL6RCVv3ou9
       +F064UzzyM9ApyWna7b0+1R1XPS+VttWZliLefPUCgYAb0iV/A7T9qczeogHEwmpI
       +nfZRvfKeaIzUlLUCx8Xlk50HgJxIvpGdNPvozEmTc+hfHfyvkrA9pWvpgIIsqpsa
       +BQVc9tSciVmWLkEfaTOTLM1ANJkV4jtECUM0KgaT2NQUBJFeaHvWTgC1w8yfa7+/
       +KdWXzXzJOCvn5zf1Yat8lQKBgGgsfP+rqqzxkZrtzJ8sVdynCSiUHFvcA12U1c1D
       +tPhRSv8Z1LON0i68jWZhWemq/cR0ecwTKZebDVlrGnLas6rD+i5huRyItR2zsSro
       +0tIVk1c5w3vMdm4Jup62bdGa4TkQ3uc6Jeh3TJeqQ4bzvjy5DjBNfhYTS8R24KTm
       +AcFNAoGAPF4fOuTeFwy+a+LZ5ZTSHTiQ5YZYmnu27mM4YS0KjWCs2UKYKr47tOhf
       +96kuaN6zcE7gqawMTDGW+77DxTwKpbIEvKRb03PfqGnD8SHQmAQCjLOlnhW816n/
       ++AtLlzWB7dBtgO/cW9lFIzyPCVlXRcbsn3RKS5HnLgIkuXn/kZI=
       +-----END RSA PRIVATE KEY-----
   DIR diff --git a/config.cfg_sample b/config.cfg_sample
       t@@ -43,10 +43,16 @@ gap_limit = 25
        [electrum-server]
        # 0.0.0.0 to accept connections from any IP
        #127.0.0.1 to accept from only localhost
       -# recommended you accept localhost only and for connecting remotely use a ssh tunnel
       +# recommend you accept localhost only, for connecting remotely use a ssh tunnel
        host = 127.0.0.1
        port = 50002
        
       +#uses the default one, which is fine because by default nobody should be
       +# allowed to connect to your server or scan your packets
       +#to generate another certificate see https://github.com/spesmilo/electrum-server/blob/ce1b11d7f5f7a70a3b6cc7ec1d3e552436e54ffe/HOWTO.md#step-8-create-a-self-signed-ssl-cert
       +certfile = cert.crt
       +keyfile = cert.key
       +
        [misc]
        # not implemented yet
        print_debug = false
   DIR diff --git a/server.py b/server.py
       t@@ -179,6 +179,9 @@ def handle_query(sock, line, rpc, address_history, deterministic_wallets):
                    result = e.message
                debug("tx broadcast result = " + str(result))
                send_response(sock, query, result)
       +    elif method == "mempool.get_fee_histogram":
       +        result = [] #not handling, sending empty
       +        send_response(sock, query, result)
            elif method == "blockchain.estimatefee":
                estimate = rpc.call("estimatesmartfee", [query["params"][0]])
                feerate = 0.0001
       t@@ -209,7 +212,7 @@ def handle_query(sock, line, rpc, address_history, deterministic_wallets):
                send_response(sock, query, []) #no peers to report
            else:
                log("*** BUG! Not handling method: " + method + " query=" + str(query))
       -        #TODO just send back the same query will result = []
       +        #TODO just send back the same query with result = []
        
        def get_block_header(rpc, blockhash):
            rpc_head = rpc.call("getblockheader", [blockhash])
       t@@ -239,34 +242,34 @@ def create_server_socket(hostport):
            server_sock = socket.socket()
            server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            server_sock.bind(hostport)
       +    server_sock.listen(1)
            log("Listening on " + str(hostport))
            return server_sock
        
        def run_electrum_server(hostport, rpc, address_history, unconfirmed_txes,
                deterministic_wallets, poll_interval_listening,
       -        poll_interval_connected):
       +        poll_interval_connected, certfile, keyfile):
            log("Starting electrum server")
       +    server_sock = create_server_socket(hostport)
       +    server_sock.settimeout(poll_interval_listening)
            while True:
                try:
       -            server_sock = create_server_socket(hostport)
       -            server_sock.settimeout(poll_interval_listening)
       -            while True:
       +            sock = None
       +            while sock == None:
                        try:
       -                    server_sock.listen(1)
                            sock, addr = server_sock.accept()
       -                    break
       +                    sock = ssl.wrap_socket(sock, server_side=True,
       +                        certfile=certfile, keyfile=keyfile,
       +                        ssl_version=ssl.PROTOCOL_SSLv23)
                        except socket.timeout:
                            on_heartbeat_listening(rpc, address_history,
                                unconfirmed_txes, deterministic_wallets)
       -            server_sock.close()
       -            sock.settimeout(poll_interval_connected)
       -            ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
       -            #generate self signed cert with
       -            #openssl req -new -x509 -days 365 -nodes -out server.pem -keyout server.pem
       -            ctx.load_cert_chain(certfile="server.pem",
       -                keyfile="server.pem")
       -            sock = ctx.wrap_socket(sock, server_side=True)
       +                except ssl.SSLError:
       +                    sock.close()
       +                    sock = None
       +
                    log('Electrum connected from ' + str(addr))
       +            sock.settimeout(poll_interval_connected)
                    recv_buffer = bytearray()
                    while True:
                        try:
       t@@ -291,14 +294,13 @@ def run_electrum_server(hostport, rpc, address_history, unconfirmed_txes,
                        log("Electrum wallet disconnected")
                    else:
                        log("IOError: " + repr(e))
       -            import traceback
       -            traceback.print_exc()
       -            on_disconnect(address_history)
       -            time.sleep(0.2)
                    try:
       -                server_sock.close()
       +                sock.close()
                    except IOError:
                        pass
       +            sock = None
       +            on_disconnect(address_history)
       +            time.sleep(0.2)
        
        def get_input_and_output_scriptpubkeys(rpc, txid):
            gettx = rpc.call("gettransaction", [txid])
       t@@ -696,8 +698,10 @@ def main():
                    "poll_interval_listening"))
                poll_interval_connected = int(config.get("bitcoin-rpc",
                    "poll_interval_connected"))
       +        certfile = config.get("electrum-server", "certfile")
       +        keyfile = config.get("electrum-server", "keyfile")
                run_electrum_server(hostport, rpc, address_history, unconfirmed_txes,
                    deterministic_wallets, poll_interval_listening,
       -            poll_interval_connected)
       +            poll_interval_connected, certfile, keyfile)
        
        main()