diff --git a/.ci/detect_os_arch_package_format b/.ci/detect_os_arch_package_format new file mode 100755 index 0000000..dc76376 --- /dev/null +++ b/.ci/detect_os_arch_package_format @@ -0,0 +1,20 @@ +#!/usr/bin/ruby + +package_name = ARGV.first + +DEB_PACKAGE_REGEX = %r!(?[^/]+)/kasmvncserver_.+?_(?.+?).(?deb)! +RPM_PACKAGE_REGEX = %r!(?[^/]+)/kasmvncserver-.+?\.(?[^.]+).(?rpm)! + +if matches = package_name.match(DEB_PACKAGE_REGEX) +else matches = package_name.match(RPM_PACKAGE_REGEX) +end + +os = matches["os"] +arch = matches["arch"] +package_format = matches["format"] + +puts <<-EXPORT + export PACKAGE_OS=#{os} + export OS_ARCH=#{arch} + export PACKAGE_FORMAT=#{package_format} +EXPORT diff --git a/.ci/next_release_version b/.ci/next_release_version new file mode 100755 index 0000000..28ff069 --- /dev/null +++ b/.ci/next_release_version @@ -0,0 +1,25 @@ +#!/bin/bash + +set -e + +version_from_tags() { + git tag | sort -r | head -1 | sed -e 's/^v//' -e 's/\-.\+//' | awk -F. -v OFS=. 'NF==1{print ++$NF}; NF>1{if(length($NF+1)>length($NF))$(NF-1)++; $NF=sprintf("%0*d", length($NF), ($NF+1)%(10^length($NF))); print}' +} + +branch_name="$1" +if [ -z "$branch_name" ]; then + echo >&2 "Usage: `basename $0` " + exit 1 +fi + +if echo "$branch_name" | grep -Pq '^release/([\d.]+)$'; then + RELEASE_BRANCH=1 +fi + +if [ -n "$RELEASE_BRANCH" ]; then + RELEASE_VERSION=$(echo "$branch_name" | sed 's!release/!!'); +else + RELEASE_VERSION="$(version_from_tags)" +fi + +echo "$RELEASE_VERSION" diff --git a/.ci/upload.sh b/.ci/upload.sh new file mode 100644 index 0000000..f2fa0e5 --- /dev/null +++ b/.ci/upload.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +function prepare_upload_filename() { + local package="$1"; + + .ci/detect_os_arch_package_format "$package" > /tmp/os_arch_package_format; + source /tmp/os_arch_package_format; + detect_release_branch + if [ -n "$RELEASE_BRANCH" ]; then + export upload_filename="kasmvncserver_${PACKAGE_OS}_${RELEASE_VERSION}_${OS_ARCH}.${PACKAGE_FORMAT}"; + else + export SANITIZED_BRANCH="$(echo $CI_COMMIT_REF_NAME | sed 's/\//_/g')"; + export upload_filename="kasmvncserver_${PACKAGE_OS}_${RELEASE_VERSION}_${SANITIZED_BRANCH}_${CI_COMMIT_SHA:0:6}_${OS_ARCH}.${PACKAGE_FORMAT}"; + fi +}; + +function upload_to_s3() { + local package="$1"; + local upload_filename="$2"; + + # Transfer to S3 + python3 amazon-s3-bitbucket-pipelines-python/s3_upload.py "${S3_BUCKET}" "$package" "${S3_BUILD_DIRECTORY}/${upload_filename}"; + # Use the Gitlab API to tell Gitlab where the artifact was stored + export S3_URL="https://${S3_BUCKET}.s3.amazonaws.com/${S3_BUILD_DIRECTORY}/${upload_filename}"; + export BUILD_STATUS="{\"key\":\"doc\", \"state\":\"SUCCESSFUL\", \"name\":\"${upload_filename}\", \"url\":\"${S3_URL}\"}"; + curl --request POST --header "PRIVATE-TOKEN:${GITLAB_API_TOKEN}" "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/statuses/${CI_COMMIT_SHA}?state=success&name=build-url&target_url=${S3_URL}"; +}; +function prepare_to_run_scripts_and_s3_uploads() { + export DEBIAN_FRONTEND=noninteractive; + apt-get update; + apt-get install -y ruby2.7 git; + apt-get install -y python3 python3-pip python3-boto3 curl pkg-config libxmlsec1-dev; + git clone https://bitbucket.org/awslabs/amazon-s3-bitbucket-pipelines-python.git; +}; + +detect_release_branch() { + if echo $CI_COMMIT_REF_NAME | grep -Pq '^release/([\d.]+)$'; then + export RELEASE_BRANCH=1; + fi +} diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c72a155..435ccb1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,21 +4,107 @@ services: variables: GITLAB_SHARED_DIND_DIR: /builds/$CI_PROJECT_PATH/shared + GIT_FETCH_EXTRA_FLAGS: --tags stages: - build + - upload -build: +.prepare_build: &prepare_build + - ls -l + - pwd + - apk add bash + - mkdir -p "$GITLAB_SHARED_DIND_DIR" && chmod 777 "$GITLAB_SHARED_DIND_DIR" + +.prepare_artfacts: &prepare_artfacts + - mkdir output + - cp -r builder/build/* output/ + - rm output/*.tar.gz + +build_ubuntu_bionic: stage: build + before_script: + - *prepare_build + after_script: + - *prepare_artfacts script: - - ls -l - - pwd - - apk add bash - - mkdir -p "$GITLAB_SHARED_DIND_DIR" && chmod 777 "$GITLAB_SHARED_DIND_DIR" - - bash builder/build-tarball - - bash builder/build-deb - - mkdir output - - cp -r builder/build/* output/ + - bash builder/build-package ubuntu bionic artifacts: paths: - output/ + +build_ubuntu_focal: + stage: build + before_script: + - *prepare_build + after_script: + - *prepare_artfacts + script: + - bash builder/build-package ubuntu focal; + artifacts: + paths: + - output/ + +build_debian_buster: + stage: build + before_script: + - *prepare_build + after_script: + - *prepare_artfacts + script: + - bash builder/build-package debian buster; + artifacts: + paths: + - output/ + +build_debian_bullseye: + stage: build + before_script: + - *prepare_build + after_script: + - *prepare_artfacts + script: + - bash builder/build-package debian bullseye; + artifacts: + paths: + - output/ + +build_kali_rolling: + stage: build + before_script: + - *prepare_build + after_script: + - *prepare_artfacts + script: + - bash builder/build-package kali kali-rolling; + artifacts: + paths: + - output/ + +build_centos7: + stage: build + before_script: + - *prepare_build + after_script: + - *prepare_artfacts + script: + - bash builder/build-package centos core + artifacts: + paths: + - output/ + +upload: + stage: upload + image: ubuntu:focal + before_script: + - . .ci/upload.sh + script: + - export S3_BUILD_DIRECTORY="kasmvnc/${CI_COMMIT_SHA}" + - prepare_to_run_scripts_and_s3_uploads + - export RELEASE_VERSION=$(.ci/next_release_version "$CI_COMMIT_REF_NAME") + - for package in `find output/ -type f -name 'kasmvncserver_*.deb' -or -name '*.rpm'`; do + prepare_upload_filename "$package"; + echo; + echo "File to upload $upload_filename"; + upload_to_s3 "$package" "$upload_filename"; + done diff --git a/builder/build-package b/builder/build-package new file mode 100755 index 0000000..a21bf01 --- /dev/null +++ b/builder/build-package @@ -0,0 +1,19 @@ +#!/bin/bash + +set -e + +os="$1" +codename="$2" + +detect_package_format() { + package_format=rpm + if ls builder/dockerfile*"$os"* | grep -q .deb.build; then + package_format=deb + fi +} + +cd "$(dirname "$0")/.." + +detect_package_format +builder/build-tarball "$os" "$codename" +builder/build-${package_format} "$os" "$codename" diff --git a/builder/dockerfile.debian_bullseye.deb.test b/builder/dockerfile.debian_bullseye.deb.test index 8340a9a..3ad2600 100644 --- a/builder/dockerfile.debian_bullseye.deb.test +++ b/builder/dockerfile.debian_bullseye.deb.test @@ -32,6 +32,7 @@ WORKDIR $HOME RUN apt-get update && apt-get install -y supervisor xfce4 xfce4-terminal dbus-x11 xterm libnss-wrapper gettext wget RUN apt-get purge -y pm-utils xscreensaver* RUN apt-get update && apt-get install -y vim less +RUN apt-get update && apt-get -y install lsb-release RUN echo 'source $STARTUPDIR/generate_container_user' >> $HOME/.bashrc diff --git a/builder/dockerfile.debian_buster.barebones.deb.test b/builder/dockerfile.debian_buster.barebones.deb.test index a7d7218..12049c6 100644 --- a/builder/dockerfile.debian_buster.barebones.deb.test +++ b/builder/dockerfile.debian_buster.barebones.deb.test @@ -4,14 +4,16 @@ ARG KASMVNC_PACKAGE_DIR COPY $KASMVNC_PACKAGE_DIR/kasmvncserver_*.deb /tmp RUN apt-get update && dpkg -i /tmp/*.deb; apt-get -yf install RUN apt-get update && apt-get -y install xterm -# RUN apt-get update && apt-get -y install x11-xserver-utils xterm twm -RUN useradd -m foo && addgroup foo ssl-cert +COPY startup/deb/kasmvncserver-easy-start /usr/local/bin -USER foo +RUN useradd -m foo + +USER foo:ssl-cert RUN mkdir ~/.vnc && echo '/usr/bin/xterm &' >> ~/.vnc/xstartup && \ chmod +x ~/.vnc/xstartup -RUN echo bar | kasmvncpasswd -f > $HOME/.kasmpasswd && chmod 0600 $HOME/.kasmpasswd -ENTRYPOINT bash -c "vncserver :1 -interface 0.0.0.0 && vncserver -kill :1 && vncserver :1 -depth 24 -geometry 1280x1050 -websocketPort 8443 -cert /etc/ssl/certs/ssl-cert-snakeoil.pem -key /etc/ssl/private/ssl-cert-snakeoil.key -sslOnly -FrameRate=24 -interface 0.0.0.0 -httpd /usr/share/kasmvnc/www && tail -f $HOME/.vnc/*.log " +ENTRYPOINT bash -c "echo -e \"$VNC_PW\n$VNC_PW\n\" | \ + kasmvncpasswd -w -u $VNC_USER $HOME/.kasmpasswd && \ + kasmvncserver-easy-start && tail -f $HOME/.vnc/*.log" diff --git a/builder/dockerfile.debian_buster.deb.test b/builder/dockerfile.debian_buster.deb.test index 53d6b5d..ef536ea 100644 --- a/builder/dockerfile.debian_buster.deb.test +++ b/builder/dockerfile.debian_buster.deb.test @@ -32,6 +32,7 @@ WORKDIR $HOME RUN apt-get update && apt-get install -y supervisor xfce4 xfce4-terminal xterm libnss-wrapper gettext wget RUN apt-get purge -y pm-utils xscreensaver* RUN apt-get update && apt-get install -y vim less +RUN apt-get update && apt-get -y install lsb-release RUN echo 'source $STARTUPDIR/generate_container_user' >> $HOME/.bashrc diff --git a/builder/dockerfile.kali_kali-rolling.deb.test b/builder/dockerfile.kali_kali-rolling.deb.test index 7fa1ae0..a189b9b 100644 --- a/builder/dockerfile.kali_kali-rolling.deb.test +++ b/builder/dockerfile.kali_kali-rolling.deb.test @@ -32,6 +32,7 @@ WORKDIR $HOME RUN apt-get update && apt-get install -y supervisor xfce4 xfce4-terminal dbus-x11 xterm libnss-wrapper gettext wget RUN apt-get purge -y pm-utils xscreensaver* RUN apt-get update && apt-get install -y vim less +RUN apt-get update && apt-get -y install lsb-release RUN echo 'source $STARTUPDIR/generate_container_user' >> $HOME/.bashrc diff --git a/builder/dockerfile.ubuntu_bionic.deb.test b/builder/dockerfile.ubuntu_bionic.deb.test index 9a0db27..793c2ca 100644 --- a/builder/dockerfile.ubuntu_bionic.deb.test +++ b/builder/dockerfile.ubuntu_bionic.deb.test @@ -32,6 +32,7 @@ WORKDIR $HOME RUN apt-get update && apt-get install -y supervisor xfce4 xfce4-terminal xterm libnss-wrapper gettext wget RUN apt-get purge -y pm-utils xscreensaver* RUN apt-get update && apt-get install -y vim less +RUN apt-get update && apt-get -y install lsb-release RUN echo 'source $STARTUPDIR/generate_container_user' >> $HOME/.bashrc diff --git a/builder/dockerfile.ubuntu_focal.deb.test b/builder/dockerfile.ubuntu_focal.deb.test index 4d1c50b..3397848 100644 --- a/builder/dockerfile.ubuntu_focal.deb.test +++ b/builder/dockerfile.ubuntu_focal.deb.test @@ -32,6 +32,7 @@ WORKDIR $HOME RUN apt-get update && apt-get install -y supervisor xfce4 xfce4-terminal xterm libnss-wrapper gettext wget RUN apt-get purge -y pm-utils xscreensaver* RUN apt-get update && apt-get install -y vim less +RUN apt-get update && apt-get -y install lsb-release RUN echo 'source $STARTUPDIR/generate_container_user' >> $HOME/.bashrc @@ -44,6 +45,9 @@ ARG KASMVNC_PACKAGE_DIR COPY $KASMVNC_PACKAGE_DIR/kasmvncserver_*.deb /tmp RUN dpkg -i /tmp/*.deb; apt-get -yf install +RUN mkdir ~/.vnc && echo '/usr/bin/xfce4-session &' >> ~/.vnc/xstartup && \ + chmod +x ~/.vnc/xstartup + ### END CUSTOM STUFF ### RUN chown -R 1000:0 $HOME diff --git a/builder/startup/deb/kasmvncserver-easy-start b/builder/startup/deb/kasmvncserver-easy-start new file mode 100755 index 0000000..0d0bc88 --- /dev/null +++ b/builder/startup/deb/kasmvncserver-easy-start @@ -0,0 +1,46 @@ +#!/bin/bash + +set -e + +display=:10 +interface=0.0.0.0 +cert_group=ssl-cert + +if [[ "$1" = "--help" ]]; then + cat >&2 <<-USAGE +Usage: `basename $0` [options] + -d Debug output + -kill Kill vncserver + --help show this help +USAGE + exit +fi + +if [[ "$1" = "-d" ]]; then + log_option="-log *:stderr:100" +fi + +action=start +if [[ "$1" = "-kill" ]]; then + action=kill +fi + +if groups | grep -qvw ssl-cert; then + cat <<-EOF + Can't access TLS certificate. + Please add your user to $cert_group via 'addgroup ssl-cert' +EOF + exit 1 +fi + +if [[ "$action" = "kill" ]]; then + vncserver -kill $display + exit +fi + +vncserver $display -interface $interface +vncserver -kill $display +vncserver $display -depth 24 -geometry 1280x1050 -websocketPort 8443 \ + -cert /etc/ssl/certs/ssl-cert-snakeoil.pem \ + -key /etc/ssl/private/ssl-cert-snakeoil.key -sslOnly -FrameRate=24 \ + -interface $interface -httpd /usr/share/kasmvnc/www $log_option diff --git a/builder/startup/vnc_startup.sh b/builder/startup/vnc_startup.sh index 93c6079..c0c3b3c 100755 --- a/builder/startup/vnc_startup.sh +++ b/builder/startup/vnc_startup.sh @@ -50,13 +50,12 @@ VNC_IP=$(hostname -i) # first entry is control, second is view (if only one is valid for both) mkdir -p "$HOME/.vnc" PASSWD_PATH="$HOME/.vnc/passwd" -# echo -e "$VNC_PW\n$VNC_PW" | kasmvncpasswd -w -u $VNC_USER $HOME/.kasmpasswd add_vnc_user "$VNC_USER" "$VNC_PW" "-w" add_vnc_user "$VNC_USER-ro" "$VNC_PW" add_vnc_user "$VNC_USER-owner" "$VNC_PW" "-o" add_vnc_user "$VNC_USER-to-delete" "$VNC_PW" -kasmvncpasswd -n -u "$VNC_USER-owner" -w $HOME/.kasmpasswd +kasmvncpasswd -n -u "$VNC_USER-owner" -w -o $HOME/.kasmpasswd kasmvncpasswd -d -u "$VNC_USER-to-delete" $HOME/.kasmpasswd chmod 0600 $HOME/.kasmpasswd diff --git a/builder/test-deb-barebones b/builder/test-deb-barebones index cb94966..4fe878c 100755 --- a/builder/test-deb-barebones +++ b/builder/test-deb-barebones @@ -10,6 +10,5 @@ docker build --build-arg KASMVNC_PACKAGE_DIR="build/${os_codename}" \ -t kasmvnctester_barebones_${os}:$os_codename \ -f dockerfile.${os}_${os_codename}.barebones.deb.test . echo -echo "You will be asked to set password. User name is docker." docker run -it -p 443:8443 --rm -e "VNC_USER=foo" -e "VNC_PW=foobar" \ kasmvnctester_barebones_${os}:$os_codename diff --git a/debian/Makefile.to_fakebuild_tar_package b/debian/Makefile.to_fakebuild_tar_package index d1861a9..dd097af 100644 --- a/debian/Makefile.to_fakebuild_tar_package +++ b/debian/Makefile.to_fakebuild_tar_package @@ -1,12 +1,6 @@ TARGET_OS := $(shell lsb_release -is | tr '[:upper:]' '[:lower:]') TARGET_OS_CODENAME := $(shell lsb_release -cs | tr '[:upper:]' '[:lower:]') -ifeq ($(TARGET_OS), $(filter $(TARGET_OS), centos fedora)) - PACKAGE_TYPE := rpm - TARBALL_DIR := $$RPM_SOURCE_DIR -else - PACKAGE_TYPE := deb - TARBALL_DIR := builder/build -endif +TARBALL_DIR := builder/build TARBALL := $(TARBALL_DIR)/kasmvnc.$(TARGET_OS)_$(TARGET_OS_CODENAME).tar.gz TAR_DATA := $(shell mktemp -d) SRC := $(TAR_DATA)/usr/local diff --git a/debian/examples b/debian/examples new file mode 100644 index 0000000..ff8543d --- /dev/null +++ b/debian/examples @@ -0,0 +1 @@ +builder/startup/deb/kasmvncserver-easy-start diff --git a/unix/vncpasswd/vncpasswd.man b/unix/vncpasswd/vncpasswd.man index ecf2bc9..fa15833 100644 --- a/unix/vncpasswd/vncpasswd.man +++ b/unix/vncpasswd/vncpasswd.man @@ -1,48 +1,93 @@ .TH vncpasswd 1 "" "KasmVNC" "Virtual Network Computing" .SH NAME -vncpasswd \- change the VNC password +vncpasswd \- setup VNC users and passwords .SH SYNOPSIS -\fBvncpasswd\fR [\fIpasswd-file\fR] -.br -\fBvncpasswd\fR \-f +\fBvncpasswd\fR -u [\fIusername\fR] [\fI-wnod\fR] [\fIpasswd-file\fR] .SH DESCRIPTION .B vncpasswd -allows you to set the password used to access VNC desktops. Its default -behavior is to prompt for a VNC password and then store an obfuscated version -of this password to \fIpasswd-file\fR (or to $HOME/.vnc/passwd if no password -file is specified.) The \fBvncserver\fP script runs \fBvncpasswd\fP the first -time you start a VNC desktop, and it invokes \fBXvnc\fP with the appropriate -\fB\-rfbauth\fP option. \fBvncviewer\fP can also be given a password file to -use via the \fB\-passwd\fP option. +allows you to add users and passwords used to access VNC desktops. Multiple +users can be added, each with its own permissions. You can set view-only, use of +mouse and keyboard allowed (-w), user managment permissions (-o). See OPTIONS +below for details. -The password must be at least six characters long (unless the \fB\-f\fR -command-line option is used-- see below), and only the first eight -characters are significant. Note that the stored password is \fBnot\fP -encrypted securely - anyone who has access to this file can trivially find out -the plain-text password, so \fBvncpasswd\fP always sets appropriate permissions -(read and write only by the owner.) However, when accessing a VNC desktop, a -challenge-response mechanism is used over the wire making it hard for anyone to -crack the password simply by snooping on the network. +Its default behavior is to prompt for a VNC password and then store an +obfuscated version of this password to \fIpasswd-file\fR (or to +$HOME/.kasmpasswd if no password file is specified.) The \fBvncserver\fP script +will ask you to add a user the first time you start a VNC desktop. HTTP Basic +Authentication will be used to ask for username and password, when you connect. + +The password must be at least six characters long (maximum of 128 characters). +Note that the stored password is \fBnot\fP encrypted securely - anyone who has +access to this file can trivially find out the plain-text password, so +\fBvncpasswd\fP always sets appropriate permissions (read and write only by the +owner.) However, when accessing a VNC desktop, a challenge-response mechanism +is used over the wire making it hard for anyone to crack the password simply by +snooping on the network. .SH OPTIONS .TP -.B \-f -Filter mode. Read a plain-text password from stdin and write an encrypted -version to stdout. Note that in filter mode, short or even empty passwords -will be silently accepted. +.B \-u \fIname\fR -A view-only password must be separated from the normal password by a newline -character. +Specify user name. There can be multiple users. +.TP +.B \-w + +Write permission. Enable user to use mouse and keyboard. The default mode is to +view only. + +.TP +.B \-o + +Owner permission. Allow the user to add/delete users and change their +permissions. + +.TP +.B \-d + +Delete user specified with \fI-u\fR. You need the owner permission for that. + +.TP +.B \-n + +Don't update their password, while updating permissions. .SH FILES .TP -$HOME/.vnc/passwd +$HOME/.kasmpasswd Default location of the VNC password file. +.SH EXAMPLES +.TP +Create a new user foo that can to use mouse and keyboard: +$ vncpasswd -u foo -w + +.TP +Create a new user foo that can view, but can't use mouse and keyboard: +$ vncpasswd -u foo + +.TP +Create a new user foo that can add new users AND use mouse and keyboard: +$ vncpasswd -u foo -ow + +.TP +Delete user foo +$ vncpasswd -u foo -d + +.TP +Strip all permissions from user foo, making it view only. Don't touch password. +$ vncpasswd -u foo -n + +.TP +Strip all permissions from user foo, making it view only. Change password. +$ vncpasswd -u foo + +.TP +Add write permission for user foo. Don't touch password. +$ vncpasswd -u foo -w -n + .SH SEE ALSO -.BR vncviewer (1), .BR vncserver (1), .BR Xvnc (1) .BR vncconfig (1), diff --git a/unix/vncserver.man b/unix/vncserver.man index d6240df..aae748d 100644 --- a/unix/vncserver.man +++ b/unix/vncserver.man @@ -171,9 +171,9 @@ $HOME/.vnc/config An optional server config file wherein options to be passed to Xvnc are listed to avoid hard-coding them to the physical invocation. List options in this file one per line. For those requiring an argument, simply separate the option from -the argument with an equal sign, for example: "geometry=2000x1200" or -"securitytypes=vncauth,tlsvnc". Options without an argument are simply listed -as a single word, for example: "localhost" or "alwaysshared". +the argument with an equal sign, for example: "geometry=2000x1200". Options +without an argument are simply listed as a single word, for example: "localhost" +or "alwaysshared". .TP $HOME/.vnc/passwd The VNC password file.