| 
									
										
											  
											
												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:]) |