FROM ubuntu:22.04

# Install common dependencies
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get -y update && \
    apt-get -y install sudo \
    apt-utils \
    build-essential \
    openssl \
    clang \
    graphviz-dev \
    git \
    autoconf \
    libgnutls28-dev \
    libssl-dev \
    llvm-11 llvm-11-dev clang-11 \
    python3.11 python3-pip \
    nano \
    net-tools \
    vim \
    gdb \
    netcat \
    strace \
    ftp \
    wget

RUN apt-get -y install python3.11 python3.11-dev

RUN apt-get -y install ninja-build

# Add a new user ubuntu, pass: ubuntu
RUN groupadd ubuntu && \
    useradd -rm -d /home/ubuntu -s /bin/bash -g ubuntu -G sudo -u 1000 ubuntu -p "$(openssl passwd -1 ubuntu)"

RUN chmod 777 /tmp

RUN python3 -m pip install --upgrade pip==20.3.4 && \
    pip3 install --trusted-host pypi.org --trusted-host files.pythonhosted.org gcovr==4.2

RUN python3.11 -m pip install -U pip setuptools wheel

RUN git clone https://github.com/fandango-fuzzer/fandango.git && \
    cd fandango && \
    git checkout io_replication && \
    python3.11 -m pip install --no-cache-dir -e ".[test]"

# Use ubuntu as default username
USER ubuntu
WORKDIR /home/ubuntu

# Import environment variable to pass as parameter to make (e.g., to make parallel builds with -j)
ARG MAKE_OPT

ENV CC=clang-11
ENV CXX=clang++-11
ENV LLVM_CONFIG=llvm-config-11

# Set up fuzzers
RUN git clone https://github.com/profuzzbench/aflnet.git && \
    cd aflnet && \
    make clean all $MAKE_OPT && \
    cd llvm_mode && make $MAKE_OPT

RUN git clone https://github.com/profuzzbench/aflnwe.git && \
    cd aflnwe && \
    make clean all $MAKE_OPT && \
    cd llvm_mode && make $MAKE_OPT

# Set up environment variables for AFLNet
ENV WORKDIR="/home/ubuntu/experiments"
ENV AFLNET="/home/ubuntu/aflnet"
ENV PATH="${PATH}:${AFLNET}:/home/ubuntu/.local/bin:${WORKDIR}"
ENV AFL_PATH="${AFLNET}"
ENV AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 \
    AFL_SKIP_CPUFREQ=1 \
    AFL_NO_AFFINITY=1


RUN mkdir $WORKDIR

COPY --chown=ubuntu:ubuntu fuzzing.patch ${WORKDIR}/fuzzing.patch
COPY --chown=ubuntu:ubuntu gcov.patch ${WORKDIR}/gcov.patch
COPY --chown=ubuntu:ubuntu gcov-fandango.patch ${WORKDIR}/gcov-fandango.patch

# Set up environment variables for ASAN
ENV ASAN_OPTIONS='abort_on_error=1:symbolize=0:detect_leaks=0:detect_stack_use_after_return=1:detect_container_overflow=0:poison_array_cookie=0:malloc_fill_byte=0:max_malloc_fill_size=16777216'

# Download and compile LightFTP for fuzzing
RUN cd $WORKDIR && \
    git clone https://github.com/hfiref0x/LightFTP.git && \
    cd LightFTP && \
    git checkout 5980ea1 && \
    patch -p1 < ${WORKDIR}/fuzzing.patch && \
    cd Source/Release && \
    AFL_USE_ASAN=1 CC=afl-clang-fast CXX=g++ make clean all $MAKE_OPT

# Set up LightFTP for fuzzing
RUN cd ${WORKDIR}/LightFTP/Source/Release && \
    cp ${AFLNET}/tutorials/lightftp/ftpclean.sh ./ && \
    cp ${AFLNET}/tutorials/lightftp/fftp.conf ./ && \
    cp -r ${AFLNET}/tutorials/lightftp/certificate /home/ubuntu && \
    mkdir /home/ubuntu/ftpshare

# Download and compile LightFTP for coverage analysis
RUN cd $WORKDIR && \
    git clone https://github.com/hfiref0x/LightFTP.git LightFTP-gcov && \
    cd LightFTP-gcov && \
    git checkout 5980ea1 && \
    patch -p1 < ${WORKDIR}/gcov.patch && \
    cd Source/Release && \
    make CC=gcc CXX=g++ CFLAGS="-fprofile-arcs -ftest-coverage" CPPFLAGS="-fprofile-arcs -ftest-coverage" CXXFLAGS="-fprofile-arcs -ftest-coverage" LDFLAGS="-fprofile-arcs -ftest-coverage" clean all $MAKE_OPT

# Set up LightFTP for fuzzing
RUN cd ${WORKDIR}/LightFTP-gcov/Source/Release && \
    cp ${AFLNET}/tutorials/lightftp/ftpclean.sh ./
COPY --chown=ubuntu:ubuntu fftp.conf ${WORKDIR}/LightFTP-gcov/Source/Release/

# Download and compile LightFTP for coverage analysis
RUN cd $WORKDIR && \
    git clone https://github.com/hfiref0x/LightFTP.git LightFTP-fandango && \
    cd LightFTP-fandango && \
    git checkout 5980ea1 && \
    patch -p1 < ${WORKDIR}/gcov-fandango.patch && \
    cd Source/Release && \
    make CC=gcc CXX=g++ CFLAGS="-fprofile-arcs -ftest-coverage" CPPFLAGS="-fprofile-arcs -ftest-coverage" CXXFLAGS="-fprofile-arcs -ftest-coverage" LDFLAGS="-fprofile-arcs -ftest-coverage" clean all $MAKE_OPT

# Set up LightFTP for fuzzing
RUN cd ${WORKDIR}/LightFTP-fandango/Source/Release && \
    cp ${AFLNET}/tutorials/lightftp/ftpclean.sh ./
COPY --chown=ubuntu:ubuntu fftp.conf ${WORKDIR}/LightFTP-fandango/Source/Release/


COPY --chown=ubuntu:ubuntu in-ftp ${WORKDIR}/in-ftp
COPY --chown=ubuntu:ubuntu ftp.dict ${WORKDIR}/ftp.dict
COPY --chown=ubuntu:ubuntu cov_script.sh ${WORKDIR}/cov_script
COPY --chown=ubuntu:ubuntu run.sh ${WORKDIR}/run
COPY --chown=ubuntu:ubuntu clean.sh ${WORKDIR}/ftpclean
COPY --chown=ubuntu:ubuntu fandango-scripts/ ${WORKDIR}/fandango
RUN echo "I'm a file" > /home/ubuntu/ftpshare/exist_append.txt
RUN mkdir -p /home/ubuntu/ftpshare/dir_1/dir_2
RUN echo "I'm a file" > /home/ubuntu/ftpshare/dir_1/dir_2/rn_1.txt



# For debugging purposes
USER root
RUN mkdir -p ${WORKDIR}/cov_out
RUN chown -R ubuntu:ubuntu ${WORKDIR}/cov_out
RUN chmod -R +rw ${WORKDIR}/cov_out
USER ubuntu
