Commit 7741ea33 authored by Pascal Engélibert's avatar Pascal Engélibert

Server can respond in JSON

parent 08c7d729
......@@ -58,7 +58,10 @@ def sendResponse(client, code, resp, dataformat="ubjson"):
content_raw = ubjson.dumpb(resp)
mime = "application/ubjson"
elif dataformat == "json":
content_raw = json.dumps(resp).encode()
try:
content_raw = json.dumps(resp).encode()
except TypeError:
content_raw = json.dumps({"error": "non_ascii_resp"}).encode()
mime = "text/json"
client.sendall(("HTTP/1.1 "+code+"\r\nContent-type: "+mime+"; charset=UTF-8\r\nContent-length: "+str(len(content_raw))+"\r\n\r\n").encode()+content_raw)
client.close()
......@@ -283,6 +286,7 @@ class ServerThread(Thread):
urll = len(url)
resp = {}
resp_format = "json" if "json" in url else "ubjson"
# Treat request
if "pubkey" in url:
......@@ -297,26 +301,26 @@ class ServerThread(Thread):
in_amount = int(getargv("mix", "", 2, url))
in_base = int(getargv("mix", "", 3, url))
except ValueError:
sendResponse(client, "401 Unauthorized", {"error": "bad_amount_base"})
sendResponse(client, "401 Unauthorized", {"error": "bad_amount_base"}, resp_format)
continue
send_confirm = not "client" in url
try:
sender_keys = PublicKey(sender_pubkey)
except ValueError:
sendResponse(client, "401 Unauthorized", {"error": "bad_sender_pubkey"})
sendResponse(client, "401 Unauthorized", {"error": "bad_sender_pubkey"}, resp_format)
continue
try:
raw = libnacl.sign.Verifier(sender_keys.hex_pk()).verify(content) # Verify
except ValueError:
sendResponse(client, "401 Unauthorized", {"error": "bad_signature"})
sendResponse(client, "401 Unauthorized", {"error": "bad_signature"}, resp_format)
continue
try:
data = self.keys.decrypt_seal(raw[32:]) # Decrypt
except libnacl.CryptError:
sendResponse(client, "403 Forbidden", {"error": "bad_encryption"})
sendResponse(client, "403 Forbidden", {"error": "bad_encryption"}, resp_format)
continue
try:
......@@ -328,7 +332,7 @@ class ServerThread(Thread):
assert "message" in data and type(data["message"]) == bytes
assert (data["message"] == b"" and type(data["out_seeds"][2]) == bytes and len(data["out_seeds"][2]) == 32) or (data["message"] != b"" and data["out_seeds"][2] == None)
except (ubjson.decoder.DecoderException, AssertionError):
sendResponse(client, "403 Forbidden", {"error": "bad_ubjson"})
sendResponse(client, "403 Forbidden", {"error": "bad_ubjson"}, resp_format)
continue
receiver_pubkey = data["receiver"] # receiver pubkey
......@@ -344,13 +348,13 @@ class ServerThread(Thread):
try:
PublicKey(receiver_pubkey)
except ValueError:
sendResponse(client, "403 Forbidden", {"error": "bad_rec_pubkey"})
sendResponse(client, "403 Forbidden", {"error": "bad_rec_pubkey"}, resp_format)
continue
try:
PublicKey(onetime_pubkey)
except ValueError:
sendResponse(client, "403 Forbidden", {"error": "bad_onetime_pubkey"})
sendResponse(client, "403 Forbidden", {"error": "bad_onetime_pubkey"}, resp_format)
continue
# Save tx in pool
......@@ -372,21 +376,21 @@ class ServerThread(Thread):
try:
out_seed1 = bytes.fromhex(getargv("confirm", "", 2, url))
except ValueError:
sendResponse(client, "401 Unauthorized", {"error": "bad_url"})
sendResponse(client, "401 Unauthorized", {"error": "bad_url"}, resp_format)
continue
if not out_seed1 in self.tx_out_index:
sendResponse(client, "404 Not Found", {"error": "unknown_tx"})
sendResponse(client, "404 Not Found", {"error": "unknown_tx"}, resp_format)
continue
tx = self.tx_out_index[out_seed1]
if len(tx.confirms) > 0 or tx.can_confirm or not tx.need_confirm or tx.need_send:
sendResponse(client, "403 Forbidden", {"error": "cannot_confirm"})
sendResponse(client, "403 Forbidden", {"error": "cannot_confirm"}, resp_format)
continue
if receiver_pubkey != tx.receiver_pubkey:
sendResponse(client, "401 Unauthorized", {"error": "bad_rec_pubkey"})
sendResponse(client, "401 Unauthorized", {"error": "bad_rec_pubkey"}, resp_format)
continue
receiver_keys = PublicKey(tx.receiver_pubkey)
......@@ -394,17 +398,17 @@ class ServerThread(Thread):
try:
data = libnacl.sign.Verifier(receiver_keys.hex_pk()).verify(content) # Verify
except ValueError:
sendResponse(client, "401 Unauthorized", {"error": "bad_signature"})
sendResponse(client, "401 Unauthorized", {"error": "bad_signature"}, resp_format)
continue
try:
data = self.keys.decrypt_seal(data) # Decrypt
except libnacl.CryptError:
sendResponse(client, "403 Forbidden", {"error": "bad_encryption"})
sendResponse(client, "403 Forbidden", {"error": "bad_encryption"}, resp_format)
continue
if data[:32] != tx.out_seeds[1] or len(data) < 64:
sendResponse(client, "401 Unauthorized", {"error": "bad_seed"})
sendResponse(client, "401 Unauthorized", {"error": "bad_seed"}, resp_format)
continue
tx.confirms = data[64:]# TODO check size
......@@ -420,21 +424,21 @@ class ServerThread(Thread):
try:
in_seed1 = bytes.fromhex(getargv("getconfirm", "", 2, url))
except ValueError:
sendResponse(client, "401 Unauthorized", {"error": "bad_url"})
sendResponse(client, "401 Unauthorized", {"error": "bad_url"}, resp_format)
continue
if not in_seed1 in self.tx_in_index:
sendResponse(client, "404 Not Found", {"error": "unknown_tx"})
sendResponse(client, "404 Not Found", {"error": "unknown_tx"}, resp_format)
continue
tx = self.tx_in_index[in_seed1]
if not tx.can_confirm or not tx.need_confirm or tx.need_send:
sendResponse(client, "403 Forbidden", {"error": "cannot_confirm"})
sendResponse(client, "403 Forbidden", {"error": "cannot_confirm"}, resp_format)
continue
if sender_pubkey != tx.sender_pubkey:
sendResponse(client, "401 Unauthorized", {"error": "bad_rec_pubkey"})
sendResponse(client, "401 Unauthorized", {"error": "bad_rec_pubkey"}, resp_format)
continue
message = tx.genMixConfirm(self.keys)
......@@ -454,22 +458,22 @@ class ServerThread(Thread):
try:
new_keys = PublicKey(new_pubkey)
except ValueError:
sendResponse(client, "401 Unauthorized", {"error": "bad_pubkey"})
sendResponse(client, "401 Unauthorized", {"error": "bad_pubkey"}, resp_format)
continue
try:
message = libnacl.sign.Verifier(new_keys.hex_pk()).verify(content) # Verify
except ValueError:
sendResponse(client, "401 Unauthorized", {"error": "bad_signature"})
sendResponse(client, "401 Unauthorized", {"error": "bad_signature"}, resp_format)
continue
try:
message = self.keys.decrypt_seal(message) # Decrypt
except libnacl.CryptError:
sendResponse(client, "403 Forbidden", {"error": "bad_encryption"})
sendResponse(client, "403 Forbidden", {"error": "bad_encryption"}, resp_format)
continue
try:
message = ubjson.loadb(message)
except ubjson.decoder.DecoderException:
sendResponse(client, "400 Bad Request", {"error": "bad_ubjson"})
sendResponse(client, "400 Bad Request", {"error": "bad_ubjson"}, resp_format)
continue
if new_pubkey == message["pubkey"]:
......@@ -483,7 +487,7 @@ class ServerThread(Thread):
logPrint("Up "+str(peer), LOG_TRACE)
# Send response
sendResponse(client, "200 OK", resp)
sendResponse(client, "200 OK", resp, resp_format)
self.sock.close()
def stop(self):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment