setup(
name='canari',
author='Nadeem Douba',
- version='0.4',
+ version='0.5',
author_email='ndouba@gmail.com',
description='Rapid transform development and transform execution framework for Maltego.',
license='GPL',
'argparse'
],
dependency_links=[]
-)
\ No newline at end of file
+)
__credits__ = []
__license__ = 'GPL'
-__version__ = '0.1'
+__version__ = '0.2'
__maintainer__ = 'Nadeem Douba'
__email__ = 'ndouba@gmail.com'
__status__ = 'Development'
def write_resources(package_name, resources, init, values):
write_template(
path.join(resources, '__init__.py'),
- init + generate_all('etc', 'images', 'maltego')
+ init + generate_all('etc', 'images', 'maltego', 'external')
)
write_template(
init
)
+ write_template(
+ path.join(resources, 'external', '__init__.py'),
+ init
+ )
+
write_template(
path.join(resources, 'maltego', '__init__.py'),
init
resources,
[resources, 'etc'],
[resources, 'images'],
+ [resources, 'external'],
[resources, 'maltego']
)
else:
from cStringIO import StringIO
from socket import getfqdn
from urlparse import urlsplit
+from re import sub, findall
from hashlib import md5
from sys import argv
-from re import sub
+
__author__ = 'Nadeem Douba'
__credits__ = []
__license__ = 'GPL'
-__version__ = '0.3'
+__version__ = '0.4'
__maintainer__ = 'Nadeem Douba'
__email__ = 'ndouba@gmail.com'
__status__ = 'Development'
r.send_header('Connection', 'close')
r.end_headers()
- sio = StringIO()
- for e in m.entities:
- if e.iconurl is not None:
- e.iconurl = e.iconurl.strip()
- if e.iconurl.startswith('file://'):
- path = '/%s' % md5(e.iconurl).hexdigest()
- new_url = '%s://%s%s' % ('https' if r.server.is_ssl else 'http', r.server.hostname, path)
- if path not in r.server.resources:
- r.server.resources[path] = e.iconurl[7:]
- e.iconurl = new_url
-
- Message(MaltegoMessage(m)).write(sio)
- v = sio.getvalue()
+ v = None
+ if isinstance(m, basestring):
+ for url in findall("<iconurl>\s*(file://[^\s<]+)\s*</iconurl>(?im)", m):
+ path = '/%s' % md5(url).hexdigest()
+ new_url = '%s://%s%s' % ('https' if r.server.is_ssl else 'http', r.server.hostname, path)
+ if path not in r.server.resources:
+ r.server.resources[path] = url[7:]
+ m.replace(url, new_url, 1)
+ v = m
+ else:
+ sio = StringIO()
+ for e in m.entities:
+ if e.iconurl is not None:
+ e.iconurl = e.iconurl.strip()
+ if e.iconurl.startswith('file://'):
+ path = '/%s' % md5(e.iconurl).hexdigest()
+ new_url = '%s://%s%s' % ('https' if r.server.is_ssl else 'http', r.server.hostname, path)
+ if path not in r.server.resources:
+ r.server.resources[path] = e.iconurl[7:]
+ e.iconurl = new_url
+
+ Message(MaltegoMessage(m)).write(sio)
+ v = sio.getvalue()
# Get rid of those nasty unicode 32 characters
r.wfile.write(sub(r'(&#\d{5};){2}', r'', v))
def dotransform(self, t):
-
try:
if 'Content-Length' not in self.headers:
self.send_error(500, 'What?')
return
- xml = fromstring(self.rfile.read(int(self.headers['Content-Length']))).find('MaltegoTransformRequestMessage')
+ request_str = self.rfile.read(int(self.headers['Content-Length']))
+
+ xml = fromstring(request_str).find('MaltegoTransformRequestMessage')
e = xml.find('Entities/Entity')
etype = e.get('Type', '')
fields = dict([(f.get('Name', ''), f.text) for f in xml.findall('Entities/Entity/AdditionalFields/Field')])
params = dict([(f.get('Name', ''), f.text) for f in xml.findall('TransformFields/Field')])
for k, i in params.items():
- config[k.replace('.', '/', 1)] = i
+ if '.' in k:
+ config[k.replace('.', '/', 1)] = i
+ else:
+ config['default/%s' % k] = i
limits = xml.find('Limits').attrib
+
msg = t[0](
type(
'MaltegoTransformRequestMessage',
'limits' : limits
}
)(),
- MaltegoTransformResponseMessage()
+ request_str if hasattr(t[0], 'cmd') and callable(t[0].cmd) else MaltegoTransformResponseMessage()
)
- if isinstance(msg, MaltegoTransformResponseMessage):
+ if isinstance(msg, MaltegoTransformResponseMessage) or isinstance(msg, basestring):
message(msg, self)
return
- elif isinstance(msg, basestring):
- raise MaltegoException(msg)
else:
raise MaltegoException('Could not resolve message type returned by transform.')
#!/usr/bin/env python
+from subprocess import PIPE, Popen
+
+from canari.resource import external_resource
+from canari.utils.stack import modulecallee
+
+from os import execvp, path
+from re import split
+
__author__ = 'Nadeem Douba'
__copyright__ = 'Copyright 2012, Canari Project'
__credits__ = []
__license__ = 'GPL'
-__version__ = '0.1'
+__version__ = '0.2'
__maintainer__ = 'Nadeem Douba'
__email__ = 'ndouba@gmail.com'
__status__ = 'Development'
raise TypeError('Expected type list (got %s instead)' % type(kwargs['inputs']))
kwargs['description'] = kwargs.get('description', '')
kwargs['debug'] = kwargs.get('debug', False)
+ self.function = kwargs.get('cmd', None)
self.specification = kwargs
def __call__(self, f):
+ if callable(self.function):
+ self.function.__dict__.update(f.__dict__)
+ f = self.function
f.__dict__.update(self.specification)
return f
+
+
+class ExternalCommand(object):
+
+ def __init__(self, transform_name, transform_args=[], interpreter=None, is_resource=True):
+ self._extra_external_args = []
+
+ if interpreter is not None:
+ self._extra_external_args.append(interpreter)
+ libpath = external_resource(
+ path.dirname(transform_name),
+ '%s.resources.external' % modulecallee().__name__.split('.')[0]
+ )
+ if interpreter.startswith('perl') or interpreter.startswith('ruby'):
+ self._extra_external_args.extend([ '-I', libpath ])
+ elif interpreter.startswith('java'):
+ self._extra_external_args.extend([ '-cp', libpath ])
+
+ if ' ' in transform_name:
+ raise ValueError('Transform name %s cannot have spaces.' % repr(transform_name))
+ elif not is_resource:
+ self._extra_external_args.append(transform_name)
+ else:
+ self._extra_external_args.append(
+ external_resource(
+ transform_name,
+ '%s.resources.external' % modulecallee().__name__.split('.')[0]
+ )
+ )
+
+ if isinstance(transform_args, basestring):
+ self._extra_external_args = split('\s+', transform_args)
+ else:
+ self._extra_external_args.extend(transform_args)
+
+ def __call__(self, request, request_xml):
+ args = [request.value]
+ if isinstance(request.params, list) and request.params:
+ args.extend(request.params)
+ if request.fields:
+ args.append('#'.join(['%s=%s' % (k, v) for k, v in request.fields.iteritems()]))
+ if isinstance(request_xml, basestring):
+ p = Popen(self._extra_external_args + list(args), stdin=PIPE, stdout=PIPE)
+ out, err = p.communicate(request_xml)
+ return out
+ execvp(self._extra_external_args[0], self._extra_external_args + list(args))
#!/usr/bin/env python
-from pkg_resources import resource_filename
+from utils.stack import modulecallee
+from pkg_resources import resource_filename
__author__ = 'Nadeem Douba'
__copyright__ = 'Copyright 2012, Canari Project'
__credits__ = []
__license__ = 'GPL'
-__version__ = '0.1'
+__version__ = '0.2'
__maintainer__ = 'Nadeem Douba'
__email__ = 'ndouba@gmail.com'
__status__ = 'Development'
def imagepath(pkg, name):
return '%s' % resource_filename(pkg, name)
+def external_resource(name, pkg=None):
+ if pkg is None:
+ pkg = '%s.resources.external' % modulecallee().__name__.split('.')[0]
+ return resource_filename(pkg, name)
+
# etc
conf = resource_filename(etc, 'canari.conf')
\ No newline at end of file
--- /dev/null
+#!/usr/bin/env python
+
+from inspect import stack, getmodule
+
+__author__ = 'Nadeem Douba'
+__copyright__ = 'Copyright 2012, Canari Project'
+__credits__ = []
+
+__license__ = 'GPL'
+__version__ = '0.1'
+__maintainer__ = 'Nadeem Douba'
+__email__ = 'ndouba@gmail.com'
+__status__ = 'Development'
+
+__all__ = [
+ 'modulecallee'
+]
+
+def modulecallee(atframe=2):
+ frame = stack()[atframe]
+ return getmodule(frame[0])
\ No newline at end of file