Compare commits
79 Commits
release/1.
...
release/1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
001ff1aa47 | ||
|
|
12066abc66 | ||
|
|
a10358b5ca | ||
|
|
124d36a981 | ||
|
|
f02fbb0e2d | ||
|
|
8c7dd2ed30 | ||
|
|
ae70375afe | ||
|
|
127ab45329 | ||
|
|
3bc1024e7f | ||
|
|
228eb87db1 | ||
|
|
4f726e3654 | ||
|
|
ed9fbcbec2 | ||
|
|
659a4198fc | ||
|
|
5456ccc072 | ||
|
|
fddaab5124 | ||
|
|
7be7e34b51 | ||
|
|
5b64eb32f8 | ||
|
|
eef8e7264f | ||
|
|
e8b54db6bf | ||
|
|
7b442658e1 | ||
|
|
408fcd3415 | ||
|
|
7cdb7e1f3e | ||
|
|
b595c0bce8 | ||
|
|
4c9b065c31 | ||
|
|
8b5ee59ae2 | ||
|
|
4114d73ed6 | ||
|
|
1d8a2ed59a | ||
|
|
c055920348 | ||
|
|
b2d965b58d | ||
|
|
446497ad06 | ||
|
|
0de752f65e | ||
|
|
f712f5e7f8 | ||
|
|
d090e1b707 | ||
|
|
fb7570709a | ||
|
|
73c3bda8cd | ||
|
|
9a73cb4a60 | ||
|
|
6cd50869c2 | ||
|
|
5823b550a4 | ||
|
|
29c48a8679 | ||
|
|
c88b683354 | ||
|
|
7399e5dc62 | ||
|
|
e4a5004f4b | ||
|
|
da7c481fc8 | ||
|
|
32f4398115 | ||
|
|
7350b12b3d | ||
|
|
1b25ad8e54 | ||
|
|
2165c3e1ba | ||
|
|
d390d187b4 | ||
|
|
a4034865e6 | ||
|
|
7d6244fe1c | ||
|
|
21d2ae5018 | ||
|
|
dcea208d73 | ||
|
|
44555f9581 | ||
|
|
561ea86e85 | ||
|
|
446d03d479 | ||
|
|
04f95d2b62 | ||
|
|
c0ed7d7b1a | ||
|
|
dda29172c1 | ||
|
|
fa88480914 | ||
|
|
b4f6fafd73 | ||
|
|
6a73d1cb49 | ||
|
|
6207b1b60f | ||
|
|
0923f300a0 | ||
|
|
7b8a4e8388 | ||
|
|
b9e9a2d2a0 | ||
|
|
25a996cb97 | ||
|
|
6774cbf3a2 | ||
|
|
fc0f2a3192 | ||
|
|
9a14b07ba4 | ||
|
|
0527c9f76e | ||
|
|
e41bc997a6 | ||
|
|
75c51c1e93 | ||
|
|
9450157af1 | ||
|
|
f9e46f5a13 | ||
|
|
13bafe3759 | ||
|
|
d5080eca8f | ||
|
|
4d3a9b749a | ||
|
|
12ba00f939 | ||
|
|
3bae812364 |
@@ -89,3 +89,26 @@ detect_revision() {
|
|||||||
|
|
||||||
REVISION=$(echo "$package" | sed "s/_${arch}.\+//" | sed 's/.\++//')
|
REVISION=$(echo "$package" | sed "s/_${arch}.\+//" | sed 's/.\++//')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
make_index_html() {
|
||||||
|
local body=""
|
||||||
|
local bname
|
||||||
|
|
||||||
|
for f in "$@"; do
|
||||||
|
bname=$(basename "$f")
|
||||||
|
body="${body}<a href=/$f>$bname</a><br>"
|
||||||
|
done
|
||||||
|
|
||||||
|
cat <<EOF
|
||||||
|
<!doctype html>
|
||||||
|
<html lang=en>
|
||||||
|
<head>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<title>KasmVNC preview build</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
$body
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|||||||
276
.gitlab-ci.yml
276
.gitlab-ci.yml
@@ -6,12 +6,13 @@ variables:
|
|||||||
KASMVNC_COMMIT_ID: $CI_COMMIT_SHA
|
KASMVNC_COMMIT_ID: $CI_COMMIT_SHA
|
||||||
GITLAB_SHARED_DIND_DIR: /builds/$CI_PROJECT_PATH/shared
|
GITLAB_SHARED_DIND_DIR: /builds/$CI_PROJECT_PATH/shared
|
||||||
GIT_SUBMODULE_STRATEGY: normal
|
GIT_SUBMODULE_STRATEGY: normal
|
||||||
GIT_FETCH_EXTRA_FLAGS: --tags
|
GIT_FETCH_EXTRA_FLAGS: --tags --force
|
||||||
# E.g. BUILD_JOBS: build_debian_buster,build_ubuntu_bionic. This will include
|
# E.g. BUILD_JOBS: build_debian_buster,build_ubuntu_bionic. This will include
|
||||||
# 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
|
||||||
@@ -243,9 +256,50 @@ build_debian_bullseye_arm:
|
|||||||
paths:
|
paths:
|
||||||
- output/
|
- output/
|
||||||
|
|
||||||
|
|
||||||
|
build_debian_bookworm:
|
||||||
|
stage: build
|
||||||
|
allow_failure: true
|
||||||
|
tags:
|
||||||
|
- oci-fixed-amd
|
||||||
|
before_script:
|
||||||
|
- *prepare_build
|
||||||
|
- *prepare_www
|
||||||
|
after_script:
|
||||||
|
- *prepare_artfacts
|
||||||
|
script:
|
||||||
|
- bash builder/build-package debian bookworm;
|
||||||
|
only:
|
||||||
|
variables:
|
||||||
|
- $BUILD_JOBS == 'all' || $BUILD_JOBS =~ $CI_JOB_NAME
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- output/
|
||||||
|
|
||||||
|
build_debian_bookworm_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 debian bookworm;
|
||||||
|
only:
|
||||||
|
variables:
|
||||||
|
- $BUILD_JOBS == 'all' || $BUILD_JOBS =~ $CI_JOB_NAME
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- output/
|
||||||
|
|
||||||
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
|
||||||
@@ -264,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
|
||||||
@@ -282,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
|
||||||
@@ -299,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
|
||||||
@@ -317,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
|
||||||
@@ -335,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
|
||||||
@@ -353,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
|
||||||
@@ -371,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
|
||||||
@@ -389,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
|
||||||
@@ -407,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
|
||||||
@@ -425,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
|
||||||
@@ -440,9 +504,87 @@ build_fedora_thirtyseven_arm:
|
|||||||
paths:
|
paths:
|
||||||
- output/
|
- output/
|
||||||
|
|
||||||
|
build_fedora_thirtyeight:
|
||||||
|
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 thirtyeight;
|
||||||
|
only:
|
||||||
|
variables:
|
||||||
|
- $BUILD_JOBS == 'all' || $BUILD_JOBS =~ $CI_JOB_NAME
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- output/
|
||||||
|
|
||||||
|
build_fedora_thirtyeight_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 thirtyeight;
|
||||||
|
only:
|
||||||
|
variables:
|
||||||
|
- $BUILD_JOBS == 'all' || $BUILD_JOBS =~ $CI_JOB_NAME
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- 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
|
||||||
@@ -461,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
|
||||||
@@ -478,14 +620,98 @@ build_alpine_317_arm:
|
|||||||
|
|
||||||
test:
|
test:
|
||||||
stage: test
|
stage: test
|
||||||
|
tags:
|
||||||
|
- oci-fixed-amd
|
||||||
before_script:
|
before_script:
|
||||||
- *prepare_build
|
- *prepare_build
|
||||||
script:
|
script:
|
||||||
- bash builder/test-vncserver
|
- bash builder/test-vncserver
|
||||||
|
|
||||||
|
|
||||||
|
build_alpine_318:
|
||||||
|
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 318;
|
||||||
|
only:
|
||||||
|
variables:
|
||||||
|
- $BUILD_JOBS == 'all' || $BUILD_JOBS =~ $CI_JOB_NAME
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- output/
|
||||||
|
|
||||||
|
build_alpine_318_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 318;
|
||||||
|
only:
|
||||||
|
variables:
|
||||||
|
- $BUILD_JOBS == 'all' || $BUILD_JOBS =~ $CI_JOB_NAME
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- 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:
|
||||||
|
paths:
|
||||||
|
- output/
|
||||||
before_script:
|
before_script:
|
||||||
- . .ci/upload.sh
|
- . .ci/upload.sh
|
||||||
script:
|
script:
|
||||||
@@ -502,6 +728,7 @@ upload:
|
|||||||
done
|
done
|
||||||
- export S3_BUILD_DIRECTORY="kasmvnc/${CI_COMMIT_SHA}"
|
- export S3_BUILD_DIRECTORY="kasmvnc/${CI_COMMIT_SHA}"
|
||||||
- export RELEASE_VERSION=$(.ci/next_release_version "$CI_COMMIT_REF_NAME")
|
- export RELEASE_VERSION=$(.ci/next_release_version "$CI_COMMIT_REF_NAME")
|
||||||
|
- uploaded_files=()
|
||||||
- for package in `find output/ -type f -name '*.deb' -or -name '*.rpm' -or -name '*.tgz'`; do
|
- for package in `find output/ -type f -name '*.deb' -or -name '*.rpm' -or -name '*.tgz'`; do
|
||||||
prepare_upload_filename "$package";
|
prepare_upload_filename "$package";
|
||||||
upload_filename="${S3_BUILD_DIRECTORY}/$upload_filename";
|
upload_filename="${S3_BUILD_DIRECTORY}/$upload_filename";
|
||||||
@@ -510,4 +737,25 @@ upload:
|
|||||||
upload_to_s3 "$package" "$upload_filename" "$S3_BUCKET";
|
upload_to_s3 "$package" "$upload_filename" "$S3_BUCKET";
|
||||||
UPLOAD_NAME=$(basename $upload_filename | sed 's#kasmvncserver_##' | sed -r 's#_([0-9]{1,3}\.){2}[0-9]{1,2}_\S+?([a-f0-9]{6})##' | sed -r 's#\.(deb|rpm|tgz)##');
|
UPLOAD_NAME=$(basename $upload_filename | sed 's#kasmvncserver_##' | sed -r 's#_([0-9]{1,3}\.){2}[0-9]{1,2}_\S+?([a-f0-9]{6})##' | sed -r 's#\.(deb|rpm|tgz)##');
|
||||||
curl --request POST --header "PRIVATE-TOKEN:${GITLAB_API_TOKEN}" "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/statuses/${CI_COMMIT_SHA}?state=success&name=${UPLOAD_NAME}&target_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=${UPLOAD_NAME}&target_url=${S3_URL}";
|
||||||
|
uploaded_files+=("$upload_filename");
|
||||||
done
|
done
|
||||||
|
- make_index_html "${uploaded_files[@]}" > output/index.html;
|
||||||
|
|
||||||
|
upload_build_preview:
|
||||||
|
stage: upload
|
||||||
|
needs: ["upload"]
|
||||||
|
dependencies: ["upload"]
|
||||||
|
image: ubuntu:focal
|
||||||
|
tags:
|
||||||
|
- oci-fixed-amd
|
||||||
|
before_script:
|
||||||
|
- . .ci/upload.sh
|
||||||
|
resource_group: upload_build_preview
|
||||||
|
only:
|
||||||
|
variables:
|
||||||
|
- $CI_COMMIT_BRANCH == 'master'
|
||||||
|
script:
|
||||||
|
- prepare_to_run_scripts_and_s3_uploads
|
||||||
|
- preview_builds_dir=kasmvnc/preview-builds
|
||||||
|
- upload_to_s3 "output/index.html" "$preview_builds_dir/index.html" "$S3_BUCKET"
|
||||||
|
- curl --request POST --header "PRIVATE-TOKEN:${GITLAB_API_TOKEN}" "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/statuses/${CI_COMMIT_SHA}?state=success&name=index.html&target_url=${S3_URL}";
|
||||||
|
|||||||
2
.gitmodules
vendored
2
.gitmodules
vendored
@@ -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.0
|
||||||
|
|||||||
@@ -154,6 +154,9 @@ find_package(PNG REQUIRED)
|
|||||||
# Check for libjpeg
|
# Check for libjpeg
|
||||||
find_package(JPEG REQUIRED)
|
find_package(JPEG REQUIRED)
|
||||||
|
|
||||||
|
find_package(Freetype REQUIRED)
|
||||||
|
include_directories(${FREETYPE_INCLUDE_DIRS})
|
||||||
|
|
||||||
# Staticly link libjpeg-turbo
|
# Staticly link libjpeg-turbo
|
||||||
set(JPEG_LIBRARIES "-Wl,-Bstatic -lturbojpeg -Wl,-Bdynamic")
|
set(JPEG_LIBRARIES "-Wl,-Bstatic -lturbojpeg -Wl,-Bdynamic")
|
||||||
# Warn if it doesn't seem to be the accelerated libjpeg that's found
|
# Warn if it doesn't seem to be the accelerated libjpeg that's found
|
||||||
|
|||||||
@@ -15,6 +15,11 @@ bump_deb() {
|
|||||||
builder/bump-package-version-deb "$new_version"
|
builder/bump-package-version-deb "$new_version"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bump_xvnc_binary() {
|
||||||
|
local cmd="s/#define XVNCVERSION.\+$/#define XVNCVERSION \"KasmVNC $new_version\"/"
|
||||||
|
sed -i -e "$cmd" unix/xserver/hw/vnc/xvnc.c
|
||||||
|
}
|
||||||
|
|
||||||
new_version="$1"
|
new_version="$1"
|
||||||
|
|
||||||
if [[ -z "$new_version" ]]; then
|
if [[ -z "$new_version" ]]; then
|
||||||
@@ -25,5 +30,6 @@ fi
|
|||||||
cd "$(dirname "$0")/.."
|
cd "$(dirname "$0")/.."
|
||||||
|
|
||||||
update_version_to_meet_packaging_standards
|
update_version_to_meet_packaging_standards
|
||||||
|
bump_xvnc_binary
|
||||||
bump_rpm
|
bump_rpm
|
||||||
bump_deb
|
bump_deb
|
||||||
|
|||||||
7
builder/dockerfile.alpine_318.apk.build
Normal file
7
builder/dockerfile.alpine_318.apk.build
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
FROM alpine:3.18
|
||||||
|
|
||||||
|
RUN apk add shadow bash
|
||||||
|
|
||||||
|
RUN useradd -m docker && echo "docker:docker" | chpasswd
|
||||||
|
|
||||||
|
USER docker
|
||||||
82
builder/dockerfile.alpine_318.build
Normal file
82
builder/dockerfile.alpine_318.build
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
FROM alpine:3.18
|
||||||
|
|
||||||
|
ENV KASMVNC_BUILD_OS alpine
|
||||||
|
ENV KASMVNC_BUILD_OS_CODENAME 318
|
||||||
|
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"]
|
||||||
7
builder/dockerfile.alpine_319.apk.build
Normal file
7
builder/dockerfile.alpine_319.apk.build
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
FROM alpine:3.19
|
||||||
|
|
||||||
|
RUN apk add shadow bash
|
||||||
|
|
||||||
|
RUN useradd -m docker && echo "docker:docker" | chpasswd
|
||||||
|
|
||||||
|
USER docker
|
||||||
82
builder/dockerfile.alpine_319.build
Normal file
82
builder/dockerfile.alpine_319.build
Normal 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"]
|
||||||
38
builder/dockerfile.debian_bookworm.build
Normal file
38
builder/dockerfile.debian_bookworm.build
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
FROM debian:bookworm-slim
|
||||||
|
|
||||||
|
ENV KASMVNC_BUILD_OS debian
|
||||||
|
ENV KASMVNC_BUILD_OS_CODENAME bookworm
|
||||||
|
ENV XORG_VER 1.20.10
|
||||||
|
ENV DEBIAN_FRONTEND noninteractive
|
||||||
|
|
||||||
|
RUN \
|
||||||
|
echo "**** add all sources ****" && \
|
||||||
|
echo "deb http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware" > /etc/apt/sources.list && \
|
||||||
|
echo "deb-src http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware" >> /etc/apt/sources.list && \
|
||||||
|
echo "deb http://deb.debian.org/debian bookworm-updates main contrib non-free non-free-firmware" >> /etc/apt/sources.list && \
|
||||||
|
echo "deb-src http://deb.debian.org/debian bookworm-updates main contrib non-free non-free-firmware" >> /etc/apt/sources.list && \
|
||||||
|
echo "deb http://deb.debian.org/debian bookworm-backports main contrib non-free non-free-firmware" >> /etc/apt/sources.list && \
|
||||||
|
echo "deb-src http://deb.debian.org/debian bookworm-backports main contrib non-free non-free-firmware" >> /etc/apt/sources.list && \
|
||||||
|
echo "deb http://security.debian.org/debian-security/ bookworm-security main contrib non-free non-free-firmware" >> /etc/apt/sources.list && \
|
||||||
|
echo "deb-src http://security.debian.org/debian-security/ bookworm-security main contrib non-free non-free-firmware" >> /etc/apt/sources.list && \
|
||||||
|
rm -f /etc/apt/sources.list.d/debian.sources
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get -y install sudo
|
||||||
|
|
||||||
|
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata
|
||||||
|
RUN apt-get update && apt-get -y build-dep xorg-server libxfont-dev
|
||||||
|
RUN apt-get update && apt-get -y install cmake git libgnutls28-dev vim wget tightvncserver curl
|
||||||
|
RUN apt-get update && apt-get -y install libpng-dev libtiff-dev libgif-dev libavcodec-dev libssl-dev libxrandr-dev libxcursor-dev
|
||||||
|
|
||||||
|
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 && adduser docker sudo
|
||||||
|
|
||||||
|
COPY --chown=docker:docker . /src/
|
||||||
|
|
||||||
|
USER docker
|
||||||
|
ENTRYPOINT ["/src/builder/build.sh"]
|
||||||
19
builder/dockerfile.debian_bookworm.deb.build
Normal file
19
builder/dockerfile.debian_bookworm.deb.build
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
FROM debian:bookworm
|
||||||
|
|
||||||
|
ENV DEBIAN_FRONTEND noninteractive
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get -y install vim build-essential devscripts equivs
|
||||||
|
|
||||||
|
# Install build-deps for the package.
|
||||||
|
COPY ./debian/control /tmp
|
||||||
|
RUN apt-get update && echo YYY | mk-build-deps --install --remove /tmp/control
|
||||||
|
|
||||||
|
ARG L_UID
|
||||||
|
RUN if [ "$L_UID" -eq 0 ]; then \
|
||||||
|
useradd -m docker; \
|
||||||
|
else \
|
||||||
|
useradd -m docker -u $L_UID;\
|
||||||
|
fi
|
||||||
|
|
||||||
|
USER docker
|
||||||
57
builder/dockerfile.debian_bookworm.deb.test
Normal file
57
builder/dockerfile.debian_bookworm.deb.test
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
FROM debian:bookworm-slim
|
||||||
|
|
||||||
|
ENV DISPLAY=:1 \
|
||||||
|
VNC_PORT=8443 \
|
||||||
|
VNC_RESOLUTION=1280x720 \
|
||||||
|
MAX_FRAME_RATE=24 \
|
||||||
|
VNCOPTIONS="-PreferBandwidth -DynamicQualityMin=4 -DynamicQualityMax=7" \
|
||||||
|
HOME=/home/user \
|
||||||
|
TERM=xterm \
|
||||||
|
STARTUPDIR=/dockerstartup \
|
||||||
|
INST_SCRIPTS=/dockerstartup/install \
|
||||||
|
KASM_RX_HOME=/dockerstartup/kasmrx \
|
||||||
|
DEBIAN_FRONTEND=noninteractive \
|
||||||
|
VNC_COL_DEPTH=24 \
|
||||||
|
VNC_RESOLUTION=1280x1024 \
|
||||||
|
VNC_PW=vncpassword \
|
||||||
|
VNC_USER=user \
|
||||||
|
VNC_VIEW_ONLY_PW=vncviewonlypassword \
|
||||||
|
LD_LIBRARY_PATH=/usr/local/lib/ \
|
||||||
|
OMP_WAIT_POLICY=PASSIVE \
|
||||||
|
SHELL=/bin/bash \
|
||||||
|
SINGLE_APPLICATION=0 \
|
||||||
|
KASMVNC_BUILD_OS=debian \
|
||||||
|
KASMVNC_BUILD_OS_CODENAME=buster
|
||||||
|
|
||||||
|
EXPOSE $VNC_PORT
|
||||||
|
|
||||||
|
WORKDIR $HOME
|
||||||
|
|
||||||
|
### REQUIRED STUFF ###
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
RUN mkdir -p $STARTUPDIR
|
||||||
|
COPY builder/startup/ $STARTUPDIR
|
||||||
|
|
||||||
|
### START CUSTOM STUFF ####
|
||||||
|
|
||||||
|
COPY ./builder/scripts/ /tmp/scripts/
|
||||||
|
COPY ./debian/changelog /tmp
|
||||||
|
|
||||||
|
ARG KASMVNC_PACKAGE_DIR
|
||||||
|
COPY $KASMVNC_PACKAGE_DIR/kasmvncserver_*.deb /tmp/
|
||||||
|
RUN /tmp/scripts/install_kasmvncserver_package
|
||||||
|
|
||||||
|
### END CUSTOM STUFF ###
|
||||||
|
|
||||||
|
RUN chown -R 1000:0 $HOME
|
||||||
|
USER 1000:ssl-cert
|
||||||
|
WORKDIR $HOME
|
||||||
|
|
||||||
|
ENTRYPOINT [ "/dockerstartup/vnc_startup.sh" ]
|
||||||
19
builder/dockerfile.fedora_thirtyeight.barebones.rpm.test
Normal file
19
builder/dockerfile.fedora_thirtyeight.barebones.rpm.test
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
FROM fedora:38
|
||||||
|
|
||||||
|
ENV STARTUPDIR=/dockerstartup
|
||||||
|
|
||||||
|
RUN dnf install -y xterm
|
||||||
|
RUN dnf install -y vim less
|
||||||
|
RUN yum install -y redhat-lsb-core
|
||||||
|
|
||||||
|
ARG KASMVNC_PACKAGE_DIR
|
||||||
|
COPY $KASMVNC_PACKAGE_DIR/*.rpm /tmp/
|
||||||
|
RUN dnf localinstall -y /tmp/*.rpm
|
||||||
|
|
||||||
|
RUN mkdir -p $STARTUPDIR
|
||||||
|
COPY startup/vnc_startup_barebones.sh $STARTUPDIR
|
||||||
|
|
||||||
|
RUN useradd -m foo
|
||||||
|
USER foo:kasmvnc-cert
|
||||||
|
|
||||||
|
ENTRYPOINT "/$STARTUPDIR/vnc_startup_barebones.sh"
|
||||||
86
builder/dockerfile.fedora_thirtyeight.build
Normal file
86
builder/dockerfile.fedora_thirtyeight.build
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
FROM fedora:38
|
||||||
|
|
||||||
|
ENV KASMVNC_BUILD_OS fedora
|
||||||
|
ENV KASMVNC_BUILD_OS_CODENAME thirtyeight
|
||||||
|
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"]
|
||||||
13
builder/dockerfile.fedora_thirtyeight.rpm.build
Normal file
13
builder/dockerfile.fedora_thirtyeight.rpm.build
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
FROM fedora:38
|
||||||
|
|
||||||
|
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
|
||||||
62
builder/dockerfile.fedora_thirtyeight.rpm.test
Normal file
62
builder/dockerfile.fedora_thirtyeight.rpm.test
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
FROM fedora:38
|
||||||
|
|
||||||
|
ENV DISPLAY=:1 \
|
||||||
|
VNC_PORT=8443 \
|
||||||
|
VNC_RESOLUTION=1280x720 \
|
||||||
|
MAX_FRAME_RATE=24 \
|
||||||
|
VNCOPTIONS="-PreferBandwidth -DynamicQualityMin=4 -DynamicQualityMax=7" \
|
||||||
|
HOME=/home/user \
|
||||||
|
TERM=xterm \
|
||||||
|
STARTUPDIR=/dockerstartup \
|
||||||
|
INST_SCRIPTS=/dockerstartup/install \
|
||||||
|
KASM_RX_HOME=/dockerstartup/kasmrx \
|
||||||
|
DEBIAN_FRONTEND=noninteractive \
|
||||||
|
VNC_COL_DEPTH=24 \
|
||||||
|
VNC_RESOLUTION=1280x1024 \
|
||||||
|
VNC_PW=vncpassword \
|
||||||
|
VNC_USER=user \
|
||||||
|
VNC_VIEW_ONLY_PW=vncviewonlypassword \
|
||||||
|
LD_LIBRARY_PATH=/usr/local/lib/ \
|
||||||
|
OMP_WAIT_POLICY=PASSIVE \
|
||||||
|
SHELL=/bin/bash \
|
||||||
|
SINGLE_APPLICATION=0 \
|
||||||
|
KASMVNC_BUILD_OS=fedora \
|
||||||
|
KASMVNC_BUILD_OS_CODENAME=thirtythree
|
||||||
|
|
||||||
|
EXPOSE $VNC_PORT
|
||||||
|
|
||||||
|
WORKDIR $HOME
|
||||||
|
|
||||||
|
### REQUIRED STUFF ###
|
||||||
|
|
||||||
|
RUN dnf install -y openssl xterm gettext wget
|
||||||
|
RUN dnf install -y nss_wrapper
|
||||||
|
RUN dnf install -y xorg-x11-xauth xkeyboard-config
|
||||||
|
# xorg-x11-server-Xorg
|
||||||
|
# RUN dnf install -y @xfce-desktop-environment
|
||||||
|
RUN dnf erase -y pm-utils xscreensaver*
|
||||||
|
RUN dnf install -y redhat-lsb-core
|
||||||
|
RUN dnf install -y vim less
|
||||||
|
RUN dnf install -y @xfce-desktop-environment
|
||||||
|
|
||||||
|
RUN echo 'source $STARTUPDIR/generate_container_user' >> $HOME/.bashrc
|
||||||
|
|
||||||
|
RUN mkdir -p $STARTUPDIR
|
||||||
|
COPY builder/startup/ $STARTUPDIR
|
||||||
|
|
||||||
|
### START CUSTOM STUFF ####
|
||||||
|
COPY ./builder/scripts/ /tmp/scripts/
|
||||||
|
COPY ./fedora/kasmvncserver.spec /tmp
|
||||||
|
|
||||||
|
ARG KASMVNC_PACKAGE_DIR
|
||||||
|
COPY $KASMVNC_PACKAGE_DIR/*.rpm /tmp/
|
||||||
|
# RUN dnf remove -y tigervnc-server-minimal
|
||||||
|
RUN /tmp/scripts/install_kasmvncserver_package
|
||||||
|
|
||||||
|
### END CUSTOM STUFF ###
|
||||||
|
|
||||||
|
RUN chown -R 1000:0 $HOME
|
||||||
|
USER 1000:kasmvnc-cert
|
||||||
|
WORKDIR $HOME
|
||||||
|
|
||||||
|
ENTRYPOINT [ "/dockerstartup/vnc_startup.sh" ]
|
||||||
86
builder/dockerfile.fedora_thirtynine.build
Normal file
86
builder/dockerfile.fedora_thirtynine.build
Normal 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"]
|
||||||
13
builder/dockerfile.fedora_thirtynine.rpm.build
Normal file
13
builder/dockerfile.fedora_thirtynine.rpm.build
Normal 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
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM opensuse/leap:15.3
|
FROM opensuse/leap:15.5
|
||||||
|
|
||||||
ENV STARTUPDIR=/dockerstartup
|
ENV STARTUPDIR=/dockerstartup
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM opensuse/leap:15.3
|
FROM opensuse/leap:15.5
|
||||||
|
|
||||||
ENV KASMVNC_BUILD_OS opensuse
|
ENV KASMVNC_BUILD_OS opensuse
|
||||||
ENV KASMVNC_BUILD_OS_CODENAME 15
|
ENV KASMVNC_BUILD_OS_CODENAME 15
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM opensuse/leap:15.3
|
FROM opensuse/leap:15.5
|
||||||
|
|
||||||
ENV KASMVNC_BUILD_OS opensuse
|
ENV KASMVNC_BUILD_OS opensuse
|
||||||
ENV KASMVNC_BUILD_OS_CODENAME 15
|
ENV KASMVNC_BUILD_OS_CODENAME 15
|
||||||
|
|||||||
@@ -58,7 +58,8 @@ RUN echo 'alias tv="./run-specs spec/vncserver_yaml_validation_spec.py"' >> ~/.b
|
|||||||
RUN echo 'alias ty="./run-specs spec/vncserver_*spec.py"' >> ~/.bashrc
|
RUN echo 'alias ty="./run-specs spec/vncserver_*spec.py"' >> ~/.bashrc
|
||||||
RUN echo 'alias ta="./run-specs"' >> ~/.bashrc
|
RUN echo 'alias ta="./run-specs"' >> ~/.bashrc
|
||||||
RUN echo 'alias vd="vncserver -dry-run"' >> ~/.bashrc
|
RUN echo 'alias vd="vncserver -dry-run"' >> ~/.bashrc
|
||||||
ENV SET_PASSWORD_FUNC 'sp() { echo -e "$VNC_PW\\n$VNC_PW\\n" | kasmvncpasswd -w -u $USER $HOME/.kasmpasswd; }'
|
RUN echo 'alias ss="sp; vncserver -select-de xfce"' >> ~/.bashrc
|
||||||
|
ENV SET_PASSWORD_FUNC 'sp() { echo -e "$VNC_PW\\n$VNC_PW\\n" | kasmvncpasswd -w -u $VNC_USER $HOME/.kasmpasswd; }'
|
||||||
RUN echo $SET_PASSWORD_FUNC >> ~/.bashrc
|
RUN echo $SET_PASSWORD_FUNC >> ~/.bashrc
|
||||||
|
|
||||||
ENV LC_ALL=C.UTF-8
|
ENV LC_ALL=C.UTF-8
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
Name: kasmvncserver
|
Name: kasmvncserver
|
||||||
Version: 1.1.0
|
Version: 1.3.0
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: VNC server accessible from a web browser
|
Summary: VNC server accessible from a web browser
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@ License: GPLv2+
|
|||||||
URL: https://github.com/kasmtech/KasmVNC
|
URL: https://github.com/kasmtech/KasmVNC
|
||||||
|
|
||||||
BuildRequires: rsync
|
BuildRequires: rsync
|
||||||
Requires: xorg-x11-xauth, xorg-x11-xkb-utils, xkeyboard-config, xorg-x11-server-utils, openssl, perl, perl-Switch, perl-YAML-Tiny, perl-Hash-Merge-Simple, perl-Scalar-List-Utils, perl-List-MoreUtils, perl-Try-Tiny
|
Requires: xorg-x11-xauth, xorg-x11-xkb-utils, xkeyboard-config, xorg-x11-server-utils, openssl, perl, perl-Switch, perl-YAML-Tiny, perl-Hash-Merge-Simple, perl-Scalar-List-Utils, perl-List-MoreUtils, perl-Try-Tiny, perl-DateTime-TimeZone
|
||||||
Conflicts: tigervnc-server, tigervnc-server-minimal
|
Conflicts: tigervnc-server, tigervnc-server-minimal
|
||||||
|
|
||||||
%description
|
%description
|
||||||
@@ -83,6 +83,24 @@ 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
|
||||||
|
* 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
|
||||||
|
- Add support for Unix relays for bidirectional communication between noVNC
|
||||||
|
and containerized applications.
|
||||||
|
- Text based watermark overlays with date and time support.
|
||||||
|
- New builds for Bookworm, Alpine 3.18, and Fedora 38.
|
||||||
|
- Multi-language support.
|
||||||
|
- Add support for rendering pixmaps via DRI3 GPU acceleration allowing
|
||||||
|
compositing and other 3d accelerated workloads in a KasmVNC session.
|
||||||
|
- Fix crash that can occur.
|
||||||
|
- Fixed tearing when compositing is enabled with DRI3 hardware acceleration.
|
||||||
|
- Fix stuck command key on MacOS clients.
|
||||||
* Wed Apr 05 2023 KasmTech <info@kasmweb.com> - 1.1.0-1
|
* Wed Apr 05 2023 KasmTech <info@kasmweb.com> - 1.1.0-1
|
||||||
- Upstream release
|
- Upstream release
|
||||||
* Tue Nov 29 2022 KasmTech <info@kasmweb.com> - 1.0.0-1
|
* Tue Nov 29 2022 KasmTech <info@kasmweb.com> - 1.0.0-1
|
||||||
|
|||||||
17
cmake/Modules/FindFreetype.cmake
Normal file
17
cmake/Modules/FindFreetype.cmake
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# - Find freetype
|
||||||
|
# Find the freetype libraries
|
||||||
|
#
|
||||||
|
# This module defines the following variables:
|
||||||
|
# FREETYPE_FOUND - True if freetype is found
|
||||||
|
# FREETYPE_INCLUDE_DIRS - include directories
|
||||||
|
#
|
||||||
|
|
||||||
|
find_package(PkgConfig)
|
||||||
|
pkg_check_modules(PC_FREETYPE freetype2)
|
||||||
|
find_path(FREETYPE_INCLUDE_DIRS NAMES ft2build.h HINTS ${PC_FREETYPE_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
set(FPHSA_NAME_MISMATCHED 1)
|
||||||
|
find_package_handle_standard_args(freetype DEFAULT_MSG FREETYPE_INCLUDE_DIRS)
|
||||||
|
unset(FPHSA_NAME_MISMATCHED)
|
||||||
|
mark_as_advanced(FREETYPE_INCLUDE_DIRS)
|
||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|||||||
@@ -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; }
|
||||||
|
|
||||||
|
|||||||
@@ -88,6 +88,9 @@ namespace rfb {
|
|||||||
|
|
||||||
virtual void clearLocalClipboards() {}
|
virtual void clearLocalClipboards() {}
|
||||||
|
|
||||||
|
virtual void receivedUnixRelayData(const char name[], const unsigned char *buf,
|
||||||
|
const unsigned len) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~SDesktop() {}
|
virtual ~SDesktop() {}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -98,6 +98,9 @@ namespace rfb {
|
|||||||
virtual void udpUpgrade(const char *resp) = 0;
|
virtual void udpUpgrade(const char *resp) = 0;
|
||||||
virtual void udpDowngrade(const bool) = 0;
|
virtual void udpDowngrade(const bool) = 0;
|
||||||
|
|
||||||
|
virtual void subscribeUnixRelay(const char *name) = 0;
|
||||||
|
virtual void unixRelay(const char *name, const rdr::U8 *buf, const unsigned len) = 0;
|
||||||
|
|
||||||
ConnParams cp;
|
ConnParams cp;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,6 +100,12 @@ void SMsgReader::readMsg()
|
|||||||
case msgTypeUpgradeToUdp:
|
case msgTypeUpgradeToUdp:
|
||||||
readUpgradeToUdp();
|
readUpgradeToUdp();
|
||||||
break;
|
break;
|
||||||
|
case msgTypeSubscribeUnixRelay:
|
||||||
|
readSubscribeUnixRelay();
|
||||||
|
break;
|
||||||
|
case msgTypeUnixRelay:
|
||||||
|
readUnixRelay();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "unknown message type %d\n", msgType);
|
fprintf(stderr, "unknown message type %d\n", msgType);
|
||||||
throw Exception("unknown message type");
|
throw Exception("unknown message type");
|
||||||
@@ -165,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,3 +366,42 @@ void SMsgReader::readUpgradeToUdp()
|
|||||||
|
|
||||||
handler->udpUpgrade(resp);
|
handler->udpUpgrade(resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SMsgReader::readSubscribeUnixRelay()
|
||||||
|
{
|
||||||
|
const rdr::U8 namelen = is->readU8();
|
||||||
|
char name[64];
|
||||||
|
if (namelen >= sizeof(name)) {
|
||||||
|
vlog.error("Ignoring subscribe with too large name");
|
||||||
|
is->skip(namelen);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
is->readBytes(name, namelen);
|
||||||
|
name[namelen] = '\0';
|
||||||
|
|
||||||
|
handler->subscribeUnixRelay(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMsgReader::readUnixRelay()
|
||||||
|
{
|
||||||
|
const rdr::U8 namelen = is->readU8();
|
||||||
|
char name[64];
|
||||||
|
if (namelen >= sizeof(name)) {
|
||||||
|
vlog.error("Ignoring relay packet with too large name");
|
||||||
|
is->skip(namelen);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
is->readBytes(name, namelen);
|
||||||
|
name[namelen] = '\0';
|
||||||
|
|
||||||
|
const rdr::U32 len = is->readU32();
|
||||||
|
rdr::U8 buf[1024 * 1024];
|
||||||
|
if (len >= sizeof(buf)) {
|
||||||
|
vlog.error("Ignoring relay packet with too large data");
|
||||||
|
is->skip(len);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
is->readBytes(buf, len);
|
||||||
|
|
||||||
|
handler->unixRelay(name, buf, len);
|
||||||
|
}
|
||||||
|
|||||||
@@ -65,6 +65,9 @@ namespace rfb {
|
|||||||
|
|
||||||
void readUpgradeToUdp();
|
void readUpgradeToUdp();
|
||||||
|
|
||||||
|
void readSubscribeUnixRelay();
|
||||||
|
void readUnixRelay();
|
||||||
|
|
||||||
SMsgHandler* handler;
|
SMsgHandler* handler;
|
||||||
rdr::InStream* is;
|
rdr::InStream* is;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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);
|
||||||
@@ -749,3 +750,29 @@ void SMsgWriter::writeUdpUpgrade(const char *resp)
|
|||||||
|
|
||||||
endMsg();
|
endMsg();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SMsgWriter::writeSubscribeUnixRelay(const bool success, const char *msg)
|
||||||
|
{
|
||||||
|
startMsg(msgTypeSubscribeUnixRelay);
|
||||||
|
|
||||||
|
const rdr::U8 len = strlen(msg);
|
||||||
|
os->writeU8(success);
|
||||||
|
os->writeU8(len);
|
||||||
|
os->writeBytes(msg, len);
|
||||||
|
|
||||||
|
endMsg();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMsgWriter::writeUnixRelay(const char *name, const rdr::U8 *buf, const unsigned len)
|
||||||
|
{
|
||||||
|
startMsg(msgTypeUnixRelay);
|
||||||
|
|
||||||
|
const rdr::U8 namelen = strlen(name);
|
||||||
|
os->writeU8(namelen);
|
||||||
|
os->writeBytes(name, namelen);
|
||||||
|
|
||||||
|
os->writeU32(len);
|
||||||
|
os->writeBytes(buf, len);
|
||||||
|
|
||||||
|
endMsg();
|
||||||
|
}
|
||||||
|
|||||||
@@ -129,6 +129,9 @@ namespace rfb {
|
|||||||
|
|
||||||
void writeUdpUpgrade(const char *resp);
|
void writeUdpUpgrade(const char *resp);
|
||||||
|
|
||||||
|
void writeSubscribeUnixRelay(const bool success, const char *msg);
|
||||||
|
void writeUnixRelay(const char *name, const rdr::U8 *buf, const unsigned len);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void startMsg(int type);
|
void startMsg(int type);
|
||||||
void endMsg();
|
void endMsg();
|
||||||
@@ -162,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;
|
||||||
|
|||||||
@@ -189,6 +189,22 @@ rfb::IntParameter rfb::Server::DLP_WatermarkRepeatSpace
|
|||||||
("DLP_WatermarkRepeatSpace",
|
("DLP_WatermarkRepeatSpace",
|
||||||
"Number of pixels between repeats of the watermark",
|
"Number of pixels between repeats of the watermark",
|
||||||
0, 0, 4096);
|
0, 0, 4096);
|
||||||
|
rfb::IntParameter rfb::Server::DLP_WatermarkFontSize
|
||||||
|
("DLP_WatermarkFontSize",
|
||||||
|
"Font size for -DLP_WatermarkText",
|
||||||
|
48, 8, 256);
|
||||||
|
rfb::IntParameter rfb::Server::DLP_WatermarkTimeOffset
|
||||||
|
("DLP_WatermarkTimeOffset",
|
||||||
|
"Offset from UTC for -DLP_WatermarkText",
|
||||||
|
0, -24, 24);
|
||||||
|
rfb::IntParameter rfb::Server::DLP_WatermarkTimeOffsetMinutes
|
||||||
|
("DLP_WatermarkTimeOffsetMinutes",
|
||||||
|
"Offset from UTC for -DLP_WatermarkText, minutes",
|
||||||
|
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",
|
||||||
@@ -201,6 +217,14 @@ rfb::StringParameter rfb::Server::DLP_WatermarkTint
|
|||||||
("DLP_WatermarkTint",
|
("DLP_WatermarkTint",
|
||||||
"Tint the greyscale watermark by this color.",
|
"Tint the greyscale watermark by this color.",
|
||||||
"255,255,255,255");
|
"255,255,255,255");
|
||||||
|
rfb::StringParameter rfb::Server::DLP_WatermarkText
|
||||||
|
("DLP_WatermarkText",
|
||||||
|
"Use this text instead of an image for the watermark, with strftime time formatting",
|
||||||
|
"");
|
||||||
|
rfb::StringParameter rfb::Server::DLP_WatermarkFont
|
||||||
|
("DLP_WatermarkFont",
|
||||||
|
"Use this font for -DLP_WatermarkText instead of the bundled one",
|
||||||
|
"");
|
||||||
|
|
||||||
rfb::StringParameter rfb::Server::maxVideoResolution
|
rfb::StringParameter rfb::Server::maxVideoResolution
|
||||||
("MaxVideoResolution",
|
("MaxVideoResolution",
|
||||||
|
|||||||
@@ -49,12 +49,18 @@ namespace rfb {
|
|||||||
static IntParameter DLP_ClipDelay;
|
static IntParameter DLP_ClipDelay;
|
||||||
static IntParameter DLP_KeyRateLimit;
|
static IntParameter DLP_KeyRateLimit;
|
||||||
static IntParameter DLP_WatermarkRepeatSpace;
|
static IntParameter DLP_WatermarkRepeatSpace;
|
||||||
|
static IntParameter DLP_WatermarkFontSize;
|
||||||
|
static IntParameter DLP_WatermarkTimeOffset;
|
||||||
|
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;
|
||||||
static StringParameter DLP_WatermarkImage;
|
static StringParameter DLP_WatermarkImage;
|
||||||
static StringParameter DLP_WatermarkLocation;
|
static StringParameter DLP_WatermarkLocation;
|
||||||
static StringParameter DLP_WatermarkTint;
|
static StringParameter DLP_WatermarkTint;
|
||||||
|
static StringParameter DLP_WatermarkText;
|
||||||
|
static StringParameter DLP_WatermarkFont;
|
||||||
static BoolParameter DLP_RegionAllowClick;
|
static BoolParameter DLP_RegionAllowClick;
|
||||||
static BoolParameter DLP_RegionAllowRelease;
|
static BoolParameter DLP_RegionAllowRelease;
|
||||||
static IntParameter jpegVideoQuality;
|
static IntParameter jpegVideoQuality;
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ static Cursor emptyCursor(0, 0, Point(0, 0), NULL);
|
|||||||
|
|
||||||
extern rfb::BoolParameter disablebasicauth;
|
extern rfb::BoolParameter disablebasicauth;
|
||||||
|
|
||||||
|
extern "C" char unixrelaynames[MAX_UNIX_RELAYS][MAX_UNIX_RELAY_NAME_LEN];
|
||||||
|
|
||||||
VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
|
VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
|
||||||
bool reverse)
|
bool reverse)
|
||||||
: upgradingToUdp(false), sock(s), reverseConnection(reverse),
|
: upgradingToUdp(false), sock(s), reverseConnection(reverse),
|
||||||
@@ -73,6 +75,10 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
|
|||||||
memset(bstats_total, 0, sizeof(bstats_total));
|
memset(bstats_total, 0, sizeof(bstats_total));
|
||||||
gettimeofday(&connStart, NULL);
|
gettimeofday(&connStart, NULL);
|
||||||
|
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < MAX_UNIX_RELAYS; i++)
|
||||||
|
unixRelaySubscriptions[i][0] = '\0';
|
||||||
|
|
||||||
// Check their permissions, if applicable
|
// Check their permissions, if applicable
|
||||||
kasmpasswdpath[0] = '\0';
|
kasmpasswdpath[0] = '\0';
|
||||||
wordexp_t wexp;
|
wordexp_t wexp;
|
||||||
@@ -82,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';
|
||||||
}
|
}
|
||||||
@@ -991,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)) {
|
||||||
@@ -1015,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[])
|
||||||
@@ -1629,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
|
||||||
@@ -1789,3 +1803,54 @@ void VNCSConnectionST::udpDowngrade(const bool byServer)
|
|||||||
vlog.info("Client %s downgrading from udp by %s", sock->getPeerAddress(),
|
vlog.info("Client %s downgrading from udp by %s", sock->getPeerAddress(),
|
||||||
byServer ? "the server" : "its own request");
|
byServer ? "the server" : "its own request");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VNCSConnectionST::subscribeUnixRelay(const char *name)
|
||||||
|
{
|
||||||
|
bool read, write, owner;
|
||||||
|
if (!getPerms(read, write, owner) || !write) {
|
||||||
|
// Need write permissions to subscribe
|
||||||
|
writer()->writeSubscribeUnixRelay(false, "No permissions");
|
||||||
|
vlog.info("Client tried to subscribe to unix channel %s without permissions", name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned i;
|
||||||
|
bool found = false;
|
||||||
|
for (i = 0; i < MAX_UNIX_RELAYS; i++) {
|
||||||
|
if (!strcmp(name, unixrelaynames[i])) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
writer()->writeSubscribeUnixRelay(false, "No such unix channel");
|
||||||
|
vlog.info("Client tried to subscribe to nonexistent unix channel %s", name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
writer()->writeSubscribeUnixRelay(true, "Ok");
|
||||||
|
for (i = 0; i < MAX_UNIX_RELAYS; i++) {
|
||||||
|
if (!unixRelaySubscriptions[i][0]) {
|
||||||
|
strcpy(unixRelaySubscriptions[i], name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VNCSConnectionST::unixRelay(const char *name, const rdr::U8 *buf, const unsigned len)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < MAX_UNIX_RELAYS; i++) {
|
||||||
|
if (!strcmp(unixRelaySubscriptions[i], name)) {
|
||||||
|
server->desktop->receivedUnixRelayData(name, buf, len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VNCSConnectionST::sendUnixRelayData(const char name[], const unsigned char *buf,
|
||||||
|
const unsigned len)
|
||||||
|
{
|
||||||
|
writer()->writeUnixRelay(name, buf, len);
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,6 +33,9 @@
|
|||||||
#include <rfb/EncodeManager.h>
|
#include <rfb/EncodeManager.h>
|
||||||
#include <rfb/SConnection.h>
|
#include <rfb/SConnection.h>
|
||||||
#include <rfb/Timer.h>
|
#include <rfb/Timer.h>
|
||||||
|
#include <rfb/unixRelayLimits.h>
|
||||||
|
|
||||||
|
#include "kasmpasswd.h"
|
||||||
|
|
||||||
namespace rfb {
|
namespace rfb {
|
||||||
class VNCServerST;
|
class VNCServerST;
|
||||||
@@ -200,6 +203,22 @@ namespace rfb {
|
|||||||
|
|
||||||
bool upgradingToUdp;
|
bool upgradingToUdp;
|
||||||
|
|
||||||
|
bool isSubscribedToUnixRelay(const char *name) const {
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < MAX_UNIX_RELAYS; i++) {
|
||||||
|
if (!strcmp(unixRelaySubscriptions[i], name))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void sendUnixRelayData(const char name[], const unsigned char *buf,
|
||||||
|
const unsigned len);
|
||||||
|
|
||||||
|
bool sendWatermark() const {
|
||||||
|
return server->sendWatermark;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// SConnection callbacks
|
// SConnection callbacks
|
||||||
|
|
||||||
@@ -222,6 +241,8 @@ namespace rfb {
|
|||||||
virtual void handleClipboardAnnounce(bool available);
|
virtual void handleClipboardAnnounce(bool available);
|
||||||
virtual void handleClipboardAnnounceBinary(const unsigned num, const char mimes[][32]);
|
virtual void handleClipboardAnnounceBinary(const unsigned num, const char mimes[][32]);
|
||||||
virtual void udpUpgrade(const char *resp);
|
virtual void udpUpgrade(const char *resp);
|
||||||
|
virtual void subscribeUnixRelay(const char *name);
|
||||||
|
virtual void unixRelay(const char *name, const rdr::U8 *buf, const unsigned len);
|
||||||
virtual void supportsLocalCursor();
|
virtual void supportsLocalCursor();
|
||||||
virtual void supportsFence();
|
virtual void supportsFence();
|
||||||
virtual void supportsContinuousUpdates();
|
virtual void supportsContinuousUpdates();
|
||||||
@@ -303,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;
|
||||||
|
|
||||||
@@ -324,6 +345,8 @@ namespace rfb {
|
|||||||
|
|
||||||
bool frameTracking;
|
bool frameTracking;
|
||||||
uint32_t udpFramesSinceFull;
|
uint32_t udpFramesSinceFull;
|
||||||
|
|
||||||
|
char unixRelaySubscriptions[MAX_UNIX_RELAYS][MAX_UNIX_RELAY_NAME_LEN];
|
||||||
bool complainedAboutNoViewRights;
|
bool complainedAboutNoViewRights;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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++;
|
||||||
@@ -974,6 +980,11 @@ void VNCServerST::writeUpdate()
|
|||||||
blackOut();
|
blackOut();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (watermarkData && Server::DLP_WatermarkText[0] && watermarkTextNeedsUpdate(true)) {
|
||||||
|
// The text may have changed
|
||||||
|
sendWatermark = true;
|
||||||
|
}
|
||||||
|
|
||||||
comparer->getUpdateInfo(&ui, pb->getRect());
|
comparer->getUpdateInfo(&ui, pb->getRect());
|
||||||
toCheck = ui.changed.union_(ui.copied);
|
toCheck = ui.changed.union_(ui.copied);
|
||||||
|
|
||||||
@@ -1099,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);
|
||||||
@@ -1248,3 +1261,15 @@ void VNCServerST::refreshClients()
|
|||||||
(*i)->add_changed_all();
|
(*i)->add_changed_all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VNCServerST::sendUnixRelayData(const char name[],
|
||||||
|
const unsigned char *buf, const unsigned len)
|
||||||
|
{
|
||||||
|
// For each client subscribed to this channel, send the data to them
|
||||||
|
std::list<VNCSConnectionST*>::iterator i;
|
||||||
|
for (i = clients.begin(); i != clients.end(); i++) {
|
||||||
|
if ((*i)->isSubscribedToUnixRelay(name)) {
|
||||||
|
(*i)->sendUnixRelayData(name, buf, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -198,6 +198,7 @@ namespace rfb {
|
|||||||
const char mimes[][32]);
|
const char mimes[][32]);
|
||||||
|
|
||||||
void refreshClients();
|
void refreshClients();
|
||||||
|
void sendUnixRelayData(const char name[], const unsigned char *buf, const unsigned len);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@@ -289,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,14 +16,20 @@
|
|||||||
* USA.
|
* USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
#include <png.h>
|
#include <png.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
#include <rfb/LogWriter.h>
|
#include <rfb/LogWriter.h>
|
||||||
#include <rfb/ServerCore.h>
|
#include <rfb/ServerCore.h>
|
||||||
#include <rfb/VNCServerST.h>
|
#include <rfb/VNCServerST.h>
|
||||||
|
#include "font.h"
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
#include FT_GLYPH_H
|
||||||
|
|
||||||
#include "Watermark.h"
|
#include "Watermark.h"
|
||||||
|
|
||||||
@@ -36,6 +42,10 @@ watermarkInfo_t watermarkInfo;
|
|||||||
uint8_t *watermarkData, *watermarkUnpacked, *watermarkTmp;
|
uint8_t *watermarkData, *watermarkUnpacked, *watermarkTmp;
|
||||||
uint32_t watermarkDataLen;
|
uint32_t watermarkDataLen;
|
||||||
static uint16_t rw, rh;
|
static uint16_t rw, rh;
|
||||||
|
static time_t lastUpdate;
|
||||||
|
|
||||||
|
static FT_Library ft = NULL;
|
||||||
|
static FT_Face face;
|
||||||
|
|
||||||
#define MAXW 4096
|
#define MAXW 4096
|
||||||
#define MAXH 4096
|
#define MAXH 4096
|
||||||
@@ -92,15 +102,313 @@ static bool loadimage(const char path[]) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note: w and h are absolute
|
||||||
|
static void str(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) {
|
||||||
|
|
||||||
|
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++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t x, y;
|
||||||
|
|
||||||
|
x = x_;
|
||||||
|
y = y_;
|
||||||
|
for (i = 0; i < ucslen; i++) {
|
||||||
|
if (FT_Load_Char(face, ucs[i], FT_LOAD_RENDER))
|
||||||
|
continue;
|
||||||
|
const FT_Bitmap * const map = &(face->glyph->bitmap);
|
||||||
|
|
||||||
|
if (FT_HAS_KERNING(face) && i) {
|
||||||
|
FT_Vector delta;
|
||||||
|
FT_Get_Kerning(face, ucs[i - 1], ucs[i], ft_kerning_default, &delta);
|
||||||
|
x += delta.x >> 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t drawnwidth(const char *txt) {
|
||||||
|
|
||||||
|
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++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t x;
|
||||||
|
|
||||||
|
x = 0;
|
||||||
|
for (i = 0; i < ucslen; i++) {
|
||||||
|
if (FT_Load_Char(face, ucs[i], FT_LOAD_DEFAULT))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (FT_HAS_KERNING(face) && i) {
|
||||||
|
FT_Vector delta;
|
||||||
|
FT_Get_Kerning(face, ucs[i - 1], ucs[i], ft_kerning_default, &delta);
|
||||||
|
x += delta.x >> 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
x += face->glyph->advance.x >> 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
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[],
|
||||||
|
const uint8_t fontsize) {
|
||||||
|
char buf[PATH_MAX];
|
||||||
|
|
||||||
|
if (!ft) {
|
||||||
|
if (FT_Init_FreeType(&ft))
|
||||||
|
abort();
|
||||||
|
if (fontpath[0]) {
|
||||||
|
if (FT_New_Face(ft, fontpath, 0, &face))
|
||||||
|
abort();
|
||||||
|
} else {
|
||||||
|
if (FT_New_Memory_Face(ft, font_otf, sizeof(font_otf), 0, &face))
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
FT_Set_Pixel_Sizes(face, fontsize, fontsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t now = lastUpdate = time(NULL);
|
||||||
|
now += utcOff * 60;
|
||||||
|
|
||||||
|
struct tm *tm = gmtime(&now);
|
||||||
|
size_t len = strftime(buf, PATH_MAX, fmt, tm);
|
||||||
|
if (!len)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
free(watermarkInfo.src);
|
||||||
|
if (Server::DLP_WatermarkTextAngle) {
|
||||||
|
uint32_t w, h, recw, recy = fontsize;
|
||||||
|
bool invx, invy;
|
||||||
|
angledsize(buf, w, h, recw, recy, invx, invy);
|
||||||
|
|
||||||
|
// The max is because a rotated text with the time can change size.
|
||||||
|
// With the max op, at least it will only grow instead of bouncing.
|
||||||
|
w = __rfbmax(w, watermarkInfo.w);
|
||||||
|
h = __rfbmax(h, watermarkInfo.h);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
bool watermarkInit() {
|
bool watermarkInit() {
|
||||||
memset(&watermarkInfo, 0, sizeof(watermarkInfo_t));
|
memset(&watermarkInfo, 0, sizeof(watermarkInfo_t));
|
||||||
watermarkData = watermarkUnpacked = watermarkTmp = NULL;
|
watermarkData = watermarkUnpacked = watermarkTmp = NULL;
|
||||||
rw = rh = 0;
|
rw = rh = 0;
|
||||||
|
|
||||||
if (!Server::DLP_WatermarkImage[0])
|
if (!Server::DLP_WatermarkImage[0] && !Server::DLP_WatermarkText[0])
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!loadimage(Server::DLP_WatermarkImage))
|
if (Server::DLP_WatermarkImage[0] && Server::DLP_WatermarkText[0]) {
|
||||||
|
vlog.error("WatermarkImage and WatermarkText can't be used together");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Server::DLP_WatermarkImage[0] && !loadimage(Server::DLP_WatermarkImage))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (Server::DLP_WatermarkText[0] &&
|
||||||
|
!drawtext(Server::DLP_WatermarkText,
|
||||||
|
Server::DLP_WatermarkTimeOffset * 60 + Server::DLP_WatermarkTimeOffsetMinutes,
|
||||||
|
Server::DLP_WatermarkFont, Server::DLP_WatermarkFontSize))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (Server::DLP_WatermarkRepeatSpace && Server::DLP_WatermarkLocation[0]) {
|
if (Server::DLP_WatermarkRepeatSpace && Server::DLP_WatermarkLocation[0]) {
|
||||||
@@ -135,11 +443,48 @@ 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
|
||||||
void VNCServerST::updateWatermark() {
|
void VNCServerST::updateWatermark() {
|
||||||
if (rw == pb->width() &&
|
if (rw == pb->width() &&
|
||||||
rh == pb->height())
|
rh == pb->height()) {
|
||||||
return;
|
|
||||||
|
if (Server::DLP_WatermarkImage[0])
|
||||||
|
return;
|
||||||
|
if (!watermarkTextNeedsUpdate(false))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Server::DLP_WatermarkText[0] && watermarkTextNeedsUpdate(false)) {
|
||||||
|
drawtext(Server::DLP_WatermarkText,
|
||||||
|
Server::DLP_WatermarkTimeOffset * 60 + Server::DLP_WatermarkTimeOffsetMinutes,
|
||||||
|
Server::DLP_WatermarkFont, Server::DLP_WatermarkFontSize);
|
||||||
|
}
|
||||||
|
|
||||||
rw = pb->width();
|
rw = pb->width();
|
||||||
rh = pb->height();
|
rh = pb->height();
|
||||||
@@ -203,46 +548,20 @@ void VNCServerST::updateWatermark() {
|
|||||||
rw - sx);
|
rw - sx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
packWatermark();
|
||||||
|
|
||||||
|
sendWatermark = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void packWatermark(const Region &changed) {
|
// Limit changes to once per second
|
||||||
// Take the expanded 4-bit data, filter it by the changed rects, pack
|
bool watermarkTextNeedsUpdate(const bool early) {
|
||||||
// to shared bytes, and compress with zlib
|
static time_t now;
|
||||||
|
|
||||||
uint16_t x, y;
|
// We're called a couple times per frame, only grab the
|
||||||
uint8_t pix[2], cur = 0;
|
// time on the first time so it doesn't change inside a frame
|
||||||
uint8_t *dst = watermarkTmp;
|
if (early)
|
||||||
|
now = time(NULL);
|
||||||
|
|
||||||
const Rect &bounding = changed.get_bounding_rect();
|
return now != lastUpdate && strchr(Server::DLP_WatermarkText, '%');
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ 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);
|
||||||
|
|
||||||
extern uint8_t *watermarkData;
|
extern uint8_t *watermarkData;
|
||||||
extern uint32_t watermarkDataLen;
|
extern uint32_t watermarkDataLen;
|
||||||
|
|||||||
3107
common/rfb/font.h
Normal file
3107
common/rfb/font.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -33,6 +33,8 @@ namespace rfb {
|
|||||||
const int msgTypeRequestFrameStats = 179;
|
const int msgTypeRequestFrameStats = 179;
|
||||||
const int msgTypeBinaryClipboard = 180;
|
const int msgTypeBinaryClipboard = 180;
|
||||||
const int msgTypeUpgradeToUdp = 181;
|
const int msgTypeUpgradeToUdp = 181;
|
||||||
|
const int msgTypeSubscribeUnixRelay = 182;
|
||||||
|
const int msgTypeUnixRelay = 183;
|
||||||
|
|
||||||
const int msgTypeServerFence = 248;
|
const int msgTypeServerFence = 248;
|
||||||
|
|
||||||
@@ -54,6 +56,8 @@ namespace rfb {
|
|||||||
// same as the other direction
|
// same as the other direction
|
||||||
//const int msgTypeBinaryClipboard = 180;
|
//const int msgTypeBinaryClipboard = 180;
|
||||||
//const int msgTypeUpgradeToUdp = 181;
|
//const int msgTypeUpgradeToUdp = 181;
|
||||||
|
//const int msgTypeSubscribeUnixRelay = 182;
|
||||||
|
//const int msgTypeUnixRelay = 183;
|
||||||
|
|
||||||
const int msgTypeClientFence = 248;
|
const int msgTypeClientFence = 248;
|
||||||
|
|
||||||
|
|||||||
7
common/rfb/unixRelayLimits.h
Normal file
7
common/rfb/unixRelayLimits.h
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#ifndef UNIX_RELAY_LIMITS_H
|
||||||
|
#define UNIX_RELAY_LIMITS_H
|
||||||
|
|
||||||
|
#define MAX_UNIX_RELAYS 4
|
||||||
|
#define MAX_UNIX_RELAY_NAME_LEN 64
|
||||||
|
|
||||||
|
#endif
|
||||||
26
debian/changelog
vendored
26
debian/changelog
vendored
@@ -1,3 +1,29 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
* Add support for Unix relays for bidirectional communication between noVNC
|
||||||
|
and containerized applications.
|
||||||
|
* Text based watermark overlays with date and time support.
|
||||||
|
* New builds for Bookworm, Alpine 3.18, and Fedora 38.
|
||||||
|
* Multi-language support.
|
||||||
|
* Add support for rendering pixmaps via DRI3 GPU acceleration allowing
|
||||||
|
compositing and other 3d accelerated workloads in a KasmVNC session.
|
||||||
|
* Fix crash that can occur.
|
||||||
|
* Fixed tearing when compositing is enabled with DRI3 hardware acceleration.
|
||||||
|
* Fix stuck command key on MacOS clients.
|
||||||
|
|
||||||
|
-- Kasm Technologies LLC <info@kasmweb.com> Fri, 25 Aug 2023 05:23:19 +0000
|
||||||
|
|
||||||
kasmvnc (1.1.0-1) unstable; urgency=medium
|
kasmvnc (1.1.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
* New upstream release.
|
* New upstream release.
|
||||||
|
|||||||
2
debian/control
vendored
2
debian/control
vendored
@@ -14,7 +14,7 @@ Architecture: amd64 arm64
|
|||||||
Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}, ssl-cert, xauth,
|
Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}, ssl-cert, xauth,
|
||||||
x11-xkb-utils, xkb-data, procps, libswitch-perl, libyaml-tiny-perl,
|
x11-xkb-utils, xkb-data, procps, libswitch-perl, libyaml-tiny-perl,
|
||||||
libhash-merge-simple-perl, libscalar-list-utils-perl, liblist-moreutils-perl,
|
libhash-merge-simple-perl, libscalar-list-utils-perl, liblist-moreutils-perl,
|
||||||
libtry-tiny-perl, libgbm1
|
libtry-tiny-perl, libdatetime-timezone-perl, libgbm1
|
||||||
Provides: vnc-server
|
Provides: vnc-server
|
||||||
Description: KasmVNC provides remote web-based access to a Desktop or application.
|
Description: KasmVNC provides remote web-based access to a Desktop or application.
|
||||||
While VNC is in the name, KasmVNC differs from other VNC variants such
|
While VNC is in the name, KasmVNC differs from other VNC variants such
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
Name: kasmvncserver
|
Name: kasmvncserver
|
||||||
Version: 1.1.0
|
Version: 1.3.0
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: VNC server accessible from a web browser
|
Summary: VNC server accessible from a web browser
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@ License: GPLv2+
|
|||||||
URL: https://github.com/kasmtech/KasmVNC
|
URL: https://github.com/kasmtech/KasmVNC
|
||||||
|
|
||||||
BuildRequires: rsync
|
BuildRequires: rsync
|
||||||
Requires: xorg-x11-xauth, xkeyboard-config, xkbcomp, openssl, perl, perl-Switch, perl-YAML-Tiny, perl-Hash-Merge-Simple, perl-Scalar-List-Utils, perl-List-MoreUtils, perl-Try-Tiny, mesa-libgbm, libxshmfence
|
Requires: xorg-x11-xauth, xkeyboard-config, xkbcomp, openssl, perl, perl-Switch, perl-YAML-Tiny, perl-Hash-Merge-Simple, perl-Scalar-List-Utils, perl-List-MoreUtils, perl-Try-Tiny, perl-DateTime-TimeZone, mesa-libgbm, libxshmfence
|
||||||
Conflicts: tigervnc-server, tigervnc-server-minimal
|
Conflicts: tigervnc-server, tigervnc-server-minimal
|
||||||
|
|
||||||
%description
|
%description
|
||||||
@@ -83,6 +83,24 @@ 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
|
||||||
|
* 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
|
||||||
|
- Add support for Unix relays for bidirectional communication between noVNC
|
||||||
|
and containerized applications.
|
||||||
|
- Text based watermark overlays with date and time support.
|
||||||
|
- New builds for Bookworm, Alpine 3.18, and Fedora 38.
|
||||||
|
- Multi-language support.
|
||||||
|
- Add support for rendering pixmaps via DRI3 GPU acceleration allowing
|
||||||
|
compositing and other 3d accelerated workloads in a KasmVNC session.
|
||||||
|
- Fix crash that can occur.
|
||||||
|
- Fixed tearing when compositing is enabled with DRI3 hardware acceleration.
|
||||||
|
- Fix stuck command key on MacOS clients.
|
||||||
* Wed Apr 05 2023 KasmTech <info@kasmweb.com> - 1.1.0-1
|
* Wed Apr 05 2023 KasmTech <info@kasmweb.com> - 1.1.0-1
|
||||||
- Upstream release
|
- Upstream release
|
||||||
* Tue Nov 29 2022 KasmTech <info@kasmweb.com> - 1.0.0-1
|
* Tue Nov 29 2022 KasmTech <info@kasmweb.com> - 1.0.0-1
|
||||||
|
|||||||
2
kasmweb
2
kasmweb
Submodule kasmweb updated: 3873a59941...958a60b947
@@ -1,5 +1,5 @@
|
|||||||
Name: kasmvncserver
|
Name: kasmvncserver
|
||||||
Version: 1.1.0
|
Version: 1.3.0
|
||||||
Release: leap15
|
Release: leap15
|
||||||
Summary: VNC server accessible from a web browser
|
Summary: VNC server accessible from a web browser
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@ License: GPLv2+
|
|||||||
URL: https://github.com/kasmtech/KasmVNC
|
URL: https://github.com/kasmtech/KasmVNC
|
||||||
|
|
||||||
BuildRequires: rsync
|
BuildRequires: rsync
|
||||||
Requires: xauth, hostname, libxkbcommon-x11-0, xkeyboard-config, x11-tools, openssl, perl, libpixman-1-0, libjpeg8, libgomp1, libXfont2-2, libXdmcp6, libglvnd, xkbcomp, perl-Switch, perl-YAML-Tiny, perl-Hash-Merge-Simple, perl-Scalar-List-Utils, perl-List-MoreUtils, perl-Try-Tiny, libgbm1, libxshmfence1
|
Requires: xauth, hostname, libxkbcommon-x11-0, xkeyboard-config, x11-tools, openssl, perl, libpixman-1-0, libjpeg8, libgomp1, libXfont2-2, libXdmcp6, libglvnd, xkbcomp, perl-Switch, perl-YAML-Tiny, perl-Hash-Merge-Simple, perl-Scalar-List-Utils, perl-List-MoreUtils, perl-Try-Tiny, perl-DateTime, perl-DateTime-TimeZone, libgbm1, libxshmfence1
|
||||||
Conflicts: tigervnc, tigervnc-x11vnc
|
Conflicts: tigervnc, tigervnc-x11vnc
|
||||||
|
|
||||||
%description
|
%description
|
||||||
@@ -81,6 +81,24 @@ 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
|
||||||
|
* 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
|
||||||
|
- Add support for Unix relays for bidirectional communication between noVNC
|
||||||
|
and containerized applications.
|
||||||
|
- Text based watermark overlays with date and time support.
|
||||||
|
- New builds for Bookworm, Alpine 3.18, and Fedora 38.
|
||||||
|
- Multi-language support.
|
||||||
|
- Add support for rendering pixmaps via DRI3 GPU acceleration allowing
|
||||||
|
compositing and other 3d accelerated workloads in a KasmVNC session.
|
||||||
|
- Fix crash that can occur.
|
||||||
|
- Fixed tearing when compositing is enabled with DRI3 hardware acceleration.
|
||||||
|
- Fix stuck command key on MacOS clients.
|
||||||
* Wed Apr 05 2023 KasmTech <info@kasmweb.com> - 1.1.0-leap15
|
* Wed Apr 05 2023 KasmTech <info@kasmweb.com> - 1.1.0-leap15
|
||||||
- Upstream release
|
- Upstream release
|
||||||
* Tue Nov 29 2022 KasmTech <info@kasmweb.com> - 1.0.0-leap15
|
* Tue Nov 29 2022 KasmTech <info@kasmweb.com> - 1.0.0-leap15
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
Name: kasmvncserver
|
Name: kasmvncserver
|
||||||
Version: 1.1.0
|
Version: 1.3.0
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: VNC server accessible from a web browser
|
Summary: VNC server accessible from a web browser
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@ License: GPLv2+
|
|||||||
URL: https://github.com/kasmtech/KasmVNC
|
URL: https://github.com/kasmtech/KasmVNC
|
||||||
|
|
||||||
BuildRequires: rsync
|
BuildRequires: rsync
|
||||||
Requires: xorg-x11-xauth, xorg-x11-xkb-utils, xkeyboard-config, xorg-x11-server-utils, openssl, perl, perl-Switch, perl-YAML-Tiny, perl-Hash-Merge-Simple, perl-Scalar-List-Utils, perl-List-MoreUtils, perl-Try-Tiny, hostname, mesa-libgbm, libxshmfence
|
Requires: xorg-x11-xauth, xorg-x11-xkb-utils, xkeyboard-config, xorg-x11-server-utils, openssl, perl, perl-Switch, perl-YAML-Tiny, perl-Hash-Merge-Simple, perl-Scalar-List-Utils, perl-List-MoreUtils, perl-Try-Tiny, perl-DateTime-TimeZone, hostname, mesa-libgbm, libxshmfence
|
||||||
Conflicts: tigervnc-server, tigervnc-server-minimal
|
Conflicts: tigervnc-server, tigervnc-server-minimal
|
||||||
|
|
||||||
%description
|
%description
|
||||||
@@ -82,6 +82,24 @@ 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
|
||||||
|
* 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
|
||||||
|
- Add support for Unix relays for bidirectional communication between noVNC
|
||||||
|
and containerized applications.
|
||||||
|
- Text based watermark overlays with date and time support.
|
||||||
|
- New builds for Bookworm, Alpine 3.18, and Fedora 38.
|
||||||
|
- Multi-language support.
|
||||||
|
- Add support for rendering pixmaps via DRI3 GPU acceleration allowing
|
||||||
|
compositing and other 3d accelerated workloads in a KasmVNC session.
|
||||||
|
- Fix crash that can occur.
|
||||||
|
- Fixed tearing when compositing is enabled with DRI3 hardware acceleration.
|
||||||
|
- Fix stuck command key on MacOS clients.
|
||||||
* Wed Apr 05 2023 KasmTech <info@kasmweb.com> - 1.1.0-1
|
* Wed Apr 05 2023 KasmTech <info@kasmweb.com> - 1.1.0-1
|
||||||
- Upstream release
|
- Upstream release
|
||||||
* Tue Nov 29 2022 KasmTech <info@kasmweb.com> - 1.0.0-1
|
* Tue Nov 29 2022 KasmTech <info@kasmweb.com> - 1.0.0-1
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
Name: kasmvncserver
|
Name: kasmvncserver
|
||||||
Version: 1.1.0
|
Version: 1.3.0
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: VNC server accessible from a web browser
|
Summary: VNC server accessible from a web browser
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@ License: GPLv2+
|
|||||||
URL: https://github.com/kasmtech/KasmVNC
|
URL: https://github.com/kasmtech/KasmVNC
|
||||||
|
|
||||||
BuildRequires: rsync
|
BuildRequires: rsync
|
||||||
Requires: xorg-x11-xauth, xkeyboard-config, xorg-x11-server-utils, xkbcomp, openssl, perl, perl-Switch, perl-YAML-Tiny, perl-Hash-Merge-Simple, perl-Scalar-List-Utils, perl-List-MoreUtils, perl-Try-Tiny, hostname, mesa-libgbm, libxshmfence
|
Requires: xorg-x11-xauth, xkeyboard-config, xorg-x11-server-utils, xkbcomp, openssl, perl, perl-Switch, perl-YAML-Tiny, perl-Hash-Merge-Simple, perl-Scalar-List-Utils, perl-List-MoreUtils, perl-Try-Tiny, perl-DateTime-TimeZone, hostname, mesa-libgbm, libxshmfence
|
||||||
Conflicts: tigervnc-server, tigervnc-server-minimal
|
Conflicts: tigervnc-server, tigervnc-server-minimal
|
||||||
|
|
||||||
%description
|
%description
|
||||||
@@ -82,6 +82,24 @@ 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
|
||||||
|
* 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
|
||||||
|
- Add support for Unix relays for bidirectional communication between noVNC
|
||||||
|
and containerized applications.
|
||||||
|
- Text based watermark overlays with date and time support.
|
||||||
|
- New builds for Bookworm, Alpine 3.18, and Fedora 38.
|
||||||
|
- Multi-language support.
|
||||||
|
- Add support for rendering pixmaps via DRI3 GPU acceleration allowing
|
||||||
|
compositing and other 3d accelerated workloads in a KasmVNC session.
|
||||||
|
- Fix crash that can occur.
|
||||||
|
- Fixed tearing when compositing is enabled with DRI3 hardware acceleration.
|
||||||
|
- Fix stuck command key on MacOS clients.
|
||||||
* Wed Apr 05 2023 KasmTech <info@kasmweb.com> - 1.1.0-1
|
* Wed Apr 05 2023 KasmTech <info@kasmweb.com> - 1.1.0-1
|
||||||
- Upstream release
|
- Upstream release
|
||||||
* Tue Nov 29 2022 KasmTech <info@kasmweb.com> - 1.0.0-1
|
* Tue Nov 29 2022 KasmTech <info@kasmweb.com> - 1.0.0-1
|
||||||
|
|||||||
6
spec/fixtures/defaults_config.yaml
vendored
6
spec/fixtures/defaults_config.yaml
vendored
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import os
|
|||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
from os.path import expanduser
|
from os.path import expanduser
|
||||||
from mamba import description, context, fcontext, it, fit, before, after
|
from mamba import description, context, fcontext, it, fit, _it, before, after
|
||||||
from expects import expect, equal, contain, match
|
from expects import expect, equal, contain, match
|
||||||
|
|
||||||
from helper.spec_helper import start_xvnc, kill_xvnc, run_cmd, clean_env, \
|
from helper.spec_helper import start_xvnc, kill_xvnc, run_cmd, clean_env, \
|
||||||
@@ -268,6 +268,18 @@ with description('YAML to CLI') as self:
|
|||||||
completed_process.stdout)
|
completed_process.stdout)
|
||||||
expect(cli_option).to(equal("-geometry '1024x768'"))
|
expect(cli_option).to(equal("-geometry '1024x768'"))
|
||||||
|
|
||||||
|
with it("allows wide utf characters"):
|
||||||
|
write_config('''
|
||||||
|
data_loss_prevention:
|
||||||
|
watermark:
|
||||||
|
text:
|
||||||
|
template: "星街すいせい"
|
||||||
|
''')
|
||||||
|
completed_process = run_vncserver()
|
||||||
|
cli_option = pick_cli_option('DLP_WatermarkText',
|
||||||
|
completed_process.stdout)
|
||||||
|
expect(cli_option).to(equal("-DLP_WatermarkText '星街すいせい'"))
|
||||||
|
|
||||||
with it("ignores empty section override"):
|
with it("ignores empty section override"):
|
||||||
write_config('''
|
write_config('''
|
||||||
security:
|
security:
|
||||||
|
|||||||
9
t
Normal file
9
t
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
use DateTime::TimeZone;
|
||||||
|
|
||||||
|
my $timezone = $ARGV[0];
|
||||||
|
|
||||||
|
if (DateTime::TimeZone->is_valid_name($timezone)) {
|
||||||
|
print "Valid timezone\n";
|
||||||
|
} else {
|
||||||
|
print "Invalid timezone\n";
|
||||||
|
}
|
||||||
11
t2
Normal file
11
t2
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
use DateTime;
|
||||||
|
use DateTime::TimeZone;
|
||||||
|
|
||||||
|
#my $timezone_name = 'America/New_York';
|
||||||
|
my $timezone_name = 'UTC';
|
||||||
|
|
||||||
|
my $dt = DateTime->now(time_zone => $timezone_name);
|
||||||
|
my $offset = $dt->offset();
|
||||||
|
|
||||||
|
print "Timezone: $timezone_name\n";
|
||||||
|
print "Offset: $offset seconds\n";
|
||||||
37
unix/KasmVNC/CallbackValidator.pm
Normal file
37
unix/KasmVNC/CallbackValidator.pm
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package KasmVNC::CallbackValidator;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use v5.10;
|
||||||
|
use Data::Dumper;
|
||||||
|
|
||||||
|
use KasmVNC::Utils;
|
||||||
|
|
||||||
|
sub new {
|
||||||
|
my ($class, $args) = @_;
|
||||||
|
my $self = bless {
|
||||||
|
isValidCallback => $args->{isValidCallback},
|
||||||
|
errorMessage => $args->{errorMessage}
|
||||||
|
}, $class;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub validate {
|
||||||
|
my $self = shift;
|
||||||
|
$self->{configKey} = shift;
|
||||||
|
my @values = @{ listify($self->{configKey}->value()) };
|
||||||
|
|
||||||
|
foreach my $value (@values) {
|
||||||
|
$self->validateValue($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub validateValue {
|
||||||
|
my $self = shift;
|
||||||
|
my $value = shift;
|
||||||
|
|
||||||
|
unless ($self->{isValidCallback}($value)) {
|
||||||
|
$self->{configKey}->addErrorMessage($self->{errorMessage});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
@@ -45,6 +45,8 @@ sub isPresent {
|
|||||||
sub deriveBoolean {
|
sub deriveBoolean {
|
||||||
my $value = shift;
|
my $value = shift;
|
||||||
|
|
||||||
|
return $value if containsWideSymbols($value);
|
||||||
|
|
||||||
switch($value) {
|
switch($value) {
|
||||||
case 'true' {
|
case 'true' {
|
||||||
return 1;
|
return 1;
|
||||||
@@ -63,4 +65,12 @@ sub printStackTrace {
|
|||||||
print { *STDERR } $trace->as_string;
|
print { *STDERR } $trace->as_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub containsWideSymbols {
|
||||||
|
my $string = shift;
|
||||||
|
|
||||||
|
return 1 unless defined($string);
|
||||||
|
|
||||||
|
$string =~ /[^\x00-\xFF]/;
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ network:
|
|||||||
pem_certificate: /etc/ssl/certs/ssl-cert-snakeoil.pem
|
pem_certificate: /etc/ssl/certs/ssl-cert-snakeoil.pem
|
||||||
pem_key: /etc/ssl/private/ssl-cert-snakeoil.key
|
pem_key: /etc/ssl/private/ssl-cert-snakeoil.key
|
||||||
require_ssl: true
|
require_ssl: true
|
||||||
|
# unix_relay:
|
||||||
|
# name:
|
||||||
|
# path:
|
||||||
|
|
||||||
user_session:
|
user_session:
|
||||||
# session_type: shared
|
# session_type: shared
|
||||||
@@ -92,6 +95,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:
|
||||||
# "verbose" SETTING LOGS YOUR PRIVATE INFORMATION. Keypresses and clipboard content
|
# "verbose" SETTING LOGS YOUR PRIVATE INFORMATION. Keypresses and clipboard content
|
||||||
level: off
|
level: off
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
125
unix/vncserver
125
unix/vncserver
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
use v5.10;
|
use v5.10;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
use utf8;
|
||||||
|
|
||||||
sub DEVENV() { $ENV{KASMVNC_DEVELOPMENT} };
|
sub DEVENV() { $ENV{KASMVNC_DEVELOPMENT} };
|
||||||
use if DEVENV, Devel::StackTrace;
|
use if DEVENV, Devel::StackTrace;
|
||||||
@@ -38,11 +39,14 @@ use List::Util qw(first);
|
|||||||
use List::MoreUtils qw(any uniq);
|
use List::MoreUtils qw(any uniq);
|
||||||
use Data::Dumper;
|
use Data::Dumper;
|
||||||
use Try::Tiny;
|
use Try::Tiny;
|
||||||
|
use DateTime;
|
||||||
|
use DateTime::TimeZone;
|
||||||
|
|
||||||
use KasmVNC::CliOption;
|
use KasmVNC::CliOption;
|
||||||
use KasmVNC::ConfigKey;
|
use KasmVNC::ConfigKey;
|
||||||
use KasmVNC::PatternValidator;
|
use KasmVNC::PatternValidator;
|
||||||
use KasmVNC::EnumValidator;
|
use KasmVNC::EnumValidator;
|
||||||
|
use KasmVNC::CallbackValidator;
|
||||||
use KasmVNC::Config;
|
use KasmVNC::Config;
|
||||||
use KasmVNC::Users;
|
use KasmVNC::Users;
|
||||||
use KasmVNC::TextOption;
|
use KasmVNC::TextOption;
|
||||||
@@ -56,6 +60,7 @@ use constant {
|
|||||||
OPTIONAL_ARG_VALUE => 2
|
OPTIONAL_ARG_VALUE => 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
UseUtfStdio();
|
||||||
InitLogger();
|
InitLogger();
|
||||||
|
|
||||||
CheckWeCanRunInThisEnvironment();
|
CheckWeCanRunInThisEnvironment();
|
||||||
@@ -664,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;
|
||||||
@@ -675,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 &");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1397,6 +1403,24 @@ sub DefineConfigToCLIConversion {
|
|||||||
})
|
})
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
|
KasmVNC::CliOption->new({
|
||||||
|
name => 'UnixRelay',
|
||||||
|
configKeys => [
|
||||||
|
KasmVNC::ConfigKey->new({
|
||||||
|
name => "network.unix_relay.name",
|
||||||
|
type => KasmVNC::ConfigKey::ANY
|
||||||
|
}),
|
||||||
|
KasmVNC::ConfigKey->new({
|
||||||
|
name => "network.unix_relay.path",
|
||||||
|
type => KasmVNC::ConfigKey::ANY
|
||||||
|
})
|
||||||
|
],
|
||||||
|
deriveValueSub => sub {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
$self->{"network.unix_relay.name"} . ":" . $self->{"network.unix_relay.path"};
|
||||||
|
},
|
||||||
|
}),
|
||||||
KasmVNC::CliOption->new({
|
KasmVNC::CliOption->new({
|
||||||
name => 'AlwaysShared',
|
name => 'AlwaysShared',
|
||||||
configKeys => [
|
configKeys => [
|
||||||
@@ -1765,6 +1789,97 @@ sub DefineConfigToCLIConversion {
|
|||||||
})
|
})
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
|
KasmVNC::CliOption->new({
|
||||||
|
name => 'DLP_WatermarkText',
|
||||||
|
configKeys => [
|
||||||
|
KasmVNC::ConfigKey->new({
|
||||||
|
name => "data_loss_prevention.watermark.text.template",
|
||||||
|
validator => KasmVNC::CallbackValidator->new({
|
||||||
|
isValidCallback => sub {
|
||||||
|
my $value = shift;
|
||||||
|
|
||||||
|
isBlank(ConfigValue("data_loss_prevention.watermark.image"));
|
||||||
|
},
|
||||||
|
errorMessage => "Watermark image and text can't be used at the same time"
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
]
|
||||||
|
}),
|
||||||
|
KasmVNC::CliOption->new({
|
||||||
|
name => 'DLP_WatermarkFont',
|
||||||
|
configKeys => [
|
||||||
|
KasmVNC::ConfigKey->new({
|
||||||
|
name => "data_loss_prevention.watermark.text.font",
|
||||||
|
type => KasmVNC::ConfigKey::ANY
|
||||||
|
})
|
||||||
|
],
|
||||||
|
isActiveSub => sub {
|
||||||
|
$self = shift;
|
||||||
|
|
||||||
|
my $value = $self->configValue();
|
||||||
|
isPresent($value) && $value ne "auto";
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
KasmVNC::CliOption->new({
|
||||||
|
name => 'DLP_WatermarkFontSize',
|
||||||
|
configKeys => [
|
||||||
|
KasmVNC::ConfigKey->new({
|
||||||
|
name => "data_loss_prevention.watermark.text.font_size",
|
||||||
|
validator => KasmVNC::CallbackValidator->new({
|
||||||
|
isValidCallback => sub {
|
||||||
|
my $value = shift;
|
||||||
|
|
||||||
|
return 0 unless $value =~ /^\d+$/;
|
||||||
|
|
||||||
|
$value >= 8 && $value <= 256;
|
||||||
|
},
|
||||||
|
errorMessage => "must be in range 8..256"
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
]
|
||||||
|
}),
|
||||||
|
KasmVNC::CliOption->new({
|
||||||
|
name => 'DLP_WatermarkTimeOffsetMinutes',
|
||||||
|
configKeys => [
|
||||||
|
KasmVNC::ConfigKey->new({
|
||||||
|
name => "data_loss_prevention.watermark.text.timezone_name",
|
||||||
|
validator => KasmVNC::CallbackValidator->new({
|
||||||
|
isValidCallback => sub {
|
||||||
|
my $timezone_name = shift;
|
||||||
|
|
||||||
|
DateTime::TimeZone->is_valid_name($timezone_name);
|
||||||
|
},
|
||||||
|
errorMessage => "must be a valid timezone name like Australia/Adelaide"
|
||||||
|
})
|
||||||
|
})
|
||||||
|
],
|
||||||
|
deriveValueSub => sub {
|
||||||
|
my $self = shift;
|
||||||
|
my $timezone_name = $self->configValue();
|
||||||
|
my $dt = DateTime->now(time_zone => $timezone_name);
|
||||||
|
my $offset_in_seconds = $dt->offset();
|
||||||
|
|
||||||
|
$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 => [
|
||||||
@@ -2835,3 +2950,7 @@ sub InitLogger {
|
|||||||
my $debugEnabled = any { $_ eq "-debug" } @ARGV;
|
my $debugEnabled = any { $_ eq "-debug" } @ARGV;
|
||||||
$logger = KasmVNC::Logger->new({ level => $debugEnabled ? "debug" : "warn" });
|
$logger = KasmVNC::Logger->new({ level => $debugEnabled ? "debug" : "warn" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub UseUtfStdio {
|
||||||
|
use open qw( :std :encoding(UTF-8) );
|
||||||
|
}
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -52,7 +52,8 @@ Xvnc_CPPFLAGS = $(XVNC_CPPFLAGS) -DKASMVNC -DNO_MODULE_EXTS \
|
|||||||
-I$(top_srcdir)/dri3 @LIBDRM_CFLAGS@
|
-I$(top_srcdir)/dri3 @LIBDRM_CFLAGS@
|
||||||
|
|
||||||
Xvnc_LDADD = $(XVNC_LIBS) libvnccommon.la $(COMMON_LIBS) \
|
Xvnc_LDADD = $(XVNC_LIBS) libvnccommon.la $(COMMON_LIBS) \
|
||||||
$(XSERVER_LIBS) $(XSERVER_SYS_LIBS) $(XVNC_SYS_LIBS) -lX11 -lwebp -lssl -lcrypto -lcrypt
|
$(XSERVER_LIBS) $(XSERVER_SYS_LIBS) $(XVNC_SYS_LIBS) -lX11 -lwebp -lssl -lcrypto -lcrypt \
|
||||||
|
-lfreetype
|
||||||
|
|
||||||
Xvnc_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) -fopenmp
|
Xvnc_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) -fopenmp
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
|
|
||||||
@@ -51,6 +53,7 @@ extern "C" {
|
|||||||
void vncSetGlueContext(int screenIndex);
|
void vncSetGlueContext(int screenIndex);
|
||||||
|
|
||||||
extern int wakeuppipe[2];
|
extern int wakeuppipe[2];
|
||||||
|
extern struct sockaddr_un unixrelayclients[MAX_UNIX_RELAYS];
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace rfb;
|
using namespace rfb;
|
||||||
@@ -323,6 +326,26 @@ void XserverDesktop::handleSocketEvent(int fd, bool read, bool write)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < MAX_UNIX_RELAYS; i++) {
|
||||||
|
if (unixrelays[i] == -1)
|
||||||
|
break;
|
||||||
|
if (fd == unixrelays[i]) {
|
||||||
|
do {
|
||||||
|
struct sockaddr_un client;
|
||||||
|
socklen_t addrlen = sizeof(struct sockaddr_un);
|
||||||
|
const ssize_t len = recvfrom(unixrelays[i], unixbuf, sizeof(unixbuf),
|
||||||
|
MSG_DONTWAIT,
|
||||||
|
(struct sockaddr *) &client, &addrlen);
|
||||||
|
if (len <= 0)
|
||||||
|
break;
|
||||||
|
memcpy(&unixrelayclients[i], &client, addrlen);
|
||||||
|
server->sendUnixRelayData(unixrelaynames[i], unixbuf, len);
|
||||||
|
} while (1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (handleListenerEvent(fd, &listeners, server))
|
if (handleListenerEvent(fd, &listeners, server))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -557,3 +580,21 @@ bool XserverDesktop::handleTimeout(Timer* t)
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XserverDesktop::receivedUnixRelayData(const char name[], const unsigned char *buf,
|
||||||
|
const unsigned len)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < MAX_UNIX_RELAYS; i++) {
|
||||||
|
if (unixrelays[i] == -1)
|
||||||
|
break;
|
||||||
|
if (strcmp(name, unixrelaynames[i]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (sendto(unixrelays[i], buf, len, 0,
|
||||||
|
(struct sockaddr *) &unixrelayclients[i], sizeof(struct sockaddr_un)) == -1)
|
||||||
|
vlog.error("Error writing unix relay data to %s", name);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -110,6 +110,9 @@ public:
|
|||||||
const char* userName,
|
const char* userName,
|
||||||
char** reason);
|
char** reason);
|
||||||
|
|
||||||
|
virtual void receivedUnixRelayData(const char name[], const unsigned char *buf,
|
||||||
|
const unsigned len);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool handleListenerEvent(int fd,
|
bool handleListenerEvent(int fd,
|
||||||
std::list<network::SocketListener*>* sockets,
|
std::list<network::SocketListener*>* sockets,
|
||||||
@@ -138,5 +141,7 @@ private:
|
|||||||
rfb::Point oldCursorPos;
|
rfb::Point oldCursorPos;
|
||||||
|
|
||||||
bool resizing;
|
bool resizing;
|
||||||
|
|
||||||
|
uint8_t unixbuf[1024 * 1024];
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -89,6 +89,11 @@ Use IPv4 for incoming and outgoing connections. Default is on.
|
|||||||
Use IPv6 for incoming and outgoing connections. Default is on.
|
Use IPv6 for incoming and outgoing connections. Default is on.
|
||||||
.
|
.
|
||||||
.TP
|
.TP
|
||||||
|
.B \-UnixRelay \fIname:path\fP
|
||||||
|
Create a local named unix socket, for relaying data. May be given multiple times.
|
||||||
|
Example: -UnixRelay audio:/tmp/audiosock
|
||||||
|
.
|
||||||
|
.TP
|
||||||
.B \-rfbunixpath \fIpath\fP
|
.B \-rfbunixpath \fIpath\fP
|
||||||
Specifies the path of a Unix domain socket on which Xvnc listens for
|
Specifies the path of a Unix domain socket on which Xvnc listens for
|
||||||
connections from viewers, instead of listening on a TCP port.
|
connections from viewers, instead of listening on a TCP port.
|
||||||
@@ -243,6 +248,8 @@ Default \fB-1\fP.
|
|||||||
.B \-WebpVideoQuality \fInum\fP
|
.B \-WebpVideoQuality \fInum\fP
|
||||||
The WEBP quality to use when in video mode.
|
The WEBP quality to use when in video mode.
|
||||||
Default \fB-1\fP.
|
Default \fB-1\fP.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
.B \-MaxVideoResolution \fI1920x1080\fP
|
.B \-MaxVideoResolution \fI1920x1080\fP
|
||||||
When in video mode, downscale the screen to max this size. Keeps aspect ratio.
|
When in video mode, downscale the screen to max this size. Keeps aspect ratio.
|
||||||
Default \fB1920x1080\fP.
|
Default \fB1920x1080\fP.
|
||||||
@@ -372,6 +379,32 @@ The color components can be used to colorize the greyscale watermark, and the al
|
|||||||
can be used to make it fainter.
|
can be used to make it fainter.
|
||||||
.
|
.
|
||||||
.TP
|
.TP
|
||||||
|
.B \-DLP_WatermarkText \fI"foo %H:%M"\fP
|
||||||
|
Instead of an image, render this text as the watermark. Takes time formatting options
|
||||||
|
for \fBstrftime\fP.
|
||||||
|
.
|
||||||
|
.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
|
||||||
|
Use a different font for -DLP_WatermarkText than the bundled one. TTF and OTF fonts
|
||||||
|
are accepted.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.B \-DLP_WatermarkFontSize \fI48\fP
|
||||||
|
Font size for -DLP_WatermarkText. Default \fI48\fP.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.B \-DLP_WatermarkTimeOffset \fI0\fP
|
||||||
|
Time offset from UTC, hours. Default \fI0\fP.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.B \-DLP_WatermarkTimeOffsetMinutes \fI0\fP
|
||||||
|
Time offset from UTC, minutes. Default \fI0\fP.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
.B \-selfBench
|
.B \-selfBench
|
||||||
Run a set of self-benchmarks and exit.
|
Run a set of self-benchmarks and exit.
|
||||||
.
|
.
|
||||||
|
|||||||
@@ -55,6 +55,15 @@ typedef struct gbm_pixmap gbm_pixmap;
|
|||||||
static DevPrivateKeyRec dri3_pixmap_private_key;
|
static DevPrivateKeyRec dri3_pixmap_private_key;
|
||||||
static struct timeval start;
|
static struct timeval start;
|
||||||
|
|
||||||
|
#define MAX_TEXPIXMAPS 32
|
||||||
|
static PixmapPtr texpixmaps[MAX_TEXPIXMAPS];
|
||||||
|
static uint32_t num_texpixmaps;
|
||||||
|
static CARD32 update_texpixmaps(OsTimerPtr timer, CARD32 time, void *arg);
|
||||||
|
static OsTimerPtr texpixmaptimer;
|
||||||
|
|
||||||
|
void xvnc_sync_dri3_textures(void);
|
||||||
|
void xvnc_sync_dri3_pixmap(PixmapPtr pixmap);
|
||||||
|
void xvnc_init_dri3(void);
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -99,6 +108,29 @@ static gbm_pixmap *gbm_pixmap_get(PixmapPtr pixmap)
|
|||||||
return dixLookupPrivate(&pixmap->devPrivates, &dri3_pixmap_private_key);
|
return dixLookupPrivate(&pixmap->devPrivates, &dri3_pixmap_private_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void add_texpixmap(PixmapPtr pix)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
for (i = 0; i < MAX_TEXPIXMAPS; i++) {
|
||||||
|
if (texpixmaps[i] == pix)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_TEXPIXMAPS; i++) {
|
||||||
|
if (!texpixmaps[i]) {
|
||||||
|
texpixmaps[i] = pix;
|
||||||
|
pix->refcnt++;
|
||||||
|
num_texpixmaps++;
|
||||||
|
// start if not running
|
||||||
|
if (!texpixmaptimer)
|
||||||
|
texpixmaptimer = TimerSet(NULL, 0, 16, update_texpixmaps, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorF("Max number of texpixmaps reached\n");
|
||||||
|
}
|
||||||
|
|
||||||
static PixmapPtr
|
static PixmapPtr
|
||||||
create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo, CARD8 depth)
|
create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo, CARD8 depth)
|
||||||
{
|
{
|
||||||
@@ -164,14 +196,33 @@ xvnc_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
|
|||||||
uint64_t *modifier)
|
uint64_t *modifier)
|
||||||
{
|
{
|
||||||
gbm_pixmap *gp = gbm_pixmap_get(pixmap);
|
gbm_pixmap *gp = gbm_pixmap_get(pixmap);
|
||||||
if (!gp)
|
|
||||||
return 0;
|
if (!gp) {
|
||||||
|
gp = calloc(1, sizeof(gbm_pixmap));
|
||||||
|
if (!gp)
|
||||||
|
return 0;
|
||||||
|
gp->bo = gbm_bo_create(priv.gbm,
|
||||||
|
pixmap->drawable.width,
|
||||||
|
pixmap->drawable.height,
|
||||||
|
gbm_format_for_depth(pixmap->drawable.depth),
|
||||||
|
(pixmap->usage_hint == CREATE_PIXMAP_USAGE_SHARED ?
|
||||||
|
GBM_BO_USE_LINEAR : 0) |
|
||||||
|
GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT);
|
||||||
|
if (!gp->bo) {
|
||||||
|
ErrorF("Failed to create bo\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dri3_pixmap_set_private(pixmap, gp);
|
||||||
|
}
|
||||||
|
|
||||||
fds[0] = gbm_bo_get_fd(gp->bo);
|
fds[0] = gbm_bo_get_fd(gp->bo);
|
||||||
strides[0] = gbm_bo_get_stride(gp->bo);
|
strides[0] = gbm_bo_get_stride(gp->bo);
|
||||||
offsets[0] = 0;
|
offsets[0] = 0;
|
||||||
*modifier = DRM_FORMAT_MOD_INVALID;
|
*modifier = DRM_FORMAT_MOD_INVALID;
|
||||||
|
|
||||||
|
add_texpixmap(pixmap);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,12 +270,13 @@ void xvnc_sync_dri3_pixmap(PixmapPtr pixmap)
|
|||||||
void *ptr;
|
void *ptr;
|
||||||
uint32_t stride, w, h;
|
uint32_t stride, w, h;
|
||||||
void *opaque = NULL;
|
void *opaque = NULL;
|
||||||
|
gbm_pixmap *gp;
|
||||||
|
|
||||||
// We may not be running on hw if there's a compositor using PRESENT on llvmpipe
|
// We may not be running on hw if there's a compositor using PRESENT on llvmpipe
|
||||||
if (!driNode)
|
if (!driNode)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gbm_pixmap *gp = gbm_pixmap_get(pixmap);
|
gp = gbm_pixmap_get(pixmap);
|
||||||
if (!gp) {
|
if (!gp) {
|
||||||
//ErrorF("Present tried to copy from a non-dri3 pixmap\n");
|
//ErrorF("Present tried to copy from a non-dri3 pixmap\n");
|
||||||
return;
|
return;
|
||||||
@@ -252,6 +304,69 @@ void xvnc_sync_dri3_pixmap(PixmapPtr pixmap)
|
|||||||
gbm_bo_unmap(gp->bo, opaque);
|
gbm_bo_unmap(gp->bo, opaque);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void xvnc_sync_dri3_textures(void)
|
||||||
|
{
|
||||||
|
// Sync the tracked pixmaps into their textures (bos)
|
||||||
|
// This is a bit of an ugly solution, but we don't know
|
||||||
|
// when the pixmaps have changed nor when the textures are read.
|
||||||
|
//
|
||||||
|
// This is called both from the global damage report and the timer,
|
||||||
|
// to account for cases that do not use the damage report.
|
||||||
|
|
||||||
|
uint32_t i, y;
|
||||||
|
gbm_pixmap *gp;
|
||||||
|
uint8_t *src, *dst;
|
||||||
|
uint32_t srcstride, dststride;
|
||||||
|
void *opaque = NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_TEXPIXMAPS; i++) {
|
||||||
|
if (!texpixmaps[i])
|
||||||
|
continue;
|
||||||
|
if (texpixmaps[i]->refcnt == 1) {
|
||||||
|
// We are the only user left, delete it
|
||||||
|
texpixmaps[i]->drawable.pScreen->DestroyPixmap(texpixmaps[i]);
|
||||||
|
texpixmaps[i] = NULL;
|
||||||
|
num_texpixmaps--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
gp = gbm_pixmap_get(texpixmaps[i]);
|
||||||
|
opaque = NULL;
|
||||||
|
dst = gbm_bo_map(gp->bo, 0, 0,
|
||||||
|
texpixmaps[i]->drawable.width,
|
||||||
|
texpixmaps[i]->drawable.height,
|
||||||
|
GBM_BO_TRANSFER_WRITE, &dststride, &opaque);
|
||||||
|
if (!dst) {
|
||||||
|
ErrorF("gbm map failed, errno %d\n", errno);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
srcstride = texpixmaps[i]->devKind;
|
||||||
|
src = texpixmaps[i]->devPrivate.ptr;
|
||||||
|
|
||||||
|
for (y = 0; y < texpixmaps[i]->drawable.height; y++) {
|
||||||
|
memcpy(dst, src, srcstride);
|
||||||
|
dst += dststride;
|
||||||
|
src += srcstride;
|
||||||
|
}
|
||||||
|
|
||||||
|
gbm_bo_unmap(gp->bo, opaque);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static CARD32 update_texpixmaps(OsTimerPtr timer, CARD32 time, void *arg)
|
||||||
|
{
|
||||||
|
xvnc_sync_dri3_textures();
|
||||||
|
|
||||||
|
if (!num_texpixmaps) {
|
||||||
|
TimerFree(texpixmaptimer);
|
||||||
|
texpixmaptimer = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 16; // Reschedule next tick
|
||||||
|
}
|
||||||
|
|
||||||
void xvnc_init_dri3(void)
|
void xvnc_init_dri3(void)
|
||||||
{
|
{
|
||||||
memset(&priv, 0, sizeof(priv));
|
memset(&priv, 0, sizeof(priv));
|
||||||
|
|||||||
@@ -241,6 +241,14 @@ void vncExtensionInit(void)
|
|||||||
fcntl(wakeuppipe[0], F_SETFL, flags | O_NONBLOCK);
|
fcntl(wakeuppipe[0], F_SETFL, flags | O_NONBLOCK);
|
||||||
vncSetNotifyFd(wakeuppipe[0], 0, true, false);
|
vncSetNotifyFd(wakeuppipe[0], 0, true, false);
|
||||||
|
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < MAX_UNIX_RELAYS; i++) {
|
||||||
|
if (unixrelays[i] == -1)
|
||||||
|
break;
|
||||||
|
vncSetNotifyFd(unixrelays[i], 0, true, false);
|
||||||
|
vlog.info("Listening to unix relay socket %s", unixrelaynames[i]);
|
||||||
|
}
|
||||||
|
|
||||||
initialised = true;
|
initialised = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
|
|
||||||
|
#include <rfb/unixRelayLimits.h>
|
||||||
|
|
||||||
// Only from C++
|
// Only from C++
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
namespace rfb { class StringParameter; };
|
namespace rfb { class StringParameter; };
|
||||||
@@ -106,6 +108,9 @@ void vncRefreshScreenLayout(int scrIdx);
|
|||||||
|
|
||||||
int vncOverrideParam(const char *nameAndValue);
|
int vncOverrideParam(const char *nameAndValue);
|
||||||
|
|
||||||
|
extern int unixrelays[MAX_UNIX_RELAYS];
|
||||||
|
extern char unixrelaynames[MAX_UNIX_RELAYS][MAX_UNIX_RELAY_NAME_LEN];
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -61,8 +61,11 @@ from the X Consortium.
|
|||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "mipointer.h"
|
#include "mipointer.h"
|
||||||
#include "micmap.h"
|
#include "micmap.h"
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@@ -93,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.1.0"
|
#define XVNCVERSION "KasmVNC 1.3.0"
|
||||||
#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")
|
||||||
|
|
||||||
@@ -163,6 +166,73 @@ static char displayNumStr[16];
|
|||||||
|
|
||||||
static int vncVerbose = DEFAULT_LOG_VERBOSITY;
|
static int vncVerbose = DEFAULT_LOG_VERBOSITY;
|
||||||
|
|
||||||
|
int unixrelays[MAX_UNIX_RELAYS];
|
||||||
|
char unixrelaynames[MAX_UNIX_RELAYS][MAX_UNIX_RELAY_NAME_LEN];
|
||||||
|
struct sockaddr_un unixrelayclients[MAX_UNIX_RELAYS];
|
||||||
|
|
||||||
|
static unsigned addrelay(const char * const arg)
|
||||||
|
{
|
||||||
|
const char *ptr = strchr(arg, ':');
|
||||||
|
if (!ptr) {
|
||||||
|
ErrorF("Invalid unixrelay\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned namelen = ptr - arg;
|
||||||
|
if (namelen >= MAX_UNIX_RELAY_NAME_LEN) {
|
||||||
|
ErrorF("Unix relay name too long\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned i;
|
||||||
|
unsigned char found = 0;
|
||||||
|
for (i = 0; i < MAX_UNIX_RELAYS; i++) {
|
||||||
|
if (unixrelays[i] == -1) {
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
ErrorF("Too many unix relays\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(unixrelaynames[i], arg, namelen);
|
||||||
|
unixrelaynames[i][namelen] = '\0';
|
||||||
|
|
||||||
|
unixrelays[i] = socket(AF_UNIX, SOCK_DGRAM, 0);
|
||||||
|
if (unixrelays[i] < 0) {
|
||||||
|
ErrorF("Failed to create unix sock\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr++;
|
||||||
|
struct sockaddr_un sa;
|
||||||
|
if (strlen(ptr) >= sizeof(sa.sun_path)) {
|
||||||
|
ErrorF("Unix relay path too long\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sa.sun_family = AF_UNIX;
|
||||||
|
strcpy(sa.sun_path, ptr);
|
||||||
|
|
||||||
|
// SO_REUSEADDR doesn't exist for unix sockets, if the socket exists
|
||||||
|
// (from our previous run), we need to delete it first. Check it's a
|
||||||
|
// socket so we don't delete wrong files
|
||||||
|
struct stat st;
|
||||||
|
if (stat(ptr, &st) == 0) {
|
||||||
|
if (S_ISSOCK(st.st_mode))
|
||||||
|
unlink(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bind(unixrelays[i], (struct sockaddr *) &sa, sizeof(struct sockaddr_un))) {
|
||||||
|
ErrorF("Failed to bind unix sock\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
char *extra_headers = NULL;
|
char *extra_headers = NULL;
|
||||||
unsigned extra_headers_len = 0;
|
unsigned extra_headers_len = 0;
|
||||||
|
|
||||||
@@ -374,6 +444,7 @@ void ddxUseMsg(void)
|
|||||||
ErrorF("-inetd has been launched from inetd\n");
|
ErrorF("-inetd has been launched from inetd\n");
|
||||||
ErrorF("-http-header name=val append this header to all HTTP responses\n");
|
ErrorF("-http-header name=val append this header to all HTTP responses\n");
|
||||||
ErrorF("-noclipboard disable clipboard settings modification via vncconfig utility\n");
|
ErrorF("-noclipboard disable clipboard settings modification via vncconfig utility\n");
|
||||||
|
ErrorF("-unixrelay name:path create a local named unix relay socket\n");
|
||||||
ErrorF("-verbose [n] verbose startup messages\n");
|
ErrorF("-verbose [n] verbose startup messages\n");
|
||||||
ErrorF("-quiet minimal startup messages\n");
|
ErrorF("-quiet minimal startup messages\n");
|
||||||
ErrorF("-version show the server version\n");
|
ErrorF("-version show the server version\n");
|
||||||
@@ -426,6 +497,13 @@ ddxProcessArgument(int argc, char *argv[], int i)
|
|||||||
|
|
||||||
vfbInitializeDefaultScreens();
|
vfbInitializeDefaultScreens();
|
||||||
vfbInitializePixmapDepths();
|
vfbInitializePixmapDepths();
|
||||||
|
|
||||||
|
unsigned r;
|
||||||
|
for (r = 0; r < MAX_UNIX_RELAYS; r++) {
|
||||||
|
unixrelays[r] = -1;
|
||||||
|
unixrelaynames[r][0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
firstTime = FALSE;
|
firstTime = FALSE;
|
||||||
vncInitRFB();
|
vncInitRFB();
|
||||||
}
|
}
|
||||||
@@ -692,6 +770,16 @@ ddxProcessArgument(int argc, char *argv[], int i)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strcasecmp(argv[i], "-unixrelay") == 0)
|
||||||
|
{
|
||||||
|
fail_unless_args(argc, i, 1);
|
||||||
|
++i;
|
||||||
|
|
||||||
|
if (addrelay(argv[i]))
|
||||||
|
return 0;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
if (!strcmp(argv[i], "-verbose")) {
|
if (!strcmp(argv[i], "-verbose")) {
|
||||||
if (++i < argc && argv[i]) {
|
if (++i < argc && argv[i]) {
|
||||||
char *end;
|
char *end;
|
||||||
@@ -1916,6 +2004,8 @@ InitOutput(ScreenInfo *scrInfo, int argc, char **argv)
|
|||||||
#else
|
#else
|
||||||
FatalError("DRI3 disabled at compile time\n");
|
FatalError("DRI3 disabled at compile time\n");
|
||||||
#endif
|
#endif
|
||||||
|
} else {
|
||||||
|
driNode = NULL;
|
||||||
}
|
}
|
||||||
} /* end InitOutput */
|
} /* end InitOutput */
|
||||||
|
|
||||||
|
|||||||
@@ -111,3 +111,23 @@ Index: xserver/mi/miinitext.c
|
|||||||
gc = GetScratchGC(drawable->depth, screen);
|
gc = GetScratchGC(drawable->depth, screen);
|
||||||
if (update) {
|
if (update) {
|
||||||
ChangeGCVal changes[2];
|
ChangeGCVal changes[2];
|
||||||
|
--- xserver.orig/damageext/damageext.c 2019-02-26 21:28:50.000000000 +0200
|
||||||
|
+++ xserver/damageext/damageext.c 2023-03-21 12:52:58.411647186 +0200
|
||||||
|
@@ -87,6 +87,8 @@
|
||||||
|
*h = draw->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
+void xvnc_sync_dri3_textures(void);
|
||||||
|
+
|
||||||
|
static void
|
||||||
|
DamageExtNotify(DamageExtPtr pDamageExt, BoxPtr pBoxes, int nBoxes)
|
||||||
|
{
|
||||||
|
@@ -97,6 +99,8 @@
|
||||||
|
|
||||||
|
damageGetGeometry(pDrawable, &x, &y, &w, &h);
|
||||||
|
|
||||||
|
+ xvnc_sync_dri3_textures();
|
||||||
|
+
|
||||||
|
UpdateCurrentTimeIf();
|
||||||
|
ev = (xDamageNotifyEvent) {
|
||||||
|
.type = DamageEventBase + XDamageNotify,
|
||||||
|
|||||||
Reference in New Issue
Block a user