diff --git a/addon_example/hello_addon.tar.gz b/addon_example/hello_addon.tar.gz new file mode 100644 index 00000000..bf9c1901 Binary files /dev/null and b/addon_example/hello_addon.tar.gz differ diff --git a/addon_example/hello_addon/__init__.py b/addon_example/hello_addon/__init__.py new file mode 100644 index 00000000..1e5303ba --- /dev/null +++ b/addon_example/hello_addon/__init__.py @@ -0,0 +1 @@ +__author__ = 'mercolino' diff --git a/addon_example/hello_addon/templates/hello_world.html b/addon_example/hello_addon/templates/hello_world.html new file mode 100644 index 00000000..20e44f99 --- /dev/null +++ b/addon_example/hello_addon/templates/hello_world.html @@ -0,0 +1,31 @@ +{% extends "base.html" %} +{% block title %} Hello World Add-on{% endblock %} +{% block content %} +
+
+

Hello World Add-On

+
+
+
+
Here it is the Add-On Content.
+

You could add everything you want here!!!

+
+
+
+{% endblock %} + +{% block footer %} + + +{% endblock %} diff --git a/addon_example/hello_addon/views.py b/addon_example/hello_addon/views.py new file mode 100644 index 00000000..c95bae41 --- /dev/null +++ b/addon_example/hello_addon/views.py @@ -0,0 +1,11 @@ +from flask import (Blueprint, render_template) +from mhn.auth import login_required + +hello_addon = Blueprint('hello_addon', __name__, template_folder='templates/', url_prefix='/addons/hello_addon') + +@hello_addon.route('/home/', methods=['GET']) +@login_required +def home(): + return render_template('hello_world.html') + +__author__ = 'mercolino' \ No newline at end of file diff --git a/scripts/deploy_kippo.sh b/scripts/deploy_kippo.sh index d940db3e..a02b92ba 100755 --- a/scripts/deploy_kippo.sh +++ b/scripts/deploy_kippo.sh @@ -64,14 +64,14 @@ sed -i 's/twistd -y kippo.tac -l log\/kippo.log --pidfile kippo.pid/su kippo -c # Config for supervisor. cat > /etc/supervisor/conf.d/kippo.conf <{}'.format(self.to_dict()) + + def to_dict(self): + return dict(menu_name=self.menu_name, dir_name=self.dir_name, active=self.active, reboot=self.reboot) \ No newline at end of file diff --git a/server/mhn/auth/views.py b/server/mhn/auth/views.py index 73546d9e..59628add 100644 --- a/server/mhn/auth/views.py +++ b/server/mhn/auth/views.py @@ -55,13 +55,13 @@ def create_user(): return error_response( apierrors.API_FIELDS_MISSING.format(missing), 400) else: - user = get_datastore().create_user( + try: + user = get_datastore().create_user( email=request.json.get('email'), password=encrypt_password(request.json.get('password'))) - userrole = user_datastore.find_role('admin') - user_datastore.add_role_to_user(user, userrole) + userrole = user_datastore.find_role('admin') + user_datastore.add_role_to_user(user, userrole) - try: db.session.add(user) db.session.flush() @@ -81,8 +81,10 @@ def delete_user(user_id): user = User.query.get(user_id) if not user: return error_response(errors.AUTH_NOT_FOUND.format(user_id), 404) - user.active= False - db.session.add(user) + #user.active= False + #db.session.add(user) + #Lets delete the user instead of deactivate them + db.session.delete(user) db.session.commit() return jsonify({}) diff --git a/server/mhn/common/contextprocessors.py b/server/mhn/common/contextprocessors.py index 8fe808d9..ffe6cef5 100644 --- a/server/mhn/common/contextprocessors.py +++ b/server/mhn/common/contextprocessors.py @@ -1,14 +1,19 @@ from flask import current_app +import mhn.common.utils as utils def config_ctx(): """ Inserts some settings to be used in templates. """ + settings = { 'server_url': current_app.config['SERVER_BASE_URL'], 'honeymap_url': current_app.config['HONEYMAP_URL'], 'deploy_key': current_app.config['DEPLOY_KEY'], - 'supported_honeypots': current_app.config['HONEYPOT_CHANNELS'].keys() + 'supported_honeypots': current_app.config['HONEYPOT_CHANNELS'].keys(), + 'add_ons_enabled': current_app.config['ADD_ONS'] } + if current_app.config['ADD_ONS']: + settings['add_ons'] = utils.get_addons() return dict(settings=settings) diff --git a/server/mhn/common/utils.py b/server/mhn/common/utils.py index c32432fa..6b758d24 100644 --- a/server/mhn/common/utils.py +++ b/server/mhn/common/utils.py @@ -1,8 +1,61 @@ from math import ceil -from flask import jsonify, g +from flask import jsonify, g, current_app -from mhn.constants import PAGE_SIZE +from mhn.constants import PAGE_SIZE, ALLOWED_ADDON_EXTENSIONS + +from mhn.api.models import AddOns + +import os +import pwd +import grp + +import mhn.api.errors as apierrors + +def change_own(path, user, group): + uid = pwd.getpwnam(user).pw_uid + gid = grp.getgrnam(group).gr_gid + os.chown(path, uid, gid) + for item in os.listdir(path): + itempath = os.path.join(path, item) + if os.path.isfile(itempath): + os.chown(itempath, uid, gid) + elif os.path.isdir(itempath): + os.chown(itempath, uid, gid) + change_own(itempath, user, group) + + +def get_addons(): + add_ons = [] + for addon in AddOns.query.all(): + if addon.active == True and addon.reboot == False: + if addon.dir_name not in current_app.config['DISABLED_ADDONS']: + add_ons.append((addon.dir_name, addon.menu_name)) + return add_ons + + +def allowed_addon_filename(filename): + """ + Function to check if the nam of the file to upload is valid + :return: + return a tuple (Boolean, Error_Text) + True: If the filename follows a pattern [name_of_the_file_without_spaces].allowed_extension, Error is empty + False: Pattern is no correct, Error send + """ + extensions = filename.split(".") + if len(extensions) > 2: + extension = extensions[1] + for subext in extensions[2:]: + extension = extension + "." + subext + else: + extension = extensions[1] + + if (len(extensions) != 3) or (len(extensions[0].split(" ")) !=1): + return (False, apierrors.API_ADDON_NAME_INVALID.format(filename)) + elif extension not in ALLOWED_ADDON_EXTENSIONS: + return (False, apierrors.API_ADDON_EXTENSION_INVALID) + + return (True, '', '') def error_response(message, status_code=400): diff --git a/server/mhn/constants.py b/server/mhn/constants.py index 6e07ccf5..5c4eea2d 100644 --- a/server/mhn/constants.py +++ b/server/mhn/constants.py @@ -1 +1,2 @@ PAGE_SIZE = 15 +ALLOWED_ADDON_EXTENSIONS = ['tar.gz'] diff --git a/server/mhn/static/js/main.js b/server/mhn/static/js/main.js index 327acd7e..71979dfa 100644 --- a/server/mhn/static/js/main.js +++ b/server/mhn/static/js/main.js @@ -293,6 +293,25 @@ $(document).ready(function() { }); }); + $('.delete-addon').click(function(e) { + e.preventDefault(); + var addonId = $(this).attr('addon-id'); + + $.ajax({ + type: 'DELETE', + headers: {'X-CSRFToken': $('#_csrf_token').val()}, + url: '/ui/delete_addon/' + addonId + '/', + contentType: 'application/json', + success: function(resp) { + window.location.reload(); + + }, + error: function(resp) { + alert('Could not delete add-on.'); + } + }); + }); + if ($('#pass-form').length >= 1) { $('#submit-pass').click(function(e) { e.preventDefault(); diff --git a/server/mhn/templates/base.html b/server/mhn/templates/base.html index 5aa2b9da..b1632abb 100644 --- a/server/mhn/templates/base.html +++ b/server/mhn/templates/base.html @@ -42,10 +42,19 @@

MHN Server

  • Add sensor
  • - - - -
  • + + {% if settings.add_ons_enabled %} +
  • + Add-Ons + +
  • + {% endif %} + +
  • Charts