diff --git a/docker/Dockerfile b/docker/Dockerfile index 2436ff9..ae8257f 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -3,14 +3,13 @@ FROM golang:1.16 AS build # Install dependencies RUN apt-get update && apt-get install -y libsecret-1-dev +ARG PROTONMAIL_BRIDGE_VERSION + # Build WORKDIR /build/ -COPY VERSION /build/ - -RUN VERSION=$(cat VERSION) && \ - curl -L https://github.com/ProtonMail/proton-bridge/archive/refs/tags/${VERSION}.tar.gz \ - | tar zx --strip-component 1 && \ - make build-nogui +RUN curl -L https://github.com/ProtonMail/proton-bridge/archive/refs/tags/${PROTONMAIL_BRIDGE_VERSION}.tar.gz \ + | tar zx --strip-component 1 +RUN make build-nogui FROM ubuntu:bionic LABEL maintainer="Xiaonan Shen " @@ -24,19 +23,20 @@ RUN apt-get update \ expect socat pass libsecret-1-0 ca-certificates \ && rm -rf /var/lib/apt/lists/* +ENV PATH="/srv/protonmail:$PATH" + # Copy protonmail -COPY --from=build /build/proton-bridge/proton-bridge /protonmail/ +COPY --from=build /build/proton-bridge /srv/protonmail/ # Copy bash scripts -COPY gpgparams entrypoint.sh login.exp /protonmail/ +COPY gpgparams entrypoint.sh auto-login.exp login.sh /srv/protonmail/ -RUN chmod +x /protonmail/login.exp - -# Add a user 'protonmail' with UID 8535 -RUN useradd -u 8535 -d /home/protonmail protonmail \ - && mkdir -p /home/protonmail \ - && chown protonmail: /home/protonmail -# change to non-privileged user for extra security +# Create use and group for protonmail +RUN groupadd --gid 8535 protonmail \ + && useradd --uid 8535 --gid 8535 --home-dir /protonmail protonmail \ + && mkdir /protonmail \ + && chown protonmail:protonmail /protonmail USER protonmail +WORKDIR /protonmail -ENTRYPOINT ["bash", "/protonmail/entrypoint.sh"] +ENTRYPOINT ["bash", "/srv/protonmail/entrypoint.sh"] diff --git a/docker/auto-login.exp b/docker/auto-login.exp new file mode 100755 index 0000000..4fa6c4f --- /dev/null +++ b/docker/auto-login.exp @@ -0,0 +1,98 @@ +#!/usr/bin/expect -f + +set timeout 15; + +spawn proton-bridge -cli {*}$argv ; + +# wait for inital prompt +expect { + ">>> " { + # protonmail-bridge started without error, do nothing + } + + timeout { + puts "Timed out" + exit 2 + } +} + +send "login\n" +expect { + "Username: " { + # login start, enter username + } + + timeout { + puts "Timed out" + exit 2 + } +} + +send "$::env(PROTONMAIL_USERNAME)\n" +expect { + "Password: " { + # username entered, enter password + } + + timeout { + puts "Timed out" + exit 2 + } +} + +stty -echo +sleep 1 +send "$::env(PROTONMAIL_PASSWORD)\n" +stty echo +expect { + "was added successfully." { + # login ok + } + + "Two factor code: " { + # 2FA enabled, enter OTP + if ![info exists ::env(PROTONMAIL_OTP)] { + puts "\n2FA enabled but PROTONMAIL_OTP is not set. Exiting" + exit 1 + } + send "$::env(PROTONMAIL_OTP)\n" + expect { + "was added successfully." { + # login ok + } + + "Server error" { + # login failed + exit 1 + } + + timeout { + puts "Timed out" + exit 2 + } + } + } + + "Server error" { + # login failed + exit 1 + } + + timeout { + puts "Timed out" + exit 2 + } +} + +send "info\n" +expect { + "Configuration for " { + # successfully got info. Wait for printing + sleep 1 + } + + timeout { + puts "Timed out" + exit 2 + } +} diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 3f4f653..27a4783 100644 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -1,14 +1,10 @@ #!/bin/bash -set -ex +set -e -id -# Go to current user's homedir -cd -echo $PWD - -# Initialize -if [[ $1 == init ]]; then +# Generate gpg keys +if [ ! -f ${HOME}/.gnupg ]; then + echo "Generateing gpg keys..." # set GNUPGHOME as a workaround for # # gpg-agent[106]: error binding socket to '/root/.gnupg/S.gpg-agent': File name too long @@ -17,42 +13,50 @@ if [[ $1 == init ]]; then # # ref: https://dev.gnupg.org/T2964 # - - export GNUPGHOME="${GNUPGHOME:-"/tmp/gnupg"}" - rm -rf "${GNUPGHOME}" || true - mkdir -p "${GNUPGHOME}" - chmod 0700 "${GNUPGHOME}" - - # Initialize pass - gpg --generate-key --batch /protonmail/gpgparams - pass init "${KEY_ID:-"pass-key"}" - - # Login - do_login="/protonmail/proton-bridge --cli $*" - if [[ "x${PROTONMAIL_USERNAME}" != "x" && "x${PROTONMAIL_PASSWORD}" != "x" ]]; then - # automated login if both username and password are set - do_login="/protonmail/login.exp ${do_login}" - fi - - $do_login - - # copy gnupg files to default path - mkdir -p /root/.gnupg - kill "$(pidof gpg-agent)" - cp -a "${GNUPGHOME}/" /root/.gnupg/ - -else - - # socat will make the conn appear to come from 127.0.0.1 - # ProtonMail Bridge currently expects that. - # It also allows us to bind to the real ports :) - socat TCP-LISTEN:25,fork TCP:127.0.0.1:1025 & - socat TCP-LISTEN:143,fork TCP:127.0.0.1:1143 & - - # Start protonmail - # Fake a terminal, so it does not quit because of EOF... - rm -f faketty - mkfifo faketty - cat faketty | /protonmail/proton-bridge --cli $@ - + export GNUPGHOME=/tmp/gnupg + mkdir ${GNUPGHOME} + chmod 700 ${GNUPGHOME} + gpg --generate-key --batch /srv/protonmail/gpgparams + pkill gpg-agent + mv ${GNUPGHOME} ${HOME}/.gnupg + export GNUPGHOME="" fi + +# Initialize pass +if [ ! -f ${HOME}/.password-store/.gpg-id ]; then + echo "Initializing pass" + pass init pass-key +fi + +# Login +if [ ! -f ${HOME}/.logged-in ]; then + if [[ -n ${PROTONMAIL_USERNAME} && -n ${PROTONMAIL_PASSWORD} ]]; then + echo "Logging in" + auto-login.exp $@ + echo "" > ${HOME}/.logged-in + else + # Wait for manual login + echo "==============================================================================" + echo "PROTONMAIL_USERNAME or PROTONMAIL_PASSWORD is not set. Will not do auto login." + echo "Run docker exec -it protonmail login.sh to login manually." + echo "Waiting for manual login..." + while [ ! -f ${HOME}/.logged-in ]; do + sleep 5 + done + fi +fi + +echo "Logged in flag detected. Starting protonmail bridge" + + +# socat will make the conn appear to come from 127.0.0.1 +# ProtonMail Bridge currently expects that. +# It also allows us to bind to the real ports :) +socat TCP-LISTEN:2025,fork TCP:127.0.0.1:1025 & +socat TCP-LISTEN:2143,fork TCP:127.0.0.1:1143 & + +# Start protonmail +# Fake a terminal, so it does not quit because of EOF... +rm -f faketty +mkfifo faketty +cat faketty | proton-bridge --cli $@ diff --git a/docker/login.exp b/docker/login.exp deleted file mode 100644 index 0fbb553..0000000 --- a/docker/login.exp +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/expect -f - -set timeout 15; - -spawn {*}$argv ; - -# wait for inital prompt -expect { - ">>> " { - # protonmail-bridge started without error, do nothing - } - - timeout { - exit 2 - } -} - -send "login\r" -expect { - "Username: " { - # login start, enter username - } - - timeout { - exit 2 - } -} - -send "$env(PROTONMAIL_USERNAME)\r" -expect { - "Password: " { - # username entered, enter password - } - - timeout { - exit 2 - } -} - -stty -echo -sleep 1 -send "$env(PROTONMAIL_PASSWORD)\r" -stty echo -expect { - "was added successfully." { - # login ok - exit 0 - } - - "Server error" { - # login failed - exit 1 - } - - timeout { - exit 2 - } -} diff --git a/docker/login.sh b/docker/login.sh new file mode 100755 index 0000000..a206be3 --- /dev/null +++ b/docker/login.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +echo "Start manual login" +echo "========================================================================" +echo "IMPORTANT: Use `exit` instead of CTRL-C when you successfully logged in." +echo "Otherwise protonmail bridge will not start." +echo "========================================================================" + +proton-bridge -cli + +echo "Consider logged in. Add flag." +echo "" > $HOME/.logged-in diff --git a/version-config.yaml b/version-config.yaml new file mode 100644 index 0000000..2cee06f --- /dev/null +++ b/version-config.yaml @@ -0,0 +1,4 @@ +image_version: 0.1 +protonmail_version: + latest: v1.8.7 # Latest stable version + pre: v1.8.9 # Latest preview version