From 94861b7cd29e2d40febe9d28c0f1c3c1459f913c Mon Sep 17 00:00:00 2001 From: Jose Date: Wed, 30 Oct 2019 11:46:50 -0400 Subject: [PATCH] Added WebGUI feature set --- CHANGELOG | 6 + LICENSE | 28 ++ bastille-init | 275 +++++++++---- conf/bastille.conf.ext | 20 + conf/bastille.conf.sample | 37 ++ gui/bastille_manager-lib.inc | 187 +++++++++ gui/bastille_manager_add.php | 188 +++++++++ gui/bastille_manager_config.php | 177 +++++++++ gui/bastille_manager_editor.php | 162 ++++++++ gui/bastille_manager_gui.php | 351 ++++++++++++++++ gui/bastille_manager_info.php | 148 +++++++ ...i.php => bastille_manager_maintenance.php} | 141 ++++--- gui/bastille_manager_tarballs.php | 214 ++++++++++ gui/bastille_manager_util.php | 376 ++++++++++++++++++ gui/ext/bastille-gui/menu.inc | 1 - gui/ext/bastille/menu.inc | 1 + gui/images/bsd_icon.png | Bin 0 -> 872 bytes gui/images/icon.png | Bin 0 -> 8554 bytes gui/images/icon_small.png | Bin 0 -> 482 bytes release_notes | 11 - version | 2 +- 21 files changed, 2172 insertions(+), 153 deletions(-) create mode 100644 CHANGELOG create mode 100644 LICENSE create mode 100644 conf/bastille.conf.ext create mode 100644 conf/bastille.conf.sample create mode 100755 gui/bastille_manager-lib.inc create mode 100644 gui/bastille_manager_add.php create mode 100644 gui/bastille_manager_config.php create mode 100644 gui/bastille_manager_editor.php create mode 100644 gui/bastille_manager_gui.php create mode 100644 gui/bastille_manager_info.php rename gui/{bastille-gui.php => bastille_manager_maintenance.php} (60%) create mode 100644 gui/bastille_manager_tarballs.php create mode 100644 gui/bastille_manager_util.php delete mode 100644 gui/ext/bastille-gui/menu.inc create mode 100644 gui/ext/bastille/menu.inc create mode 100644 gui/images/bsd_icon.png create mode 100644 gui/images/icon.png create mode 100644 gui/images/icon_small.png delete mode 100644 release_notes diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..484594e --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,6 @@ +====================== += Extension Bastille = +====================== +Version Description + +1.0.0......First Public Release. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..85f2386 --- /dev/null +++ b/LICENSE @@ -0,0 +1,28 @@ +--------------------------------------------------------- + Copyright (c) 2019, José Rivera + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the developer nor the names of contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE DEVELOPER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + --------------------------------------------------------- diff --git a/bastille-init b/bastille-init index 88d0f26..db9a554 100755 --- a/bastille-init +++ b/bastille-init @@ -1,33 +1,40 @@ #!/bin/sh # bastille-init # Bastille Extension for XigmaNAS x64 11.x and later. -# Bastille Homepage: http://bastillebsd.org/ +# Bastille Extension Forum: https://www.xigmanas.com/forums/viewtopic.php?f=71&t=14848 +# Bastille Extension GitHub: https://github.com/JRGTH/xigmanas-bastille-extension +# Bastille Homepage: http://bastillebsd.org/ +# Bastille GitHub: https://github.com/BastilleBSD/bastille # -# ***(For Preview/Testing)*** # Debug script #set -x -# Copyright (c) 2019 José Rivera (JoseMR) +# Copyright (c) 2019, José Rivera (joserprg@gmail.com). # All rights reserved. -# + # Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that following conditions are met: +# modification, are permitted provided that the following conditions +# are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS 'AS IS' AND ANY -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY -# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# 3. Neither the name of the developer nor the names of contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. + +# THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE DEVELOPER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. # Set environment. PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin @@ -45,8 +52,7 @@ CONFIG="/cf/conf/config.xml" PRDNAME="Bastille" APPNAME="bastille" EXTLOGFILE="${CWDIR}/log/bastille_ext.log" -FULLAPPNAME="${APPNAME}-addon" -PKGCONF="/etc/pkg/FreeBSD.conf" +FULLAPPNAME="${APPNAME}-main" WWWPATH="/usr/local/www" PKGCACHE="/var/cache/pkg" USRLOCAL="/usr/local" @@ -56,11 +62,12 @@ EXTCONFLINK="/var/etc/${APPNAME}_conf" BASTILLERCD="/usr/local/etc/rc.d/${APPNAME}" BASTILLEPATH="${USRLOCAL}/bin" BASTILLECONF="${USRLOCAL}/etc/${APPNAME}/${APPNAME}.conf" -BASTILLECONFLINK="/var/etc/bastilleconf" +BASTILLECONFLINK="/var/etc/bastille_conf" +BASTILLECONF_EXT="${CWDIR}/conf/bastille.conf.ext" INSTALLPATH="${CWDIR}/${FULLAPPNAME}" BRANCH="master" -#BATSILLE_URL="https://github.com/BastilleBSD/${APPNAME}/archive/${BRANCH}.zip" # Official Bastille repository(Pending some updates/fixes) -BATSILLE_URL="https://github.com/JRGTH/${APPNAME}/archive/${BRANCH}.zip" # Alternate Bastille repository(Updated, supports 11.3-RELEASE base) +BATSILLE_URL="https://github.com/BastilleBSD/${APPNAME}/archive/${BRANCH}.zip" # Official Bastille Repository) +#BATSILLE_URL="https://github.com/JRGTH/${APPNAME}/archive/${BRANCH}.zip" # Alternate Bastille Repository) BASTILE_VERSION="https://raw.githubusercontent.com/BastilleBSD/${APPNAME}/${BRANCH}/usr/local/bin/${APPNAME}" GITURL="https://github.com/JRGTH/xigmanas-${APPNAME}-extension/archive/${BRANCH}.zip" VERFILE="https://raw.githubusercontent.com/JRGTH/xigmanas-${APPNAME}-extension/${BRANCH}/version" @@ -81,6 +88,9 @@ runtime_config() sysrc -f ${INSTALLPATH}/${BASTILLECONF} bastille_prefix="${CWDIR}" >/dev/null 2>&1 fi fi + if [ ! -d ${CWDIR}/backups ]; then + mkdir -p ${CWDIR}/backups + fi if [ ! -d ${CWDIR}/conf ]; then mkdir -p ${CWDIR}/conf fi @@ -110,9 +120,10 @@ bastille_pkg_extract() if [ -f ${CWDIR}/${BRANCH}.zip ]; then if [ ! -f ${CWDIR}/${FULLAPPNAME}${BASTILLEPATH}/${APPNAME} ]; then echo "Extracting ${APPNAME}..." - tar -xf ${CWDIR}/${BRANCH}.zip --exclude='.git*' --strip-components 1 -C ${CWDIR}/${FULLAPPNAME} || \ + tar -xf ${CWDIR}/${BRANCH}.zip --exclude='.git*' --exclude='docs' --exclude='bastille.conf' --strip-components 1 -C ${CWDIR}/${FULLAPPNAME} || \ error_notify "Error: A problem has occurred while extractig ${APPNAME} files." chmod 555 ${CWDIR}/${FULLAPPNAME}${BASTILLEPATH}/${APPNAME} + chmod 555 ${CWDIR}/${FULLAPPNAME}${BASTILLERCD} rm -f ${CWDIR}/${BRANCH}.zip echo "Done!" fi @@ -123,7 +134,7 @@ bastille_upgrade() { # Perform an online bastille upgrade. DATE=$(date +"%a %b %d %T %Y") - echo "Looking for new ${APPNAME} package!" + echo "Looking for new ${PRDNAME} package!" mkdir -p ${CWDIR}/update fetch -ao ${CWDIR}/update --no-verify-peer --timeout=30 ${BASTILE_VERSION} || \ error_notify "Error: A problem has occurred while fetching version file." @@ -136,10 +147,11 @@ bastille_upgrade() echo "New ${APPNAME} package found, performing upgrade..." fetch -ao ${CWDIR}/update --no-verify-peer --timeout=30 ${BATSILLE_URL} || \ error_notify "Error: A problem has occurred while fetching ${APPNAME} package." - tar -xf ${CWDIR}/update/${BRANCH}.zip --exclude='.git*' --strip-components 1 -C ${CWDIR}/update + tar -xf ${CWDIR}/update/${BRANCH}.zip --exclude='.git*' --exclude='docs' --exclude='bastille.conf' --strip-components 1 -C ${CWDIR}/update rm -f ${CWDIR}/update/${BRANCH}.zip rm -f ${CWDIR}/update/${APPNAME} chmod 555 ${CWDIR}/update/${BASTILLEPATH}/${APPNAME} + chmod 555 ${CWDIR}/${FULLAPPNAME}${BASTILLERCD} cp -Rf ${CWDIR}/update/* ${CWDIR}/${FULLAPPNAME}/ rm -R ${CWDIR}/update @@ -209,10 +221,13 @@ extension_upgrade() create_addon_env() { - # Set bastile dir proper permissions. + # Set bastille dir required permissions. chmod 0750 ${CWDIR} # Create required directories. + if [ ! -d "${CWDIR}/backups" ]; then + mkdir -p ${CWDIR}/backups + fi if [ ! -d "${CWDIR}/log" ]; then mkdir -p ${CWDIR}/log fi @@ -252,7 +267,7 @@ bin_symlinks() cd ${INSTALLPATH}/${BASTILLEPATH} for file in * do - ln -Ffhs ${INSTALLPATH}/${BASTILLEPATH}/${file} ${USRLOCAL}/bin/${file} + ln -fhs ${INSTALLPATH}/${BASTILLEPATH}/${file} ${USRLOCAL}/bin/${file} done fi } @@ -262,26 +277,26 @@ sys_symlinkdir() # Check and create/relink required symlinks/dirs for bastille. # This environment will be checked each time the script is started for consistency. + # Link required binaries. + bin_symlinks + # Required directories for bastille. if [ ! -d "${USRLOCAL}/share/licenses" ]; then mkdir -p ${USRLOCAL}/share/licenses fi - # Link required binaries. - bin_symlinks - # Required symlinks for bastille. if [ -d "${INSTALLPATH}/${USRLOCAL}/share/licenses" ]; then cd ${INSTALLPATH}/${USRLOCAL}/share/licenses for file in * do - ln -Ffhs ${INSTALLPATH}/${USRLOCAL}/share/licenses/${file} ${USRLOCAL}/share/licenses/${file} + ln -fhs ${INSTALLPATH}/${USRLOCAL}/share/licenses/${file} ${USRLOCAL}/share/licenses/${file} done fi # Link bastile config file directory. if [ -d "${INSTALLPATH}/${USRLOCAL}/etc/${APPNAME}" ]; then - ln -Ffhs ${INSTALLPATH}/${USRLOCAL}/etc/${APPNAME} ${USRLOCAL}/etc/${APPNAME} + ln -fhs ${INSTALLPATH}/${USRLOCAL}/etc/${APPNAME} ${USRLOCAL}/etc/${APPNAME} fi # Link bastile config file. @@ -290,11 +305,15 @@ sys_symlinkdir() if [ ! -f "${APPNAME}.conf" ]; then cp ${APPNAME}.conf.sample ${APPNAME}.conf fi + else + if [ -f "${BASTILLECONF_EXT}" ]; then + cp ${BASTILLECONF_EXT} ${INSTALLPATH}/${USRLOCAL}/etc/${APPNAME}/${APPNAME}.conf + fi fi # Copy bastille shared. if [ -d "${INSTALLPATH}/${USRLOCAL}/share/${APPNAME}" ]; then - ln -Ffhs ${INSTALLPATH}/${USRLOCAL}/share/${APPNAME} ${USRLOCAL}/share/${APPNAME} + ln -fhs ${INSTALLPATH}/${USRLOCAL}/share/${APPNAME} ${USRLOCAL}/share/${APPNAME} fi # Copy bastille rc. @@ -309,8 +328,8 @@ postinit_cmd() if ! grep -qw ${CWDIR}/${SCRIPTNAME} ${CONFIG}; then touch ${CWDIR}/postinit || error_notify "Error: A problem has occurred while creating the postinit file." chmod +x ${CWDIR}/postinit - if [ ! "${PRDVERSION}" -ge "110" ]; then - # Generate php script for NAS4Free 10.3 versions. + if [ ! "${PRDVERSION}" -ge "112" ]; then + # Generate php script for previous product versions. cat << EOF > ${CWDIR}/postinit EOF else - # Generate php script for NAS4Free/XigmaNAS 11.x versions. + # Generate php script for later product versions. cat << EOF > ${CWDIR}/postinit EOF fi @@ -359,7 +402,7 @@ EOF echo "Done!" fi - # Set extension to disable by default. + # Set extension to enable by default. sysrc -f ${CWDIR}${EXTCONF} GUI_ENABLE=YES INSTALL_DIR=${CWDIR} >/dev/null 2>&1 fi } @@ -382,21 +425,31 @@ gui_start() sysrc -f ${CWDIR}${EXTCONF} INSTALL_DIR=${CWDIR} >/dev/null 2>&1 fi mkdir -p ${BASTILLECONFLINK} - ln -Ffhs ${CWDIR}/conf ${BASTILLECONFLINK}/conf - # Copy the gui files. - cp -R ${CWDIR}/gui/* ${WWWPATH}/ || error_notify "Error: A problem has occurred while copying extension gui files." + ln -fhs ${CWDIR}/conf ${BASTILLECONFLINK}/conf + # Link the gui files. + if [ ! -d "${WWWPATH}/ext" ]; then + mkdir -p ${WWWPATH}/ext + fi + ln -fhs ${CWDIR}/gui/ext/bastille ${WWWPATH}/ext/ || error_notify "Error: A problem has occurred while copying extension gui files." + ln -fhs ${CWDIR}/gui/images ${WWWPATH}/ext/bastille/ || error_notify "Error: A problem has occurred while copying extension gui files." + ln -fhs ${CWDIR}/gui/bastille_manager_*.php ${WWWPATH}/ || error_notify "Error: A problem has occurred while linking extension gui files." fi fi } gui_enable() { - # Relink conf and copy the gui files. + # Relink conf and gui files. if [ -d "${CWDIR}/gui" ]; then mkdir -p ${BASTILLECONFLINK} - ln -Ffhs ${CWDIR}/conf ${BASTILLECONFLINK}/conf + ln -fhs ${CWDIR}/conf ${BASTILLECONFLINK}/conf sysrc -f ${CWDIR}${EXTCONF} GUI_ENABLE=YES >/dev/null 2>&1 - cp -R ${CWDIR}/gui/* ${WWWPATH}/ || error_notify "Error: A problem has occurred while copying extension gui files." + if [ ! -d "${WWWPATH}/ext" ]; then + mkdir -p ${WWWPATH}/ext + fi + ln -fhs ${CWDIR}/gui/ext/bastille ${WWWPATH}/ext/ || error_notify "Error: A problem has occurred while copying extension gui files." + ln -fhs ${CWDIR}/gui/images ${WWWPATH}/ext/bastille/ || error_notify "Error: A problem has occurred while copying extension gui files." + ln -fhs ${CWDIR}/gui/bastille_manager_*.php ${WWWPATH}/ || error_notify "Error: A problem has occurred while copying extension gui files." exit 0 else error_notify "Error: Extension gui files not found." @@ -407,10 +460,11 @@ gui_disable() { # Disable gui if -t option specified. if [ -d "${CWDIR}/gui" ]; then - rm -f ${WWWPATH}bastille-gui.php - rm -Rf ${WWWPATH}/ext/bastille-gui + rm -f ${WWWPATH}bastille_manager_*.php + rm -rf ${WWWPATH}/ext/bastille + rm -rf ${WWWPATH}/ext/bastille/images rm -f ${LOCALSHAREPATH}/locale-bastille - rm -Rf ${BASTILLECONFLINK} + rm -rf ${BASTILLECONFLINK} sysrc -f ${CWDIR}${EXTCONF} GUI_ENABLE=NO >/dev/null 2>&1 || error_notify "Error: A problem while removing extension gui files." exit 0 else @@ -420,7 +474,7 @@ gui_disable() # Remove empty ext folder to prevent empty "Extensions" tab. if [ -d "${WWWPATH}/ext" ]; then if [ ! "$(ls -A ${WWWPATH}/ext)" ]; then - rm -R ${WWWPATH}/ext + rm -r ${WWWPATH}/ext fi fi } @@ -442,8 +496,8 @@ reset_install() { # Reset the extension environment. echo "Removing extension files..." - if [ -d ${CWDIR}/conf ]; then - rm -rf ${CWDIR}/conf + if [ -f ${CWDIR}/conf/bastille_config ]; then + rm -rf ${CWDIR}/conf/bastille_config fi if [ -d ${CWDIR}/${FULLAPPNAME} ]; then rm -rf ${CWDIR}/${FULLAPPNAME} @@ -470,11 +524,11 @@ remove_addon() echo "Proceeding..." # Check for working platform and remove symlinks. - if [ "${PRDPLATFORM}" = "x64-embedded" ]; then + if [ "${PRDPLATFORM}" = "x64-embedded" ] || [ "${PRDPLATFORM}" = "x64-full" ]; then if [ -d "${USRLOCAL}/share/licenses/${APPNAME}-*" ]; then rm -rf ${USRLOCAL}/share/licenses/${APPNAME}-* fi - if [ -d ${USRLOCAL}/share/locale-bastille ]; then + if [ -d $"{USRLOCAL}/share/locale-bastille" ]; then rm -rf ${USRLOCAL}/share/locale-bastille fi if [ -f "${USRLOCAL}/etc/rc.d/${APPNAME}" ]; then @@ -489,21 +543,19 @@ remove_addon() if [ -d "${VARLOG}/${APPNAME}" ]; then rm -rf ${VARLOG}/${APPNAME} fi - elif [ "${PRDPLATFORM}" = "x64-full" ]; then - pkg delete -y ${APPNAME} fi # Remove extension and GUI components. - if [ -f "${WWWPATH}/${APPNAME}-gui.php" ]; then - rm -f ${WWWPATH}/${APPNAME}-gui.php + if [ -f "${WWWPATH}/bastille_manager_gui.php" ]; then + rm -f ${WWWPATH}/bastille_manager_*.php fi - if [ -d "${WWWPATH}/ext/bastille-gui" ]; then - rm -rf ${WWWPATH}/ext/bastille-gui + if [ -d "${WWWPATH}/ext/bastille" ]; then + rm -rf ${WWWPATH}/ext/bastille fi - if [ -f ${USRLOCAL}/bin/${APPNAME} ]; then + if [ -f "${USRLOCAL}/bin/${APPNAME}" ]; then rm -rf ${USRLOCAL}/bin/${APPNAME} fi - if [ -d ${VARLOG}/${APPNAME} ]; then + if [ -d "${VARLOG}/${APPNAME}" ]; then rm -rf ${VARLOG}/${APPNAME} fi @@ -515,11 +567,12 @@ remove_addon() fi # Remove addon related files and folders only- - # to protect any user-created custom files. - FILES="conf download gui locale-bastille log bastille-addon README.md postinit release_notes version bastille-init" - for file in ${FILES}; do - if [ -f ${CWDIR}/${file} ] || [ -d ${CWDIR}/${file} ]; then - rm -rf ${CWDIR}/${file} + # to protect any user-created custom files- + # as well as for the containers dirs/files. + FILES="conf download gui locale-bastille log bastille-main LICENSE README.md postinit release_notes version bastille-init" + for FILE in ${FILES}; do + if [ -f "${CWDIR}/${file}" ] || [ -d "${CWDIR}/${file}" ]; then + rm -rf ${CWDIR}/${FILE} fi done @@ -530,7 +583,7 @@ remove_addon() get_versions() { - # Get bastille-addon extension version. + # Get product versions. if [ -f "${CWDIR}/version" ]; then APPVERSION=$(cat ${CWDIR}/version) else @@ -540,7 +593,6 @@ get_versions() # Display product versions. BASTILLEVER=$(${USRLOCAL}/bin/bastille --version) echo "Bastille version: ${BASTILLEVER}" - echo "Extension version: ${APPVERSION}" exit 0 } @@ -548,15 +600,15 @@ get_versions() ext_start() { # Start bastille jails. - if [ "${PRDPLATFORM}" = "x64-embedded" ]; then - if [ -d "${CWDIR}/jails" ]; then - if [ "$(ls -A ${CWDIR}/jails)" ]; then - JAIL_AUTO_START=$(sysrc -qn bastille_enable) - if [ "${JAIL_AUTO_START}" = "YES" ]; then - service bastille start + if [ -d "${CWDIR}/jails" ]; then + JAIL_LIST=$(bastille list jail) + for jail in ${JAIL_LIST}; do + if sysrc -f ${CWDIR}${EXTCONF} -qn ${jail}_AUTO_START | grep -w "YES" >/dev/null; then + if ! jls | sed "1 d" | awk '{print $3}' | grep -qw ${jail}; then + bastille start ${jail} fi fi - fi + done fi if [ $? -eq 0 ]; then @@ -572,27 +624,70 @@ ext_start() rc_params() { - # Bastille rc parameters. + # Bastille required parameters. + + # Set bastille prefix. if ! sysrc -f ${BASTILLECONF} -qn bastille_prefix | grep -q "${CWDIR}"; then sysrc -f ${BASTILLECONF} bastille_prefix="${CWDIR}" >/dev/null 2>&1 fi - # Default network interface. - ACTIVE_NETIF=$(ifconfig | grep "UP,BROADCAST" | awk -F":" '{print $1}') - if ! sysrc -f ${BASTILLECONF} -qn bastille_jail_external >/dev/null 2>&1; then - echo "" >> ${BASTILLECONF} && echo "## default network interface" >> ${BASTILLECONF} + # Set bastille.conf location. + if ! sysrc -f ${CWDIR}${EXTCONF} -n BASTILLE_CONFIG 2>/dev/null | grep -q "${CWDIR}/${FULLAPPNAME}${BASTILLECONF}"; then + sysrc -f ${CWDIR}${EXTCONF} BASTILLE_CONFIG="${CWDIR}/${FULLAPPNAME}${BASTILLECONF}" >/dev/null 2>&1 + fi + + # Default first network interface. + ACTIVE_NETIF=$(ifconfig | grep "UP,BROADCAST" | awk -F":" '{print $1}' | sed 1q) + if ! sysrc -f ${BASTILLECONF} -qn bastille_jail_external | grep -q "${ACTIVE_NETIF}" >/dev/null 2>&1; then + #echo "" >> ${BASTILLECONF} && echo "## default network interface" >> ${BASTILLECONF} sysrc -f ${BASTILLECONF} bastille_jail_external="${ACTIVE_NETIF}" >/dev/null 2>&1 else - BLANK_NETIF=$(sysrc -f ${BASTILLECONF} -qn bastille_jail_external) - if [ -z "${BLANK_NETIF}" ]; then - echo "" >> ${BASTILLECONF} && echo "## default network interface" >> ${BASTILLECONF} + EXT_NETIF=$(sysrc -f ${BASTILLECONF} -qn bastille_jail_external) + if [ -z "${EXT_NETIF}" ]; then + #echo "" >> ${BASTILLECONF} && echo "## default network interface" >> ${BASTILLECONF} sysrc -f ${BASTILLECONF} bastille_jail_external="${ACTIVE_NETIF}" >/dev/null 2>&1 fi fi - # Start all jails by default. + # Do't start containers by default. if ! sysrc -qn bastille_enable >/dev/null 2>&1; then - sysrc bastille_enable="YES" >/dev/null 2>&1 + sysrc bastille_enable="NO" >/dev/null 2>&1 + fi +} + +bastille_start() +{ + # Start all bastille containers. + echo "${PRDNAME} Extension: Starting all containers..." + bastille start ALL + if [ $? -eq 0 ]; then + exit 0 + else + exit 1 + fi +} + +bastille_stop() +{ + # Stop all bastille containers. + echo "${PRDNAME} Extension: Stopping all containers..." + bastille stop ALL + if [ $? -eq 0 ]; then + exit 0 + else + exit 1 + fi +} + +bastille_restart() +{ + # Restart all bastille containers. + echo "${PRDNAME} Extension: Restarting all containers..." + bastille restart ALL + if [ $? -eq 0 ]; then + exit 0 + else + exit 1 fi } @@ -603,7 +698,7 @@ bastille_init() echo "Unsupported platform!"; exit 1 fi # Check for product compatibility. - if [ ! "${PRDVERSION}" -ge "110" ]; then + if [ ! "${PRDVERSION}" -ge "112" ]; then echo "Unsupported version!"; exit 1 fi @@ -621,18 +716,24 @@ bastille_init() # Run-time configuration. runtime_config -while getopts ":ouxRvgth" option; do +while getopts ":ospruxRvgth" option; do case ${option} in [h]) echo "Usage: ${SCRIPTNAME} -[option]"; echo "Options:" + echo " -s Start All ${PRDNAME} Containers." + echo " -p Stop All ${PRDNAME} Containers." + echo " -r Restart All ${PRDNAME} Containers." echo " -u Upgrade ${PRDNAME}/Extension packages." echo " -v Display product versions." echo " -g Enables the addon GUI." echo " -t Disable the addon GUI." echo " -x Reset ${PRDNAME}/Extension config." - echo " -R Remove ${PRDNAME}." + echo " -R Remove ${PRDNAME} (Extension files only)." echo " -h Display this help message."; exit 0;; [o]) OBI_INSTALL="ON";; # To prevent nested PHP-CGI call for installation with OBI. + [s]) bastille_start;; + [p]) bastille_stop;; + [r]) bastille_restart;; [u]) pkg_upgrade;; [x]) reset_install;; [R]) remove_addon;; diff --git a/conf/bastille.conf.ext b/conf/bastille.conf.ext new file mode 100644 index 0000000..88c4805 --- /dev/null +++ b/conf/bastille.conf.ext @@ -0,0 +1,20 @@ +bastille_prefix="/usr/local/bastille" +bastille_cachedir="${bastille_prefix}/cache" +bastille_jailsdir="${bastille_prefix}/jails" +bastille_logsdir="${bastille_prefix}/logs" +bastille_releasesdir="${bastille_prefix}/releases" +bastille_templatesdir="${bastille_prefix}/templates" +bastille_sharedir="/usr/local/share/bastille" +bastille_bootstrap_archives="base" +bastille_tzdata="etc/UTC" +bastille_resolv_conf="/etc/resolv.conf" +bastille_zfs_enable="" +bastille_zfs_zpool="" +bastille_zfs_prefix="bastille" +bastille_zfs_mountpoint="${bastille_prefix}" +bastille_zfs_options="-o compress=lz4 -o atime=off" +bastille_jail_loopback="" +bastille_jail_interface="" +bastille_jail_external="" +bastille_jail_addr="" +bastille_jail_gateway="" diff --git a/conf/bastille.conf.sample b/conf/bastille.conf.sample new file mode 100644 index 0000000..2bef663 --- /dev/null +++ b/conf/bastille.conf.sample @@ -0,0 +1,37 @@ +##################### +## [ BastilleBSD ] ## +##################### + +## default paths +bastille_prefix="/usr/local/bastille" ## default: "/usr/local/bastille" +bastille_cachedir="${bastille_prefix}/cache" ## default: ${bastille_prefix}/cache +bastille_jailsdir="${bastille_prefix}/jails" ## default: ${bastille_prefix}/jails +bastille_logsdir="${bastille_prefix}/logs" ## default: ${bastille_prefix}/logs +bastille_releasesdir="${bastille_prefix}/releases" ## default: ${bastille_prefix}/releases +bastille_templatesdir="${bastille_prefix}/templates" ## default: ${bastille_prefix}/templates + +## bastille scripts directory (assumed by bastille pkg) +bastille_sharedir="/usr/local/share/bastille" ## default: "/usr/local/share/bastille" + +## bootstrap archives (base, lib32, ports, src, test) +bastille_bootstrap_archives="base" ## default: "base" + +## default timezone +bastille_tzdata="etc/UTC" ## default: "etc/UTC" + +## default jail resolv.conf +bastille_resolv_conf="/etc/resolv.conf" ## default: "/etc/resolv.conf" + +## ZFS options +bastille_zfs_enable="" ## default: "" +bastille_zfs_zpool="" ## default: "" +bastille_zfs_prefix="bastille" ## default: "${bastille_zfs_zpool}/bastille" +bastille_zfs_mountpoint=${bastille_prefix} ## default: "${bastille_prefix}" +bastille_zfs_options="-o compress=lz4 -o atime=off" ## default: "-o compress=lz4 -o atime=off" + +## Networking +bastille_jail_loopback="lo1" ## default: "lo1" +bastille_jail_interface="bastille0" ## default: "bastille0" +bastille_jail_external="" ## default: "" +bastille_jail_addr="10.17.89.10" ## default: "10.17.89.10" +bastille_jail_gateway="" ## default: "" diff --git a/gui/bastille_manager-lib.inc b/gui/bastille_manager-lib.inc new file mode 100755 index 0000000..37c0aeb --- /dev/null +++ b/gui/bastille_manager-lib.inc @@ -0,0 +1,187 @@ +/dev/null)"); +if ($avail_releases == ''): + $empty_releases = "YES"; + $avail_releases = "No base releases detected!"; +endif; + +// Ensure the root directory is configured. +if ($rootfolder == "") + $input_errors[] = gtext("Extension installed with fault"); +else { +// Initialize locales. + $textdomain = "/usr/local/share/locale"; + $textdomain_bastille = "/usr/local/share/locale-bastille"; + if (!is_link($textdomain_bastille)) { mwexec("ln -s {$rootfolder}/locale-bastille {$textdomain_bastille}", true); } + bindtextdomain("xigmanas", $textdomain_bastille); +} +if (is_file("{$rootfolder}/postinit")) unlink("{$rootfolder}/postinit"); + +// Get all base releases list. +function get_all_release_list() { + global $rootfolder; + global $g; + exec("/bin/echo; /bin/ls {$rootfolder}/releases 2>/dev/null | /usr/bin/tr -s ' ' '\n'",$relinfo); + array_shift($relinfo); + $rellist = []; + foreach($relinfo as $rel): + $arel = preg_split("/\s+/",ltrim($rel)); + $relname = chop($arel[0]); + if(substr($relname,-1) === '*'): + $relname = substr($relname,0,strlen($relname) - 1); + endif; + $rellist[$relname] = []; + endforeach; + return $rellist; +} + +// Get all interface list. +function get_all_interface_list() { + global $g; + exec("/bin/echo; /sbin/ifconfig -l | /usr/bin/tr -s ' ' '\n'; /bin/echo 'NONE'",$linkinfo); + array_shift($linkinfo); + $iflist = []; + foreach($linkinfo as $link): + $alink = preg_split("/\s+/",ltrim($link)); + $ifname = chop($alink[0]); + if(substr($ifname,-1) === '*'): + $ifname = substr($ifname,0,strlen($ifname) - 1); + endif; + $iflist[$ifname] = []; + endforeach; + return $iflist; +} + +// Get jail infos. +function get_jail_infos() { + global $img_path; + global $image_dir; + global $configfile; + global $jail_dir; + $result = []; + if(is_dir($jail_dir)): + $cmd = '/usr/local/bin/bastille list jail 2>&1'; + else: + $cmd = ":"; + endif; + mwexec2($cmd,$rawdata); + foreach($rawdata as $line): + $a = preg_split('/\t/',$line); + $r = []; + $name = $a[0]; + if(preg_match('/(.*)/', $name, $m)): + $r['name'] = $m[1]; + else: + $r['name'] = '-'; + endif; + $r['jailname'] = $r['name']; + + // Set the JID on the running jails. + $item = $r['jailname']; + $r['id'] = exec("/usr/sbin/jls | /usr/bin/grep {$item} | /usr/bin/awk '{print $1}'"); + if (!$r['id']): + $r['id'] = "-"; + endif; + // Set the IPv4 on the running jails. + //$r['ip'] = exec("/usr/sbin/jls | /usr/bin/grep {$item} | /usr/bin/awk '{print $2}'"); + $r['ip'] = exec("/usr/bin/grep -w 'ip4.addr' {$jail_dir}/{$item}/jail.conf | /usr/bin/awk '{print $3}' | /usr/bin/tr -d ';'"); + if (!$r['ip']): + $r['ip'] = "-"; + endif; + // Display interfaces. + $r['nic'] = exec("/usr/bin/grep -w 'interface' {$jail_dir}/{$item}/jail.conf | /usr/bin/awk '{print $3}' | /usr/bin/tr -d ';'"); + if (!$r['nic']): + $r['nic'] = "-"; + endif; + // Display path. + $r['path'] = exec("/usr/bin/grep -w 'path' {$jail_dir}/{$item}/jail.conf | /usr/bin/awk '{print $3}' | /usr/bin/tr -d ';'"); + if (!$r['path']): + $r['path'] = "-"; + endif; + // Display auto-start settings. + $jail_autostart = exec("/usr/sbin/sysrc -qn -f {$configfile} {$item}_AUTO_START"); + if ($jail_autostart == 'YES') { + $r['boot'] = $img_path['ena']; + } elseif ($jail_autostart == 'NO') { + $r['boot'] = $img_path['dis']; + } else { + $r['boot'] = $img_path['dis']; + } + // Display running status icons. + $jail_running = exec("/usr/sbin/jls | /usr/bin/grep -w {$item}"); + if ($jail_running): + $r['stat'] = $img_path['ena']; + else: + $r['stat'] = $img_path['dis']; + endif; + // Display custom template icons if available. + $item = $item; + $template_icon = "{$image_dir}/{$item}_icon.png"; + if(file_exists($template_icon)): + $r['logo'] = "{$image_dir}/{$item}_icon.png"; + else: + // Display standard FreeBSD icon. + $r['logo'] = "{$image_dir}/bsd_icon.png"; + endif; + + $result[] = $r; + endforeach; + return $result; +} + +?> diff --git a/gui/bastille_manager_add.php b/gui/bastille_manager_add.php new file mode 100644 index 0000000..1990b57 --- /dev/null +++ b/gui/bastille_manager_add.php @@ -0,0 +1,188 @@ +. + XigmaNAS® is a registered trademark of Michael Zoon (zoon01@xigmanas.com). + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the developer nor the names of contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE DEVELOPER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +*/ + +require_once 'auth.inc'; +require_once 'guiconfig.inc'; +require_once("bastille_manager-lib.inc"); + +$pgtitle = array(gtext("Extensions"), "Bastille", "Create"); + +if(!$pconfig['jailname']): + $pconfig['jailname'] = 'jail1'; +endif; +if(!$pconfig['ipaddress']): + $pconfig['ipaddress'] = ''; +endif; + +// list of configured interfaces +$a_interface = get_all_interface_list(); +$l_interfaces = []; +foreach($a_interface as $k_interface => $ifinfo): + $l_interfaces[$k_interface] = $k_interface; +endforeach; + +// list base releases +$a_release = get_all_release_list(); +$l_release = []; +foreach($a_release as $k_release => $release): + $l_release[$k_release] = $k_release; +endforeach; + +if(!is_dir($jail_dir)): + $errormsg = gtext('No base releases extracted yet.') + . ' ' + . '' + . gtext('Please download a base release first.') + . ''; + $prerequisites_ok = false; +endif; + +if($_POST): + global $empty_releases; + global $configfile; + unset($input_errors); + $pconfig = $_POST; + if(isset($_POST['Cancel']) && $_POST['Cancel']): + header('Location: bastille_manager_gui.php'); + exit; + endif; + if(isset($_POST['Create']) && $_POST['Create']): + $jname = $pconfig['jailname']; + $ipaddr = $pconfig['ipaddress']; + $release = $pconfig['release']; + if ($_POST['interface'] == 'NONE'): + $interface = ""; + else: + $interface = $pconfig['interface']; + endif; + + if($empty_releases !== "YES"): + if ($_POST['nowstart']): + $cmd = ("/usr/local/bin/bastille create {$jname} {$release} {$ipaddr} {$interface} && /usr/local/bin/bastille start {$jname}"); + else: + $cmd = ("/usr/local/bin/bastille create {$jname} {$release} {$ipaddr} {$interface}"); + endif; + else: + $cmd = ""; + endif; + if ($_POST['Create']): + if ($_POST['autostart']): + exec("/usr/sbin/sysrc -f {$configfile} {$jname}_AUTO_START=\"YES\""); + endif; + unset($output,$retval);mwexec2($cmd,$output,$retval); + if($retval == 0): + //$savemsg .= gtext("Boot Environment created and activated successfully."); + header('Location: bastille_manager_gui.php'); + exit; + else: + $errormsg .= gtext("Failed to create container."); + endif; + endif; + endif; +endif; + +include 'fbegin.inc'; +?> + + + add_area_tabnav()-> + push()-> + add_tabnav_upper()-> + ins_tabnav_record('bastille_manager_gui.php',gettext('Containers'),gettext('Reload page'),true)-> + ins_tabnav_record('bastille_manager_info.php',gettext('Information'),gettext('Reload page'),true)-> + ins_tabnav_record('bastille_manager_maintenance.php',gettext('Maintenance'),gettext('Reload page'),true); +$document->render(); +?> +
+ + + + + + + + + + + + +
+
+ + + +
+ +
+ diff --git a/gui/bastille_manager_config.php b/gui/bastille_manager_config.php new file mode 100644 index 0000000..7a34e4c --- /dev/null +++ b/gui/bastille_manager_config.php @@ -0,0 +1,177 @@ +"; + return $result; +} + +function htmlButton($name, $text, $value="", $title="", $confirm="", $buttonImage="") { + $onClick = ($confirm == "") ? "" : "onclick='return confirm(\"{$confirm}\")'"; + switch ($buttonImage) { + case "save": $buttonImage = ""; break; + default: $buttonImage = ""; + } + $result = ""; + return $result; +} + +function parseConfigFile($configFile) { + $fileArray = file($configFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); // load config file content to array + $configArray = array(); + foreach($fileArray as $line) { // create array from config + $line = trim($line); // remove leading/trailing space + if ($line[0] == "#") continue; // skip if comment line + if ($line[0] == "[") { // add as section + $configArray[$line] = []; + $section = $line; // remember section name for params + } else { // process params + $parameter = explode("=", $line, 2); // seperate key and value, (Split at the first occurrence only) + $key = trim($parameter[0]); // set key + $val = explode("#", trim($parameter[1])); // get value, remove trailing comments + $value = $val[0]; // set value + $configArray[$section][$key] = $value; // add param to section + } + } + return $configArray; +} + +function saveConfigFile($configFile, $configArray, $hashTag="", $prettyPrint=true) { + //$printTab = ($prettyPrint) ? "\t" : ""; // Print leading tab. + //$printSpace = ($prettyPrint) ? " " : ""; // Print spaces. + $printTab = ($prettyPrint) ? "" : ""; // Do not print leading tab. + $printSpace = ($prettyPrint) ? "" : ""; // Do not print spaces. + + $cFile = fopen($configFile, "w"); + foreach($configArray as $key => $line) { // traverse array, key = section + if (is_array($line)) { + if ($key != '') fwrite($cFile, $key.PHP_EOL); // write section if not "['']" => NO section + foreach($line as $pName => $pValue) fwrite($cFile, $printTab.$pName.$printSpace."=".$printSpace.$pValue.PHP_EOL); // "\t".$pName = add TAB for output formatting + fwrite($cFile, PHP_EOL); + } else fwrite($cFile, $key.$printSpace."=".$printSpace.$line.PHP_EOL); + } // end foreach + fclose($cFile); + if (!empty($hashTag)) header("Location:#{$hashTag}"); +} + +// load addon config - use selected config from Bastille tab or alternative if exist +$configAddonArray = parseConfigFile($configAddon); // read addon config file +if (empty($configAddonArray['']['ALTERNATIVE_CONFIG'])) $configFile = str_replace('"', "", $configAddonArray['']['BASTILLE_CONFIG']); // get Bastille config file path and name +else $configFile = str_replace('"', "", $configAddonArray['']['ALTERNATIVE_CONFIG']); // get Bastille config file path and name + +// load Bastille config +if (!is_file($configFile)) $input_errors[] = sprintf(gtext("%s not found!"), gettext("Configuration File")." {$configFile}"); +else { + $configArray = parseConfigFile($configFile); // parse Bastille config file + //$savemsg = gtext("Loaded config file").": ".basename($configFile).""; +} + +if ($_POST) { + unset($input_errors); + + if (isset($_POST['saveParam']) && $_POST['saveParam']) { // saveParam s/n/v: [[outputs.influxdb]]#urls outputsinfluxdburls ["http://192.168.1.XYZ:8086"] + $buttonTag = explode("#", $_POST['saveParam']); // buttonTag[0] = section, buttonTag[1] = paramName + $hashTag = str_replace(["[", "]", ".", "#"], "", $buttonTag[0]); // create destination to jump to after post + $nameTag = str_replace(["[", "]", ".", "#"], "", $_POST['saveParam']); // nameTag = + $configArray[$buttonTag[0]][$buttonTag[1]] = $_POST[$nameTag]; // save param to section + # $savemsg .= "saveParam s/n/v: ".$_POST['saveParam']." ".$nameTag." ".$_POST[$nameTag]; + } + + if (empty($input_errors) && !isset($_POST['loadConfig'])) saveConfigFile($configFile, $configArray, $hashTag); +} + +bindtextdomain("xigmanas", $textdomain); +include("fbegin.inc"); +bindtextdomain("xigmanas", $textdomain_bastille); +?> +
+ + + +
+
    +
  • +
  • +
+
+ + "; + // loop through configuration + $firstSection = true; // prevent first html_separator in loop + if (is_array($configArray) && !empty($configArray)) + foreach($configArray as $key => $line) { // traverse array, key = section + $nameTag = str_replace(["[", "]", "."], "", $key); // create tag for post jump address and config changes + if (is_array($line)) { + if ($firstSection === true) $firstSection = false; + else html_separator(); + html_titleline(gtext("Variable Name").": ".$key, 2, $nameTag); // section title bar + foreach($line as $pName => $pValue) // traverse params within section, pName = param name, pValue = param value + html_text($pName, $pName, // create param entry + htmlInput($nameTag.$pName, gtext("Parameter Value"), $pValue).$wSpace. + htmlButton("saveParam", "", $key."#".$pName, gtext("Save"), "", "save").$wSpace. "", + ); + } + echo ""; + } + echo ""; + ?> +
"; + if (!empty($input_errors)) print_input_errors($input_errors); + if (!empty($savemsg)) print_info_box($savemsg); + echo "
"; + echo "
"; + html_remark("noteAddSection", gtext("Note"), gtext("Please be careful, as no validation will be performed on your input!")); + echo "
+
+
+ diff --git a/gui/bastille_manager_editor.php b/gui/bastille_manager_editor.php new file mode 100644 index 0000000..5ac2316 --- /dev/null +++ b/gui/bastille_manager_editor.php @@ -0,0 +1,162 @@ +. + XigmaNAS® is a registered trademark of Michael Zoon (zoon01@xigmanas.com). + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the developer nor the names of contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE DEVELOPER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +*/ + +require_once 'auth.inc'; +require_once 'guiconfig.inc'; +require_once("bastille_manager-lib.inc"); + +$savetopath = "{$rootfolder}/jails/"; +if (isset($_POST['savetopath'])) { + $savetopath = htmlspecialchars($_POST['savetopath']); +} +if(isset($_POST['submit'])) { + switch($_POST['submit']) { + case 'edit': + if(preg_match('/\S/', $savetopath)) { + if(file_exists($savetopath) && is_file($savetopath)) { + $content = file_get_contents($savetopath); + $edit_area = ""; + if (stristr($savetopath, ".php") == true) $language = "php"; + else if (stristr($savetopath, ".inc") == true) $language = "php"; + else if (stristr($savetopath, ".sh") == true) $language = "core"; + else if (stristr($savetopath, ".xml") == true) $language = "xml"; + else if (stristr($savetopath, ".js") == true) $language = "js"; + else if (stristr($savetopath, ".css") == true) $language = "css"; + } else { + $savemsg = sprintf('%s %s', gtext('File not found'), $savetopath); + $content = ''; + $savetopath = ''; + } + } + break; + case 'save': + if(preg_match('/\S/', $savetopath)) { + conf_mount_rw(); + $content = preg_replace("/\r/","",$_POST['code']) ; + file_put_contents($savetopath, $content); + $edit_area = ""; + $savemsg = sprintf('%s %s', gtext('Saved file to'), $savetopath); + if ($savetopath === "{$g['cf_conf_path']}/config.xml") { + unlink_if_exists("{$g['tmp_path']}/config.cache"); + } + conf_mount_ro(); + } + break; + case 'bastille': + // Return to Bastille index. + header('Location: bastille_manager_gui.php'); + break; + } +} + +if(isset($_POST['rows']) && !empty($_POST['rows'])) { + $rows = $_POST['rows']; +} else { + $rows = 30; +} +if(isset($_POST['cols']) && !empty($_POST['cols'])) { + $cols = $_POST['cols']; +} else { + $cols = 66; +} +$pgtitle = [gtext('Bastille'), gtext('File Editor')]; +include 'fbegin.inc'; +?> + +
+ + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+
+ + +
+
+ +
+ +. + XigmaNAS® is a registered trademark of Michael Zoon (zoon01@xigmanas.com). + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the developer nor the names of contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE DEVELOPER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +*/ + +require_once 'auth.inc'; +require_once 'guiconfig.inc'; +require_once 'bastille_manager-lib.inc'; + +$sphere_scriptname = basename(__FILE__); +$sphere_scriptname_child = 'bastille_manager_util.php'; +$sphere_header = 'Location: '.$sphere_scriptname; +$sphere_header_parent = $sphere_header; +$sphere_array = []; +$sphere_record = []; +$checkbox_member_name = 'checkbox_member_array'; +$checkbox_member_array = []; +$checkbox_member_record = []; +$gt_record_add = gtext('Create new jail'); +$gt_record_mod = gtext('Utilities'); +$gt_selection_start = gtext('Start Selected'); +$gt_selection_stop = gtext('Stop Selected'); +$gt_selection_restart = gtext('Restart Selected'); +$gt_record_inf = gtext('Information'); +$gt_selection_start_confirm = gtext('Do you really want to start selected jail(s)?'); +$gt_selection_stop_confirm = gtext('Do you want to stop the selected jail(s)?'); +$gt_selection_restart_confirm = gtext('Do you want to restart the selected jail(s)?'); +$img_path = [ + 'add' => 'images/add.png', + 'mod' => 'images/edit.png', + 'del' => 'images/delete.png', + 'loc' => 'images/locked.png', + 'unl' => 'images/unlocked.png', + 'mai' => 'images/maintain.png', + 'inf' => 'images/info.png', + 'ena' => 'images/status_enabled.png', + 'dis' => 'images/status_disabled.png', + 'mup' => 'images/up.png', + 'mdn' => 'images/down.png' +]; + +$jls_list = get_jail_infos(); +$sphere_array = $jls_list; + +if($_POST): + if(isset($_POST['apply']) && $_POST['apply']): + $ret = array('output' => [], 'retval' => 0); + if(!file_exists($d_sysrebootreqd_path)): + // Process notifications + endif; + $savemsg = get_std_save_message($ret['retval']); + if($ret['retval'] == 0): + updatenotify_delete($sphere_notifier); + header($sphere_header); + exit; + endif; + updatenotify_delete($sphere_notifier); + $errormsg = implode("\n", $ret['output']); + endif; + + if(isset($_POST['start_selected_jail']) && $_POST['start_selected_jail']): + $checkbox_member_array = isset($_POST[$checkbox_member_name]) ? $_POST[$checkbox_member_name] : []; + foreach($checkbox_member_array as $checkbox_member_record): + if(false !== ($index = array_search_ex($checkbox_member_record, $sphere_array, 'jailname'))): + if(!isset($sphere_array[$index]['protected'])): + $cmd = ("/usr/local/bin/bastille start {$checkbox_member_record}"); + $return_val = mwexec($cmd); + if($return_val == 0): + //$savemsg .= gtext("Jail(s) started successfully."); + header($sphere_header); + else: + $errormsg .= gtext("Failed to start jail(s)."); + endif; + endif; + endif; + endforeach; + endif; + + if(isset($_POST['stop_selected_jail']) && $_POST['stop_selected_jail']): + $checkbox_member_array = isset($_POST[$checkbox_member_name]) ? $_POST[$checkbox_member_name] : []; + foreach($checkbox_member_array as $checkbox_member_record): + if(false !== ($index = array_search_ex($checkbox_member_record, $sphere_array, 'jailname'))): + if(!isset($sphere_array[$index]['protected'])): + $cmd = ("/usr/local/bin/bastille stop {$checkbox_member_record}"); + $return_val = mwexec($cmd); + if($return_val == 0): + //$savemsg .= gtext("Jail(s) stopped successfully."); + header($sphere_header); + else: + $errormsg .= gtext("Failed to stop jail(s)."); + endif; + endif; + endif; + endforeach; + endif; + + if(isset($_POST['restart_selected_jail']) && $_POST['restart_selected_jail']): + $checkbox_member_array = isset($_POST[$checkbox_member_name]) ? $_POST[$checkbox_member_name] : []; + foreach($checkbox_member_array as $checkbox_member_record): + if(false !== ($index = array_search_ex($checkbox_member_record, $sphere_array, 'jailname'))): + if(!isset($sphere_array[$index]['protected'])): + $cmd = ("/usr/local/bin/bastille restart {$checkbox_member_record}"); + $return_val = mwexec($cmd); + if($return_val == 0): + //$savemsg .= gtext("Jail(s) restarted successfully."); + header($sphere_header); + else: + $errormsg .= gtext("Failed to restart jail(s)."); + endif; + endif; + endif; + endforeach; + endif; +endif; + +$pgtitle = [gtext("Extensions"), gtext('Bastille')]; +include 'fbegin.inc'; +?> + + + add_area_tabnav()-> + push()-> + add_tabnav_upper()-> + ins_tabnav_record('bastille_manager_gui.php',gettext('Containers'))-> + ins_tabnav_record('bastille_manager_info.php',gettext('Information'))-> + ins_tabnav_record('bastille_manager_maintenance.php',gettext('Maintenance')); +$document->render(); +?> +
+ + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +       + + + + + +
+ + <?=$gt_record_mod;?> + + <?=$gt_record_del;?> + + <?=$gt_record_loc;?> + + + + <?=$gt_record_inf?> +
+
+ <?=$gt_record_add;?> +
+
+ + + +
+ +
+. + XigmaNAS® is a registered trademark of Michael Zoon (zoon01@xigmanas.com). + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the developer nor the names of contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE DEVELOPER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +*/ + +require_once 'auth.inc'; +require_once 'guiconfig.inc'; +require_once("bastille_manager-lib.inc"); + +function jls_get_jail_list(string $entity_name = NULL) { + if(isset($entity_name)): + $cmd = "/usr/sbin/jls -v -j $entity_name 2>&1"; + else: + $cmd = '/usr/sbin/jls -v 2>&1'; + endif; + unset($output); + mwexec2($cmd,$output); + return implode(PHP_EOL,$output); +} + +function jls_get_all(string $entity_name = NULL) { + if(isset($entity_name)): + $cmd = "/usr/sbin/jls -qn -j $entity_name | tr -s \" \" \"\n\" 2>&1"; + else: + $cmd = ':'; + endif; + unset($a_names); + mwexec2($cmd,$a_names); + if(is_array($a_names) && count($a_names) > 0): + $names = implode(' ',array_map('escapeshellarg',$a_names)); + unset($output); + mwexec2($cmd,$output); + else: + $output = [gtext('Parameters information available for individual selection only.')]; + endif; + return implode(PHP_EOL,$output); +} + +$entity_name = NULL; +if(isset($_GET['uuid']) && is_string($_GET['uuid'])): + $entity_name = sprintf('%s',$_GET['uuid']); +endif; +$pgtitle = [gtext("Extensions"), gtext('Bastille'),gtext('Information')]; +include 'fbegin.inc'; +$document = new co_DOMDocument(); +$document-> + add_area_tabnav()-> + push()-> + add_tabnav_upper()-> + ins_tabnav_record('bastille_manager_gui.php',gettext('Containers'),gettext('Reload page'),true)-> + ins_tabnav_record('bastille_manager_info.php',gettext('Information'),gettext('Reload page'),true)-> + ins_tabnav_record('bastille_manager_maintenance.php',gettext('Maintenance'),gettext('Reload page'),true); +$document->render(); +?> + + + + +
+ + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + +
+
+
+
+ diff --git a/gui/bastille-gui.php b/gui/bastille_manager_maintenance.php similarity index 60% rename from gui/bastille-gui.php rename to gui/bastille_manager_maintenance.php index a07688e..810cfe5 100644 --- a/gui/bastille-gui.php +++ b/gui/bastille_manager_maintenance.php @@ -1,48 +1,50 @@ . All rights reserved. Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the developer nor the names of contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the NAS4Free Project. + THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE DEVELOPER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. */ + require("auth.inc"); require("guiconfig.inc"); +require_once("bastille_manager-lib.inc"); $application = "Bastille"; -$pgtitle = array(gtext("Extensions"), "Bastille"); +$pgtitle = array(gtext("Extensions"), "Bastille", "Maintenance"); -// For NAS4Free 10.x versions. +// For legacy product versions. $return_val = mwexec("/bin/cat /etc/prd.version | cut -d'.' -f1 | /usr/bin/grep '10'", true); if ($return_val == 0) { if (is_array($config['rc']['postinit'] ) && is_array( $config['rc']['postinit']['cmd'] ) ) { @@ -50,29 +52,15 @@ if ($return_val == 0) { } } -// Initialize some variables. -//$rootfolder = dirname($config['rc']['postinit']['cmd'][$i]); -$confdir = "/var/etc/bastilleconf"; -$cwdir = exec("/usr/bin/grep 'INSTALL_DIR=' {$confdir}/conf/bastille_config | cut -d'\"' -f2"); -$rootfolder = $cwdir; -$configfile = "{$rootfolder}/conf/bastille_config"; -$versionfile = "{$rootfolder}/version"; -$date = strftime('%c'); -$logfile = "{$rootfolder}/log/bastille_ext.log"; -$logevent = "{$rootfolder}/log/bastille_last_event.log"; +// Set default backup directory. +if (1 == mwexec("/bin/cat {$configfile} | /usr/bin/grep 'BACKUP_DIR='")) { + if (is_file("{$configfile}")) exec("/usr/sbin/sysrc -f {$configfile} BACKUP_DIR={$rootfolder}/backups"); +} +$backup_path = exec("/bin/cat {$configfile} | /usr/bin/grep 'BACKUP_DIR=' | cut -d'\"' -f2"); + $prdname = "bastille"; $tarballversion = "/usr/local/bin/bastille"; -if ($rootfolder == "") $input_errors[] = gtext("Extension installed with fault"); -else { -// Initialize locales. - $textdomain = "/usr/local/share/locale"; - $textdomain_bastille = "/usr/local/share/locale-bastille"; - if (!is_link($textdomain_bastille)) { mwexec("ln -s {$rootfolder}/locale-bastille {$textdomain_bastille}", true); } - bindtextdomain("xigmanas", $textdomain_bastille); -} -if (is_file("{$rootfolder}/postinit")) unlink("{$rootfolder}/postinit"); - if ($_POST) { if(isset($_POST['upgrade']) && $_POST['upgrade']): $cmd = sprintf('%1$s/bastille-init -u > %2$s',$rootfolder,$logevent); @@ -105,7 +93,7 @@ if ($_POST) { if (is_link("/var/cache/pkg")) mwexec("rm /var/cache/pkg", true); if (is_link("/var/db/pkg")) mwexec("rm /var/db/pkg && mkdir /var/db/pkg", true); - // Remove postinit cmd in NAS4Free 10.x versions. + // Remove postinit cmd in legacy product versions. $return_val = mwexec("/bin/cat /etc/prd.version | cut -d'.' -f1 | /usr/bin/grep '10'", true); if ($return_val == 0) { if (is_array($config['rc']['postinit']) && is_array($config['rc']['postinit']['cmd'])) { @@ -117,7 +105,7 @@ if ($_POST) { write_config(); } - // Remove postinit cmd in NAS4Free later versions. + // Remove postinit cmd in later product versions. if (is_array($config['rc']) && is_array($config['rc']['param'])) { $postinit_cmd = "{$rootfolder}/bastille-init"; $value = $postinit_cmd; @@ -135,6 +123,29 @@ if ($_POST) { header("Location:index.php"); } + if (isset($_POST['save']) && $_POST['save']) { + // Ensure to have NO whitespace & trailing slash. + $backup_path = rtrim(trim($_POST['backup_path']),'/'); + if ("{$backup_path}" == "") { + $backup_path = "{$rootfolder}/backups"; + } + if (!is_file($backup_path)) { + $cmd = "/usr/sbin/sysrc -f {$configfile} BACKUP_DIR={$backup_path}"; + unset($retval);mwexec($cmd,$retval); + if ($retval == 0) { + $savemsg .= gtext("Extension settings saved successfully."); + exec("echo '{$date}: {$application} Extension settings saved successfully' >> {$logfile}"); + } + else { + $input_errors[] = gtext("Failed to save extension settings."); + exec("echo '{$date}: {$application} Failed to save extension settings' >> {$logfile}"); + } + } + else { + $input_errors[] = gtext("Failed to save extension settings."); + exec("echo '{$date}: {$application} Failed to save extension settings' >> {$logfile}"); + } + } } function get_version_bastille() { @@ -185,11 +196,33 @@ $(document).ready(function(){ } //--> -
+ + + +
+
    +
  • +
  • +
  • +
+
+
    +
  • +
  • +
+
- - @@ -201,8 +234,10 @@ $(document).ready(function(){ +
+ " value=""/> " value="" />
@@ -215,7 +250,7 @@ $(document).ready(function(){
- " value="" onclick="return confirm('')" /> + " value="" onclick="return confirm('')" />
diff --git a/gui/bastille_manager_tarballs.php b/gui/bastille_manager_tarballs.php new file mode 100644 index 0000000..491238f --- /dev/null +++ b/gui/bastille_manager_tarballs.php @@ -0,0 +1,214 @@ +. + XigmaNAS® is a registered trademark of Michael Zoon (zoon01@xigmanas.com). + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the developer nor the names of contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE DEVELOPER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +*/ + +require_once 'auth.inc'; +require_once 'guiconfig.inc'; +require_once("bastille_manager-lib.inc"); + +$gt_selection_delete_confirm = gtext('Do you really want to destroy this base release?'); +$pgtitle = [gtext("Extensions"), gtext('Bastille'),gtext('Releases')]; + +$sphere_array = []; +$sphere_record = []; + +function get_rel_list() { + global $rootfolder; + $result = []; + if (is_dir("{$rootfolder}/releases")): + $entries = preg_grep('/^([^.])/', scandir("{$rootfolder}/releases")); + foreach($entries as $entry): + $a = preg_split('/\t/',$entry); + $r = []; + $name = $a[0]; + if(preg_match('/^[0-9]+\.[0-9]+\-RELEASE/', $name, $m)): + $r['name'] = $m[0]; + else: + $r['name'] = 'unknown'; + endif; + $r['relname'] = $r['name']; + + $result[] = $r; + endforeach; + endif; + return $result; +} +$rel_list = get_rel_list(); +$sphere_array = $rel_list; + +if($_POST): + unset($input_errors); + unset($savemsg); + $pconfig = $_POST; + if(isset($_POST['Cancel']) && $_POST['Cancel']): + header('Location: bastille_manager_gui.php'); + exit; + endif; + + if (isset($_POST['Download']) && $_POST['Download']): + $get_release = $pconfig['release_item']; + $check_release = ("{$rootfolder}/releases/{$get_release}"); + $cmd = ("/usr/local/bin/bastille bootstrap {$get_release}"); + if(file_exists($check_release)): + // FreeBSD base release check. + $savemsg .= sprintf(gtext('%s base appears to be already extracted.'),$get_release); + else: + // Download a FreeBSD base release. + if ($_POST['Download']): + unset($output,$retval);mwexec2($cmd,$output,$retval); + if($retval == 0): + //$savemsg .= sprintf(gtext('%s base downloaded and extracted successfully.'),$get_release); + header('Location: bastille_manager_tarballs.php'); + else: + $errormsg .= sprintf(gtext('%s Failed to download and/or extract release base.'),$get_release); + endif; + endif; + endif; + endif; + + if (isset($_POST['Destroy']) && $_POST['Destroy']): + if ($_POST['Destroy']): + $get_release = $pconfig['release_item']; + $check_release = ("{$rootfolder}/releases/{$get_release}"); + $cmd = ("/usr/local/bin/bastille destroy {$get_release}"); + if(!file_exists($check_release)): + // FreeBSD base release check. + $savemsg .= sprintf(gtext('%s base does not exist, nothing to do.'),$get_release); + else: + // Delete the FreeBSD base release/directory. + if ($_POST['Destroy']): + unset($output,$retval);mwexec2($cmd,$output,$retval); + if($retval == 0): + //$savemsg .= sprintf(gtext('%s base deleted successfully.'),$get_release); + header('Location: bastille_manager_tarballs.php'); + else: + $errormsg .= sprintf(gtext('%s failed to delete.'),$get_release); + endif; + endif; + endif; + endif; + endif; +endif; + +include 'fbegin.inc'; +?> + + + add_area_tabnav()-> + push()-> + add_tabnav_upper()-> + ins_tabnav_record('bastille_manager_gui.php',gettext('Containers'),gettext('Reload page'),true)-> + ins_tabnav_record('bastille_manager_info.php',gettext('Information'),gettext('Reload page'),true)-> + ins_tabnav_record('bastille_manager_maintenance.php',gettext('Maintenance'),gettext('Reload page'),true)-> + pop()->add_tabnav_lower()-> + ins_tabnav_record('bastille_manager_config.php',gettext('Bastille Configuration'),gettext('Reload page'),true)-> + ins_tabnav_record('bastille_manager_tarballs.php',gettext('Base Releases'),gettext('Reload page'),true); +$document->render(); +?> +
+ + + + + + + + + + + gettext('12.1-RELEASE'), + '12.0-RELEASE' => gettext('12.0-RELEASE'), + '11.3-RELEASE' => gettext('11.3-RELEASE'), + '11.2-RELEASE' => gettext('11.2-RELEASE'), + ]; + html_combobox2('release_item',gettext('Select Base Release'),$pconfig['release_item'],$a_action,'',true,false,'action_change()'); +?> + +
+
+ " onclick="enable_change(true)" /> + + "/> + + + " /> +
+
+ +
+ +
+ diff --git a/gui/bastille_manager_util.php b/gui/bastille_manager_util.php new file mode 100644 index 0000000..165b78f --- /dev/null +++ b/gui/bastille_manager_util.php @@ -0,0 +1,376 @@ +. + XigmaNAS® is a registered trademark of Michael Zoon (zoon01@xigmanas.com). + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the developer nor the names of contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE DEVELOPER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +*/ + +require_once 'auth.inc'; +require_once 'guiconfig.inc'; +require_once("bastille_manager-lib.inc"); + +if(isset($_GET['uuid'])): + $uuid = $_GET['uuid']; +endif; +if(isset($_POST['uuid'])): + $uuid = $_POST['uuid']; +endif; + +$pgtitle = [gtext("Extensions"), gtext('Bastille'),gtext('Utilities')]; + +if(isset($_GET['jailname'])): + $container = $_GET['jailname']; +endif; +if(isset($_POST['jailname'])): + $container = $_POST['jailname']; +endif; + +$cnid = FALSE; +if(isset($container) && !empty($container)): + $pconfig['uuid'] = uuid(); + $pconfig['jailname'] = $container; + if(preg_match('/^([^\/\@]+)(\/([^\@]+))?\@(.*)$/', $pconfig['jailname'], $m)): + $pconfig['name'] = $m['']; + else: + $pconfig['name'] = 'unknown'; + endif; + $pconfig['newname'] = ''; + $pconfig['recursive'] = false; + $pconfig['action'] = 'activate'; +else: + // not supported + $pconfig = []; +endif; + +if($_POST): + global $configfile; + global $backup_path; + global $rootfolder; + unset($input_errors); + $pconfig = $_POST; + if(isset($_POST['Cancel']) && $_POST['Cancel']): + header('Location: bastille_manager_gui.php'); + exit; + endif; + if(isset($_POST['action'])): + $action = $_POST['action']; + endif; + if(empty($action)): + $input_errors[] = sprintf(gtext("The attribute '%s' is required."), gtext("Action")); + else: + switch($action): + case 'advanced': + // Input validation not required + if(empty($input_errors)): + $container = []; + $container['uuid'] = $_POST['uuid']; + $container['jailname'] = $_POST['jailname']; + $confirm_name = $pconfig['confirmname']; + $item = $container['jailname']; + if ($_POST['advanced']): + header('Location: bastille_manager_editor.php'); + exit; + else: + $errormsg .= gtext("Failed to open editor, confirmation is required."); + endif; + endif; + break; + + case 'backup': + // Input validation not required + if(empty($input_errors)): + $container = []; + $container['uuid'] = $_POST['uuid']; + $container['jailname'] = $_POST['jailname']; + $confirm_name = $pconfig['confirmname']; + $item = $container['jailname']; + $date = (strftime('%Y-%m-%d-%H%M%S')); + $cmd = ("cd {$rootfolder}/jails && /usr/bin/tar -cf {$item}-{$date}.tar --exclude=.bastille --exclude=.template {$item} && /bin/mv {$item}-{$date}.tar {$backup_path}"); + unset($output,$retval);mwexec2($cmd,$output,$retval); + if($retval == 0): + $savemsg .= gtext("Container backup process completed successfully."); + //header('Location: bastille_manager_gui.php'); + //exit; + else: + $errormsg .= gtext("Failed to backup container."); + endif; + endif; + break; + + case 'autoboot': + // Input validation not required + if(empty($input_errors)): + $container = []; + $container['uuid'] = $_POST['uuid']; + $container['jailname'] = $_POST['jailname']; + $confirm_name = $pconfig['confirmname']; + $item = $container['jailname']; + $cmd = ("/usr/sbin/sysrc -f {$configfile} {$item}_AUTO_START=\"YES\""); + unset($output,$retval);mwexec2($cmd,$output,$retval); + if($retval == 0): + header('Location: bastille_manager_gui.php'); + exit; + else: + $errormsg .= gtext("Failed to set auto-boot."); + endif; + endif; + break; + + case 'noauto': + // Input validation not required + if(empty($input_errors)): + $container = []; + $container['uuid'] = $_POST['uuid']; + $container['jailname'] = $_POST['jailname']; + $confirm_name = $pconfig['confirmname']; + $item = $container['jailname']; + $cmd = ("/usr/sbin/sysrc -f {$configfile} {$item}_AUTO_START=\"NO\""); + unset($output,$retval);mwexec2($cmd,$output,$retval); + if($retval == 0): + header('Location: bastille_manager_gui.php'); + exit; + else: + $errormsg .= gtext("Failed to set no-auto."); + endif; + endif; + break; + + case 'fstab': + // Input validation not required + if(empty($input_errors)): + $container = []; + $container['uuid'] = $_POST['uuid']; + $container['jailname'] = $_POST['jailname']; + $confirm_name = $pconfig['confirmname']; + $item = $container['jailname']; + $sourcedir = $pconfig['source_path']; + $targetdir = $pconfig['target_path']; + + if ($_POST['readonly']): + $dir_mode = "ro"; + else: + $dir_mode = "rw"; + endif; + + $cmd = ("/bin/echo \"{$sourcedir} {$targetdir} nullfs {$dir_mode} 0 0\" >> {$rootfolder}/jails/{$item}/fstab"); + unset($output,$retval);mwexec2($cmd,$output,$retval); + if($retval == 0): + if ($_POST['createdir']): + mkdir("$targetdir"); + endif; + + $savemsg .= gtext("Container backup process completed successfully."); + //header('Location: bastille_manager_gui.php'); + //exit; + else: + $errormsg .= gtext("Failed to backup container."); + endif; + endif; + break; + + case 'delete': + // Delete a contained + if(empty($input_errors)): + $container = []; + $container['uuid'] = $_POST['uuid']; + $container['jailname'] = $_POST['jailname']; + $confirm_name = $pconfig['confirmname']; + $item = $container['jailname']; + + if(strcmp($confirm_name, $item) !== 0): + $errormsg .= gtext("Failed to destroy container, name confirmation is required."); + break; + else: + if ($_POST['nowstop']): + $cmd = ("/usr/local/bin/bastille stop {$item} && /usr/local/bin/bastille destroy {$item}"); + else: + $cmd = ("/usr/local/bin/bastille destroy {$item}"); + endif; + unset($output,$retval);mwexec2($cmd,$output,$retval); + if($retval == 0): + exec("/usr/sbin/sysrc -f {$configfile} -qx {$item}_AUTO_START"); + header('Location: bastille_manager_gui.php'); + exit; + else: + $errormsg .= gtext("Failed to destroy container, make sure this container is stopped."); + endif; + endif; + endif; + break; + default: + $input_errors[] = sprintf(gtext("The attribute '%s' is invalid."), 'action'); + break; + endswitch; + endif; +endif; +include 'fbegin.inc'; +?> + + + add_area_tabnav()-> + push()-> + add_tabnav_upper()-> + ins_tabnav_record('bastille_manager_gui.php',gettext('Containers'),gettext('Reload page'),true)-> + ins_tabnav_record('bastille_manager_info.php',gettext('Information'),gettext('Reload page'),true)-> + ins_tabnav_record('bastille_manager_maintenance.php',gettext('Maintenance'),gettext('Reload page'),true); +$document->render(); +?> +
+ + + + + + + + + + + gettext('Backup'), + 'autoboot' => gettext('Autoboot'), + 'noauto' => gettext('Noauto'), + 'fstab' => gettext('Fstab'), + 'delete' => gettext('Destroy'), + 'advanced' => gettext('Advanced'), + ]; + html_combobox2('action',gettext('Action'),$pconfig['action'],$a_action,'',true,false,'action_change()'); + html_inputbox2('confirmname',gettext('Enter name for confirmation'),$pconfig['confirmname'],'',true,30); + html_checkbox2('nowstop',gettext('Stop container'),!empty($pconfig['nowstop']) ? true : false,gettext('Stop the container if running before deletetion.'),'',false); + html_filechooser("source_path", gtext("Source Data Directory"), $pconfig['source_path'], gtext("Source data directory to be shared, full path here."), $source_path, true, 60); + html_filechooser("target_path", gtext("Target Data Directory"), $pconfig['target_path'], gtext("Target data directory to be mapped, path within the jail only."), $target_path, true, 60); + html_checkbox2('advanced',gettext('Advanced jail configuration Files'),!empty($pconfig['advanced']) ? true : false,gettext('I understand the risks, take me to the advanced jail config files.'),'',true); + html_checkbox2('readonly',gettext('Read-Only Mode'),!empty($pconfig['readonly']) ? true : false,gettext('Set target directory in Read-Only mode.'),'',false); + html_checkbox2('createdir',gettext('Create Target Directory'),!empty($pconfig['createdir']) ? true : true,gettext('Create target directory if missing (recommended).'),'',true); + //html_checkbox2('dateadd',gettext('Date'),!empty($pconfig['dateadd']) ? true : false,gettext('Append the date in the following format: ITEM-XXXX-XX-XX-XXXXXX.'),'',false); +?> + +
+
+ " onclick="enable_change(true)" /> + " /> + + + +
+
+ +
+ +
+ + diff --git a/gui/ext/bastille-gui/menu.inc b/gui/ext/bastille-gui/menu.inc deleted file mode 100644 index f98b809..0000000 --- a/gui/ext/bastille-gui/menu.inc +++ /dev/null @@ -1 +0,0 @@ -Bastille \ No newline at end of file diff --git a/gui/ext/bastille/menu.inc b/gui/ext/bastille/menu.inc new file mode 100644 index 0000000..9db5777 --- /dev/null +++ b/gui/ext/bastille/menu.inc @@ -0,0 +1 @@ +Bastille \ No newline at end of file diff --git a/gui/images/bsd_icon.png b/gui/images/bsd_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..6b5e20d02a36acfac250cdf55263694be17860b4 GIT binary patch literal 872 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 YFaG*wa%KAH-T(jq07*qoM6N<$g3g%G;{X5v literal 0 HcmV?d00001 diff --git a/release_notes b/release_notes deleted file mode 100644 index 44c9969..0000000 --- a/release_notes +++ /dev/null @@ -1,11 +0,0 @@ -====================== -= Extension Bastille = -====================== -Version Description - -0.0.6......Switch to alternate repository supporting 11.3-RELEASE base. -0.0.5......Start all jails once. -0.0.4......Start jails if directory not empty. -0.0.3......Minor code adjustment. -0.0.2......Added addon preview page. -0.0.1......First Release. diff --git a/version b/version index 1750564..3eefcb9 100644 --- a/version +++ b/version @@ -1 +1 @@ -0.0.6 +1.0.0