commit 76386c21c7e1c6b766949144be00dd59036ba559
parent 471fc07f4e89b11919017c2f912301c912ba93ae
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:
5 files changed, 82 insertions(+), 32 deletions(-)
diff --git a/README.md b/README.md
@@ -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`.
@@ -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.
@@ -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/
diff --git a/cert.crt b/cert.crt
@@ -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-----
diff --git a/cert.key b/cert.key
@@ -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-----
diff --git a/config.cfg_sample b/config.cfg_sample
@@ -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
diff --git a/server.py b/server.py
@@ -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
@@ -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])
@@ -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:
@@ -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])
@@ -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()