API¶
implant.core¶
The core module is transfered to the remote process and will bootstrap pipe communication.
It creates default channels and dispatches commands accordingly.
-
class
implant.core.BaseHeaderItem(*, default=None, encoder=None, decoder=None)[source]¶ Bases:
objectA base item of a header.
-
class
implant.core.Channel(name=None, *, send, loop=None)[source]¶ Bases:
asyncio.queues.QueueChannel provides means to send and receive messages bound to a specific channel name.
-
__init__(name=None, *, send, loop=None)[source]¶ Initialize the channel.
Parameters: - name – the channel name
- send – the partial send method of Channels
- loop – the event loop
-
send= None¶ The send method bound to this channel’s name. See
Channels.send()for details.
-
-
class
implant.core.Channels(reader, writer, *, loop=None)[source]¶ Bases:
objectHold references to all channel queues and route messages accordingly.
-
__init__(reader, writer, *, loop=None)[source]¶ Create a
Channelsinstance which delegates incomming messages into their appropriateChannelqueues.Parameters: - reader –
asyncio.StreamReader - writer –
asyncio.StreamWriter - loop – the event loop
- reader –
-
coroutine
_finalize_message(buffer, chunk)[source]¶ Finalize the message if
Header.eomisTrue.This will also acknowledge the message if
Header.send_ackisTrue.
-
acknowledgements= None¶ Global acknowledgment futures distinctive by uid.
-
chunk_size= 32768¶
-
coroutine
enqueue()[source]¶ Schedule receive tasks.
Incomming chunks are collected and stored in the appropriate channel queue.
-
get_channel(channel_name)[source]¶ Create a channel and weakly register its queue.
Parameters: channel_name – the name of the channel to create Returns: Channelinstance with a bound send method
-
incomming= None¶ A collection of all active channels.
-
log= <logging.Logger object>¶
-
coroutine
send(channel_name, data, ack=False, compress=6)[source]¶ Send data in a encoded form to the channel.
Parameters: - channel_name – the name of the channel
- data – the python object to send
- ack – request acknowledgement of the reception of that message
- compress – compress the data with zlib
Messages are split into chunks and put into the outgoing queue.
-
-
class
implant.core.Chunk(header, channel_name, data)¶ Bases:
tuple-
__getnewargs__()¶ Return self as a plain tuple. Used by copy and pickle.
-
static
__new__(_cls, header, channel_name, data)¶ Create new instance of Chunk(header, channel_name, data)
-
__repr__()¶ Return a nicely formatted representation string
-
_asdict()¶ Return a new OrderedDict which maps field names to their values.
-
classmethod
_make(iterable, new=<built-in method __new__ of type object at 0xa385c0>, len=<built-in function len>)¶ Make a new Chunk object from a sequence or iterable
-
_replace(**kwds)¶ Return a new Chunk object replacing specified fields with new values
-
channel_name¶ Alias for field number 1
-
data¶ Alias for field number 2
-
header¶ Alias for field number 0
-
-
class
implant.core.Command(**parameters)[source]¶ Bases:
objectCommon ancestor of all Commands.
-
command_name= 'implant.core:Command'¶
-
dispatch_data¶ Data to be dispatched.
-
parameters= {}¶
-
-
class
implant.core.CommandRemote(full_classname)[source]¶ Bases:
objectDelegates remote task to another class.
This is usefull, if one wants not to import remote modules at the master side.
-
log= <logging.Logger object>¶
-
-
class
implant.core.ConnectionLostStreamReaderProtocol(*args, connection_lost_cb, **kwargs)[source]¶ Bases:
asyncio.streams.StreamReaderProtocolCall a callback on connection_lost.
-
class
implant.core.Core(loop, *, echo=None, **kwargs)[source]¶ Bases:
objectCorestarts theDispatcher.-
coroutine
communicate(reader, writer)[source]¶ Start the dispatcher and register the
ShutdownRemoteEvent.- On shutdown:
- the import hook is removed
- the
Dispatcher.dispatchtask is stopped - the
Channels.enqueuetask is stopped
-
coroutine
connect_sysio()[source]¶ Connect to
sys.stdinandsys.stdout.
-
log= <logging.Logger object>¶
-
classmethod
main(debug=False, log_config=None, *, loop=None, **kwargs)[source]¶ Start the event loop and schedule core communication.
-
static
setup_import_hook(module_finder)[source]¶ Add module finder to
sys.meta_path.
-
static
teardown_import_hook(module_finder)[source]¶ Remove a module finder from
sys.meta_path.
-
coroutine
-
class
implant.core.DispatchCommand(fqin, command_name, command_class, command_module, params)[source]¶ Bases:
implant.core.DispatchMessageArguments for a command dispatch.
-
log= <logging.Logger object>¶
-
-
class
implant.core.DispatchException(fqin, exception, tb=None)[source]¶ Bases:
implant.core.DispatchMessageRemote execution ended in an exception.
-
implant.core.DispatchLocalContext¶ alias of
implant.core.DispatchContext
-
class
implant.core.DispatchMessage(fqin)[source]¶ Bases:
objectBase class for command dispatch communication.
-
coroutine
__call__(dispatcher)[source]¶ Executes appropriate
Dispatchermethods to implement the core protocol.
-
log= <logging.Logger object>¶
-
coroutine
-
class
implant.core.DispatchReady(fqin)[source]¶ Bases:
implant.core.DispatchMessageSet the dispatch ready.
-
implant.core.DispatchRemoteContext¶ alias of
implant.core.DispatchContext
-
class
implant.core.DispatchResult(fqin, result=None)[source]¶ Bases:
implant.core.DispatchMessageThe result of a remote execution.
-
class
implant.core.Dispatcher(channels, *, loop=None)[source]¶ Bases:
objectEnables execution of
Commands.A
Commandis split into local and remote part, where a context with a dedicatedChannelis provided to enable streaming of arbitrary data. The local part also gets a remote future passed, which resolves to the result of the remote part of theCommand.-
__init__(channels, *, loop=None)[source]¶ Create a dispatcher, which executes messages on its own
Channelto enable Command execution and communication via distinctChannels.
-
coroutine
_execute_channels()[source]¶ Execute messages sent via our
Dispatcher.channel.
-
channel= None¶ A channel for the dispatcher itself.
-
channels= None¶ The collection of all channels.
-
coroutine
execute(command_name, **params)[source]¶ Execute a command.
First creating the remote side and its future and second executing its local part.
-
coroutine
execute_dispatch_command(fqin, command_name, params)[source]¶ Create a command and execute it.
-
coroutine
execute_remote(fqin, command)[source]¶ Execute the remote part of a Command. This method is called by a DispatchCommand message. The result is send via Dispatcher.channel to resolve the pending command future.
-
local_context(fqin, remote_future)[source]¶ Create a local context to pass to a
Commands local part.The
Channelis built via a fully qualified instance name (fqin).
-
log= <logging.Logger object>¶
-
pending_dispatches= None¶ A collection of dispatches, which are still not finished.
-
remote_context(fqin, pending_remote_task)[source]¶ Create a remote context to pass to a
Commands remote part.The
Channelis built via a fully qualified instance name (fqin).
-
remote_future(fqin, command)[source]¶ Create a context for remote command future by sending DispatchCommand and returning its pending future.
-
-
class
implant.core.FindSpecData(**parameters)[source]¶ Bases:
implant.core.CommandFind spec data for a module to import from the remote side.
-
command_name= 'implant.core:FindSpecData'¶
-
fullname¶ Define a Command parameter.
-
parameters= {'fullname': <implant.core.Parameter object at 0x7ff315003cf8>}¶
-
-
class
implant.core.Flag(*, default=None, encoder=None, decoder=None)[source]¶ Bases:
implant.core.BaseHeaderItemA boolean flag of a header.
-
class
implant.core.Header[source]¶ Bases:
bytesThe chunk header with flags and items.
-
channel_name_len¶ An item of a header.
-
compression¶ A boolean flag of a header.
-
data_len¶ An item of a header.
-
eom¶ A boolean flag of a header.
-
items= {'channel_name_len': <implant.core.HeaderItem object at 0x7ff315092860>, 'compression': <implant.core.Flag object at 0x7ff315092588>, 'data_len': <implant.core.HeaderItem object at 0x7ff315092908>, 'eom': <implant.core.Flag object at 0x7ff315092390>, 'recv_ack': <implant.core.Flag object at 0x7ff3150924e0>, 'send_ack': <implant.core.Flag object at 0x7ff315092470>, 'uid': <implant.core.HeaderItem object at 0x7ff315092748>}¶
-
recv_ack¶ A boolean flag of a header.
-
send_ack¶ A boolean flag of a header.
-
size= 23¶
-
uid¶ An item of a header.
-
-
class
implant.core.HeaderItem(fmt, **kwargs)[source]¶ Bases:
implant.core.BaseHeaderItemAn item of a header.
-
size¶ The size of the item.
-
-
class
implant.core.Incomming(*, connection_lost_cb=None, pipe=<_io.TextIOWrapper name='<stdin>' mode='r' encoding='UTF-8'>, loop=None)[source]¶ Bases:
asyncio.streams.StreamReaderA context for an incomming pipe.
-
coroutine
readexactly(n)[source]¶ Read exactly n bytes from the stream.
This is a short and faster implementation then the original one (see of https://github.com/python/asyncio/issues/394).
-
coroutine
-
class
implant.core.InvokeImport(**parameters)[source]¶ Bases:
implant.core.CommandInvoke an import of a module on the remote side.
The local side will import the module first. The remote side will trigger the remote import hook, which in turn will receive all missing modules from the local side.
The import is executed in a separate executor thread, to have a separate event loop available.
-
command_name= 'implant.core:InvokeImport'¶
-
fullname¶ Define a Command parameter.
-
parameters= {'fullname': <implant.core.Parameter object at 0x7ff315003cc0>}¶
-
-
class
implant.core.NoDefault[source]¶ Bases:
objectJust a marker class to represent no default.
This is to separate really nothing and None.
-
class
implant.core.NotifyEvent(**parameters)[source]¶ Bases:
implant.core.CommandNotify about an event.
If the remote side registers for this event, it gets notified.
-
command_name= 'implant.core:NotifyEvent'¶
-
dispatch_local¶ Define a Command parameter.
-
event¶ Define a Command parameter.
-
log= <logging.Logger object>¶
-
parameters= {'dispatch_local': <implant.core.Parameter object at 0x7ff315003c88>, 'event': <implant.core.Parameter object at 0x7ff315003c50>}¶
-
-
class
implant.core.OrderedMeta[source]¶ Bases:
typePreserve the order of instance creation.
-
items= [<implant.core.Flag object>, <implant.core.Flag object>, <implant.core.Flag object>, <implant.core.Flag object>, <implant.core.HeaderItem object>, <implant.core.HeaderItem object>, <implant.core.HeaderItem object>]¶
-
-
class
implant.core.Outgoing(*, pipe=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>, reader=None, loop=None)[source]¶ Bases:
objectA context for an outgoing pipe.
-
class
implant.core.Parameter(*, default=<class 'implant.core.NoDefault'>, description=None)[source]¶ Bases:
objectDefine a Command parameter.
-
exception
implant.core.RemoteClassNotSetException[source]¶ Bases:
ExceptionRaised when remote class is not set for
CommandRemote
-
class
implant.core.RemoteModuleFinder(dispatcher, *, loop)[source]¶ Bases:
importlib.abc.MetaPathFinderImport hook that execute a
FindSpecDatacommand in the main loop.See pep-0302, pep-0420 and pep-0451 for internals.
-
log= <logging.Logger object>¶
-
-
class
implant.core.RemoteModuleLoader(source, filename=None, is_package=False)[source]¶ Bases:
importlib.abc.ExecutionLoaderLoad the found module spec.
-
get_filename(fullname)[source]¶ Abstract method which should return the value that __file__ is to be set to.
Raises ImportError if the module cannot be found.
-
get_source(fullname)[source]¶ Abstract method which should return the source code for the module. The fullname is a str. Returns a str.
Raises ImportError if the module cannot be found.
-
-
class
implant.core.ShutdownRemoteEvent[source]¶ Bases:
objectA Shutdown event.
Shutting down a remote connection is done by gracefully canceling all remote tasks. See
Core.communicatefor details.
-
class
implant.core.StopAsyncIterationEncoder[source]¶ Bases:
objectEncoder for
StopAsyncIteration.
-
class
implant.core.Uid(bytes=None)[source]¶ Bases:
uuid.UUIDA unique id, which is basically a
uuid.uuid1instance.-
time¶ The timestamp of the uuid1.
-
-
implant.core.event_handler(event_class, handler_=None, decorator=False)[source]¶ Define an event handler for a (new-style) class.
This can be called with a class and a handler, or with just a class and the result used as a handler decorator.
implant.bootstrap¶
Bootstrap of a remote python process.
implant.connect¶
Remote connection is established by a Connector.
-
class
implant.connect.ConnectorMeta[source]¶ Bases:
abc.ABCMetaConnector meta base.
-
connectors= {'local': <class 'implant.connect.Local'>, 'lxd': <class 'implant.connect.Lxd'>, 'ssh': <class 'implant.connect.Ssh'>}¶
-
scheme¶ The unique connector scheme is the lowered class name.
-
-
class
implant.connect.Local(*, sudo=None)[source]¶ Bases:
implant.connect.SubprocessConnectorA Connector to a local python process.
-
arguments(*, code=None, options=None, python_bin=None)[source]¶ Iterate over the arguments to start a process.
Parameters: - code – the code to bootstrap the remote process
- options – options for the remote process
- python_bin – the path to the python binary
-
sudo¶
-
-
class
implant.connect.Lxd(*, container, hostname=None, user=None, sudo=None)[source]¶ Bases:
implant.connect.SshA Connector for accessing a lxd container.
If the hostname is omitted, the lxd container is local.
-
arguments(*, code=None, options=None, python_bin=None)[source]¶ Iterate over the arguments to start a process.
Parameters: - code – the code to bootstrap the remote process
- options – options for the remote process
- python_bin – the path to the python binary
-
container¶
-
hostname¶
-
sudo¶
-
user¶
-
-
class
implant.connect.Remote(*, stdin=None, stdout=None, stderr=None, loop=None)[source]¶ Bases:
objectA remote receiving commands.
-
exception
implant.connect.RemoteMisbehavesError[source]¶ Bases:
ExceptionException is raised, when a remote process seems to be not what we expect.
-
class
implant.connect.Ssh(*, hostname=None, user=None, sudo=None)[source]¶ Bases:
implant.connect.LocalA Connector for remote hosts reachable via SSH.
If a hostname is omitted, this connector acts like Local.
-
arguments(*, code=None, options=None, python_bin=None)[source]¶ Iterate over the arguments to start a process.
Parameters: - code – the code to bootstrap the remote process
- options – options for the remote process
- python_bin – the path to the python binary
-
hostname¶
-
sudo¶
-
user¶
-
-
class
implant.connect.SubprocessConnector[source]¶ Bases:
implant.connect.ConnectorA Connector uniquely defines a remote target.
-
arguments(*, code=None, options=None, python_bin=None)[source]¶ Iterate over the arguments to start a process.
Parameters: - code – the code to bootstrap the remote process
- options – options for the remote process
- python_bin – the path to the python binary
-
static
bootstrap_code(code=<module 'implant.core' from '/home/docs/checkouts/readthedocs.org/user_builds/implant/envs/latest/lib/python3.5/site-packages/implant-0.1.2-py3.5.egg/implant/core.py'>, options=None)[source]¶ Create the python bootstrap code.
-
coroutine
launch(*, loop=None, code=None, options=None, python_bin=None, **kwargs)[source]¶ Launch a remote process.
Parameters: - code – the python module to bootstrap
- options – options to send to remote
- python_bin – the path to the python binary to execute
- kwargs – further arguments to create the process
-
-
class
implant.connect.SubprocessRemote(transport, protocol, *, loop=None)[source]¶ Bases:
implant.connect.RemoteA remote process.
-
returncode¶ The exit code of the process.
-