Skip to content

Commit

Permalink
Merge pull request #8 from redcanari/adding-remote-dispatcher
Browse files Browse the repository at this point in the history
ENH: added `remote-transform` sub command
  • Loading branch information
allfro committed Aug 8, 2016
2 parents 5222bc5 + cfaf309 commit 4b483b1
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 2 deletions.
3 changes: 2 additions & 1 deletion src/canari/commands/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@
'shell',
'unload_plume_package',
'version',
'generate_entities_doc'
'generate_entities_doc',
'remote_transform'
]
130 changes: 130 additions & 0 deletions src/canari/commands/remote_transform.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import argparse

from canari.commands.common import canari_main
from canari.commands.framework import SubCommand, Argument
from canari.maltego.message import _Entity, Field, Limits, MaltegoMessage
from canari.maltego.runner import remote_canari_transform_runner, console_writer

__author__ = 'Nadeem Douba'
__copyright__ = 'Copyright 2016, Canari Project'
__credits__ = []

__license__ = 'GPL'
__version__ = '0.1'
__maintainer__ = 'Nadeem Douba'
__email__ = 'ndouba@gmail.com'
__status__ = 'Development'

__all__ = []


@SubCommand(
canari_main,
help='Runs Canari local transforms in a terminal-friendly fashion.',
description='Runs Canari local transforms in a terminal-friendly fashion.'
)
@Argument(
'host',
metavar='<host[:port]>',
help='The hostname or IP address and optionally the port of the remote Canari transform server.'
)
@Argument(
'transform',
metavar='<transform>',
help='The UUID of the transform you wish to run (e.g. sploitego3.IPToLocation).'
)
@Argument(
'input',
metavar='<entity name>=<value>',
help='The name and value of the input entity being passed into the local transform (e.g. "maltego.Person=Bob").'
)
@Argument(
'-f',
'--entity-field',
metavar='<name>=<value>',
# nargs='*',
help='The entity field name and value pair (e.g. "person.firstname=Bob"). Can be specified multiple times.',
action='append',
default=[]
)
@Argument(
'-p',
'--transform-parameter',
metavar='<name>=<value>',
# nargs='*',
help='Transform parameter name and value pair (e.g. "api.key=123"). Can be specified multiple times.',
action='append',
default=[]
)
@Argument(
'-r',
'--raw-output',
help='Print out raw XML output instead of prettified format.',
action='store_true',
default=False
)
@Argument(
'--ssl',
help='Perform request over HTTPS (default: False).',
action='store_true',
default=False
)
@Argument(
'-b',
'--base-path',
metavar='<base path>',
default='/',
help='The base path of the Canari transform server (default: "/").'
)
@Argument(
'--soft-limit',
type=int,
default=500,
metavar='<soft limit>',
help='Set the soft limit (default: 500)'
)
@Argument(
'--hard-limit',
type=int,
metavar='<hard limit>',
default=10000,
help='Set the hard limit (default: 10000)'
)
def remote_transform(args):
entity_type, value = args.input.split('=', 1)
fields = {}
params = []

for f in args.entity_field:
name, value = f.split('=', 1)
fields[name] = Field(name=name, value=value)

for p in args.transform_parameter:
name, value = p.split('=', 1)
params += Field(name=name, value=value)

r = remote_canari_transform_runner(
args.host,
args.base_path,
args.transform,
[_Entity(type=entity_type, value=value, fields=fields)],
params,
Limits(soft=args.soft_limit, hard=args.hard_limit),
args.ssl
)

if r.status == 200:
data = r.read()
if args.raw_output:
print data
else:
console_writer(MaltegoMessage.parse(data))
exit(0)

print 'ERROR: Received status %d for %s://%s/%s. Are you sure you got the right server?' % (
r.status,
'https' if args.ssl else 'http',
args.host,
args.transform
)
exit(-1)
21 changes: 20 additions & 1 deletion src/canari/maltego/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import traceback
from distutils.spawn import find_executable
from importlib import import_module
from httplib import HTTPSConnection, HTTPConnection

import re
from defusedxml.cElementTree import fromstring
Expand All @@ -13,7 +14,7 @@

from canari.config import load_config
from canari.maltego.message import MaltegoTransformResponseMessage, UIMessage, MaltegoTransformRequestMessage, Field, \
MaltegoException, EntityTypeFactory, Entity
MaltegoException, EntityTypeFactory, Entity, MaltegoMessage
from canari.maltego.utils import message, on_terminate, to_entity, croak, highlight

__author__ = 'Nadeem Douba'
Expand Down Expand Up @@ -41,6 +42,24 @@ def load_object(classpath):
return module.__dict__[cls]


def remote_canari_transform_runner(host, base_path, transform, entities, parameters, limits, is_ssl=False):
c = HTTPSConnection(host) if is_ssl else HTTPConnection(host)

m = MaltegoTransformRequestMessage()

for e in entities:
m += e

for p in parameters:
m += p

m += limits

c.request('POST', re.sub(r'/+', '/', '/'.join([base_path, transform])), MaltegoMessage(message=m).render())

return c.getresponse()


def local_transform_runner(transform, value, fields, params, config, message_writer=message):
"""
Internal API: The local transform runner is responsible for executing the local transform.
Expand Down

0 comments on commit 4b483b1

Please sign in to comment.