Factor out components of cli daemon runnable to cli module
This commit is contained in:
parent
787d92c4ee
commit
6dda9fa764
0
crypto_dev_signer/cli/__init__.py
Normal file
0
crypto_dev_signer/cli/__init__.py
Normal file
0
crypto_dev_signer/cli/cmd.py
Normal file
0
crypto_dev_signer/cli/cmd.py
Normal file
122
crypto_dev_signer/cli/handle.py
Normal file
122
crypto_dev_signer/cli/handle.py
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
# standard imports
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
|
||||||
|
# external imports
|
||||||
|
from jsonrpc.exceptions import (
|
||||||
|
JSONRPCServerError,
|
||||||
|
JSONRPCParseError,
|
||||||
|
JSONRPCInvalidParams,
|
||||||
|
)
|
||||||
|
|
||||||
|
# local imports
|
||||||
|
from crypto_dev_signer.eth.transaction import EIP155Transaction
|
||||||
|
from crypto_dev_signer.error import (
|
||||||
|
UnknownAccountError,
|
||||||
|
SignerError,
|
||||||
|
)
|
||||||
|
from crypto_dev_signer.cli.jsonrpc import jsonrpc_ok
|
||||||
|
from .jsonrpc import (
|
||||||
|
jsonrpc_error,
|
||||||
|
is_valid_json,
|
||||||
|
)
|
||||||
|
|
||||||
|
logg = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
#methods = {
|
||||||
|
# 'personal_newAccount': personal_new_account,
|
||||||
|
# 'personal_signTransaction': personal_signTransaction,
|
||||||
|
# 'eth_signTransaction': eth_signTransaction,
|
||||||
|
# 'eth_sign': eth_sign,
|
||||||
|
# }
|
||||||
|
|
||||||
|
|
||||||
|
class SignRequestHandler:
|
||||||
|
|
||||||
|
keystore = None
|
||||||
|
signer = None
|
||||||
|
|
||||||
|
def process_input(self, j):
|
||||||
|
rpc_id = j['id']
|
||||||
|
m = j['method']
|
||||||
|
p = j['params']
|
||||||
|
return (rpc_id, getattr(self, m)(p)) #methods[m](p))
|
||||||
|
|
||||||
|
|
||||||
|
def handle_jsonrpc(self, d):
|
||||||
|
j = None
|
||||||
|
try:
|
||||||
|
j = json.loads(d)
|
||||||
|
is_valid_json(j)
|
||||||
|
logg.debug('{}'.format(d.decode('utf-8')))
|
||||||
|
except Exception as e:
|
||||||
|
logg.exception('input error {}'.format(e))
|
||||||
|
j = json.dumps(jsonrpc_error(None, JSONRPCParseError)).encode('utf-8')
|
||||||
|
raise SignerError(j)
|
||||||
|
|
||||||
|
try:
|
||||||
|
(rpc_id, r) = self.process_input(j)
|
||||||
|
r = jsonrpc_ok(rpc_id, r)
|
||||||
|
j = json.dumps(r).encode('utf-8')
|
||||||
|
except ValueError as e:
|
||||||
|
# TODO: handle cases to give better error context to caller
|
||||||
|
logg.exception('process error {}'.format(e))
|
||||||
|
j = json.dumps(jsonrpc_error(j['id'], JSONRPCServerError)).encode('utf-8')
|
||||||
|
raise SignerError(j)
|
||||||
|
except UnknownAccountError as e:
|
||||||
|
logg.exception('process unknown account error {}'.format(e))
|
||||||
|
j = json.dumps(jsonrpc_error(j['id'], JSONRPCServerError)).encode('utf-8')
|
||||||
|
raise SignerError(j)
|
||||||
|
|
||||||
|
return j
|
||||||
|
|
||||||
|
|
||||||
|
def personal_newAccount(self, p):
|
||||||
|
password = p
|
||||||
|
if p.__class__.__name__ != 'str':
|
||||||
|
if p.__class__.__name__ != 'list':
|
||||||
|
e = JSONRPCInvalidParams()
|
||||||
|
e.data = 'parameter must be list containing one string'
|
||||||
|
raise ValueError(e)
|
||||||
|
logg.error('foo {}'.format(p))
|
||||||
|
if len(p) != 1:
|
||||||
|
e = JSONRPCInvalidParams()
|
||||||
|
e.data = 'parameter must be list containing one string'
|
||||||
|
raise ValueError(e)
|
||||||
|
if p[0].__class__.__name__ != 'str':
|
||||||
|
e = JSONRPCInvalidParams()
|
||||||
|
e.data = 'parameter must be list containing one string'
|
||||||
|
raise ValueError(e)
|
||||||
|
password = p[0]
|
||||||
|
|
||||||
|
r = self.keystore.new(password)
|
||||||
|
|
||||||
|
return add_0x(r)
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: move to translation module ("personal" rpc namespace is node-specific)
|
||||||
|
def personal_signTransaction(self, p):
|
||||||
|
logg.debug('got {} to sign'.format(p[0]))
|
||||||
|
t = EIP155Transaction(p[0], p[0]['nonce'], p[0]['chainId'])
|
||||||
|
raw_signed_tx = self.signer.sign_transaction_to_rlp(t, p[1])
|
||||||
|
o = {
|
||||||
|
'raw': '0x' + raw_signed_tx.hex(),
|
||||||
|
'tx': t.serialize(),
|
||||||
|
}
|
||||||
|
logg.debug('signed {}'.format(o))
|
||||||
|
return o
|
||||||
|
|
||||||
|
|
||||||
|
def eth_signTransaction(self, tx):
|
||||||
|
o = personal_signTransaction([tx[0], ''])
|
||||||
|
return o['raw']
|
||||||
|
|
||||||
|
|
||||||
|
def eth_sign(self, p):
|
||||||
|
logg.debug('got message {} to sign'.format(p[1]))
|
||||||
|
message_type = type(p[1]).__name__
|
||||||
|
if message_type != 'str':
|
||||||
|
raise ValueError('invalid message format, must be {}, not {}'.format(message_type))
|
||||||
|
z = self.signer.sign_ethereum_message(p[0], p[1][2:])
|
||||||
|
return str(z)
|
||||||
|
|
85
crypto_dev_signer/cli/http.py
Normal file
85
crypto_dev_signer/cli/http.py
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
# standard imports
|
||||||
|
import logging
|
||||||
|
|
||||||
|
# external imports
|
||||||
|
from http.server import (
|
||||||
|
HTTPServer,
|
||||||
|
BaseHTTPRequestHandler,
|
||||||
|
)
|
||||||
|
|
||||||
|
# local imports
|
||||||
|
from .handle import SignRequestHandler
|
||||||
|
from crypto_dev_signer.error import SignerError
|
||||||
|
|
||||||
|
logg = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def start_server_http(spec):
|
||||||
|
httpd = HTTPServer(spec, HTTPSignRequestHandler)
|
||||||
|
logg.debug('starting http server {}'.format(spec))
|
||||||
|
httpd.serve_forever()
|
||||||
|
|
||||||
|
|
||||||
|
class HTTPSignRequestHandler(SignRequestHandler, BaseHTTPRequestHandler):
|
||||||
|
|
||||||
|
def do_POST(self):
|
||||||
|
if self.headers.get('Content-Type') != 'application/json':
|
||||||
|
self.send_response(400, 'me read json only')
|
||||||
|
self.end_headers()
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
if 'application/json' not in self.headers.get('Accept').split(','):
|
||||||
|
self.send_response(400, 'me json only speak')
|
||||||
|
self.end_headers()
|
||||||
|
return
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
l = self.headers.get('Content-Length')
|
||||||
|
try:
|
||||||
|
l = int(l)
|
||||||
|
except ValueError:
|
||||||
|
self.send_response(400, 'content length must be integer')
|
||||||
|
self.end_headers()
|
||||||
|
return
|
||||||
|
if l > 4096:
|
||||||
|
self.send_response(400, 'too much information')
|
||||||
|
self.end_headers()
|
||||||
|
return
|
||||||
|
if l < 0:
|
||||||
|
self.send_response(400, 'you are too negative')
|
||||||
|
self.end_headers()
|
||||||
|
return
|
||||||
|
|
||||||
|
b = b''
|
||||||
|
c = 0
|
||||||
|
while c < l:
|
||||||
|
d = self.rfile.read(l-c)
|
||||||
|
if d == None:
|
||||||
|
break
|
||||||
|
b += d
|
||||||
|
c += len(d)
|
||||||
|
if c > 4096:
|
||||||
|
self.send_response(413, 'i should slap you around for lying about your size')
|
||||||
|
self.end_headers()
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
r = self.handle_jsonrpc(d)
|
||||||
|
except SignerError as e:
|
||||||
|
r = e.to_jsonrpc()
|
||||||
|
|
||||||
|
l = len(r)
|
||||||
|
self.send_response(200, 'You are the Keymaster')
|
||||||
|
self.send_header('Content-Length', str(l))
|
||||||
|
self.send_header('Cache-Control', 'no-cache')
|
||||||
|
self.send_header('Content-Type', 'application/json')
|
||||||
|
self.end_headers()
|
||||||
|
|
||||||
|
c = 0
|
||||||
|
while c < l:
|
||||||
|
n = self.wfile.write(r[c:])
|
||||||
|
c += n
|
||||||
|
|
||||||
|
|
30
crypto_dev_signer/cli/jsonrpc.py
Normal file
30
crypto_dev_signer/cli/jsonrpc.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# local imports
|
||||||
|
from crypto_dev_signer.error import UnknownAccountError
|
||||||
|
|
||||||
|
|
||||||
|
def jsonrpc_error(rpc_id, err):
|
||||||
|
return {
|
||||||
|
'jsonrpc': '2.0',
|
||||||
|
'id': rpc_id,
|
||||||
|
'error': {
|
||||||
|
'code': err.CODE,
|
||||||
|
'message': err.MESSAGE,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def jsonrpc_ok(rpc_id, response):
|
||||||
|
return {
|
||||||
|
'jsonrpc': '2.0',
|
||||||
|
'id': rpc_id,
|
||||||
|
'result': response,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def is_valid_json(j):
|
||||||
|
if j.get('id') == 'None':
|
||||||
|
raise ValueError('id missing')
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
58
crypto_dev_signer/cli/socket.py
Normal file
58
crypto_dev_signer/cli/socket.py
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# standard imports
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
import socket
|
||||||
|
import stat
|
||||||
|
|
||||||
|
# local imports
|
||||||
|
from crypto_dev_signer.error import SignerError
|
||||||
|
from .handle import SignRequestHandler
|
||||||
|
|
||||||
|
logg = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def start_server_socket(s):
|
||||||
|
s.listen(10)
|
||||||
|
logg.debug('server started')
|
||||||
|
handler = SignRequestHandler()
|
||||||
|
while True:
|
||||||
|
(csock, caddr) = s.accept()
|
||||||
|
d = csock.recv(4096)
|
||||||
|
|
||||||
|
r = None
|
||||||
|
try:
|
||||||
|
r = handler.handle_jsonrpc(d)
|
||||||
|
except SignerError as e:
|
||||||
|
r = e.to_jsonrpc()
|
||||||
|
|
||||||
|
csock.send(r)
|
||||||
|
csock.close()
|
||||||
|
s.close()
|
||||||
|
|
||||||
|
os.unlink(socket_path)
|
||||||
|
|
||||||
|
|
||||||
|
def start_server_tcp(spec):
|
||||||
|
s = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
|
||||||
|
s.bind(spec)
|
||||||
|
logg.debug('created tcp socket {}'.format(spec))
|
||||||
|
start_server_socket(s)
|
||||||
|
|
||||||
|
|
||||||
|
def start_server_unix(socket_path):
|
||||||
|
socket_dir = os.path.dirname(socket_path)
|
||||||
|
try:
|
||||||
|
fi = os.stat(socket_dir)
|
||||||
|
if not stat.S_ISDIR:
|
||||||
|
RuntimeError('socket path {} is not a directory'.format(socket_dir))
|
||||||
|
except FileNotFoundError:
|
||||||
|
os.mkdir(socket_dir)
|
||||||
|
|
||||||
|
try:
|
||||||
|
os.unlink(socket_path)
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
s = socket.socket(family = socket.AF_UNIX, type = socket.SOCK_STREAM)
|
||||||
|
s.bind(socket_path)
|
||||||
|
logg.debug('created unix ipc socket {}'.format(socket_path))
|
||||||
|
start_server_socket(s)
|
@ -8,3 +8,17 @@ class TransactionRevertError(Exception):
|
|||||||
|
|
||||||
class NetworkError(Exception):
|
class NetworkError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class SignerError(Exception):
|
||||||
|
|
||||||
|
def __init__(self, s):
|
||||||
|
super(SignerError, self).__init__(s)
|
||||||
|
self.jsonrpc_error = s
|
||||||
|
|
||||||
|
|
||||||
|
def to_jsonrpc(self):
|
||||||
|
return self.jsonrpc_error
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,17 +2,10 @@
|
|||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import stat
|
|
||||||
import socket
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import argparse
|
import argparse
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
from http.server import (
|
|
||||||
HTTPServer,
|
|
||||||
BaseHTTPRequestHandler,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# external imports
|
# external imports
|
||||||
import confini
|
import confini
|
||||||
@ -20,10 +13,10 @@ from jsonrpc.exceptions import *
|
|||||||
from hexathon import add_0x
|
from hexathon import add_0x
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
|
from crypto_dev_signer.cli.cmd import *
|
||||||
from crypto_dev_signer.eth.signer import ReferenceSigner
|
from crypto_dev_signer.eth.signer import ReferenceSigner
|
||||||
from crypto_dev_signer.eth.transaction import EIP155Transaction
|
|
||||||
from crypto_dev_signer.keystore.reference import ReferenceKeystore
|
from crypto_dev_signer.keystore.reference import ReferenceKeystore
|
||||||
from crypto_dev_signer.error import UnknownAccountError
|
from crypto_dev_signer.cli.handle import SignRequestHandler
|
||||||
|
|
||||||
logging.basicConfig(level=logging.WARNING)
|
logging.basicConfig(level=logging.WARNING)
|
||||||
logg = logging.getLogger()
|
logg = logging.getLogger()
|
||||||
@ -80,266 +73,12 @@ re_http = r'^http'
|
|||||||
re_tcp = r'^tcp'
|
re_tcp = r'^tcp'
|
||||||
re_unix = r'^ipc'
|
re_unix = r'^ipc'
|
||||||
|
|
||||||
class MissingSecretError(BaseException):
|
class MissingSecretError(Exception):
|
||||||
|
pass
|
||||||
def __init__(self, message):
|
|
||||||
super(MissingSecretError, self).__init__(message)
|
|
||||||
|
|
||||||
|
|
||||||
def personal_new_account(p):
|
def main():
|
||||||
password = p
|
|
||||||
if p.__class__.__name__ != 'str':
|
|
||||||
if p.__class__.__name__ != 'list':
|
|
||||||
e = JSONRPCInvalidParams()
|
|
||||||
e.data = 'parameter must be list containing one string'
|
|
||||||
raise ValueError(e)
|
|
||||||
logg.error('foo {}'.format(p))
|
|
||||||
if len(p) != 1:
|
|
||||||
e = JSONRPCInvalidParams()
|
|
||||||
e.data = 'parameter must be list containing one string'
|
|
||||||
raise ValueError(e)
|
|
||||||
if p[0].__class__.__name__ != 'str':
|
|
||||||
e = JSONRPCInvalidParams()
|
|
||||||
e.data = 'parameter must be list containing one string'
|
|
||||||
raise ValueError(e)
|
|
||||||
password = p[0]
|
|
||||||
|
|
||||||
r = db.new(password)
|
|
||||||
|
|
||||||
return add_0x(r)
|
|
||||||
|
|
||||||
|
|
||||||
# TODO: move to translation module ("personal" rpc namespace is node-specific)
|
|
||||||
def personal_signTransaction(p):
|
|
||||||
logg.debug('got {} to sign'.format(p[0]))
|
|
||||||
#t = EIP155Transaction(p[0], p[0]['nonce'], 8995)
|
|
||||||
t = EIP155Transaction(p[0], p[0]['nonce'], p[0]['chainId'])
|
|
||||||
# z = signer.sign_transaction(t, p[1])
|
|
||||||
# raw_signed_tx = t.rlp_serialize()
|
|
||||||
raw_signed_tx = signer.sign_transaction_to_rlp(t, p[1])
|
|
||||||
o = {
|
|
||||||
'raw': '0x' + raw_signed_tx.hex(),
|
|
||||||
'tx': t.serialize(),
|
|
||||||
}
|
|
||||||
logg.debug('signed {}'.format(o))
|
|
||||||
return o
|
|
||||||
|
|
||||||
|
|
||||||
def eth_signTransaction(tx):
|
|
||||||
o = personal_signTransaction([tx[0], ''])
|
|
||||||
return o['raw']
|
|
||||||
|
|
||||||
|
|
||||||
def eth_sign(p):
|
|
||||||
logg.debug('got message {} to sign'.format(p[1]))
|
|
||||||
message_type = type(p[1]).__name__
|
|
||||||
if message_type != 'str':
|
|
||||||
raise ValueError('invalid message format, must be {}, not {}'.format(message_type))
|
|
||||||
z = signer.sign_ethereum_message(p[0], p[1][2:])
|
|
||||||
return str(z)
|
|
||||||
|
|
||||||
|
|
||||||
methods = {
|
|
||||||
'personal_newAccount': personal_new_account,
|
|
||||||
'personal_signTransaction': personal_signTransaction,
|
|
||||||
'eth_signTransaction': eth_signTransaction,
|
|
||||||
'eth_sign': eth_sign,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def jsonrpc_error(rpc_id, err):
|
|
||||||
return {
|
|
||||||
'jsonrpc': '2.0',
|
|
||||||
'id': rpc_id,
|
|
||||||
'error': {
|
|
||||||
'code': err.CODE,
|
|
||||||
'message': err.MESSAGE,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def jsonrpc_ok(rpc_id, response):
|
|
||||||
return {
|
|
||||||
'jsonrpc': '2.0',
|
|
||||||
'id': rpc_id,
|
|
||||||
'result': response,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def is_valid_json(j):
|
|
||||||
if j.get('id') == 'None':
|
|
||||||
raise ValueError('id missing')
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def process_input(j):
|
|
||||||
rpc_id = j['id']
|
|
||||||
m = j['method']
|
|
||||||
p = j['params']
|
|
||||||
return (rpc_id, methods[m](p))
|
|
||||||
|
|
||||||
|
|
||||||
def start_server_tcp(spec):
|
|
||||||
s = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
|
|
||||||
s.bind(spec)
|
|
||||||
logg.debug('created tcp socket {}'.format(spec))
|
|
||||||
start_server_socket(s)
|
|
||||||
|
|
||||||
|
|
||||||
def start_server_unix(socket_path):
|
|
||||||
socket_dir = os.path.dirname(socket_path)
|
|
||||||
try:
|
|
||||||
fi = os.stat(socket_dir)
|
|
||||||
if not stat.S_ISDIR:
|
|
||||||
RuntimeError('socket path {} is not a directory'.format(socket_dir))
|
|
||||||
except FileNotFoundError:
|
|
||||||
os.mkdir(socket_dir)
|
|
||||||
|
|
||||||
try:
|
|
||||||
os.unlink(socket_path)
|
|
||||||
except FileNotFoundError:
|
|
||||||
pass
|
|
||||||
s = socket.socket(family = socket.AF_UNIX, type = socket.SOCK_STREAM)
|
|
||||||
s.bind(socket_path)
|
|
||||||
logg.debug('created unix ipc socket {}'.format(socket_path))
|
|
||||||
start_server_socket(s)
|
|
||||||
|
|
||||||
|
|
||||||
def start_server_http(spec):
|
|
||||||
httpd = HTTPServer(spec, HTTPSignRequestHandler)
|
|
||||||
logg.debug('starting http server {}'.format(spec))
|
|
||||||
httpd.serve_forever()
|
|
||||||
|
|
||||||
|
|
||||||
class SignerError(Exception):
|
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, s):
|
|
||||||
super(SignerError, self).__init__(s)
|
|
||||||
self.jsonrpc_error = s
|
|
||||||
|
|
||||||
|
|
||||||
def to_jsonrpc(self):
|
|
||||||
return self.jsonrpc_error
|
|
||||||
|
|
||||||
|
|
||||||
class SignRequestHandler:
|
|
||||||
|
|
||||||
def handle_jsonrpc(self, d):
|
|
||||||
j = None
|
|
||||||
try:
|
|
||||||
j = json.loads(d)
|
|
||||||
is_valid_json(j)
|
|
||||||
logg.debug('{}'.format(d.decode('utf-8')))
|
|
||||||
except Exception as e:
|
|
||||||
logg.exception('input error {}'.format(e))
|
|
||||||
j = json.dumps(jsonrpc_error(None, JSONRPCParseError)).encode('utf-8')
|
|
||||||
raise SignerError(j)
|
|
||||||
|
|
||||||
try:
|
|
||||||
(rpc_id, r) = process_input(j)
|
|
||||||
r = jsonrpc_ok(rpc_id, r)
|
|
||||||
j = json.dumps(r).encode('utf-8')
|
|
||||||
except ValueError as e:
|
|
||||||
# TODO: handle cases to give better error context to caller
|
|
||||||
logg.exception('process error {}'.format(e))
|
|
||||||
j = json.dumps(jsonrpc_error(j['id'], JSONRPCServerError)).encode('utf-8')
|
|
||||||
raise SignerError(j)
|
|
||||||
except UnknownAccountError as e:
|
|
||||||
logg.exception('process unknown account error {}'.format(e))
|
|
||||||
j = json.dumps(jsonrpc_error(j['id'], JSONRPCServerError)).encode('utf-8')
|
|
||||||
raise SignerError(j)
|
|
||||||
|
|
||||||
return j
|
|
||||||
|
|
||||||
|
|
||||||
class HTTPSignRequestHandler(BaseHTTPRequestHandler, SignRequestHandler):
|
|
||||||
|
|
||||||
def do_POST(self):
|
|
||||||
if self.headers.get('Content-Type') != 'application/json':
|
|
||||||
self.send_response(400, 'me read json only')
|
|
||||||
self.end_headers()
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
|
||||||
if 'application/json' not in self.headers.get('Accept').split(','):
|
|
||||||
self.send_response(400, 'me json only speak')
|
|
||||||
self.end_headers()
|
|
||||||
return
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
l = self.headers.get('Content-Length')
|
|
||||||
try:
|
|
||||||
l = int(l)
|
|
||||||
except ValueError:
|
|
||||||
self.send_response(400, 'content length must be integer')
|
|
||||||
self.end_headers()
|
|
||||||
return
|
|
||||||
if l > 4096:
|
|
||||||
self.send_response(400, 'too much information')
|
|
||||||
self.end_headers()
|
|
||||||
return
|
|
||||||
if l < 0:
|
|
||||||
self.send_response(400, 'you are too negative')
|
|
||||||
self.end_headers()
|
|
||||||
return
|
|
||||||
|
|
||||||
b = b''
|
|
||||||
c = 0
|
|
||||||
while c < l:
|
|
||||||
d = self.rfile.read(l-c)
|
|
||||||
if d == None:
|
|
||||||
break
|
|
||||||
b += d
|
|
||||||
c += len(d)
|
|
||||||
if c > 4096:
|
|
||||||
self.send_response(413, 'i should slap you around for lying about your size')
|
|
||||||
self.end_headers()
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
|
||||||
r = self.handle_jsonrpc(d)
|
|
||||||
except SignerError as e:
|
|
||||||
r = e.to_jsonrpc()
|
|
||||||
|
|
||||||
#b = json.dumps(r).encode('utf-8')
|
|
||||||
l = len(r)
|
|
||||||
self.send_response(200, 'You are the Keymaster')
|
|
||||||
self.send_header('Content-Length', str(l))
|
|
||||||
self.send_header('Cache-Control', 'no-cache')
|
|
||||||
self.send_header('Content-Type', 'application/json')
|
|
||||||
self.end_headers()
|
|
||||||
|
|
||||||
c = 0
|
|
||||||
while c < l:
|
|
||||||
n = self.wfile.write(r[c:])
|
|
||||||
c += n
|
|
||||||
|
|
||||||
|
|
||||||
def start_server_socket(s):
|
|
||||||
s.listen(10)
|
|
||||||
logg.debug('server started')
|
|
||||||
handler = SignRequestHandler()
|
|
||||||
while True:
|
|
||||||
(csock, caddr) = s.accept()
|
|
||||||
d = csock.recv(4096)
|
|
||||||
|
|
||||||
r = None
|
|
||||||
try:
|
|
||||||
r = handler.handle_jsonrpc(d)
|
|
||||||
except SignerError as e:
|
|
||||||
r = e.to_jsonrpc()
|
|
||||||
|
|
||||||
csock.send(r)
|
|
||||||
csock.close()
|
|
||||||
s.close()
|
|
||||||
|
|
||||||
os.unlink(socket_path)
|
|
||||||
|
|
||||||
|
|
||||||
def init():
|
|
||||||
global db, signer
|
|
||||||
secret_hex = config.get('SIGNER_SECRET')
|
secret_hex = config.get('SIGNER_SECRET')
|
||||||
if secret_hex == None:
|
if secret_hex == None:
|
||||||
raise MissingSecretError('please provide a valid hex value for the SIGNER_SECRET configuration variable')
|
raise MissingSecretError('please provide a valid hex value for the SIGNER_SECRET configuration variable')
|
||||||
@ -348,12 +87,9 @@ def init():
|
|||||||
kw = {
|
kw = {
|
||||||
'symmetric_key': secret,
|
'symmetric_key': secret,
|
||||||
}
|
}
|
||||||
db = ReferenceKeystore(dsn, **kw)
|
SignRequestHandler.keystore = ReferenceKeystore(dsn, **kw)
|
||||||
signer = ReferenceSigner(db)
|
SignRequestHandler.signer = ReferenceSigner(SignRequestHandler.keystore)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
init()
|
|
||||||
arg = None
|
arg = None
|
||||||
try:
|
try:
|
||||||
arg = json.loads(sys.argv[1])
|
arg = json.loads(sys.argv[1])
|
||||||
@ -363,16 +99,19 @@ def main():
|
|||||||
if socket_url.scheme != '':
|
if socket_url.scheme != '':
|
||||||
scheme = socket_url.scheme
|
scheme = socket_url.scheme
|
||||||
if re.match(re_tcp, socket_url.scheme):
|
if re.match(re_tcp, socket_url.scheme):
|
||||||
|
from crypto_dev_signer.cli.socket import start_server_tcp
|
||||||
socket_spec = socket_url.netloc.split(':')
|
socket_spec = socket_url.netloc.split(':')
|
||||||
host = socket_spec[0]
|
host = socket_spec[0]
|
||||||
port = int(socket_spec[1])
|
port = int(socket_spec[1])
|
||||||
start_server_tcp((host, port))
|
start_server_tcp((host, port))
|
||||||
elif re.match(re_http, socket_url.scheme):
|
elif re.match(re_http, socket_url.scheme):
|
||||||
|
from crypto_dev_signer.cli.http import start_server_http
|
||||||
socket_spec = socket_url.netloc.split(':')
|
socket_spec = socket_url.netloc.split(':')
|
||||||
host = socket_spec[0]
|
host = socket_spec[0]
|
||||||
port = int(socket_spec[1])
|
port = int(socket_spec[1])
|
||||||
start_server_http((host, port))
|
start_server_http((host, port))
|
||||||
else:
|
else:
|
||||||
|
from crypto_dev_signer.cli.socket import start_server_unix
|
||||||
start_server_unix(socket_url.path)
|
start_server_unix(socket_url.path)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user