diff --git a/Dockerfile b/Dockerfile index 17fa426..f05fc33 100644 --- a/Dockerfile +++ b/Dockerfile @@ -53,14 +53,17 @@ COPY nginx/nginx.conf ${TFW_NGINX_CONF} COPY nginx/default.conf ${TFW_NGINX_DEFAULT} COPY lib ${TFW_LIB_DIR} +RUN for dir in "${TFW_LIB_DIR}" "/etc/nginx" "/etc/supervisor"; do \ + chown -R root:root "$dir" && chmod -R 700 "$dir"; \ + done + ONBUILD ARG BUILD_CONTEXT="." ONBUILD ARG NOFRONTEND="" ONBUILD COPY ${BUILD_CONTEXT}/nginx/components/ ${TFW_NGINX_COMPONENTS} ONBUILD COPY ${BUILD_CONTEXT}/supervisor/components/ ${TFW_SUPERVISORD_COMPONENTS} -ONBUILD RUN chown -R ${AVATAO_USER} /var/log/nginx /var/lib/nginx &&\ - for f in "${TFW_NGINX_DEFAULT}" ${TFW_NGINX_COMPONENTS}/*.conf; do \ +ONBUILD RUN for f in "${TFW_NGINX_DEFAULT}" ${TFW_NGINX_COMPONENTS}/*.conf; do \ envsubst "$(printenv | cut -d= -f1 | grep TFW_ | sed -e 's/^/$/g')" < $f > $f~ && mv $f~ $f ;\ done ONBUILD VOLUME ["/etc/nginx", "/var/lib/nginx", "/var/log/nginx"] diff --git a/lib/tfw/components/source_code_event_handler.py b/lib/tfw/components/source_code_event_handler.py index 6bc020c..fbaffd8 100644 --- a/lib/tfw/components/source_code_event_handler.py +++ b/lib/tfw/components/source_code_event_handler.py @@ -1,7 +1,7 @@ # Copyright (C) 2018 Avatao.com Innovative Learning Kft. # All Rights Reserved. See LICENSE file for details. -from os.path import isfile, join, relpath, exists, isdir +from os.path import isfile, join, relpath, exists, isdir, realpath from glob import glob from fnmatch import fnmatchcase from collections import Iterable @@ -13,9 +13,10 @@ from tfw.config.logs import logging LOG = logging.getLogger(__name__) -class FileManager: - def __init__(self, working_directory, selected_file=None, exclude=None): +class FileManager: # pylint: disable=too-many-instance-attributes + def __init__(self, working_directory, allowed_directories, selected_file=None, exclude=None): self._exclude, self.exclude = None, exclude + self._allowed_directories, self.allowed_directories = None, allowed_directories self._workdir, self.workdir = None, working_directory self._filename, self.filename = None, selected_file or self.files[0] @@ -39,8 +40,18 @@ class FileManager: def workdir(self, directory): if not exists(directory) or not isdir(directory): raise EnvironmentError('"{}" is not a directory!'.format(directory)) + if not self._is_whitelisted(directory): + raise EnvironmentError('Directory "{}" is not in whitelist!'.format(directory)) self._workdir = directory + @property + def allowed_directories(self): + return self._allowed_directories + + @allowed_directories.setter + def allowed_directories(self, directories): + self._allowed_directories = directories + @property def filename(self): return self._filename @@ -54,8 +65,9 @@ class FileManager: @property def files(self): return [self._relpath(file) for file in glob(join(self._workdir, '**/*'), recursive=True) - if isfile(file) and - not any(fnmatchcase(file, blacklisted) for blacklisted in self.exclude)] + if isfile(file) + and self._is_whitelisted(file) + and not any(fnmatchcase(file, blacklisted) for blacklisted in self.exclude)] @property def file_contents(self): @@ -67,6 +79,9 @@ class FileManager: with open(self._filepath(self.filename), 'w', errors='surrogateescape') as ofile: ofile.write(value) + def _is_whitelisted(self, file): + return any(realpath(file).startswith(allowed_dir) for allowed_dir in self.allowed_directories) + def _filepath(self, filename): return join(self._workdir, filename) @@ -75,9 +90,11 @@ class FileManager: class SourceCodeEventHandler(TriggerlessEventHandler): - def __init__(self, key, directory, selected_file=None, exclude=None): + # pylint: disable=too-many-arguments + def __init__(self, key, directory, allowed_directories, selected_file=None, exclude=None): super().__init__(key) - self.filemanager = FileManager(directory, selected_file=selected_file, exclude=exclude) + self.filemanager = FileManager(allowed_directories=allowed_directories, working_directory=directory, + selected_file=selected_file, exclude=exclude) self.commands = {'read': self.read, 'write': self.write, diff --git a/lib/tfw/components/terminado_event_handler.py b/lib/tfw/components/terminado_event_handler.py index 50245f5..76621a4 100644 --- a/lib/tfw/components/terminado_event_handler.py +++ b/lib/tfw/components/terminado_event_handler.py @@ -5,6 +5,7 @@ from tfw.components.terminado_mini_server import TerminadoMiniServer from tfw.event_handler_base import TriggerlessEventHandler from tfw.config import TFWENV from tfw.config.logs import logging +from tao.config import TAOENV LOG = logging.getLogger(__name__) @@ -14,7 +15,8 @@ class TerminadoEventHandler(TriggerlessEventHandler): super().__init__(key) self.working_directory = TFWENV.TERMINADO_DIR self._historymonitor = monitor - self.terminado_server = TerminadoMiniServer('/terminal', TFWENV.TERMINADO_PORT, TFWENV.TERMINADO_WD, ['bash']) + bash_as_user_cmd = ['sudo', '-u', TAOENV.USER, 'bash'] + self.terminado_server = TerminadoMiniServer('/terminal', TFWENV.TERMINADO_PORT, TFWENV.TERMINADO_WD, bash_as_user_cmd) self.commands = {'write': self.write, 'read': self.read} if self._historymonitor: diff --git a/supervisor/supervisord.conf b/supervisor/supervisord.conf index 4a14c2b..6e9e04c 100644 --- a/supervisor/supervisord.conf +++ b/supervisor/supervisord.conf @@ -1,5 +1,5 @@ [supervisord] -user=user +user=root logfile = /tmp/supervisord.log loglevel = debug pidfile = /tmp/supervisord.pid @@ -18,9 +18,5 @@ command=/usr/sbin/nginx -g 'daemon off;' autostart=true autorestart=true -[program:app] -directory=%(ENV_TFW_APP_DIR)s -command=python3 app.py - [include] files=%(ENV_TFW_SUPERVISORD_COMPONENTS)s/*.conf