cmd/clef, signer: initial poc of the standalone signer (#16154)
* signer: introduce external signer command
* cmd/signer, rpc: Implement new signer. Add info about remote user to Context
* signer: refactored request/response, made use of urfave.cli
* cmd/signer: Use common flags
* cmd/signer: methods to validate calldata against abi
* cmd/signer: work on abi parser
* signer: add mutex around UI
* cmd/signer: add json 4byte directory, remove passwords from api
* cmd/signer: minor changes
* cmd/signer: Use ErrRequestDenied, enable lightkdf
* cmd/signer: implement tests
* cmd/signer: made possible for UI to modify tx parameters
* cmd/signer: refactors, removed channels in ui comms, added UI-api via stdin/out
* cmd/signer: Made lowercase json-definitions, added UI-signer test functionality
* cmd/signer: update documentation
* cmd/signer: fix bugs, improve abi detection, abi argument display
* cmd/signer: minor change in json format
* cmd/signer: rework json communication
* cmd/signer: implement mixcase addresses in API, fix json id bug
* cmd/signer: rename fromaccount, update pythonpoc with new json encoding format
* cmd/signer: make use of new abi interface
* signer: documentation
* signer/main: remove redundant option
* signer: implement audit logging
* signer: create package 'signer', minor changes
* common: add 0x-prefix to mixcaseaddress in json marshalling + validation
* signer, rules, storage: implement rules + ephemeral storage for signer rules
* signer: implement OnApprovedTx, change signing response (API BREAKAGE)
* signer: refactoring + documentation
* signer/rules: implement dispatching to next handler
* signer: docs
* signer/rules: hide json-conversion from users, ensure context is cleaned
* signer: docs
* signer: implement validation rules, change signature of call_info
* signer: fix log flaw with string pointer
* signer: implement custom 4byte databsae that saves submitted signatures
* signer/storage: implement aes-gcm-backed credential storage
* accounts: implement json unmarshalling of url
* signer: fix listresponse, fix gas->uint64
* node: make http/ipc start methods public
* signer: add ipc capability+review concerns
* accounts: correct docstring
* signer: address review concerns
* rpc: go fmt -s
* signer: review concerns+ baptize Clef
* signer,node: move Start-functions to separate file
* signer: formatting
2018-04-16 14:04:32 +02:00
|
|
|
import os,sys, subprocess
|
|
|
|
from tinyrpc.transports import ServerTransport
|
|
|
|
from tinyrpc.protocols.jsonrpc import JSONRPCProtocol
|
|
|
|
from tinyrpc.dispatch import public,RPCDispatcher
|
|
|
|
from tinyrpc.server import RPCServer
|
|
|
|
|
|
|
|
""" This is a POC example of how to write a custom UI for Clef. The UI starts the
|
|
|
|
clef process with the '--stdio-ui' option, and communicates with clef using standard input / output.
|
|
|
|
|
|
|
|
The standard input/output is a relatively secure way to communicate, as it does not require opening any ports
|
|
|
|
or IPC files. Needless to say, it does not protect against memory inspection mechanisms where an attacker
|
|
|
|
can access process memory."""
|
|
|
|
|
|
|
|
try:
|
|
|
|
import urllib.parse as urlparse
|
|
|
|
except ImportError:
|
|
|
|
import urllib as urlparse
|
|
|
|
|
|
|
|
class StdIOTransport(ServerTransport):
|
|
|
|
""" Uses std input/output for RPC """
|
|
|
|
def receive_message(self):
|
|
|
|
return None, urlparse.unquote(sys.stdin.readline())
|
|
|
|
|
|
|
|
def send_reply(self, context, reply):
|
|
|
|
print(reply)
|
|
|
|
|
|
|
|
class PipeTransport(ServerTransport):
|
|
|
|
""" Uses std a pipe for RPC """
|
|
|
|
|
|
|
|
def __init__(self,input, output):
|
|
|
|
self.input = input
|
|
|
|
self.output = output
|
|
|
|
|
|
|
|
def receive_message(self):
|
|
|
|
data = self.input.readline()
|
|
|
|
print(">> {}".format( data))
|
|
|
|
return None, urlparse.unquote(data)
|
|
|
|
|
|
|
|
def send_reply(self, context, reply):
|
|
|
|
print("<< {}".format( reply))
|
|
|
|
self.output.write(reply)
|
|
|
|
self.output.write("\n")
|
|
|
|
|
|
|
|
class StdIOHandler():
|
|
|
|
def __init__(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
@public
|
|
|
|
def ApproveTx(self,req):
|
|
|
|
"""
|
|
|
|
Example request:
|
|
|
|
{
|
|
|
|
"jsonrpc": "2.0",
|
|
|
|
"method": "ApproveTx",
|
|
|
|
"params": [{
|
|
|
|
"transaction": {
|
|
|
|
"to": "0xae967917c465db8578ca9024c205720b1a3651A9",
|
|
|
|
"gas": "0x333",
|
|
|
|
"gasPrice": "0x123",
|
|
|
|
"value": "0x10",
|
|
|
|
"data": "0xd7a5865800000000000000000000000000000000000000000000000000000000000000ff",
|
|
|
|
"nonce": "0x0"
|
|
|
|
},
|
|
|
|
"from": "0xAe967917c465db8578ca9024c205720b1a3651A9",
|
|
|
|
"call_info": "Warning! Could not validate ABI-data against calldata\nSupplied ABI spec does not contain method signature in data: 0xd7a58658",
|
|
|
|
"meta": {
|
|
|
|
"remote": "127.0.0.1:34572",
|
|
|
|
"local": "localhost:8550",
|
|
|
|
"scheme": "HTTP/1.1"
|
|
|
|
}
|
|
|
|
}],
|
|
|
|
"id": 1
|
|
|
|
}
|
|
|
|
|
|
|
|
:param transaction: transaction info
|
|
|
|
:param call_info: info abou the call, e.g. if ABI info could not be
|
|
|
|
:param meta: metadata about the request, e.g. where the call comes from
|
2019-07-02 14:01:47 +03:00
|
|
|
:return:
|
cmd/clef, signer: initial poc of the standalone signer (#16154)
* signer: introduce external signer command
* cmd/signer, rpc: Implement new signer. Add info about remote user to Context
* signer: refactored request/response, made use of urfave.cli
* cmd/signer: Use common flags
* cmd/signer: methods to validate calldata against abi
* cmd/signer: work on abi parser
* signer: add mutex around UI
* cmd/signer: add json 4byte directory, remove passwords from api
* cmd/signer: minor changes
* cmd/signer: Use ErrRequestDenied, enable lightkdf
* cmd/signer: implement tests
* cmd/signer: made possible for UI to modify tx parameters
* cmd/signer: refactors, removed channels in ui comms, added UI-api via stdin/out
* cmd/signer: Made lowercase json-definitions, added UI-signer test functionality
* cmd/signer: update documentation
* cmd/signer: fix bugs, improve abi detection, abi argument display
* cmd/signer: minor change in json format
* cmd/signer: rework json communication
* cmd/signer: implement mixcase addresses in API, fix json id bug
* cmd/signer: rename fromaccount, update pythonpoc with new json encoding format
* cmd/signer: make use of new abi interface
* signer: documentation
* signer/main: remove redundant option
* signer: implement audit logging
* signer: create package 'signer', minor changes
* common: add 0x-prefix to mixcaseaddress in json marshalling + validation
* signer, rules, storage: implement rules + ephemeral storage for signer rules
* signer: implement OnApprovedTx, change signing response (API BREAKAGE)
* signer: refactoring + documentation
* signer/rules: implement dispatching to next handler
* signer: docs
* signer/rules: hide json-conversion from users, ensure context is cleaned
* signer: docs
* signer: implement validation rules, change signature of call_info
* signer: fix log flaw with string pointer
* signer: implement custom 4byte databsae that saves submitted signatures
* signer/storage: implement aes-gcm-backed credential storage
* accounts: implement json unmarshalling of url
* signer: fix listresponse, fix gas->uint64
* node: make http/ipc start methods public
* signer: add ipc capability+review concerns
* accounts: correct docstring
* signer: address review concerns
* rpc: go fmt -s
* signer: review concerns+ baptize Clef
* signer,node: move Start-functions to separate file
* signer: formatting
2018-04-16 14:04:32 +02:00
|
|
|
"""
|
|
|
|
transaction = req.get('transaction')
|
|
|
|
_from = req.get('from')
|
|
|
|
call_info = req.get('call_info')
|
|
|
|
meta = req.get('meta')
|
|
|
|
|
|
|
|
return {
|
|
|
|
"approved" : False,
|
|
|
|
#"transaction" : transaction,
|
|
|
|
# "from" : _from,
|
|
|
|
# "password" : None,
|
|
|
|
}
|
|
|
|
|
|
|
|
@public
|
|
|
|
def ApproveSignData(self, req):
|
|
|
|
""" Example request
|
|
|
|
|
|
|
|
"""
|
|
|
|
return {"approved": False, "password" : None}
|
|
|
|
|
|
|
|
@public
|
|
|
|
def ApproveExport(self, req):
|
|
|
|
""" Example request
|
|
|
|
|
|
|
|
"""
|
|
|
|
return {"approved" : False}
|
|
|
|
|
|
|
|
@public
|
|
|
|
def ApproveImport(self, req):
|
|
|
|
""" Example request
|
|
|
|
|
|
|
|
"""
|
|
|
|
return { "approved" : False, "old_password": "", "new_password": ""}
|
|
|
|
|
|
|
|
@public
|
|
|
|
def ApproveListing(self, req):
|
|
|
|
""" Example request
|
|
|
|
|
|
|
|
"""
|
|
|
|
return {'accounts': []}
|
|
|
|
|
|
|
|
@public
|
|
|
|
def ApproveNewAccount(self, req):
|
|
|
|
"""
|
|
|
|
Example request
|
|
|
|
|
|
|
|
:return:
|
|
|
|
"""
|
|
|
|
return {"approved": False,
|
|
|
|
#"password": ""
|
|
|
|
}
|
|
|
|
|
|
|
|
@public
|
|
|
|
def ShowError(self,message = {}):
|
|
|
|
"""
|
|
|
|
Example request:
|
|
|
|
|
|
|
|
{"jsonrpc":"2.0","method":"ShowInfo","params":{"message":"Testing 'ShowError'"},"id":1}
|
|
|
|
|
|
|
|
:param message: to show
|
|
|
|
:return: nothing
|
|
|
|
"""
|
|
|
|
if 'text' in message.keys():
|
|
|
|
sys.stderr.write("Error: {}\n".format( message['text']))
|
|
|
|
return
|
|
|
|
|
|
|
|
@public
|
|
|
|
def ShowInfo(self,message = {}):
|
|
|
|
"""
|
|
|
|
Example request
|
|
|
|
{"jsonrpc":"2.0","method":"ShowInfo","params":{"message":"Testing 'ShowInfo'"},"id":0}
|
|
|
|
|
|
|
|
:param message: to display
|
|
|
|
:return:nothing
|
|
|
|
"""
|
|
|
|
|
|
|
|
if 'text' in message.keys():
|
|
|
|
sys.stdout.write("Error: {}\n".format( message['text']))
|
|
|
|
return
|
|
|
|
|
|
|
|
def main(args):
|
2019-07-02 14:01:47 +03:00
|
|
|
cmd = ["clef", "--stdio-ui"]
|
cmd/clef, signer: initial poc of the standalone signer (#16154)
* signer: introduce external signer command
* cmd/signer, rpc: Implement new signer. Add info about remote user to Context
* signer: refactored request/response, made use of urfave.cli
* cmd/signer: Use common flags
* cmd/signer: methods to validate calldata against abi
* cmd/signer: work on abi parser
* signer: add mutex around UI
* cmd/signer: add json 4byte directory, remove passwords from api
* cmd/signer: minor changes
* cmd/signer: Use ErrRequestDenied, enable lightkdf
* cmd/signer: implement tests
* cmd/signer: made possible for UI to modify tx parameters
* cmd/signer: refactors, removed channels in ui comms, added UI-api via stdin/out
* cmd/signer: Made lowercase json-definitions, added UI-signer test functionality
* cmd/signer: update documentation
* cmd/signer: fix bugs, improve abi detection, abi argument display
* cmd/signer: minor change in json format
* cmd/signer: rework json communication
* cmd/signer: implement mixcase addresses in API, fix json id bug
* cmd/signer: rename fromaccount, update pythonpoc with new json encoding format
* cmd/signer: make use of new abi interface
* signer: documentation
* signer/main: remove redundant option
* signer: implement audit logging
* signer: create package 'signer', minor changes
* common: add 0x-prefix to mixcaseaddress in json marshalling + validation
* signer, rules, storage: implement rules + ephemeral storage for signer rules
* signer: implement OnApprovedTx, change signing response (API BREAKAGE)
* signer: refactoring + documentation
* signer/rules: implement dispatching to next handler
* signer: docs
* signer/rules: hide json-conversion from users, ensure context is cleaned
* signer: docs
* signer: implement validation rules, change signature of call_info
* signer: fix log flaw with string pointer
* signer: implement custom 4byte databsae that saves submitted signatures
* signer/storage: implement aes-gcm-backed credential storage
* accounts: implement json unmarshalling of url
* signer: fix listresponse, fix gas->uint64
* node: make http/ipc start methods public
* signer: add ipc capability+review concerns
* accounts: correct docstring
* signer: address review concerns
* rpc: go fmt -s
* signer: review concerns+ baptize Clef
* signer,node: move Start-functions to separate file
* signer: formatting
2018-04-16 14:04:32 +02:00
|
|
|
if len(args) > 0 and args[0] == "test":
|
|
|
|
cmd.extend(["--stdio-ui-test"])
|
|
|
|
print("cmd: {}".format(" ".join(cmd)))
|
|
|
|
dispatcher = RPCDispatcher()
|
|
|
|
dispatcher.register_instance(StdIOHandler(), '')
|
|
|
|
# line buffered
|
|
|
|
p = subprocess.Popen(cmd, bufsize=1, universal_newlines=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
|
|
|
|
|
|
|
rpc_server = RPCServer(
|
|
|
|
PipeTransport(p.stdout, p.stdin),
|
|
|
|
JSONRPCProtocol(),
|
|
|
|
dispatcher
|
|
|
|
)
|
|
|
|
rpc_server.serve_forever()
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main(sys.argv[1:])
|