#!/bin/ash
# Build: @build@
set -e

SETUP_DIR="/app/setup"
CONFIG_DIR="${SETUP_DIR}/config"

trap appStop SIGINT SIGTERM

doas() {
  user=$1
  shift
  su -l $user -c "$@"
}

appStart () {

  BURPUI_CONFIG=/etc/burp/burpui.cfg
  BURPUI_VERBOSE=${BURPUI_VERBOSE:-0}
  BURPUI_UID=${BURPUI_UID:-5337}
  BURPUI_GID=${BURPUI_GID:-5337}
  BURPUI_WS_WORKERS=${BURPUI_WS_WORKERS:-$(getconf _NPROCESSORS_ONLN)}
  BURPUI_RP_SCHEME=${BURPUI_RP_SCHEME:-https}
  GUNICORN_WORKERS=${GUNICORN_WORKERS:-$(getconf _NPROCESSORS_ONLN)}
  GUNICORN_WORKER_CLASS=${GUNICORN_WORKER_CLASS:-gevent}
  TIMEZONE=${TIMEZONE:-Europe/Paris}

  [ -e /usr/share/zoneinfo/$TIMEZONE ] && {
    cp /usr/share/zoneinfo/$TIMEZONE /etc/localtime
    echo "$TIMEZONE" >/etc/timezone
  }

  pip install "raven[flask]"

  cp ${CONFIG_DIR}/burp-ui/burpui.cfg /etc/burp/burpui.cfg
  rand=$(dd if=/dev/urandom bs=256 count=1 2>/dev/null | base64 | sed ':a;N;$!ba;s/\n//g')
  sed -i -r "s'@RANDOM@'$rand'" /etc/burp/burpui.cfg
  sed -i -r "s'@DSN@'$SENTRY_DSN'" /etc/burp/burpui.cfg
  sed -i -r "s'@PIWIK_URL@'$PIWIK_URL'" /etc/burp/burpui.cfg
  sed -i -r "s'@PIWIK_SCRIPT@'$PIWIK_SCRIPT'" /etc/burp/burpui.cfg
  sed -i -r "s'@PIWIK_ID@'$PIWIK_ID'" /etc/burp/burpui.cfg

  # patch demo with piwik
  REP=$(cat ${CONFIG_DIR}/patch/piwik.patch)
  awk -v r="$REP" '{gsub(/^.*@DEMO@.*$/,r)}1' /usr/local/lib/python3.6/site-packages/burpui/templates/layout.html >/tmp/layout.html
  cat /tmp/layout.html >/usr/local/lib/python3.6/site-packages/burpui/templates/layout.html
  rm /tmp/layout.html

  # Create burp-ui User
  getent group | grep -q burpui || addgroup -g $BURPUI_GID burpui
  getent passwd | grep -q burpui || adduser -h /var/lib/burpui -D -s /bin/ash -u $BURPUI_UID -G burpui burpui
  chown -R burpui: /var/log/gunicorn

  [ -e /etc/burp/this_is_a_decoy_file_to_know_if_we_can_chown ] && {
    chown -R burpui: /etc/burp
    rm /etc/burp/this_is_a_decoy_file_to_know_if_we_can_chown
  }

  # wait for redis to be up
  sleep 3

  doas burpui "/usr/local/bin/bui-manage -c $BURPUI_CONFIG db upgrade"

  WEBSOCKET="True"
  [ "$BURPUI_WS_WORKERS" == "0" ] && {
    WEBSOCKET=""
  } || {
    WS_EMBEDDED=$(doas burpui "/usr/local/bin/bui-manage -c $BURPUI_CONFIG sysinfo | grep 'WebSocket embedded' | tr -s ' ' | cut -d' ' -f3")
    WS_AVAILABLE=$(doas burpui "/usr/local/bin/bui-manage -c $BURPUI_CONFIG sysinfo | grep 'WebSocket available' | tr -s ' ' | cut -d' ' -f3")
    [ "$WS_EMBEDDED" == "True" ] && WEBSOCKET="" || {
      [ "$WS_AVAILABLE" != "True" ] && WEBSOCKET=""
    }
  }

  # Setup nginx workers
  cat ${CONFIG_DIR}/nginx/workers_header.conf >/etc/nginx/workers.conf

  [ "$WEBSOCKET" == "True" ] && {
    for i in $(seq $BURPUI_WS_WORKERS)
    do
      WORKER_ID=$i
      WORKER_PORT=$(( 5000 + $i ))
      sed -r "s'@BURPUI_CONFIG@'$BURPUI_CONFIG';s'@WORKER_ID@'$WORKER_ID';s'@WORKER_PORT@'$WORKER_PORT'" /etc/supervisor.d/websocket.ini.sample > /etc/supervisor.d/websocket-$WORKER_ID.ini
      echo "    server 127.0.0.1:$WORKER_PORT;" >>/etc/nginx/workers.conf
    done
    echo "}" >>/etc/nginx/workers.conf
  } || {
    cat >>/etc/nginx/workers.conf<<EOF
    server 127.0.0.1:5000;
}
EOF
  }

  # You can change log verbosity at runtime
  sed -r "s'@BURPUI_CONFIG@'$BURPUI_CONFIG'" /etc/supervisor.d/gunicorn.ini.sample >/etc/supervisor.d/gunicorn.ini
  sed -i -r "s'@BURPUI_VERBOSE@'$BURPUI_VERBOSE'" /etc/supervisor.d/gunicorn.ini

  sed -r "s'@BURPUI_CONFIG@'$BURPUI_CONFIG'" /etc/supervisor.d/bui-celery.ini.sample >/etc/supervisor.d/bui-celery.ini

  sed -r "s'@GUNICORN_WORKERS@'$GUNICORN_WORKERS';s'@GUNICORN_WORKER_CLASS@'$GUNICORN_WORKER_CLASS'" /etc/burp-ui/burpui_gunicorn.py.sample >/etc/burp-ui/burpui_gunicorn.py

  sed -r "s'@HTTP_SCHEME@'$BURPUI_RP_SCHEME'" ${CONFIG_DIR}/nginx/nginx.conf >/etc/nginx/nginx.conf

  # start supervisord
  /usr/bin/supervisord -c /etc/supervisord.conf

  echo "Starting crond..."
  supervisorctl start cron >/dev/null

  echo "Starting bui-celery..."
  supervisorctl start bui-celery >/dev/null

  echo "Starting gunicorn..."
  supervisorctl start gunicorn >/dev/null

  [ "$WEBSOCKET" == "True" ] && {
    for i in $(seq $BURPUI_WS_WORKERS)
    do
      echo "Starting websocket worker $i..."
      supervisorctl start websocket-$i
    done
  }

  echo "Starting nginx..."
  supervisorctl start nginx >/dev/null

  # wait a bit for the logs to be populated
  sleep 2

  # watch the access logs
  tail -F /var/log/gunicorn/burp-ui_info.log
}

appStop() {
  echo ""
  echo "Stopping nginx..."
  supervisorctl stop nginx >/dev/null
  [ "$WEBSOCKET" == "True" ] && {
    for i in $(seq $BURPUI_WS_WORKERS)
    do
      echo "Stopping websocket worker $i..."
      supervisorctl stop websocket-$i
    done
  }
  echo "Stopping gunicorn..."
  supervisorctl stop gunicorn >/dev/null
  echo "Stopping crond..."
  supervisorctl stop cron >/dev/null
  echo "Stopping supervisord..."
  kill -15 $(cat /var/run/supervisord.pid)
  exit
}

appHelp () {
  echo "Available options:"
  echo " app:start          - Starts the burp-ui server (default)"
  echo " app:help           - Displays the help"
  echo " [command]          - Execute the specified linux command eg. bash."
}

case "$1" in
  app:start)
    appStart
    ;;
  *)
    if [ -x $1 ]; then
      $1
    else
      prog=$(which $1)
      if [ -n "${prog}" ] ; then
        shift 1
        su -l burpui -c "$prog $@"
      else
        appHelp
      fi
    fi
    ;;
esac

exit 0
