Compare commits

...

54 Commits

Author SHA1 Message Date
Matthew McClaskey
230e50f7b8 Merge branch 'bugfix/KASM-5742_kasmvnc_1.3.1_bugfixes' into 'release/1.3.1'
Resolve KASM-5742 "Bugfix/ kasmvnc 1.3.1 bugfixes"

See merge request kasm-technologies/internal/KasmVNC!128
2024-03-15 09:19:45 +00:00
Matt McClaskey
57c47a9c20 update novnc ref 2024-03-14 12:34:31 -04:00
Matt McClaskey
c4ca652795 bump version number, update novnc ref 2024-03-12 11:26:10 -04:00
Matt McClaskey
6d878d3575 update novnc ref, bump package version to 1.3.0 2024-03-12 11:16:02 -04:00
Matt McClaskey
3ffb8f93f0 update novnc ref 2024-02-12 19:29:10 -05:00
Matt McClaskey
fe2d67e462 update novnc ref 2024-02-12 08:18:46 -05:00
Justin Travis
a10358b5ca Merge branch 'bugfix/KASM-5524_watermark_rotation_negative_number' into 'master'
KASM-5524 negative numbers on text rotation watermark

Closes KASM-5524

See merge request kasm-technologies/internal/KasmVNC!123
2024-01-30 18:26:11 +00:00
Matthew McClaskey
124d36a981 Merge branch 'feature/KASM-5523_always_return_desktopSize' into 'master'
Send back an ExtendedDesktopSize to a SetDesktopSize request even when resize is not allowed

Closes KASM-5523

See merge request kasm-technologies/internal/KasmVNC!122
2024-01-30 17:00:11 +00:00
Matt McClaskey
f02fbb0e2d update novnc ref to master 2024-01-30 11:59:12 -05:00
Matthew McClaskey
8c7dd2ed30 KASM-5524 negative numbers on text rotation watermark 2024-01-30 16:44:31 +00:00
Matt McClaskey
ae70375afe KASM-5523 update novnc ref 2024-01-29 10:38:31 -05:00
Lauri Kasanen
127ab45329 Send back an ExtendedDesktopSize to a SetDesktopSize request even when resize is not allowed 2024-01-29 12:20:57 +02:00
Matt McClaskey
3bc1024e7f update novnc ref 2024-01-26 15:32:59 -05:00
Matt McClaskey
228eb87db1 update novnc ref 2024-01-26 11:15:38 -05:00
Matthew McClaskey
4f726e3654 Merge branch 'feature/KASM-5466_watermark_rotation' into 'master'
Implement rotated watermark text support

Closes KASM-5466

See merge request kasm-technologies/internal/KasmVNC!121
2024-01-22 14:45:01 +00:00
Matt McClaskey
ed9fbcbec2 [skip CI] correct example config 2024-01-22 08:58:45 -05:00
Matt McClaskey
659a4198fc KASM-5466 add text rotation yaml config 2024-01-22 07:30:46 -05:00
Lauri Kasanen
5456ccc072 Implement rotated watermark text support 2024-01-22 13:32:32 +02:00
Matthew McClaskey
fddaab5124 Merge branch 'bugfix/KASM-5417_watermark_zlib_incomplete' into 'master'
Watermark refactoring, don't handle changes, only send when necessary

Closes KASM-5417

See merge request kasm-technologies/internal/KasmVNC!120
2024-01-17 15:55:17 +00:00
Matt McClaskey
7be7e34b51 [skip CI] update noVNC ref to master 2024-01-17 10:53:02 -05:00
Matt McClaskey
5b64eb32f8 pointed novnc ref to branch 2024-01-16 08:58:00 -05:00
Lauri Kasanen
eef8e7264f Watermark refactoring, don't handle changes, only send when necessary 2024-01-12 10:46:13 +02:00
Matt McClaskey
e8b54db6bf update novnc ref 2024-01-05 14:02:13 -05:00
Matt McClaskey
7b442658e1 update novnc ref 2024-01-04 09:15:36 -05:00
Matthew McClaskey
408fcd3415 Merge branch 'feature/KASM-5403-fedora-39' into 'master'
Resolve KASM-5403 "Feature/ fedora 39"

Closes KASM-5403

See merge request kasm-technologies/internal/KasmVNC!119
2024-01-03 17:02:12 +00:00
Ryan Kuba
7cdb7e1f3e Resolve KASM-5403 "Feature/ fedora 39" 2024-01-03 17:02:12 +00:00
Matthew McClaskey
b595c0bce8 Merge branch 'feature/KASM-5399-alpine-319' into 'master'
Resolve KASM-5399 "Feature/ alpine 319"

Closes KASM-5399

See merge request kasm-technologies/internal/KasmVNC!118
2024-01-03 12:01:48 +00:00
Ryan Kuba
4c9b065c31 Resolve KASM-5399 "Feature/ alpine 319" 2024-01-03 12:01:48 +00:00
Matt McClaskey
8b5ee59ae2 update novnc ref 2023-12-22 13:45:57 -05:00
Richard Koliser
4114d73ed6 Merge branch 'feature/KASM-5078_multi_monitor' into 'master'
Resolve KASM-5078 "Feature/ multi monitor"

Closes KASM-5078

See merge request kasm-technologies/internal/KasmVNC!117
2023-12-19 19:44:49 +00:00
Richard Koliser
1d8a2ed59a KASM-5078 Update NoVNC commit 2023-12-19 13:17:15 -05:00
Richard Koliser
c055920348 KASM-5078 Update noVNC branch 2023-12-19 00:09:50 -05:00
Matthew McClaskey
b2d965b58d Merge branch 'feature/KASM-5213_email_username' into 'master'
Allow emails as usernames

Closes KASM-5213

See merge request kasm-technologies/internal/KasmVNC!115
2023-11-30 12:59:21 +00:00
Matthew McClaskey
446497ad06 Merge branch 'feature/KASM-5214_log_render_settings_applied' into 'master'
Log client settings

Closes KASM-5214

See merge request kasm-technologies/internal/KasmVNC!116
2023-11-14 16:14:52 +00:00
Matthew McClaskey
0de752f65e Merge branch 'feature/KASM-3380_udp_frame_id' into 'master'
Resolve KASM-3380 "Feature/ udp frame"

Closes KASM-3380

See merge request kasm-technologies/internal/KasmVNC!114
2023-11-14 15:43:09 +00:00
Matt McClaskey
f712f5e7f8 update novnc ref 2023-11-14 10:19:40 -05:00
Matt McClaskey
d090e1b707 update novNC ref 2023-11-14 08:44:08 -05:00
Lauri Kasanen
fb7570709a Extend username limit to 128-1 2023-11-06 15:22:23 +02:00
Lauri Kasanen
73c3bda8cd Fix off-by-one in username length check 2023-11-06 13:59:37 +02:00
Lauri Kasanen
9a73cb4a60 Log client settings 2023-11-06 11:44:42 +02:00
Lauri Kasanen
6cd50869c2 Allow emails as usernames 2023-11-06 11:07:01 +02:00
Lauri Kasanen
5823b550a4 Count data rects separately for UDP flip 2023-11-01 10:26:50 +02:00
Lauri Kasanen
29c48a8679 Move frame id updating to a better location 2023-11-01 10:26:50 +02:00
Lauri Kasanen
c88b683354 Write rect count in udp lastrect's X 2023-11-01 10:26:50 +02:00
Lauri Kasanen
7399e5dc62 Add frame number to udp packets 2023-11-01 10:26:33 +02:00
Matt McClaskey
e4a5004f4b update novnc ref 2023-10-31 07:17:33 -04:00
Matt McClaskey
da7c481fc8 update novnc ref 2023-10-30 15:34:43 -04:00
Matt McClaskey
32f4398115 update novnc ref 2023-10-27 04:46:58 -04:00
Matthew McClaskey
7350b12b3d Merge branch 'bugfix/KASM-5006-improve-xstartup-debug-output' into 'master'
vncserver: more debug output for xstartup

Closes KASM-5006

See merge request kasm-technologies/internal/KasmVNC!113
2023-10-20 11:35:19 +00:00
mattmcclaskey
1b25ad8e54 update novnc ref 2023-10-16 09:26:31 -04:00
mattmcclaskey
2165c3e1ba KASM-5078 multi-monitor 2023-10-16 07:17:31 -04:00
Matthew McClaskey
d390d187b4 Merge branch 'feature/KASM-5027-document-bypassing-select-de-prompt' into 'master'
vncserver: document bypassing DE selection prompt

Closes KASM-5027

See merge request kasm-technologies/internal/KasmVNC!112
2023-09-17 09:41:48 +00:00
Dmitry Maksyoma
a4034865e6 vncserver: document bypassing DE selection prompt 2023-09-14 16:41:37 +12:00
Dmitry Maksyoma
7d6244fe1c vncserver: more debug output for xstartup
- Use "set -x" in generated xstartup.
- Announce running xstartup in logs.
2023-09-03 21:35:13 +12:00
40 changed files with 853 additions and 125 deletions

View File

@@ -11,7 +11,8 @@ variables:
# arm builds, because build_debian_buster_arm matches build_debian_buster. # arm builds, because build_debian_buster_arm matches build_debian_buster.
# "BUILD_JOBS: none" won't build any build jobs, nor www. # "BUILD_JOBS: none" won't build any build jobs, nor www.
BUILD_JOBS: all BUILD_JOBS: all
DOCKER_HOST: unix:// DOCKER_HOST: tcp://docker:2375
DOCKER_TLS_CERTDIR: ""
workflow: workflow:
rules: rules:
@@ -38,11 +39,13 @@ stages:
default: default:
tags: tags:
- oci-fixed-amd64 - oci-fixed-amd
build_www: build_www:
stage: www stage: www
allow_failure: false allow_failure: false
tags:
- oci-fixed-amd
before_script: before_script:
- *prepare_build - *prepare_build
script: script:
@@ -66,6 +69,8 @@ build_www:
build_ubuntu_bionic: build_ubuntu_bionic:
stage: build stage: build
allow_failure: true allow_failure: true
tags:
- oci-fixed-amd
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -84,7 +89,7 @@ build_ubuntu_bionic_arm:
stage: build stage: build
allow_failure: false allow_failure: false
tags: tags:
- oci-fixed-arm64 - oci-fixed-arm
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -102,6 +107,8 @@ build_ubuntu_bionic_arm:
build_ubuntu_focal: build_ubuntu_focal:
stage: build stage: build
allow_failure: true allow_failure: true
tags:
- oci-fixed-amd
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -120,7 +127,7 @@ build_ubuntu_focal_arm:
stage: build stage: build
allow_failure: true allow_failure: true
tags: tags:
- oci-fixed-arm64 - oci-fixed-arm
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -138,6 +145,8 @@ build_ubuntu_focal_arm:
build_ubuntu_jammy: build_ubuntu_jammy:
stage: build stage: build
allow_failure: true allow_failure: true
tags:
- oci-fixed-amd
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -156,7 +165,7 @@ build_ubuntu_jammy_arm:
stage: build stage: build
allow_failure: true allow_failure: true
tags: tags:
- oci-fixed-arm64 - oci-fixed-arm
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -174,6 +183,8 @@ build_ubuntu_jammy_arm:
build_debian_buster: build_debian_buster:
stage: build stage: build
allow_failure: true allow_failure: true
tags:
- oci-fixed-amd
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -192,7 +203,7 @@ build_debian_buster_arm:
stage: build stage: build
allow_failure: true allow_failure: true
tags: tags:
- oci-fixed-arm64 - oci-fixed-arm
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -210,6 +221,8 @@ build_debian_buster_arm:
build_debian_bullseye: build_debian_bullseye:
stage: build stage: build
allow_failure: true allow_failure: true
tags:
- oci-fixed-amd
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -228,7 +241,7 @@ build_debian_bullseye_arm:
stage: build stage: build
allow_failure: true allow_failure: true
tags: tags:
- oci-fixed-arm64 - oci-fixed-arm
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -247,6 +260,8 @@ build_debian_bullseye_arm:
build_debian_bookworm: build_debian_bookworm:
stage: build stage: build
allow_failure: true allow_failure: true
tags:
- oci-fixed-amd
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -265,7 +280,7 @@ build_debian_bookworm_arm:
stage: build stage: build
allow_failure: true allow_failure: true
tags: tags:
- oci-fixed-arm64 - oci-fixed-arm
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -283,6 +298,8 @@ build_debian_bookworm_arm:
build_kali_rolling: build_kali_rolling:
stage: build stage: build
allow_failure: true allow_failure: true
tags:
- oci-fixed-amd
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -301,7 +318,7 @@ build_kali_rolling_arm:
stage: build stage: build
allow_failure: true allow_failure: true
tags: tags:
- oci-fixed-arm64 - oci-fixed-arm
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -319,6 +336,8 @@ build_kali_rolling_arm:
build_centos7: build_centos7:
stage: build stage: build
allow_failure: true allow_failure: true
tags:
- oci-fixed-amd
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -336,6 +355,8 @@ build_centos7:
build_oracle_8: build_oracle_8:
stage: build stage: build
allow_failure: true allow_failure: true
tags:
- oci-fixed-amd
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -354,7 +375,7 @@ build_oracle_8_arm:
stage: build stage: build
allow_failure: true allow_failure: true
tags: tags:
- oci-fixed-arm64 - oci-fixed-arm
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -372,6 +393,8 @@ build_oracle_8_arm:
build_oracle_9: build_oracle_9:
stage: build stage: build
allow_failure: true allow_failure: true
tags:
- oci-fixed-amd
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -390,7 +413,7 @@ build_oracle_9_arm:
stage: build stage: build
allow_failure: true allow_failure: true
tags: tags:
- oci-fixed-arm64 - oci-fixed-arm
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -408,6 +431,8 @@ build_oracle_9_arm:
build_opensuse_15: build_opensuse_15:
stage: build stage: build
allow_failure: true allow_failure: true
tags:
- oci-fixed-amd
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -426,7 +451,7 @@ build_opensuse_15_arm:
stage: build stage: build
allow_failure: true allow_failure: true
tags: tags:
- oci-fixed-arm64 - oci-fixed-arm
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -444,6 +469,8 @@ build_opensuse_15_arm:
build_fedora_thirtyseven: build_fedora_thirtyseven:
stage: build stage: build
allow_failure: true allow_failure: true
tags:
- oci-fixed-amd
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -462,7 +489,7 @@ build_fedora_thirtyseven_arm:
stage: build stage: build
allow_failure: true allow_failure: true
tags: tags:
- oci-fixed-arm64 - oci-fixed-arm
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -480,6 +507,8 @@ build_fedora_thirtyseven_arm:
build_fedora_thirtyeight: build_fedora_thirtyeight:
stage: build stage: build
allow_failure: true allow_failure: true
tags:
- oci-fixed-amd
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -498,7 +527,7 @@ build_fedora_thirtyeight_arm:
stage: build stage: build
allow_failure: true allow_failure: true
tags: tags:
- oci-fixed-arm64 - oci-fixed-arm
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -513,9 +542,49 @@ build_fedora_thirtyeight_arm:
paths: paths:
- output/ - output/
build_fedora_thirtynine:
stage: build
allow_failure: true
tags:
- oci-fixed-amd
before_script:
- *prepare_build
- *prepare_www
after_script:
- *prepare_artfacts
script:
- bash builder/build-package fedora thirtynine;
only:
variables:
- $BUILD_JOBS == 'all' || $BUILD_JOBS =~ $CI_JOB_NAME
artifacts:
paths:
- output/
build_fedora_thirtynine_arm:
stage: build
allow_failure: true
tags:
- oci-fixed-arm
before_script:
- *prepare_build
- *prepare_www
after_script:
- *prepare_artfacts
script:
- bash builder/build-package fedora thirtynine;
only:
variables:
- $BUILD_JOBS == 'all' || $BUILD_JOBS =~ $CI_JOB_NAME
artifacts:
paths:
- output/
build_alpine_317: build_alpine_317:
stage: build stage: build
allow_failure: true allow_failure: true
tags:
- oci-fixed-amd
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -534,7 +603,7 @@ build_alpine_317_arm:
stage: build stage: build
allow_failure: true allow_failure: true
tags: tags:
- oci-fixed-arm64 - oci-fixed-arm
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -551,6 +620,8 @@ build_alpine_317_arm:
test: test:
stage: test stage: test
tags:
- oci-fixed-amd
before_script: before_script:
- *prepare_build - *prepare_build
script: script:
@@ -560,6 +631,8 @@ test:
build_alpine_318: build_alpine_318:
stage: build stage: build
allow_failure: true allow_failure: true
tags:
- oci-fixed-amd
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -578,7 +651,7 @@ build_alpine_318_arm:
stage: build stage: build
allow_failure: true allow_failure: true
tags: tags:
- oci-fixed-arm64 - oci-fixed-arm
before_script: before_script:
- *prepare_build - *prepare_build
- *prepare_www - *prepare_www
@@ -593,9 +666,49 @@ build_alpine_318_arm:
paths: paths:
- output/ - output/
build_alpine_319:
stage: build
allow_failure: true
tags:
- oci-fixed-amd
before_script:
- *prepare_build
- *prepare_www
after_script:
- *prepare_artfacts
script:
- bash builder/build-package alpine 319;
only:
variables:
- $BUILD_JOBS == 'all' || $BUILD_JOBS =~ $CI_JOB_NAME
artifacts:
paths:
- output/
build_alpine_319_arm:
stage: build
allow_failure: true
tags:
- oci-fixed-arm
before_script:
- *prepare_build
- *prepare_www
after_script:
- *prepare_artfacts
script:
- bash builder/build-package alpine 319;
only:
variables:
- $BUILD_JOBS == 'all' || $BUILD_JOBS =~ $CI_JOB_NAME
artifacts:
paths:
- output/
upload: upload:
stage: upload stage: upload
image: ubuntu:focal image: ubuntu:focal
tags:
- oci-fixed-amd
artifacts: artifacts:
paths: paths:
- output/ - output/
@@ -633,6 +746,8 @@ upload_build_preview:
needs: ["upload"] needs: ["upload"]
dependencies: ["upload"] dependencies: ["upload"]
image: ubuntu:focal image: ubuntu:focal
tags:
- oci-fixed-amd
before_script: before_script:
- . .ci/upload.sh - . .ci/upload.sh
resource_group: upload_build_preview resource_group: upload_build_preview

2
.gitmodules vendored
View File

@@ -1,4 +1,4 @@
[submodule "kasmweb"] [submodule "kasmweb"]
path = kasmweb path = kasmweb
url = https://github.com/kasmtech/noVNC.git url = https://github.com/kasmtech/noVNC.git
branch = master branch = release/1.2.1

View File

@@ -0,0 +1,7 @@
FROM alpine:3.19
RUN apk add shadow bash
RUN useradd -m docker && echo "docker:docker" | chpasswd
USER docker

View File

@@ -0,0 +1,82 @@
FROM alpine:3.19
ENV KASMVNC_BUILD_OS alpine
ENV KASMVNC_BUILD_OS_CODENAME 319
ENV XORG_VER 1.20.14
RUN \
echo "**** install build deps ****" && \
apk add \
alpine-release \
alpine-sdk \
autoconf \
automake \
bash \
ca-certificates \
cmake \
coreutils \
curl \
eudev-dev \
font-cursor-misc \
font-misc-misc \
font-util-dev \
git \
grep \
jq \
libdrm-dev \
libepoxy-dev \
libjpeg-turbo-dev \
libjpeg-turbo-static \
libpciaccess-dev \
libtool \
libwebp-dev \
libx11-dev \
libxau-dev \
libxcb-dev \
libxcursor-dev \
libxcvt-dev \
libxdmcp-dev \
libxext-dev \
libxfont2-dev \
libxkbfile-dev \
libxrandr-dev \
libxshmfence-dev \
libxtst-dev \
mesa-dev \
mesa-dri-gallium \
meson \
nettle-dev \
openssl-dev \
pixman-dev \
procps \
shadow \
tar \
tzdata \
wayland-dev \
wayland-protocols \
xcb-util-dev \
xcb-util-image-dev \
xcb-util-keysyms-dev \
xcb-util-renderutil-dev \
xcb-util-wm-dev \
xinit \
xkbcomp \
xkbcomp-dev \
xkeyboard-config \
xorgproto \
xorg-server-common \
xorg-server-dev \
xtrans
ENV SCRIPTS_DIR=/tmp/scripts
COPY builder/scripts $SCRIPTS_DIR
RUN $SCRIPTS_DIR/build-webp
RUN $SCRIPTS_DIR/build-libjpeg-turbo
RUN useradd -m docker && echo "docker:docker" | chpasswd
COPY --chown=docker:docker . /src/
USER docker
ENTRYPOINT ["/src/builder/build.sh"]

View File

@@ -0,0 +1,86 @@
FROM fedora:39
ENV KASMVNC_BUILD_OS fedora
ENV KASMVNC_BUILD_OS_CODENAME thirtynine
ENV XORG_VER 1.20.14
RUN \
echo "**** install build deps ****" && \
dnf group install -y \
"C Development Tools and Libraries" \
"Development Tools" && \
dnf install -y \
autoconf \
automake \
bison \
byacc \
bzip2 \
cmake \
diffutils \
doxygen \
file \
flex \
fop \
gcc \
gcc-c++ \
git \
glibc-devel \
libdrm-devel \
libepoxy-devel \
libmd-devel \
libpciaccess-devel \
libtool \
libwebp-devel \
libX11-devel \
libXau-devel \
libxcb-devel \
libXcursor-devel \
libxcvt-devel \
libXdmcp-devel \
libXext-devel \
libXfont2-devel \
libxkbfile-devel \
libXrandr-devel \
libxshmfence-devel \
libXtst-devel \
mesa-libEGL-devel \
mesa-libgbm-devel \
mesa-libGL-devel \
meson \
mingw64-binutils \
mt-st \
nettle-devel \
openssl-devel \
patch \
pixman-devel \
wayland-devel \
wget \
which \
xcb-util-devel \
xcb-util-image-devel \
xcb-util-keysyms-devel \
xcb-util-renderutil-devel \
xcb-util-wm-devel \
xinit \
xkbcomp \
xkbcomp-devel \
xkeyboard-config \
xmlto \
xorg-x11-font-utils \
xorg-x11-proto-devel \
xorg-x11-server-common \
xorg-x11-server-devel \
xorg-x11-xtrans-devel \
xsltproc
ENV SCRIPTS_DIR=/tmp/scripts
COPY builder/scripts $SCRIPTS_DIR
RUN $SCRIPTS_DIR/build-webp
RUN $SCRIPTS_DIR/build-libjpeg-turbo
RUN useradd -m docker && echo "docker:docker" | chpasswd
COPY --chown=docker:docker . /src/
USER docker
ENTRYPOINT ["/src/builder/build.sh"]

View File

@@ -0,0 +1,13 @@
FROM fedora:39
RUN dnf install -y fedora-packager fedora-review
RUN dnf install -y tree vim less
RUN dnf install -y redhat-lsb-core
RUN dnf install -y dnf-plugins-core
COPY fedora/*.spec /tmp
RUN dnf builddep -y /tmp/*.spec
RUN useradd -m docker && echo "docker:docker" | chpasswd
USER docker

View File

@@ -198,6 +198,7 @@ generate_xstartup() {
cat <<-SCRIPT > "$xstartup_script" cat <<-SCRIPT > "$xstartup_script"
#!/bin/sh #!/bin/sh
set -x
$de_cmd $de_cmd
SCRIPT SCRIPT
chmod +x "$xstartup_script" chmod +x "$xstartup_script"

View File

@@ -1,5 +1,5 @@
Name: kasmvncserver Name: kasmvncserver
Version: 1.2.0 Version: 1.3.1
Release: 1%{?dist} Release: 1%{?dist}
Summary: VNC server accessible from a web browser Summary: VNC server accessible from a web browser
@@ -83,6 +83,18 @@ cd $DST_MAN && ln -s vncpasswd.1 kasmvncpasswd.1;
%doc /usr/share/doc/kasmvncserver/README.md %doc /usr/share/doc/kasmvncserver/README.md
%changelog %changelog
* Tue Mar 12 2024 KasmTech <info@kasmweb.com> - 1.3.1-1
- Fix exception thrown on Firefox 124 and higher
- Fix artifacts on high resolution secondary screens
- Fixes for touch support on primary and secondary screens
- Fix for Oculus keyboard input
* Mon Feb 05 2024 KasmTech <info@kasmweb.com> - 1.3.0-1
- Multi-monitor support.
- Increased performance with watermark enabled.
- Added support for Fedora 39 and Alpine 319.
- Allow special characters in usernames.
- Better logging of client settings when client connects or changes settings.
- Add support for rotation of text-based watermark.
* Fri Aug 25 2023 KasmTech <info@kasmweb.com> - 1.2.0-1 * Fri Aug 25 2023 KasmTech <info@kasmweb.com> - 1.2.0-1
- Add support for Unix relays for bidirectional communication between noVNC - Add support for Unix relays for bidirectional communication between noVNC
and containerized applications. and containerized applications.

View File

@@ -550,7 +550,7 @@ void GetAPIMessager::netGetBottleneckStats(char *buf, uint32_t len) {
const char *id = it->first.c_str(); const char *id = it->first.c_str();
const char *data = it->second.c_str(); const char *data = it->second.c_str();
const char *at = strchr(id, '@'); const char *at = strrchr(id, '@');
if (!at) if (!at)
continue; continue;

View File

@@ -40,7 +40,7 @@ using namespace network;
static rfb::LogWriter vlog("WebUdp"); static rfb::LogWriter vlog("WebUdp");
static WuHost *host = NULL; static WuHost *host = NULL;
rfb::IntParameter udpSize("udpSize", "UDP packet data size", 1300, 500, 1400); rfb::IntParameter udpSize("udpSize", "UDP packet data size", 1296, 500, 1400);
extern settings_t settings; extern settings_t settings;
@@ -95,10 +95,11 @@ void *udpserver(void *nport) {
} }
// Send one packet, split into N UDP-sized pieces // Send one packet, split into N UDP-sized pieces
static uint8_t udpsend(WuClient *client, const uint8_t *data, unsigned len, uint32_t *id) { static uint8_t udpsend(WuClient *client, const uint8_t *data, unsigned len, uint32_t *id,
const uint32_t *frame) {
const uint32_t DATA_MAX = udpSize; const uint32_t DATA_MAX = udpSize;
uint8_t buf[1400 + sizeof(uint32_t) * 4]; uint8_t buf[1400 + sizeof(uint32_t) * 5];
const uint32_t pieces = (len / DATA_MAX) + ((len % DATA_MAX) ? 1 : 0); const uint32_t pieces = (len / DATA_MAX) + ((len % DATA_MAX) ? 1 : 0);
uint32_t i; uint32_t i;
@@ -111,12 +112,13 @@ static uint8_t udpsend(WuClient *client, const uint8_t *data, unsigned len, uint
memcpy(&buf[4], &i, sizeof(uint32_t)); memcpy(&buf[4], &i, sizeof(uint32_t));
memcpy(&buf[8], &pieces, sizeof(uint32_t)); memcpy(&buf[8], &pieces, sizeof(uint32_t));
memcpy(&buf[12], &hash, sizeof(uint32_t)); memcpy(&buf[12], &hash, sizeof(uint32_t));
memcpy(&buf[16], frame, sizeof(uint32_t));
memcpy(&buf[16], data, curlen); memcpy(&buf[20], data, curlen);
data += curlen; data += curlen;
len -= curlen; len -= curlen;
if (WuHostSendBinary(host, client, buf, curlen + sizeof(uint32_t) * 4) < 0) if (WuHostSendBinary(host, client, buf, curlen + sizeof(uint32_t) * 5) < 0)
return 1; return 1;
} }
@@ -125,7 +127,8 @@ static uint8_t udpsend(WuClient *client, const uint8_t *data, unsigned len, uint
return 0; return 0;
} }
UdpStream::UdpStream(): OutStream(), client(NULL), total_len(0), id(0), failed(false) { UdpStream::UdpStream(): OutStream(), client(NULL), total_len(0), id(0), failed(false),
frame(0) {
ptr = data; ptr = data;
end = data + UDPSTREAM_BUFSIZE; end = data + UDPSTREAM_BUFSIZE;
@@ -137,7 +140,7 @@ void UdpStream::flush() {
total_len += len; total_len += len;
if (client) { if (client) {
if (udpsend(client, data, len, &id)) { if (udpsend(client, data, len, &id, &frame)) {
vlog.error("Error sending udp, client gone?"); vlog.error("Error sending udp, client gone?");
failed = true; failed = true;
} }

View File

@@ -40,6 +40,10 @@ namespace network {
client = cli; client = cli;
} }
void setFrameNumber(const unsigned in) {
frame = in;
}
bool isFailed() const; bool isFailed() const;
void clearFailed(); void clearFailed();
private: private:
@@ -48,6 +52,7 @@ namespace network {
size_t total_len; size_t total_len;
uint32_t id; uint32_t id;
bool failed; bool failed;
uint32_t frame;
}; };
} }

View File

@@ -33,7 +33,6 @@
#include <openssl/sha.h> /* sha1 hash */ #include <openssl/sha.h> /* sha1 hash */
#include "websocket.h" #include "websocket.h"
#include "jsonescape.h" #include "jsonescape.h"
#include "kasmpasswd.h"
#include <network/Blacklist.h> #include <network/Blacklist.h>
/* /*
@@ -1756,7 +1755,7 @@ ws_ctx_t *do_handshake(int sock, char * const ip) {
} }
unsigned char owner = 0; unsigned char owner = 0;
char inuser[32] = "-"; char inuser[USERNAME_LEN] = "-";
if (!settings.disablebasicauth) { if (!settings.disablebasicauth) {
const char *hdr = strstr(handshake, "Authorization: Basic "); const char *hdr = strstr(handshake, "Authorization: Basic ");
if (!hdr) { if (!hdr) {
@@ -1794,7 +1793,7 @@ ws_ctx_t *do_handshake(int sock, char * const ip) {
if (resppw && *resppw) if (resppw && *resppw)
resppw++; resppw++;
if (settings.passwdfile) { if (settings.passwdfile) {
if (resppw && *resppw && resppw - response < 32) { if (resppw && *resppw && resppw - response < USERNAME_LEN + 1) {
char pwbuf[4096]; char pwbuf[4096];
struct kasmpasswd_t *set = readkasmpasswd(settings.passwdfile); struct kasmpasswd_t *set = readkasmpasswd(settings.passwdfile);
if (!set->num) { if (!set->num) {

View File

@@ -2,6 +2,7 @@
#include <stdint.h> #include <stdint.h>
#include "GetAPIEnums.h" #include "GetAPIEnums.h"
#include "datelog.h" #include "datelog.h"
#include "kasmpasswd.h"
#define BUFSIZE 65536 #define BUFSIZE 65536
#define DBUFSIZE (BUFSIZE * 3) / 4 - 20 #define DBUFSIZE (BUFSIZE * 3) / 4 - 20
@@ -57,7 +58,7 @@ typedef struct {
char *tin_buf; char *tin_buf;
char *tout_buf; char *tout_buf;
char user[32]; char user[USERNAME_LEN];
char ip[64]; char ip[64];
} ws_ctx_t; } ws_ctx_t;

View File

@@ -24,6 +24,7 @@
#include <rfb/Exception.h> #include <rfb/Exception.h>
#include <rfb/encodings.h> #include <rfb/encodings.h>
#include <rfb/ledStates.h> #include <rfb/ledStates.h>
#include <rfb/LogWriter.h>
#include <rfb/clipboardTypes.h> #include <rfb/clipboardTypes.h>
#include <rfb/ConnParams.h> #include <rfb/ConnParams.h>
#include <rfb/ServerCore.h> #include <rfb/ServerCore.h>
@@ -32,6 +33,19 @@
using namespace rfb; using namespace rfb;
static LogWriter vlog("CP");
static void clientparlog(const char name[], const bool applied) {
vlog.debug("Client sent config param %s, %s",
name,
applied ? "applied" : "ignored due to -IgnoreClientSettingsKasm/lacking perms");
}
static void clientparlog(const char name[], int val, const bool applied) {
vlog.debug("Client sent config param %s %d, %s",
name, val,
applied ? "applied" : "ignored due to -IgnoreClientSettingsKasm/lacking perms");
}
ConnParams::ConnParams() ConnParams::ConnParams()
: majorVersion(0), minorVersion(0), : majorVersion(0), minorVersion(0),
width(0), height(0), useCopyRect(false), width(0), height(0), useCopyRect(false),
@@ -147,54 +161,71 @@ void ConnParams::setEncodings(int nEncodings, const rdr::S32* encodings)
switch (encodings[i]) { switch (encodings[i]) {
case encodingCopyRect: case encodingCopyRect:
useCopyRect = true; useCopyRect = true;
clientparlog("copyrect", true);
break; break;
case pseudoEncodingCursor: case pseudoEncodingCursor:
supportsLocalCursor = true; supportsLocalCursor = true;
clientparlog("cursor", true);
break; break;
case pseudoEncodingXCursor: case pseudoEncodingXCursor:
supportsLocalXCursor = true; supportsLocalXCursor = true;
clientparlog("xcursor", true);
break; break;
case pseudoEncodingCursorWithAlpha: case pseudoEncodingCursorWithAlpha:
supportsLocalCursorWithAlpha = true; supportsLocalCursorWithAlpha = true;
clientparlog("cursorWithAlpha", true);
break; break;
case pseudoEncodingVMwareCursor: case pseudoEncodingVMwareCursor:
supportsVMWareCursor = true; supportsVMWareCursor = true;
clientparlog("vmwareCursor", true);
break; break;
case pseudoEncodingDesktopSize: case pseudoEncodingDesktopSize:
supportsDesktopResize = true; supportsDesktopResize = true;
clientparlog("desktopSize", true);
break; break;
case pseudoEncodingExtendedDesktopSize: case pseudoEncodingExtendedDesktopSize:
supportsExtendedDesktopSize = true; supportsExtendedDesktopSize = true;
clientparlog("extendedDesktopSize", true);
break; break;
case pseudoEncodingVMwareCursorPosition: case pseudoEncodingVMwareCursorPosition:
supportsCursorPosition = true; supportsCursorPosition = true;
clientparlog("vmwareCursorPosition", true);
break; break;
case pseudoEncodingDesktopName: case pseudoEncodingDesktopName:
supportsDesktopRename = true; supportsDesktopRename = true;
clientparlog("desktopRename", true);
break; break;
case pseudoEncodingLastRect: case pseudoEncodingLastRect:
supportsLastRect = true; supportsLastRect = true;
clientparlog("lastRect", true);
break; break;
case pseudoEncodingLEDState: case pseudoEncodingLEDState:
supportsLEDState = true; supportsLEDState = true;
clientparlog("ledState", true);
break; break;
case pseudoEncodingQEMUKeyEvent: case pseudoEncodingQEMUKeyEvent:
supportsQEMUKeyEvent = true; supportsQEMUKeyEvent = true;
clientparlog("qemuKeyEvent", true);
break; break;
case pseudoEncodingWEBP: case pseudoEncodingWEBP:
supportsWEBP = true; supportsWEBP = true;
clientparlog("webp", true);
break; break;
case pseudoEncodingQOI: case pseudoEncodingQOI:
supportsQOI = true; supportsQOI = true;
clientparlog("qoi", true);
break; break;
case pseudoEncodingFence: case pseudoEncodingFence:
supportsFence = true; supportsFence = true;
clientparlog("fence", true);
break; break;
case pseudoEncodingContinuousUpdates: case pseudoEncodingContinuousUpdates:
supportsContinuousUpdates = true; supportsContinuousUpdates = true;
clientparlog("continuousUpdates", true);
break; break;
case pseudoEncodingExtendedClipboard: case pseudoEncodingExtendedClipboard:
supportsExtendedClipboard = true; supportsExtendedClipboard = true;
clientparlog("extendedClipboard", true);
break; break;
case pseudoEncodingSubsamp1X: case pseudoEncodingSubsamp1X:
subsampling = subsampleNone; subsampling = subsampleNone;
@@ -215,8 +246,12 @@ void ConnParams::setEncodings(int nEncodings, const rdr::S32* encodings)
subsampling = subsample16X; subsampling = subsample16X;
break; break;
case pseudoEncodingPreferBandwidth: case pseudoEncodingPreferBandwidth:
if (!rfb::Server::ignoreClientSettingsKasm && canChangeSettings) if (!rfb::Server::ignoreClientSettingsKasm && canChangeSettings) {
Server::preferBandwidth.setParam(true); Server::preferBandwidth.setParam(true);
clientparlog("preferBandwidth", true);
} else {
clientparlog("preferBandwidth", false);
}
break; break;
case pseudoEncodingMaxVideoResolution: case pseudoEncodingMaxVideoResolution:
if (!rfb::Server::ignoreClientSettingsKasm && canChangeSettings) if (!rfb::Server::ignoreClientSettingsKasm && canChangeSettings)
@@ -225,57 +260,133 @@ void ConnParams::setEncodings(int nEncodings, const rdr::S32* encodings)
} }
if (encodings[i] >= pseudoEncodingCompressLevel0 && if (encodings[i] >= pseudoEncodingCompressLevel0 &&
encodings[i] <= pseudoEncodingCompressLevel9) encodings[i] <= pseudoEncodingCompressLevel9) {
compressLevel = encodings[i] - pseudoEncodingCompressLevel0; compressLevel = encodings[i] - pseudoEncodingCompressLevel0;
clientparlog("compressLevel", compressLevel, true);
}
if (encodings[i] >= pseudoEncodingQualityLevel0 && if (encodings[i] >= pseudoEncodingQualityLevel0 &&
encodings[i] <= pseudoEncodingQualityLevel9) encodings[i] <= pseudoEncodingQualityLevel9) {
qualityLevel = encodings[i] - pseudoEncodingQualityLevel0; qualityLevel = encodings[i] - pseudoEncodingQualityLevel0;
clientparlog("qualityLevel", qualityLevel, true);
}
if (encodings[i] >= pseudoEncodingFineQualityLevel0 && if (encodings[i] >= pseudoEncodingFineQualityLevel0 &&
encodings[i] <= pseudoEncodingFineQualityLevel100) encodings[i] <= pseudoEncodingFineQualityLevel100) {
fineQualityLevel = encodings[i] - pseudoEncodingFineQualityLevel0; fineQualityLevel = encodings[i] - pseudoEncodingFineQualityLevel0;
clientparlog("fineQualityLevel", fineQualityLevel, true);
}
if (!rfb::Server::ignoreClientSettingsKasm && canChangeSettings) { if (!rfb::Server::ignoreClientSettingsKasm && canChangeSettings) {
if (encodings[i] >= pseudoEncodingJpegVideoQualityLevel0 && if (encodings[i] >= pseudoEncodingJpegVideoQualityLevel0 &&
encodings[i] <= pseudoEncodingJpegVideoQualityLevel9) encodings[i] <= pseudoEncodingJpegVideoQualityLevel9) {
Server::jpegVideoQuality.setParam(encodings[i] - pseudoEncodingJpegVideoQualityLevel0); Server::jpegVideoQuality.setParam(encodings[i] - pseudoEncodingJpegVideoQualityLevel0);
clientparlog("jpegVideoQuality", encodings[i] - pseudoEncodingJpegVideoQualityLevel0, true);
}
if (encodings[i] >= pseudoEncodingWebpVideoQualityLevel0 && if (encodings[i] >= pseudoEncodingWebpVideoQualityLevel0 &&
encodings[i] <= pseudoEncodingWebpVideoQualityLevel9) encodings[i] <= pseudoEncodingWebpVideoQualityLevel9) {
Server::webpVideoQuality.setParam(encodings[i] - pseudoEncodingWebpVideoQualityLevel0); Server::webpVideoQuality.setParam(encodings[i] - pseudoEncodingWebpVideoQualityLevel0);
clientparlog("webpVideoQuality", encodings[i] - pseudoEncodingWebpVideoQualityLevel0, true);
}
if (encodings[i] >= pseudoEncodingTreatLosslessLevel0 && if (encodings[i] >= pseudoEncodingTreatLosslessLevel0 &&
encodings[i] <= pseudoEncodingTreatLosslessLevel10) encodings[i] <= pseudoEncodingTreatLosslessLevel10) {
Server::treatLossless.setParam(encodings[i] - pseudoEncodingTreatLosslessLevel0); Server::treatLossless.setParam(encodings[i] - pseudoEncodingTreatLosslessLevel0);
clientparlog("treatLossless", encodings[i] - pseudoEncodingTreatLosslessLevel0, true);
}
if (encodings[i] >= pseudoEncodingDynamicQualityMinLevel0 && if (encodings[i] >= pseudoEncodingDynamicQualityMinLevel0 &&
encodings[i] <= pseudoEncodingDynamicQualityMinLevel9) encodings[i] <= pseudoEncodingDynamicQualityMinLevel9) {
Server::dynamicQualityMin.setParam(encodings[i] - pseudoEncodingDynamicQualityMinLevel0); Server::dynamicQualityMin.setParam(encodings[i] - pseudoEncodingDynamicQualityMinLevel0);
clientparlog("dynamicQualityMin", encodings[i] - pseudoEncodingDynamicQualityMinLevel0, true);
}
if (encodings[i] >= pseudoEncodingDynamicQualityMaxLevel0 && if (encodings[i] >= pseudoEncodingDynamicQualityMaxLevel0 &&
encodings[i] <= pseudoEncodingDynamicQualityMaxLevel9) encodings[i] <= pseudoEncodingDynamicQualityMaxLevel9) {
Server::dynamicQualityMax.setParam(encodings[i] - pseudoEncodingDynamicQualityMaxLevel0); Server::dynamicQualityMax.setParam(encodings[i] - pseudoEncodingDynamicQualityMaxLevel0);
clientparlog("dynamicQualityMax", encodings[i] - pseudoEncodingDynamicQualityMaxLevel0, true);
}
if (encodings[i] >= pseudoEncodingVideoAreaLevel1 && if (encodings[i] >= pseudoEncodingVideoAreaLevel1 &&
encodings[i] <= pseudoEncodingVideoAreaLevel100) encodings[i] <= pseudoEncodingVideoAreaLevel100) {
Server::videoArea.setParam(encodings[i] - pseudoEncodingVideoAreaLevel1 + 1); Server::videoArea.setParam(encodings[i] - pseudoEncodingVideoAreaLevel1 + 1);
clientparlog("videoArea", encodings[i] - pseudoEncodingVideoAreaLevel1 + 1, true);
}
if (encodings[i] >= pseudoEncodingVideoTimeLevel0 && if (encodings[i] >= pseudoEncodingVideoTimeLevel0 &&
encodings[i] <= pseudoEncodingVideoTimeLevel100) encodings[i] <= pseudoEncodingVideoTimeLevel100) {
Server::videoTime.setParam(encodings[i] - pseudoEncodingVideoTimeLevel0); Server::videoTime.setParam(encodings[i] - pseudoEncodingVideoTimeLevel0);
clientparlog("videoTime", encodings[i] - pseudoEncodingVideoTimeLevel0, true);
}
if (encodings[i] >= pseudoEncodingVideoOutTimeLevel1 && if (encodings[i] >= pseudoEncodingVideoOutTimeLevel1 &&
encodings[i] <= pseudoEncodingVideoOutTimeLevel100) encodings[i] <= pseudoEncodingVideoOutTimeLevel100) {
Server::videoOutTime.setParam(encodings[i] - pseudoEncodingVideoOutTimeLevel1 + 1); Server::videoOutTime.setParam(encodings[i] - pseudoEncodingVideoOutTimeLevel1 + 1);
clientparlog("videoOutTime", encodings[i] - pseudoEncodingVideoOutTimeLevel1 + 1, true);
}
if (encodings[i] >= pseudoEncodingFrameRateLevel10 && if (encodings[i] >= pseudoEncodingFrameRateLevel10 &&
encodings[i] <= pseudoEncodingFrameRateLevel60) encodings[i] <= pseudoEncodingFrameRateLevel60) {
Server::frameRate.setParam(encodings[i] - pseudoEncodingFrameRateLevel10 + 10); Server::frameRate.setParam(encodings[i] - pseudoEncodingFrameRateLevel10 + 10);
clientparlog("frameRate", encodings[i] - pseudoEncodingFrameRateLevel10 + 10, true);
}
if (encodings[i] >= pseudoEncodingVideoScalingLevel0 && if (encodings[i] >= pseudoEncodingVideoScalingLevel0 &&
encodings[i] <= pseudoEncodingVideoScalingLevel9) encodings[i] <= pseudoEncodingVideoScalingLevel9) {
Server::videoScaling.setParam(encodings[i] - pseudoEncodingVideoScalingLevel0); Server::videoScaling.setParam(encodings[i] - pseudoEncodingVideoScalingLevel0);
clientparlog("videoScaling", encodings[i] - pseudoEncodingVideoScalingLevel0, true);
}
} else {
if (encodings[i] >= pseudoEncodingJpegVideoQualityLevel0 &&
encodings[i] <= pseudoEncodingJpegVideoQualityLevel9) {
clientparlog("jpegVideoQuality", encodings[i] - pseudoEncodingJpegVideoQualityLevel0, false);
}
if (encodings[i] >= pseudoEncodingWebpVideoQualityLevel0 &&
encodings[i] <= pseudoEncodingWebpVideoQualityLevel9) {
clientparlog("webpVideoQuality", encodings[i] - pseudoEncodingWebpVideoQualityLevel0, false);
}
if (encodings[i] >= pseudoEncodingTreatLosslessLevel0 &&
encodings[i] <= pseudoEncodingTreatLosslessLevel10) {
clientparlog("treatLossless", encodings[i] - pseudoEncodingTreatLosslessLevel0, false);
}
if (encodings[i] >= pseudoEncodingDynamicQualityMinLevel0 &&
encodings[i] <= pseudoEncodingDynamicQualityMinLevel9) {
clientparlog("dynamicQualityMin", encodings[i] - pseudoEncodingDynamicQualityMinLevel0, false);
}
if (encodings[i] >= pseudoEncodingDynamicQualityMaxLevel0 &&
encodings[i] <= pseudoEncodingDynamicQualityMaxLevel9) {
clientparlog("dynamicQualityMax", encodings[i] - pseudoEncodingDynamicQualityMaxLevel0, false);
}
if (encodings[i] >= pseudoEncodingVideoAreaLevel1 &&
encodings[i] <= pseudoEncodingVideoAreaLevel100) {
clientparlog("videoArea", encodings[i] - pseudoEncodingVideoAreaLevel1 + 1, false);
}
if (encodings[i] >= pseudoEncodingVideoTimeLevel0 &&
encodings[i] <= pseudoEncodingVideoTimeLevel100) {
clientparlog("videoTime", encodings[i] - pseudoEncodingVideoTimeLevel0, false);
}
if (encodings[i] >= pseudoEncodingVideoOutTimeLevel1 &&
encodings[i] <= pseudoEncodingVideoOutTimeLevel100) {
clientparlog("videoOutTime", encodings[i] - pseudoEncodingVideoOutTimeLevel1 + 1, false);
}
if (encodings[i] >= pseudoEncodingFrameRateLevel10 &&
encodings[i] <= pseudoEncodingFrameRateLevel60) {
clientparlog("frameRate", encodings[i] - pseudoEncodingFrameRateLevel10 + 10, false);
}
if (encodings[i] >= pseudoEncodingVideoScalingLevel0 &&
encodings[i] <= pseudoEncodingVideoScalingLevel9) {
clientparlog("videoScaling", encodings[i] - pseudoEncodingVideoScalingLevel0, false);
}
} }
if (encodings[i] > 0) if (encodings[i] > 0)

View File

@@ -363,6 +363,9 @@ void EncodeManager::doUpdate(bool allowLossy, const Region& changed_,
unsigned screenArea; unsigned screenArea;
updates++; updates++;
if (conn->cp.supportsUdp)
((network::UdpStream *) conn->getOutStream(conn->cp.supportsUdp))->setFrameNumber(updates);
// The video resolution may have changed, check it // The video resolution may have changed, check it
if (conn->cp.kasmPassed[ConnParams::KASM_MAX_VIDEO_RESOLUTION]) if (conn->cp.kasmPassed[ConnParams::KASM_MAX_VIDEO_RESOLUTION])
@@ -420,9 +423,6 @@ void EncodeManager::doUpdate(bool allowLossy, const Region& changed_,
nRects++; nRects++;
} }
if (watermarkData)
packWatermark(changed);
conn->writer()->writeFramebufferUpdateStart(nRects); conn->writer()->writeFramebufferUpdateStart(nRects);
writeCopyRects(copied, copyDelta); writeCopyRects(copied, copyDelta);
@@ -440,7 +440,7 @@ void EncodeManager::doUpdate(bool allowLossy, const Region& changed_,
if (!videoDetected) // In case detection happened between the calls if (!videoDetected) // In case detection happened between the calls
writeRects(cursorRegion, renderedCursor); writeRects(cursorRegion, renderedCursor);
if (watermarkData) { if (watermarkData && conn->sendWatermark()) {
beforeLength = conn->getOutStream(conn->cp.supportsUdp)->length(); beforeLength = conn->getOutStream(conn->cp.supportsUdp)->length();
const Rect rect(0, 0, pb->width(), pb->height()); const Rect rect(0, 0, pb->width(), pb->height());

View File

@@ -198,6 +198,10 @@ namespace rfb {
std::vector<unsigned char> data; std::vector<unsigned char> data;
}; };
virtual bool sendWatermark() const {
return false;
}
protected: protected:
void setState(stateEnum s) { state_ = s; } void setState(stateEnum s) { state_ = s; }

View File

@@ -171,6 +171,9 @@ void SMsgReader::readSetMaxVideoResolution()
if (!rfb::Server::ignoreClientSettingsKasm && handler->canChangeKasmSettings()) { if (!rfb::Server::ignoreClientSettingsKasm && handler->canChangeKasmSettings()) {
sprintf(tmp, "%ux%u", width, height); sprintf(tmp, "%ux%u", width, height);
rfb::Server::maxVideoResolution.setParam(tmp); rfb::Server::maxVideoResolution.setParam(tmp);
vlog.debug("Client sent config param maxVideoResolution %ux%u, applied", width, height);
} else {
vlog.debug("Client sent config param maxVideoResolution %ux%u, ignored due to -IgnoreClientSettingsKasm/lacking perms", width, height);
} }
} }

View File

@@ -39,7 +39,7 @@ static LogWriter vlog("SMsgWriter");
SMsgWriter::SMsgWriter(ConnParams* cp_, rdr::OutStream* os_, rdr::OutStream* udps_) SMsgWriter::SMsgWriter(ConnParams* cp_, rdr::OutStream* os_, rdr::OutStream* udps_)
: cp(cp_), os(os_), udps(udps_), : cp(cp_), os(os_), udps(udps_),
nRectsInUpdate(0), nRectsInHeader(0), nRectsInUpdate(0), dataRectsInUpdate(0), nRectsInHeader(0),
needSetDesktopSize(false), needExtendedDesktopSize(false), needSetDesktopSize(false), needExtendedDesktopSize(false),
needSetDesktopName(false), needSetCursor(false), needSetDesktopName(false), needSetCursor(false),
needSetXCursor(false), needSetCursorWithAlpha(false), needSetXCursor(false), needSetCursorWithAlpha(false),
@@ -340,7 +340,7 @@ void SMsgWriter::writeFramebufferUpdateStart(int nRects)
os->writeU16(nRects); os->writeU16(nRects);
nRectsInUpdate = 0; nRectsInUpdate = dataRectsInUpdate = 0;
if (nRects == 0xFFFF) if (nRects == 0xFFFF)
nRectsInHeader = 0; nRectsInHeader = 0;
else else
@@ -365,7 +365,7 @@ void SMsgWriter::writeFramebufferUpdateEnd()
// Send an UDP flip marker, if needed // Send an UDP flip marker, if needed
if (cp->supportsUdp) { if (cp->supportsUdp) {
udps->writeS16(0); udps->writeS16(dataRectsInUpdate);
udps->writeS16(0); udps->writeS16(0);
udps->writeU16(0); udps->writeU16(0);
udps->writeU16(0); udps->writeU16(0);
@@ -394,6 +394,7 @@ void SMsgWriter::startRect(const Rect& r, int encoding)
{ {
if (++nRectsInUpdate > nRectsInHeader && nRectsInHeader) if (++nRectsInUpdate > nRectsInHeader && nRectsInHeader)
throw Exception("SMsgWriter::startRect: nRects out of sync"); throw Exception("SMsgWriter::startRect: nRects out of sync");
++dataRectsInUpdate;
if (cp->supportsUdp) { if (cp->supportsUdp) {
udps->writeS16(r.tl.x); udps->writeS16(r.tl.x);

View File

@@ -165,6 +165,7 @@ namespace rfb {
rdr::OutStream* udps; rdr::OutStream* udps;
int nRectsInUpdate; int nRectsInUpdate;
int dataRectsInUpdate;
int nRectsInHeader; int nRectsInHeader;
bool needSetDesktopSize; bool needSetDesktopSize;

View File

@@ -201,6 +201,10 @@ rfb::IntParameter rfb::Server::DLP_WatermarkTimeOffsetMinutes
("DLP_WatermarkTimeOffsetMinutes", ("DLP_WatermarkTimeOffsetMinutes",
"Offset from UTC for -DLP_WatermarkText, minutes", "Offset from UTC for -DLP_WatermarkText, minutes",
0, -24 * 60, 24 * 60); 0, -24 * 60, 24 * 60);
rfb::IntParameter rfb::Server::DLP_WatermarkTextAngle
("DLP_WatermarkTextAngle",
"Angle for -DLP_WatermarkText rotation",
0, -359, 359);
rfb::StringParameter rfb::Server::DLP_WatermarkImage rfb::StringParameter rfb::Server::DLP_WatermarkImage
("DLP_WatermarkImage", ("DLP_WatermarkImage",
"PNG file to use as a watermark", "PNG file to use as a watermark",

View File

@@ -52,6 +52,7 @@ namespace rfb {
static IntParameter DLP_WatermarkFontSize; static IntParameter DLP_WatermarkFontSize;
static IntParameter DLP_WatermarkTimeOffset; static IntParameter DLP_WatermarkTimeOffset;
static IntParameter DLP_WatermarkTimeOffsetMinutes; static IntParameter DLP_WatermarkTimeOffsetMinutes;
static IntParameter DLP_WatermarkTextAngle;
static StringParameter DLP_ClipLog; static StringParameter DLP_ClipLog;
static StringParameter DLP_Region; static StringParameter DLP_Region;
static StringParameter DLP_Clip_Types; static StringParameter DLP_Clip_Types;

View File

@@ -88,8 +88,8 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
wordfree(&wexp); wordfree(&wexp);
user[0] = '\0'; user[0] = '\0';
const char *at = strchr(peerEndpoint.buf, '@'); const char *at = strrchr(peerEndpoint.buf, '@');
if (at && at - peerEndpoint.buf > 1 && at - peerEndpoint.buf < 32) { if (at && at - peerEndpoint.buf > 1 && at - peerEndpoint.buf < USERNAME_LEN) {
memcpy(user, peerEndpoint.buf, at - peerEndpoint.buf); memcpy(user, peerEndpoint.buf, at - peerEndpoint.buf);
user[at - peerEndpoint.buf] = '\0'; user[at - peerEndpoint.buf] = '\0';
} }
@@ -997,8 +997,8 @@ void VNCSConnectionST::setDesktopSize(int fb_width, int fb_height,
{ {
unsigned int result; unsigned int result;
if (!(accessRights & AccessSetDesktopSize)) return; if (!(accessRights & AccessSetDesktopSize)) goto justnotify;
if (!rfb::Server::acceptSetDesktopSize) return; if (!rfb::Server::acceptSetDesktopSize) goto justnotify;
// Don't bother the desktop with an invalid configuration // Don't bother the desktop with an invalid configuration
if (!layout.validate(fb_width, fb_height)) { if (!layout.validate(fb_width, fb_height)) {
@@ -1021,6 +1021,14 @@ void VNCSConnectionST::setDesktopSize(int fb_width, int fb_height,
throw Exception("Desktop configured a different screen layout than requested"); throw Exception("Desktop configured a different screen layout than requested");
server->notifyScreenLayoutChange(this); server->notifyScreenLayoutChange(this);
} }
return;
justnotify:
writer()->writeExtendedDesktopSize(reasonClient, resultProhibited,
server->pb->getRect().width(),
server->pb->getRect().height(),
server->screenLayout);
} }
void VNCSConnectionST::fence(rdr::U32 flags, unsigned len, const char data[]) void VNCSConnectionST::fence(rdr::U32 flags, unsigned len, const char data[])
@@ -1635,7 +1643,7 @@ void VNCSConnectionST::sendStats(const bool toClient) {
void VNCSConnectionST::handleFrameStats(rdr::U32 all, rdr::U32 render) void VNCSConnectionST::handleFrameStats(rdr::U32 all, rdr::U32 render)
{ {
if (server->apimessager) { if (server->apimessager) {
const char *at = strchr(peerEndpoint.buf, '@'); const char *at = strrchr(peerEndpoint.buf, '@');
if (!at) if (!at)
at = peerEndpoint.buf; at = peerEndpoint.buf;
else else

View File

@@ -35,6 +35,8 @@
#include <rfb/Timer.h> #include <rfb/Timer.h>
#include <rfb/unixRelayLimits.h> #include <rfb/unixRelayLimits.h>
#include "kasmpasswd.h"
namespace rfb { namespace rfb {
class VNCServerST; class VNCServerST;
@@ -213,6 +215,10 @@ namespace rfb {
virtual void sendUnixRelayData(const char name[], const unsigned char *buf, virtual void sendUnixRelayData(const char name[], const unsigned char *buf,
const unsigned len); const unsigned len);
bool sendWatermark() const {
return server->sendWatermark;
}
private: private:
// SConnection callbacks // SConnection callbacks
@@ -318,7 +324,7 @@ namespace rfb {
rdr::U64 bstats_total[BS_NUM]; rdr::U64 bstats_total[BS_NUM];
struct timeval connStart; struct timeval connStart;
char user[32]; char user[USERNAME_LEN];
char kasmpasswdpath[4096]; char kasmpasswdpath[4096];
bool needsPermCheck; bool needsPermCheck;

View File

@@ -135,7 +135,7 @@ VNCServerST::VNCServerST(const char* name_, SDesktop* desktop_)
queryConnectionHandler(0), keyRemapper(&KeyRemapper::defInstance), queryConnectionHandler(0), keyRemapper(&KeyRemapper::defInstance),
lastConnectionTime(0), disableclients(false), lastConnectionTime(0), disableclients(false),
frameTimer(this), apimessager(NULL), trackingFrameStats(0), frameTimer(this), apimessager(NULL), trackingFrameStats(0),
clipboardId(0) clipboardId(0), sendWatermark(false)
{ {
lastUserInputTime = lastDisconnectTime = time(0); lastUserInputTime = lastDisconnectTime = time(0);
slog.debug("creating single-threaded server %s", name.buf); slog.debug("creating single-threaded server %s", name.buf);
@@ -223,6 +223,9 @@ VNCServerST::VNCServerST(const char* name_, SDesktop* desktop_)
trackingClient[0] = 0; trackingClient[0] = 0;
if (watermarkData)
sendWatermark = true;
if (Server::selfBench) if (Server::selfBench)
SelfBench(); SelfBench();
} }
@@ -279,6 +282,9 @@ void VNCServerST::addSocket(network::Socket* sock, bool outgoing)
VNCSConnectionST* client = new VNCSConnectionST(this, sock, outgoing); VNCSConnectionST* client = new VNCSConnectionST(this, sock, outgoing);
client->init(); client->init();
if (watermarkData)
sendWatermark = true;
} }
void VNCServerST::removeSocket(network::Socket* sock) { void VNCServerST::removeSocket(network::Socket* sock) {
@@ -814,7 +820,7 @@ static void upgradeClientToUdp(const network::GetAPIMessager::action_data &act,
inet_ntop(AF_INET, &act.udp.ip, buf, 32); inet_ntop(AF_INET, &act.udp.ip, buf, 32);
const char * const who = (*ci)->getPeerEndpoint(); const char * const who = (*ci)->getPeerEndpoint();
const char *start = strchr(who, '@'); const char *start = strrchr(who, '@');
if (!start) if (!start)
continue; continue;
start++; start++;
@@ -975,8 +981,8 @@ void VNCServerST::writeUpdate()
} }
if (watermarkData && Server::DLP_WatermarkText[0] && watermarkTextNeedsUpdate(true)) { if (watermarkData && Server::DLP_WatermarkText[0] && watermarkTextNeedsUpdate(true)) {
// If using a text watermark, we have to mark everything as changed... // The text may have changed
refreshClients(); sendWatermark = true;
} }
comparer->getUpdateInfo(&ui, pb->getRect()); comparer->getUpdateInfo(&ui, pb->getRect());
@@ -1104,6 +1110,8 @@ void VNCServerST::writeUpdate()
} }
} }
sendWatermark = false; // the client now caches it, only send once
if (trackingFrameStats) { if (trackingFrameStats) {
if (enctime) { if (enctime) {
const unsigned totalMs = msSince(&start); const unsigned totalMs = msSince(&start);

View File

@@ -290,6 +290,8 @@ namespace rfb {
void checkAPIMessages(network::GetAPIMessager *apimessager, void checkAPIMessages(network::GetAPIMessager *apimessager,
rdr::U8 &trackingFrameStats, char trackingClient[]); rdr::U8 &trackingFrameStats, char trackingClient[]);
bool sendWatermark;
}; };
}; };

View File

@@ -16,6 +16,7 @@
* USA. * USA.
*/ */
#include <math.h>
#include <png.h> #include <png.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -28,6 +29,7 @@
#include "font.h" #include "font.h"
#include <ft2build.h> #include <ft2build.h>
#include FT_FREETYPE_H #include FT_FREETYPE_H
#include FT_GLYPH_H
#include "Watermark.h" #include "Watermark.h"
@@ -187,6 +189,149 @@ static uint32_t drawnwidth(const char *txt) {
return x; return x;
} }
static void angle2mat(FT_Matrix &mat) {
const float angle = Server::DLP_WatermarkTextAngle / 360.f * 2 * -3.14159f;
mat.xx = (FT_Fixed)( cosf(angle) * 0x10000L);
mat.xy = (FT_Fixed)(-sinf(angle) * 0x10000L);
mat.yx = (FT_Fixed)( sinf(angle) * 0x10000L);
mat.yy = (FT_Fixed)( cosf(angle) * 0x10000L);
}
// Note: w and h are absolute
static void angledstr(uint8_t *buf, const char *txt, const uint32_t x_, const uint32_t y_,
const uint32_t w, const uint32_t h,
const uint32_t stride, const bool invx, const bool invy) {
unsigned ucs[256], i, ucslen;
unsigned len = strlen(txt);
i = 0;
ucslen = 0;
while (len > 0 && txt[i]) {
size_t ret = rfb::utf8ToUCS4(&txt[i], len, &ucs[ucslen]);
i += ret;
len -= ret;
ucslen++;
}
FT_Matrix mat;
FT_Vector pen;
angle2mat(mat);
pen.x = 0;
pen.y = 0;
uint32_t x, y;
x = x_;
y = y_;
for (i = 0; i < ucslen; i++) {
FT_Set_Transform(face, &mat, &pen);
if (FT_Load_Char(face, ucs[i], FT_LOAD_RENDER))
continue;
const FT_Bitmap * const map = &(face->glyph->bitmap);
uint32_t row, col;
for (row = 0; row < (uint32_t) map->rows; row++) {
int ny = row + y - face->glyph->bitmap_top;
if (ny < 0)
continue;
if ((unsigned) ny >= h)
continue;
uint8_t *dst = (uint8_t *) buf;
dst += ny * stride + x;
const uint8_t *src = map->buffer + map->pitch * row;
for (col = 0; col < (uint32_t) map->width; col++) {
if (col + x >= w)
continue;
const uint8_t out = (src[col] + 8) >> 4;
dst[col] |= out < 16 ? out : 15;
}
}
x += face->glyph->advance.x >> 6;
pen.x += face->glyph->advance.x;
pen.y += face->glyph->advance.y;
}
}
static void angledsize(const char *txt, uint32_t &w, uint32_t &h,
uint32_t &recw, uint32_t &recy,
bool &invx, bool &invy) {
unsigned ucs[256], i, ucslen;
unsigned len = strlen(txt);
i = 0;
ucslen = 0;
while (len > 0 && txt[i]) {
size_t ret = rfb::utf8ToUCS4(&txt[i], len, &ucs[ucslen]);
i += ret;
len -= ret;
ucslen++;
}
FT_Matrix mat;
FT_Vector pen;
angle2mat(mat);
pen.x = 0;
pen.y = 0;
FT_BBox firstbox, lastbox;
for (i = 0; i < ucslen; i++) {
FT_Set_Transform(face, &mat, &pen);
if (FT_Load_Char(face, ucs[i], FT_LOAD_DEFAULT))
continue;
if (i == 0) {
FT_Glyph glyph;
FT_Get_Glyph(face->glyph, &glyph);
FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_PIXELS, &firstbox);
FT_Done_Glyph(glyph);
// recommended y; if the angle is steep enough, use the X bearing
#define EDGE 22
const int angle = abs(Server::DLP_WatermarkTextAngle);
if ((angle > (45 + EDGE) && angle < (135 - EDGE)) ||
(angle > (225 + EDGE) && angle < (315 - EDGE)))
recy = face->glyph->metrics.horiBearingX >> 6;
else
recy = face->glyph->metrics.horiBearingY >> 6;
#undef EDGE
} else if (i == ucslen - 1) {
FT_Glyph glyph;
FT_Get_Glyph(face->glyph, &glyph);
FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_PIXELS, &lastbox);
FT_Done_Glyph(glyph);
}
if (i != ucslen - 1) {
pen.x += face->glyph->advance.x;
pen.y += face->glyph->advance.y;
}
}
// recommended width, used when X is inverted
recw = face->size->metrics.max_advance >> 6;
// The used area is an union of first box, last box, and their relative distance
invx = pen.x < 0;
invy = pen.y > 0;
w = (firstbox.xMax - firstbox.xMin) + (lastbox.xMax - lastbox.xMin) + abs(pen.x >> 6);
h = (firstbox.yMax - firstbox.yMin) + (lastbox.yMax - lastbox.yMin) + abs(pen.y >> 6);
}
static bool drawtext(const char fmt[], const int16_t utcOff, const char fontpath[], static bool drawtext(const char fmt[], const int16_t utcOff, const char fontpath[],
const uint8_t fontsize) { const uint8_t fontsize) {
char buf[PATH_MAX]; char buf[PATH_MAX];
@@ -213,14 +358,33 @@ static bool drawtext(const char fmt[], const int16_t utcOff, const char fontpath
return false; return false;
free(watermarkInfo.src); free(watermarkInfo.src);
const uint32_t h = fontsize + 4; if (Server::DLP_WatermarkTextAngle) {
const uint32_t w = drawnwidth(buf); uint32_t w, h, recw, recy = fontsize;
bool invx, invy;
angledsize(buf, w, h, recw, recy, invx, invy);
watermarkInfo.w = w; // The max is because a rotated text with the time can change size.
watermarkInfo.h = h; // With the max op, at least it will only grow instead of bouncing.
watermarkInfo.src = (uint8_t *) calloc(w, h); w = __rfbmax(w, watermarkInfo.w);
h = __rfbmax(h, watermarkInfo.h);
str(watermarkInfo.src, buf, 0, fontsize, w, h, w); watermarkInfo.w = w;
watermarkInfo.h = h;
watermarkInfo.src = (uint8_t *) calloc(w, h);
angledstr(watermarkInfo.src, buf,
invx ? w - recw: 0, invy ? h - recy : recy,
w, h, w, invx, invy);
} else {
const uint32_t h = fontsize + 4;
const uint32_t w = drawnwidth(buf);
watermarkInfo.w = w;
watermarkInfo.h = h;
watermarkInfo.src = (uint8_t *) calloc(w, h);
str(watermarkInfo.src, buf, 0, fontsize, w, h, w);
}
return true; return true;
} }
@@ -279,6 +443,31 @@ bool watermarkInit() {
return true; return true;
} }
static void packWatermark() {
// Take the expanded 4-bit data, filter it by the changed rects, pack
// to shared bytes, and compress with zlib
uint16_t x, y;
uint8_t pix[2], cur = 0;
uint8_t *dst = watermarkTmp;
for (y = 0; y < rh; y++) {
for (x = 0; x < rw; x++) {
pix[cur] = watermarkUnpacked[y * rw + x];
if (cur || (y == rh - 1 && x == rw - 1))
*dst++ = pix[0] | (pix[1] << 4);
cur ^= 1;
}
}
uLong destLen = MAXW * MAXH / 2;
if (compress2(watermarkData, &destLen, watermarkTmp, rw * rh / 2 + 1, 1) != Z_OK)
vlog.error("Zlib compression error");
watermarkDataLen = destLen;
}
// update the screen-size rendered watermark whenever the screen is resized // update the screen-size rendered watermark whenever the screen is resized
// or if using text, every frame // or if using text, every frame
void VNCServerST::updateWatermark() { void VNCServerST::updateWatermark() {
@@ -359,48 +548,10 @@ void VNCServerST::updateWatermark() {
rw - sx); rw - sx);
} }
} }
}
void packWatermark(const Region &changed) { packWatermark();
// Take the expanded 4-bit data, filter it by the changed rects, pack
// to shared bytes, and compress with zlib
uint16_t x, y; sendWatermark = true;
uint8_t pix[2], cur = 0;
uint8_t *dst = watermarkTmp;
const Rect &bounding = changed.get_bounding_rect();
for (y = 0; y < rh; y++) {
// Is the entire line outside the changed area?
if (bounding.tl.y > y || bounding.br.y < y) {
for (x = 0; x < rw; x++) {
pix[cur] = 0;
if (cur || (y == rh - 1 && x == rw - 1))
*dst++ = pix[0] | (pix[1] << 4);
cur ^= 1;
}
} else {
for (x = 0; x < rw; x++) {
pix[cur] = 0;
if (bounding.contains(Point(x, y)) && changed.contains(x, y))
pix[cur] = watermarkUnpacked[y * rw + x];
if (cur || (y == rh - 1 && x == rw - 1))
*dst++ = pix[0] | (pix[1] << 4);
cur ^= 1;
}
}
}
uLong destLen = MAXW * MAXH / 2;
if (compress2(watermarkData, &destLen, watermarkTmp, rw * rh / 2 + 1, 1) != Z_OK)
vlog.error("Zlib compression error");
watermarkDataLen = destLen;
} }
// Limit changes to once per second // Limit changes to once per second
@@ -412,5 +563,5 @@ bool watermarkTextNeedsUpdate(const bool early) {
if (early) if (early)
now = time(NULL); now = time(NULL);
return now != lastUpdate; return now != lastUpdate && strchr(Server::DLP_WatermarkText, '%');
} }

View File

@@ -35,7 +35,6 @@ struct watermarkInfo_t {
extern watermarkInfo_t watermarkInfo; extern watermarkInfo_t watermarkInfo;
bool watermarkInit(); bool watermarkInit();
void packWatermark(const rfb::Region &changed); // filter and pack the watermark for sending
bool watermarkTextNeedsUpdate(const bool early); bool watermarkTextNeedsUpdate(const bool early);
extern uint8_t *watermarkData; extern uint8_t *watermarkData;

20
debian/changelog vendored
View File

@@ -1,3 +1,23 @@
kasmvnc (1.3.1-1) unstable; urgency=medium
* Fix exception thrown on Firefox 124 and higher
* Fix artifacts on high resolution secondary screens
* Fixes for touch support on primary and secondary screens
* Fix for Oculus keyboard input
-- Kasm Technologies LLC <info@kasmweb.com> Mon, 12 Mar 2024 11:23:00 +0000
kasmvnc (1.3.0-1) unstable; urgency=medium
* Multi-monitor support.
* Increased performance with watermark enabled.
* Added support for Fedora 39 and Alpine 319.
* Allow special characters in usernames.
* Better logging of client settings when client connects or changes settings.
* Add support for rotation of text-based watermark.
-- Kasm Technologies LLC <info@kasmweb.com> Mon, 02 Feb 2024 14:33:00 +0000
kasmvnc (1.2.0-1) unstable; urgency=medium kasmvnc (1.2.0-1) unstable; urgency=medium
* Add support for Unix relays for bidirectional communication between noVNC * Add support for Unix relays for bidirectional communication between noVNC

View File

@@ -1,5 +1,5 @@
Name: kasmvncserver Name: kasmvncserver
Version: 1.2.0 Version: 1.3.1
Release: 1%{?dist} Release: 1%{?dist}
Summary: VNC server accessible from a web browser Summary: VNC server accessible from a web browser
@@ -83,6 +83,18 @@ cd $DST_MAN && ln -s vncpasswd.1 kasmvncpasswd.1;
%doc /usr/share/doc/kasmvncserver/README.md %doc /usr/share/doc/kasmvncserver/README.md
%changelog %changelog
* Tue Mar 12 2024 KasmTech <info@kasmweb.com> - 1.3.1-1
- Fix exception thrown on Firefox 124 and higher
- Fix artifacts on high resolution secondary screens
- Fixes for touch support on primary and secondary screens
- Fix for Oculus keyboard input
* Mon Feb 05 2024 KasmTech <info@kasmweb.com> - 1.3.0-1
- Multi-monitor support.
- Increased performance with watermark enabled.
- Added support for Fedora 39 and Alpine 319.
- Allow special characters in usernames.
- Better logging of client settings when client connects or changes settings.
- Add support for rotation of text-based watermark.
* Fri Aug 25 2023 KasmTech <info@kasmweb.com> - 1.2.0-1 * Fri Aug 25 2023 KasmTech <info@kasmweb.com> - 1.2.0-1
- Add support for Unix relays for bidirectional communication between noVNC - Add support for Unix relays for bidirectional communication between noVNC
and containerized applications. and containerized applications.

Submodule kasmweb updated: 68135beedd...3891addf9c

View File

@@ -1,5 +1,5 @@
Name: kasmvncserver Name: kasmvncserver
Version: 1.2.0 Version: 1.3.1
Release: leap15 Release: leap15
Summary: VNC server accessible from a web browser Summary: VNC server accessible from a web browser
@@ -81,6 +81,18 @@ cd $DST_MAN && ln -s vncpasswd.1 kasmvncpasswd.1;
%doc /usr/share/doc/kasmvncserver/README.md %doc /usr/share/doc/kasmvncserver/README.md
%changelog %changelog
* Tue Mar 12 2024 KasmTech <info@kasmweb.com> - 1.3.1-1
- Fix exception thrown on Firefox 124 and higher
- Fix artifacts on high resolution secondary screens
- Fixes for touch support on primary and secondary screens
- Fix for Oculus keyboard input
* Mon Feb 05 2024 KasmTech <info@kasmweb.com> - 1.3.0-1
- Multi-monitor support.
- Increased performance with watermark enabled.
- Added support for Fedora 39 and Alpine 319.
- Allow special characters in usernames.
- Better logging of client settings when client connects or changes settings.
- Add support for rotation of text-based watermark.
* Fri Aug 25 2023 KasmTech <info@kasmweb.com> - 1.2.0-leap15 * Fri Aug 25 2023 KasmTech <info@kasmweb.com> - 1.2.0-leap15
- Add support for Unix relays for bidirectional communication between noVNC - Add support for Unix relays for bidirectional communication between noVNC
and containerized applications. and containerized applications.

View File

@@ -1,5 +1,5 @@
Name: kasmvncserver Name: kasmvncserver
Version: 1.2.0 Version: 1.3.1
Release: 1%{?dist} Release: 1%{?dist}
Summary: VNC server accessible from a web browser Summary: VNC server accessible from a web browser
@@ -82,6 +82,18 @@ cd $DST_MAN && ln -s vncpasswd.1 kasmvncpasswd.1;
%doc /usr/share/doc/kasmvncserver/README.md %doc /usr/share/doc/kasmvncserver/README.md
%changelog %changelog
* Tue Mar 12 2024 KasmTech <info@kasmweb.com> - 1.3.1-1
- Fix exception thrown on Firefox 124 and higher
- Fix artifacts on high resolution secondary screens
- Fixes for touch support on primary and secondary screens
- Fix for Oculus keyboard input
* Mon Feb 05 2024 KasmTech <info@kasmweb.com> - 1.3.0-1
- Multi-monitor support.
- Increased performance with watermark enabled.
- Added support for Fedora 39 and Alpine 319.
- Allow special characters in usernames.
- Better logging of client settings when client connects or changes settings.
- Add support for rotation of text-based watermark.
* Fri Aug 25 2023 KasmTech <info@kasmweb.com> - 1.2.0-1 * Fri Aug 25 2023 KasmTech <info@kasmweb.com> - 1.2.0-1
- Add support for Unix relays for bidirectional communication between noVNC - Add support for Unix relays for bidirectional communication between noVNC
and containerized applications. and containerized applications.

View File

@@ -1,5 +1,5 @@
Name: kasmvncserver Name: kasmvncserver
Version: 1.2.0 Version: 1.3.1
Release: 1%{?dist} Release: 1%{?dist}
Summary: VNC server accessible from a web browser Summary: VNC server accessible from a web browser
@@ -82,6 +82,18 @@ cd $DST_MAN && ln -s vncpasswd.1 kasmvncpasswd.1;
%doc /usr/share/doc/kasmvncserver/README.md %doc /usr/share/doc/kasmvncserver/README.md
%changelog %changelog
* Tue Mar 12 2024 KasmTech <info@kasmweb.com> - 1.3.1-1
- Fix exception thrown on Firefox 124 and higher
- Fix artifacts on high resolution secondary screens
- Fixes for touch support on primary and secondary screens
- Fix for Oculus keyboard input
* Mon Feb 05 2024 KasmTech <info@kasmweb.com> - 1.3.0-1
- Multi-monitor support.
- Increased performance with watermark enabled.
- Added support for Fedora 39 and Alpine 319.
- Allow special characters in usernames.
- Better logging of client settings when client connects or changes settings.
- Add support for rotation of text-based watermark.
* Fri Aug 25 2023 KasmTech <info@kasmweb.com> - 1.2.0-1 * Fri Aug 25 2023 KasmTech <info@kasmweb.com> - 1.2.0-1
- Add support for Unix relays for bidirectional communication between noVNC - Add support for Unix relays for bidirectional communication between noVNC
and containerized applications. and containerized applications.

View File

@@ -50,6 +50,12 @@ data_loss_prevention:
# location: 10,10 # location: 10,10
# tint: 255,20,20,128 # tint: 255,20,20,128
# repeat_spacing: 10 # repeat_spacing: 10
#text:
# template: "${USER} %H:%M"
# font: auto
# font_size: 48
# timezone_name: Australia/Adelaide
# angle: 0
logging: logging:
level: off level: off

View File

@@ -100,6 +100,7 @@ data_loss_prevention:
# font: auto # font: auto
# font_size: 48 # font_size: 48
# timezone_name: Australia/Adelaide # timezone_name: Australia/Adelaide
# angle: 0
logging: logging:
# "verbose" SETTING LOGS YOUR PRIVATE INFORMATION. Keypresses and clipboard content # "verbose" SETTING LOGS YOUR PRIVATE INFORMATION. Keypresses and clipboard content
level: off level: off

View File

@@ -6,7 +6,7 @@ extern "C" {
#endif #endif
struct kasmpasswd_entry_t { struct kasmpasswd_entry_t {
char user[32]; char user[128];
char password[128]; char password[128];
unsigned char read : 1; unsigned char read : 1;
unsigned char write : 1; unsigned char write : 1;

View File

@@ -669,9 +669,10 @@ sub RunXstartup {
DetectAndExportDisplay(); DetectAndExportDisplay();
$ENV{VNCDESKTOP}= $desktopName; $ENV{VNCDESKTOP}= $desktopName;
my $xstartupCmd = "{ echo 'Running $xstartupFile'; $xstartupFile; }";
if ($opt{'-fg'}) { if ($opt{'-fg'}) {
if (! $skipxstartup) { if (! $skipxstartup) {
system("$xstartupFile >> " . quotedString($desktopLog) . " 2>&1"); system("$xstartupCmd >> " . quotedString($desktopLog) . " 2>&1");
} }
if (IsXvncRunning()) { if (IsXvncRunning()) {
$opt{'-kill'} = ':'.$displayNumber; $opt{'-kill'} = ':'.$displayNumber;
@@ -680,12 +681,12 @@ sub RunXstartup {
} else { } else {
if ($opt{'-autokill'}) { if ($opt{'-autokill'}) {
if (! $skipxstartup) { if (! $skipxstartup) {
system("($xstartupFile; $0 -kill :$displayNumber) >> " system("($xstartupCmd; $0 -kill :$displayNumber) >> "
. quotedString($desktopLog) . " 2>&1 &"); . quotedString($desktopLog) . " 2>&1 &");
} }
} else { } else {
if (! $skipxstartup) { if (! $skipxstartup) {
system("$xstartupFile >> " . quotedString($desktopLog) system("$xstartupCmd >> " . quotedString($desktopLog)
. " 2>&1 &"); . " 2>&1 &");
} }
} }
@@ -1861,6 +1862,24 @@ sub DefineConfigToCLIConversion {
$offset_in_seconds/60; $offset_in_seconds/60;
} }
}), }),
KasmVNC::CliOption->new({
name => 'DLP_WatermarkTextAngle',
configKeys => [
KasmVNC::ConfigKey->new({
name => "data_loss_prevention.watermark.text.angle",
validator => KasmVNC::CallbackValidator->new({
isValidCallback => sub {
my $value = shift;
return 0 unless $value =~ /^-?\d+$/;
$value >= -359 && $value <= 359;
},
errorMessage => "must be in range -359..359"
}),
})
]
}),
KasmVNC::CliOption->new({ KasmVNC::CliOption->new({
name => 'DLP_Log', name => 'DLP_Log',
configKeys => [ configKeys => [

View File

@@ -43,9 +43,9 @@ vncserver :13
.RE .RE
vncserver can detect desktop environments and prompt the user to select one to vncserver can detect desktop environments and prompt the user to select one to
start with the session. The user can also manually edit the file start with the session. The user can also manually edit the file
$HOME/.vnc/xstartup to customize what commands should be run on startup of a $HOME/.vnc/xstartup to customize what commands should be run on startup of a
new session. new session.
.SH OPTIONS .SH OPTIONS
You can get a list of options by passing \fB\-h\fP as an option to vncserver. You can get a list of options by passing \fB\-h\fP as an option to vncserver.
@@ -54,11 +54,18 @@ passed to Xvnc - see the Xvnc man page, or "Xvnc \-help", for details.
.TP .TP
.B \-select-de [\fIde_name\fP] .B \-select-de [\fIde_name\fP]
Select Desktop Enviromnent to run. Cinnamon, Mate, LXDE, LXQT, KDE, Gnome, XFCE Select Desktop Enviromnent to run. Cinnamon, Mate, LXDE, LXQT, KDE, Gnome, XFCE,
are supported. If \fIde_name\fP isn't specified, a text UI prompt to select a are supported.
Desktop Enviromnent will be shown.
To trigger a text UI prompt to select a Desktop Enviromnent, run \fBvncserver\fP
for the first time, or pass this option without arguments. To bypass the prompt,
pass this option with the Desktop Enviromnent argument.
Warning: $HOME/.vnc/xstartup will be overwritten. Warning: $HOME/.vnc/xstartup will be overwritten.
To run a custom setup (not one of the supported Desktop Enviromnents), create
$HOME/.vnc/xstartup executable and specify \fB\-select-de manual\fP to signify you
don't want its contents to be auto-generated.
.TP .TP
.B \-geometry \fIwidth\fPx\fIheight\fP .B \-geometry \fIwidth\fPx\fIheight\fP
Specify the size of the VNC desktop to be created. Default is 1024x768. Specify the size of the VNC desktop to be created. Default is 1024x768.

View File

@@ -384,6 +384,10 @@ Instead of an image, render this text as the watermark. Takes time formatting op
for \fBstrftime\fP. for \fBstrftime\fP.
. .
.TP .TP
.B \-DLP_WatermarkTextAngle \fIangle\fP
Rotate the text by this many degrees, increasing clockwise. Default \fB0\fP.
.
.TP
.B \-DLP_WatermarkFont \fI/path/to/font.ttf\fP .B \-DLP_WatermarkFont \fI/path/to/font.ttf\fP
Use a different font for -DLP_WatermarkText than the bundled one. TTF and OTF fonts Use a different font for -DLP_WatermarkText than the bundled one. TTF and OTF fonts
are accepted. are accepted.

View File

@@ -96,7 +96,7 @@ from the X Consortium.
#include "version-config.h" #include "version-config.h"
#include "site.h" #include "site.h"
#define XVNCVERSION "KasmVNC 1.2.0" #define XVNCVERSION "KasmVNC 1.3.1"
#define XVNCCOPYRIGHT ("Copyright (C) 1999-2018 KasmVNC Team and many others (see README.me)\n" \ #define XVNCCOPYRIGHT ("Copyright (C) 1999-2018 KasmVNC Team and many others (see README.me)\n" \
"See http://kasmweb.com for information on KasmVNC.\n") "See http://kasmweb.com for information on KasmVNC.\n")