Compare commits

...

No commits in common. "c8" and "c9" have entirely different histories.
c8 ... c9

18 changed files with 1294 additions and 523 deletions

3
.gitignore vendored
View File

@ -1 +1,2 @@
SOURCES/gnome-remote-desktop-0.1.8.tar.xz
SOURCES/LibVNCServer-0.9.13.tar.gz
SOURCES/gnome-remote-desktop-40.0.tar.xz

View File

@ -1 +1,2 @@
3347257bd906cd0ca86887c692befd8d412afab1 SOURCES/gnome-remote-desktop-0.1.8.tar.xz
55d79e6c4305cd67cd487c601298349c17ca05c1 SOURCES/LibVNCServer-0.9.13.tar.gz
7c7688373ac31e724515f8b105922c3423e4469a SOURCES/gnome-remote-desktop-40.0.tar.xz

View File

@ -0,0 +1,92 @@
From fdc71dd25c8505b3580e70afd4b4213cad8f8ebb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Mon, 25 Oct 2021 16:14:26 +0200
Subject: [PATCH] crypto: Don't compile SHA1 support when Websockets are
disabled
SHA1 is not ideal, security wise. Let's make sure we don't even have it
compiled when nothing depends on it, e.g. Websockets.
---
common/crypto.h | 2 ++
common/crypto_included.c | 2 ++
common/crypto_libgcrypt.c | 2 ++
common/crypto_openssl.c | 2 ++
4 files changed, 8 insertions(+)
diff --git a/common/crypto.h b/common/crypto.h
index 04be9304..c1f32194 100644
--- a/common/crypto.h
+++ b/common/crypto.h
@@ -11,7 +11,9 @@
int hash_md5(void *out, const void *in, const size_t in_len);
/* Generates an SHA1 hash of 'in' and writes it to 'out', which must be 20 bytes in size. */
+#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
int hash_sha1(void *out, const void *in, const size_t in_len);
+#endif
/* Fill 'out' with 'len' random bytes. */
void random_bytes(void *out, size_t len);
diff --git a/common/crypto_included.c b/common/crypto_included.c
index b359336f..cf8d43c2 100644
--- a/common/crypto_included.c
+++ b/common/crypto_included.c
@@ -33,6 +33,7 @@ int hash_md5(void *out, const void *in, const size_t in_len)
return 0;
}
+#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
int hash_sha1(void *out, const void *in, const size_t in_len)
{
SHA1Context sha1;
@@ -45,6 +46,7 @@ int hash_sha1(void *out, const void *in, const size_t in_len)
return 1;
}
+#endif /* LIBVNCSERVER_WITH_WEBSOCKETS */
void random_bytes(void *out, size_t len)
{
diff --git a/common/crypto_libgcrypt.c b/common/crypto_libgcrypt.c
index 34d845b4..f62bdaf8 100644
--- a/common/crypto_libgcrypt.c
+++ b/common/crypto_libgcrypt.c
@@ -74,6 +74,7 @@ int hash_md5(void *out, const void *in, const size_t in_len)
return result;
}
+#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
int hash_sha1(void *out, const void *in, const size_t in_len)
{
int result = 0;
@@ -98,6 +99,7 @@ int hash_sha1(void *out, const void *in, const size_t in_len)
gcry_md_close(sha1);
return result;
}
+#endif /* LIBVNCSERVER_WITH_WEBSOCKETS */
void random_bytes(void *out, size_t len)
{
diff --git a/common/crypto_openssl.c b/common/crypto_openssl.c
index 60d4bd4d..9816eb04 100644
--- a/common/crypto_openssl.c
+++ b/common/crypto_openssl.c
@@ -49,6 +49,7 @@ int hash_md5(void *out, const void *in, const size_t in_len)
return 1;
}
+#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
int hash_sha1(void *out, const void *in, const size_t in_len)
{
SHA_CTX sha1;
@@ -60,6 +61,7 @@ int hash_sha1(void *out, const void *in, const size_t in_len)
return 0;
return 1;
}
+#endif /* LIBVNCSERVER_WITH_WEBSOCKETS */
void random_bytes(void *out, size_t len)
{
--
2.31.1

View File

@ -0,0 +1,241 @@
From e4849b01fec4494057728d1aa3a165ed21705682 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Mon, 11 Jun 2018 23:47:02 +0200
Subject: [PATCH 1/4] libvncserver: Add API to add custom I/O entry points
Add API to make it possible to channel RFB input and output through
another layer, for example TLS. This is done by making it possible to
override the default read/write/peek functions.
---
libvncserver/rfbserver.c | 4 ++
libvncserver/sockets.c | 79 ++++++++++++++++++++++++++++++++++++----
rfb/rfb.h | 17 +++++++++
3 files changed, 93 insertions(+), 7 deletions(-)
diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c
index e9eaa5fc..72e9ba79 100644
--- a/libvncserver/rfbserver.c
+++ b/libvncserver/rfbserver.c
@@ -319,6 +319,10 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen,
cl->screen = rfbScreen;
cl->sock = sock;
+ cl->readFromSocket = rfbDefaultReadFromSocket;
+ cl->peekAtSocket = rfbDefaultPeekAtSocket;
+ cl->hasPendingOnSocket = rfbDefaultHasPendingOnSocket;
+ cl->writeToSocket = rfbDefaultWriteToSocket;
cl->viewOnly = FALSE;
/* setup pseudo scaling */
cl->scaledScreen = rfbScreen;
diff --git a/libvncserver/sockets.c b/libvncserver/sockets.c
index 2c87376b..4bb881ec 100644
--- a/libvncserver/sockets.c
+++ b/libvncserver/sockets.c
@@ -101,6 +101,9 @@ int deny_severity=LOG_WARNING;
int rfbMaxClientWait = 20000; /* time (ms) after which we decide client has
gone away - needed to stop us hanging */
+static rfbBool
+rfbHasPendingOnSocket(rfbClientPtr cl);
+
static rfbBool
rfbNewConnectionFromSock(rfbScreenInfoPtr rfbScreen, rfbSocket sock)
{
@@ -364,16 +367,20 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
tv.tv_usec = usec;
nfds = select(rfbScreen->maxFd + 1, &fds, NULL, NULL /* &fds */, &tv);
if (nfds == 0) {
+ rfbBool hasPendingData = FALSE;
+
/* timed out, check for async events */
i = rfbGetClientIterator(rfbScreen);
while((cl = rfbClientIteratorNext(i))) {
if (cl->onHold)
continue;
+ hasPendingData |= rfbHasPendingOnSocket(cl);
if (FD_ISSET(cl->sock, &(rfbScreen->allFds)))
rfbSendFileTransferChunk(cl);
}
rfbReleaseClientIterator(i);
- return result;
+ if (!hasPendingData)
+ return result;
}
if (nfds < 0) {
@@ -449,9 +456,11 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
if (cl->onHold)
continue;
- if (FD_ISSET(cl->sock, &(rfbScreen->allFds)))
+ if (rfbHasPendingOnSocket (cl) ||
+ FD_ISSET(cl->sock, &(rfbScreen->allFds)))
{
- if (FD_ISSET(cl->sock, &fds))
+ if (rfbHasPendingOnSocket (cl) ||
+ FD_ISSET(cl->sock, &fds))
{
#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
do {
@@ -614,6 +623,30 @@ rfbConnect(rfbScreenInfoPtr rfbScreen,
return sock;
}
+int
+rfbDefaultReadFromSocket(rfbClientPtr cl, char *buf, int len)
+{
+ return read(cl->sock, buf, len);
+}
+
+static int
+rfbReadFromSocket(rfbClientPtr cl, char *buf, int len)
+{
+ return cl->readFromSocket(cl, buf, len);
+}
+
+rfbBool
+rfbDefaultHasPendingOnSocket(rfbClientPtr cl)
+{
+ return FALSE;
+}
+
+static rfbBool
+rfbHasPendingOnSocket(rfbClientPtr cl)
+{
+ return cl->hasPendingOnSocket(cl);
+}
+
/*
* ReadExact reads an exact number of bytes from a client. Returns 1 if
* those bytes have been read, 0 if the other end has closed, or -1 if an error
@@ -635,10 +668,10 @@ rfbReadExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
} else if (cl->sslctx) {
n = rfbssl_read(cl, buf, len);
} else {
- n = read(sock, buf, len);
+ n = rfbReadFromSocket(cl, buf, len);
}
#else
- n = read(sock, buf, len);
+ n = rfbReadFromSocket(cl, buf, len);
#endif
if (n > 0) {
@@ -670,6 +703,10 @@ rfbReadExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
continue;
}
#endif
+
+ if (rfbHasPendingOnSocket(cl))
+ continue;
+
FD_ZERO(&fds);
FD_SET(sock, &fds);
tv.tv_sec = timeout / 1000;
@@ -706,6 +743,18 @@ int rfbReadExact(rfbClientPtr cl,char* buf,int len)
return(rfbReadExactTimeout(cl,buf,len,rfbMaxClientWait));
}
+int
+rfbDefaultPeekAtSocket(rfbClientPtr cl, char *buf, int len)
+{
+ return recv(cl->sock, buf, len, MSG_PEEK);
+}
+
+int
+rfbPeekAtSocket(rfbClientPtr cl, char *buf, int len)
+{
+ cl->peekAtSocket(cl, buf, len);
+}
+
/*
* PeekExact peeks at an exact number of bytes from a client. Returns 1 if
* those bytes have been read, 0 if the other end has closed, or -1 if an
@@ -726,7 +775,7 @@ rfbPeekExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
n = rfbssl_peek(cl, buf, len);
else
#endif
- n = recv(sock, buf, len, MSG_PEEK);
+ n = rfbPeekAtSocket(cl, buf, len);
if (n == len) {
@@ -782,6 +831,22 @@ rfbPeekExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
return 1;
}
+int
+rfbDefaultWriteToSocket(rfbClientPtr cl,
+ const char *buf,
+ int len)
+{
+ return write(cl->sock, buf, len);
+}
+
+static int
+rfbWriteToSocket(rfbClientPtr cl,
+ const char *buf,
+ int len)
+{
+ return cl->writeToSocket(cl, buf, len);
+}
+
/*
* WriteExact writes an exact number of bytes to a client. Returns 1 if
* those bytes have been written, or -1 if an error occurred (errno is set to
@@ -826,7 +891,7 @@ rfbWriteExact(rfbClientPtr cl,
n = rfbssl_write(cl, buf, len);
else
#endif
- n = write(sock, buf, len);
+ n = rfbWriteToSocket(cl, buf, len);
if (n > 0) {
diff --git a/rfb/rfb.h b/rfb/rfb.h
index 5e9ba86f..3c0b25a3 100644
--- a/rfb/rfb.h
+++ b/rfb/rfb.h
@@ -387,6 +387,14 @@ typedef struct sraRegion* sraRegionPtr;
typedef void (*ClientGoneHookPtr)(struct _rfbClientRec* cl);
typedef void (*ClientFramebufferUpdateRequestHookPtr)(struct _rfbClientRec* cl, rfbFramebufferUpdateRequestMsg* furMsg);
+typedef int (*ClientReadFromSocket)(struct _rfbClientRec* cl,
+ char *buf, int len);
+typedef int (*ClientPeekAtSocket)(struct _rfbClientRec* cl,
+ char *buf, int len);
+typedef rfbBool (*ClientHasPendingOnSocket)(struct _rfbClientRec* cl);
+typedef int (*ClientWriteToSocket)(struct _rfbClientRec* cl,
+ const char *buf, int len);
+
typedef struct _rfbFileTransferData {
int fd;
int compressionEnabled;
@@ -680,6 +688,11 @@ typedef struct _rfbClientRec {
rfbBool useExtDesktopSize;
int requestedDesktopSizeChange;
int lastDesktopSizeChangeError;
+
+ ClientReadFromSocket readFromSocket; /* Read data from socket */
+ ClientPeekAtSocket peekAtSocket; /* Peek at data from socket */
+ ClientHasPendingOnSocket hasPendingOnSocket; /* Peek at data from socket */
+ ClientWriteToSocket writeToSocket; /* Write data to socket */
} rfbClientRec, *rfbClientPtr;
/**
@@ -732,8 +745,12 @@ extern void rfbDisconnectUDPSock(rfbScreenInfoPtr rfbScreen);
extern void rfbCloseClient(rfbClientPtr cl);
extern int rfbReadExact(rfbClientPtr cl, char *buf, int len);
extern int rfbReadExactTimeout(rfbClientPtr cl, char *buf, int len,int timeout);
+extern int rfbDefaultReadFromSocket(rfbClientPtr cl, char *buf, int len);
extern int rfbPeekExactTimeout(rfbClientPtr cl, char *buf, int len,int timeout);
+extern int rfbDefaultPeekAtSocket(rfbClientPtr cl, char *buf, int len);
+extern rfbBool rfbDefaultHasPendingOnSocket(rfbClientPtr cl);
extern int rfbWriteExact(rfbClientPtr cl, const char *buf, int len);
+extern int rfbDefaultWriteToSocket(rfbClientPtr cl, const char *buf, int len);
extern int rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec);
extern rfbSocket rfbConnect(rfbScreenInfoPtr rfbScreen, char* host, int port);
extern rfbSocket rfbConnectToTcpAddr(char* host, int port);
--
2.28.0

View File

@ -0,0 +1,28 @@
From d138cf90130b0e8d5062f136ecdbcaa85e734d5d Mon Sep 17 00:00:00 2001
From: Christian Beier <info@christianbeier.net>
Date: Mon, 20 Jul 2020 22:33:29 +0200
Subject: [PATCH] libvncserver: don't NULL out internal of the default cursor
...otherwise an rfbScreen created after rfbScreenCleanup() was called
gets assigned an invalid cursor struct.
---
libvncserver/main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libvncserver/main.c b/libvncserver/main.c
index 9149fda3..a3a711e3 100644
--- a/libvncserver/main.c
+++ b/libvncserver/main.c
@@ -1110,7 +1110,8 @@ void rfbScreenCleanup(rfbScreenInfoPtr screen)
FREE_IF(underCursorBuffer);
TINI_MUTEX(screen->cursorMutex);
- rfbFreeCursor(screen->cursor);
+ if(screen->cursor != &myCursor)
+ rfbFreeCursor(screen->cursor);
#ifdef LIBVNCSERVER_HAVE_LIBZ
rfbZlibCleanup(screen);
--
2.28.0

View File

@ -0,0 +1,53 @@
From 2fba1c597f272516759933ee439e6fef3f6142f3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Tue, 6 Apr 2021 11:32:14 +0200
Subject: [PATCH] pipewire-stream: Don't leak GSource's
The pipewire loop is owned by the source, and failing to free it means
pipewire will keep file descriptors open indefinitely.
While we properly "destroy":ed the source, destroying it only removes it
from the context, it doesn't destroy or unref it. To also free it, we
also need to unref it.
---
src/grd-rdp-pipewire-stream.c | 6 +++++-
src/grd-vnc-pipewire-stream.c | 6 +++++-
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/src/grd-rdp-pipewire-stream.c b/src/grd-rdp-pipewire-stream.c
index 09015e7..6c79312 100644
--- a/src/grd-rdp-pipewire-stream.c
+++ b/src/grd-rdp-pipewire-stream.c
@@ -577,7 +577,11 @@ grd_rdp_pipewire_stream_finalize (GObject *object)
g_clear_pointer (&stream->pipewire_core, pw_core_disconnect);
g_clear_pointer (&stream->pipewire_context, pw_context_destroy);
- g_clear_pointer (&stream->pipewire_source, g_source_destroy);
+ if (stream->pipewire_source)
+ {
+ g_source_destroy (stream->pipewire_source);
+ g_clear_pointer (&stream->pipewire_source, g_source_unref);
+ }
G_OBJECT_CLASS (grd_rdp_pipewire_stream_parent_class)->finalize (object);
}
diff --git a/src/grd-vnc-pipewire-stream.c b/src/grd-vnc-pipewire-stream.c
index 82ceb9b..5085062 100644
--- a/src/grd-vnc-pipewire-stream.c
+++ b/src/grd-vnc-pipewire-stream.c
@@ -594,7 +594,11 @@ grd_vnc_pipewire_stream_finalize (GObject *object)
g_clear_pointer (&stream->pipewire_core, pw_core_disconnect);
g_clear_pointer (&stream->pipewire_context, pw_context_destroy);
- g_clear_pointer (&stream->pipewire_source, g_source_destroy);
+ if (stream->pipewire_source)
+ {
+ g_source_destroy (stream->pipewire_source);
+ g_clear_pointer (&stream->pipewire_source, g_source_unref);
+ }
G_OBJECT_CLASS (grd_vnc_pipewire_stream_parent_class)->finalize (object);
}
--
2.31.1

View File

@ -1,52 +0,0 @@
From 7670167e578eb5c6e032cff38112edf85df142ee Mon Sep 17 00:00:00 2001
From: Wim Taymans <wtaymans@redhat.com>
Date: Tue, 16 Jun 2020 11:44:52 +0200
Subject: [PATCH 1/2] stream: log a warning on error
When we get an invalid buffer or we can't mmap() it, log a warning
and exit instead of carying on with invalid pointers and segfault.
---
src/grd-vnc-pipewire-stream.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/src/grd-vnc-pipewire-stream.c b/src/grd-vnc-pipewire-stream.c
index 261292a..91fb0a1 100644
--- a/src/grd-vnc-pipewire-stream.c
+++ b/src/grd-vnc-pipewire-stream.c
@@ -323,14 +323,18 @@ process_buffer (GrdVncPipeWireStream *stream,
if (buffer->datas[0].chunk->size == 0)
{
- size = 0;
- map = NULL;
- src_data = NULL;
+ g_warning ("Received empty buffer");
+ return NULL;
}
else if (buffer->datas[0].type == SPA_DATA_MemFd)
{
size = buffer->datas[0].maxsize + buffer->datas[0].mapoffset;
map = mmap (NULL, size, PROT_READ, MAP_PRIVATE, buffer->datas[0].fd, 0);
+ if (map == MAP_FAILED)
+ {
+ g_warning ("Failed to mmap buffer: %s", g_strerror (errno));
+ return NULL;
+ }
src_data = SPA_MEMBER (map, buffer->datas[0].mapoffset, uint8_t);
}
else if (buffer->datas[0].type == SPA_DATA_DmaBuf)
@@ -341,6 +345,11 @@ process_buffer (GrdVncPipeWireStream *stream,
size = buffer->datas[0].maxsize + buffer->datas[0].mapoffset;
map = mmap (NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (map == MAP_FAILED)
+ {
+ g_warning ("Failed to mmap DMA buffer: %s", g_strerror (errno));
+ return NULL;
+ }
sync_dma_buf (fd, DMA_BUF_SYNC_START);
src_data = SPA_MEMBER (map, buffer->datas[0].mapoffset, uint8_t);
--
2.26.2

View File

@ -1,73 +0,0 @@
From 78c5bcb181fe2b0b9fc17eea696feac8b504df54 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Thu, 7 May 2020 15:48:22 +0200
Subject: [PATCH] vnc/pipewire-stream: Handle stride mismatch
The VNC server framebuffer assumes a particular stride; but there is no
guarantee that we'll get the same from PipeWire. Handle this gracefully
by coping row by row instead of the whole buffer.
---
src/grd-vnc-pipewire-stream.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/src/grd-vnc-pipewire-stream.c b/src/grd-vnc-pipewire-stream.c
index 88c07be..261292a 100644
--- a/src/grd-vnc-pipewire-stream.c
+++ b/src/grd-vnc-pipewire-stream.c
@@ -187,8 +187,6 @@ on_stream_param_changed (void *user_data,
struct spa_pod_builder pod_builder;
int width;
int height;
- int stride;
- int size;
const struct spa_pod *params[3];
if (!format || id != SPA_PARAM_Format)
@@ -203,14 +201,9 @@ on_stream_param_changed (void *user_data,
grd_session_vnc_queue_resize_framebuffer (stream->session, width, height);
- stride = grd_session_vnc_get_framebuffer_stride (stream->session);
- size = stride * height;
-
params[0] = spa_pod_builder_add_object (
&pod_builder,
SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers,
- SPA_PARAM_BUFFERS_size, SPA_POD_Int (size),
- SPA_PARAM_BUFFERS_stride, SPA_POD_Int (stride),
SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int (8, 1, 8),
0);
@@ -319,6 +312,10 @@ process_buffer (GrdVncPipeWireStream *stream,
size_t size;
uint8_t *map;
void *src_data;
+ int src_stride;
+ int dst_stride;
+ int height;
+ int y;
struct spa_meta_cursor *spa_meta_cursor;
g_autofree GrdVncFrame *frame = NULL;
@@ -359,7 +356,17 @@ process_buffer (GrdVncPipeWireStream *stream,
return NULL;
}
- frame->data = g_memdup (src_data, buffer->datas[0].maxsize);
+ src_stride = buffer->datas[0].chunk->stride;
+ dst_stride = grd_session_vnc_get_framebuffer_stride (stream->session);
+ height = stream->spa_format.size.height;
+
+ frame->data = g_malloc (height * dst_stride);
+ for (y = 0; y < height; y++)
+ {
+ memcpy (((uint8_t *) frame->data) + y * dst_stride,
+ ((uint8_t *) src_data) + y * src_stride,
+ dst_stride);
+ }
if (map)
{
--
2.26.2

View File

@ -1,25 +0,0 @@
From 240d8694fbcdeb020e7f9c0f8f292a4679b88b30 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Thu, 18 Jun 2020 13:14:04 +0200
Subject: [PATCH] vnc/pipewire-stream: Remove assert
Handle lack of frames gracefully.
---
src/grd-vnc-pipewire-stream.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/grd-vnc-pipewire-stream.c b/src/grd-vnc-pipewire-stream.c
index ee8ad5d..a3f5fb6 100644
--- a/src/grd-vnc-pipewire-stream.c
+++ b/src/grd-vnc-pipewire-stream.c
@@ -463,7 +463,6 @@ on_stream_process (void *user_data)
frame = process_buffer (stream, buffer->buffer);
- g_assert (frame);
g_mutex_lock (&stream->frame_mutex);
if (stream->pending_frame)
{
--
2.26.2

View File

@ -0,0 +1,368 @@
From c9131a78878a785c3de21e9d49521d7b68400ad7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Mon, 11 Jun 2018 23:50:05 +0200
Subject: [PATCH 2/4] libvncserver: Add channel security handlers
Add another type of security handler that is meant to be used initially
to set up a secure channel. Regular security handlers would be
advertised and processed after any channel security have succeeded.
For example, this, together with the custom I/O functions allows a
LibVNCServer user to implement TLS in combination with VNCAuth. This is
done by adding a single channel security handler with the rfbTLS (18)
with a handler that initiates a TLS session, and when a TLS session is
initiated, the regular security handler list is sent.
---
libvncserver/auth.c | 164 ++++++++++++++++++++++++++++++---------
libvncserver/rfbserver.c | 1 +
rfb/rfb.h | 15 +++-
3 files changed, 142 insertions(+), 38 deletions(-)
diff --git a/libvncserver/auth.c b/libvncserver/auth.c
index 814a8142..55e0b3c9 100644
--- a/libvncserver/auth.c
+++ b/libvncserver/auth.c
@@ -37,18 +37,17 @@ void rfbClientSendString(rfbClientPtr cl, const char *reason);
* Handle security types
*/
+/* Channel security handlers to set up a secure channel, e.g. TLS. */
+static rfbSecurityHandler* channelSecurityHandlers = NULL;
+
+/* Security handlers when channel security is established. */
static rfbSecurityHandler* securityHandlers = NULL;
-/*
- * This method registers a list of new security types.
- * It avoids same security type getting registered multiple times.
- * The order is not preserved if multiple security types are
- * registered at one-go.
- */
void
-rfbRegisterSecurityHandler(rfbSecurityHandler* handler)
+rfbRegisterSecurityHandlerTo(rfbSecurityHandler* handler,
+ rfbSecurityHandler** handlerList)
{
- rfbSecurityHandler *head = securityHandlers, *next = NULL;
+ rfbSecurityHandler *head = *handlerList, *next = NULL;
if(handler == NULL)
return;
@@ -57,39 +56,35 @@ rfbRegisterSecurityHandler(rfbSecurityHandler* handler)
while(head != NULL) {
if(head == handler) {
- rfbRegisterSecurityHandler(next);
+ rfbRegisterSecurityHandlerTo(next, handlerList);
return;
}
head = head->next;
}
- handler->next = securityHandlers;
- securityHandlers = handler;
+ handler->next = *handlerList;
+ *handlerList = handler;
- rfbRegisterSecurityHandler(next);
+ rfbRegisterSecurityHandlerTo(next, handlerList);
}
-/*
- * This method unregisters a list of security types.
- * These security types won't be available for any new
- * client connection.
- */
-void
-rfbUnregisterSecurityHandler(rfbSecurityHandler* handler)
+static void
+rfbUnregisterSecurityHandlerFrom(rfbSecurityHandler* handler,
+ rfbSecurityHandler** handlerList)
{
rfbSecurityHandler *cur = NULL, *pre = NULL;
if(handler == NULL)
return;
- if(securityHandlers == handler) {
- securityHandlers = securityHandlers->next;
- rfbUnregisterSecurityHandler(handler->next);
+ if(*handlerList == handler) {
+ *handlerList = (*handlerList)->next;
+ rfbUnregisterSecurityHandlerFrom(handler->next, handlerList);
return;
}
- cur = pre = securityHandlers;
+ cur = pre = *handlerList;
while(cur) {
if(cur == handler) {
@@ -99,7 +94,50 @@ rfbUnregisterSecurityHandler(rfbSecurityHandler* handler)
pre = cur;
cur = cur->next;
}
- rfbUnregisterSecurityHandler(handler->next);
+ rfbUnregisterSecurityHandlerFrom(handler->next, handlerList);
+}
+
+void
+rfbRegisterChannelSecurityHandler(rfbSecurityHandler* handler)
+{
+ rfbRegisterSecurityHandlerTo(handler, &channelSecurityHandlers);
+}
+
+/*
+ * This method unregisters a list of security types.
+ * These security types won't be available for any new
+ * client connection.
+ */
+
+void
+rfbUnregisterChannelSecurityHandler(rfbSecurityHandler* handler)
+{
+ rfbUnregisterSecurityHandlerFrom(handler, &channelSecurityHandlers);
+}
+
+/*
+ * This method registers a list of new security types.
+ * It avoids same security type getting registered multiple times.
+ * The order is not preserved if multiple security types are
+ * registered at one-go.
+ */
+
+void
+rfbRegisterSecurityHandler(rfbSecurityHandler* handler)
+{
+ rfbRegisterSecurityHandlerTo(handler, &securityHandlers);
+}
+
+/*
+ * This method unregisters a list of security types.
+ * These security types won't be available for any new
+ * client connection.
+ */
+
+void
+rfbUnregisterSecurityHandler(rfbSecurityHandler* handler)
+{
+ rfbUnregisterSecurityHandlerFrom(handler, &securityHandlers);
}
/*
@@ -197,9 +235,22 @@ static rfbSecurityHandler VncSecurityHandlerNone = {
NULL
};
+static int32_t
+determinePrimarySecurityType(rfbClientPtr cl)
+{
+ if (!cl->screen->authPasswdData || cl->reverseConnection) {
+ /* chk if this condition is valid or not. */
+ return rfbSecTypeNone;
+ } else if (cl->screen->authPasswdData) {
+ return rfbSecTypeVncAuth;
+ } else {
+ return rfbSecTypeInvalid;
+ }
+}
-static void
-rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType)
+void
+rfbSendSecurityTypeList(rfbClientPtr cl,
+ enum rfbSecurityTag exclude)
{
/* The size of the message is the count of security types +1,
* since the first byte is the number of types. */
@@ -207,9 +258,10 @@ rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType)
rfbSecurityHandler* handler;
#define MAX_SECURITY_TYPES 255
uint8_t buffer[MAX_SECURITY_TYPES+1];
-
+ int32_t primaryType;
/* Fill in the list of security types in the client structure. (NOTE: Not really in the client structure) */
+ primaryType = determinePrimarySecurityType(cl);
switch (primaryType) {
case rfbSecTypeNone:
rfbRegisterSecurityHandler(&VncSecurityHandlerNone);
@@ -221,6 +273,9 @@ rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType)
for (handler = securityHandlers;
handler && size<MAX_SECURITY_TYPES; handler = handler->next) {
+ if (exclude && (handler->securityTags & exclude))
+ continue;
+
buffer[size] = handler->type;
size++;
}
@@ -249,7 +304,29 @@ rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType)
cl->state = RFB_SECURITY_TYPE;
}
+static void
+rfbSendChannelSecurityTypeList(rfbClientPtr cl)
+{
+ int size = 1;
+ rfbSecurityHandler* handler;
+ uint8_t buffer[MAX_SECURITY_TYPES+1];
+
+ for (handler = channelSecurityHandlers;
+ handler && size<MAX_SECURITY_TYPES; handler = handler->next) {
+ buffer[size] = handler->type;
+ size++;
+ }
+ buffer[0] = (unsigned char)size-1;
+
+ if (rfbWriteExact(cl, (char *)buffer, size) < 0) {
+ rfbLogPerror("rfbSendSecurityTypeList: write");
+ rfbCloseClient(cl);
+ return;
+ }
+ /* Dispatch client input to rfbProcessClientChannelSecurityType. */
+ cl->state = RFB_CHANNEL_SECURITY_TYPE;
+}
/*
@@ -297,18 +374,19 @@ rfbSendSecurityType(rfbClientPtr cl, int32_t securityType)
void
rfbAuthNewClient(rfbClientPtr cl)
{
- int32_t securityType = rfbSecTypeInvalid;
+ int32_t securityType;
- if (!cl->screen->authPasswdData || cl->reverseConnection) {
- /* chk if this condition is valid or not. */
- securityType = rfbSecTypeNone;
- } else if (cl->screen->authPasswdData) {
- securityType = rfbSecTypeVncAuth;
- }
+ securityType = determinePrimarySecurityType(cl);
if (cl->protocolMajorVersion==3 && cl->protocolMinorVersion < 7)
{
/* Make sure we use only RFB 3.3 compatible security types. */
+ if (channelSecurityHandlers) {
+ rfbLog("VNC channel security enabled - RFB 3.3 client rejected\n");
+ rfbClientConnFailed(cl, "Your viewer cannot hnadler required "
+ "security methods");
+ return;
+ }
if (securityType == rfbSecTypeInvalid) {
rfbLog("VNC authentication disabled - RFB 3.3 client rejected\n");
rfbClientConnFailed(cl, "Your viewer cannot handle required "
@@ -316,9 +394,13 @@ rfbAuthNewClient(rfbClientPtr cl)
return;
}
rfbSendSecurityType(cl, securityType);
+ } else if (channelSecurityHandlers) {
+ rfbLog("Send channel security type list\n");
+ rfbSendChannelSecurityTypeList(cl);
} else {
/* Here it's ok when securityType is set to rfbSecTypeInvalid. */
- rfbSendSecurityTypeList(cl, securityType);
+ rfbLog("Send channel security type 'none'\n");
+ rfbSendSecurityTypeList(cl, RFB_SECURITY_TAG_NONE);
}
}
@@ -332,6 +414,7 @@ rfbProcessClientSecurityType(rfbClientPtr cl)
int n;
uint8_t chosenType;
rfbSecurityHandler* handler;
+ rfbSecurityHandler* handlerListHead;
/* Read the security type. */
n = rfbReadExact(cl, (char *)&chosenType, 1);
@@ -344,8 +427,17 @@ rfbProcessClientSecurityType(rfbClientPtr cl)
return;
}
+ switch (cl->state) {
+ case RFB_CHANNEL_SECURITY_TYPE:
+ handlerListHead = channelSecurityHandlers;
+ break;
+ case RFB_SECURITY_TYPE:
+ handlerListHead = securityHandlers;
+ break;
+ }
+
/* Make sure it was present in the list sent by the server. */
- for (handler = securityHandlers; handler; handler = handler->next) {
+ for (handler = handlerListHead; handler; handler = handler->next) {
if (chosenType == handler->type) {
rfbLog("rfbProcessClientSecurityType: executing handler for type %d\n", chosenType);
handler->handler(cl);
diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c
index 72e9ba79..48eada64 100644
--- a/libvncserver/rfbserver.c
+++ b/libvncserver/rfbserver.c
@@ -652,6 +652,7 @@ rfbProcessClientMessage(rfbClientPtr cl)
case RFB_PROTOCOL_VERSION:
rfbProcessClientProtocolVersion(cl);
return;
+ case RFB_CHANNEL_SECURITY_TYPE:
case RFB_SECURITY_TYPE:
rfbProcessClientSecurityType(cl);
return;
diff --git a/rfb/rfb.h b/rfb/rfb.h
index 3c0b25a3..d136f884 100644
--- a/rfb/rfb.h
+++ b/rfb/rfb.h
@@ -144,6 +144,11 @@ typedef struct {
} data; /**< there have to be count*3 entries */
} rfbColourMap;
+enum rfbSecurityTag {
+ RFB_SECURITY_TAG_NONE = 0,
+ RFB_SECURITY_TAG_CHANNEL = 1 << 0
+};
+
/**
* Security handling (RFB protocol version 3.7)
*/
@@ -152,6 +157,7 @@ typedef struct _rfbSecurity {
uint8_t type;
void (*handler)(struct _rfbClientRec* cl);
struct _rfbSecurity* next;
+ enum rfbSecurityTag securityTags;
} rfbSecurityHandler;
/**
@@ -480,7 +486,7 @@ typedef struct _rfbClientRec {
/** Possible client states: */
enum {
RFB_PROTOCOL_VERSION, /**< establishing protocol version */
- RFB_SECURITY_TYPE, /**< negotiating security (RFB v.3.7) */
+ RFB_SECURITY_TYPE, /**< negotiating security (RFB v.3.7) */
RFB_AUTHENTICATION, /**< authenticating */
RFB_INITIALISATION, /**< sending initialisation messages */
RFB_NORMAL, /**< normal protocol messages */
@@ -488,7 +494,9 @@ typedef struct _rfbClientRec {
/* Ephemeral internal-use states that will never be seen by software
* using LibVNCServer to provide services: */
- RFB_INITIALISATION_SHARED /**< sending initialisation messages with implicit shared-flag already true */
+ RFB_INITIALISATION_SHARED, /**< sending initialisation messages with implicit shared-flag already true */
+
+ RFB_CHANNEL_SECURITY_TYPE, /**< negotiating security (RFB v.3.7) */
} state;
rfbBool reverseConnection;
@@ -840,6 +848,9 @@ extern void rfbProcessClientSecurityType(rfbClientPtr cl);
extern void rfbAuthProcessClientMessage(rfbClientPtr cl);
extern void rfbRegisterSecurityHandler(rfbSecurityHandler* handler);
extern void rfbUnregisterSecurityHandler(rfbSecurityHandler* handler);
+extern void rfbRegisterChannelSecurityHandler(rfbSecurityHandler* handler);
+extern void rfbUnregisterChannelSecurityHandler(rfbSecurityHandler* handler);
+extern void rfbSendSecurityTypeList(rfbClientPtr cl, enum rfbSecurityTag exclude);
/* rre.c */
--
2.28.0

View File

@ -1,62 +0,0 @@
From f3efe25a5cb173bc63b380619b8673cd5ba99f6f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Thu, 18 Jun 2020 11:35:44 +0200
Subject: [PATCH 2/2] vnc/pipewire-stream: Only try to copy frame pixels if
there are any
The producer might send empty frames with only cursor metadata, and in
this case we shouldn't try to copy any pixels, as there are no.
---
src/grd-vnc-pipewire-stream.c | 28 ++++++++++++++++------------
1 file changed, 16 insertions(+), 12 deletions(-)
diff --git a/src/grd-vnc-pipewire-stream.c b/src/grd-vnc-pipewire-stream.c
index 91fb0a1..ee8ad5d 100644
--- a/src/grd-vnc-pipewire-stream.c
+++ b/src/grd-vnc-pipewire-stream.c
@@ -312,9 +312,6 @@ process_buffer (GrdVncPipeWireStream *stream,
size_t size;
uint8_t *map;
void *src_data;
- int src_stride;
- int dst_stride;
- int height;
int y;
struct spa_meta_cursor *spa_meta_cursor;
g_autofree GrdVncFrame *frame = NULL;
@@ -365,16 +362,23 @@ process_buffer (GrdVncPipeWireStream *stream,
return NULL;
}
- src_stride = buffer->datas[0].chunk->stride;
- dst_stride = grd_session_vnc_get_framebuffer_stride (stream->session);
- height = stream->spa_format.size.height;
-
- frame->data = g_malloc (height * dst_stride);
- for (y = 0; y < height; y++)
+ if (src_data)
{
- memcpy (((uint8_t *) frame->data) + y * dst_stride,
- ((uint8_t *) src_data) + y * src_stride,
- dst_stride);
+ int src_stride;
+ int dst_stride;
+ int height;
+
+ src_stride = buffer->datas[0].chunk->stride;
+ dst_stride = grd_session_vnc_get_framebuffer_stride (stream->session);
+ height = stream->spa_format.size.height;
+
+ frame->data = g_malloc (height * dst_stride);
+ for (y = 0; y < height; y++)
+ {
+ memcpy (((uint8_t *) frame->data) + y * dst_stride,
+ ((uint8_t *) src_data) + y * src_stride,
+ dst_stride);
+ }
}
if (map)
--
2.26.2

View File

@ -0,0 +1,32 @@
From 2a77dd86a97fa5f4735f678599cea839ba09009c Mon Sep 17 00:00:00 2001
From: Christian Beier <info@christianbeier.net>
Date: Sun, 9 Aug 2020 20:11:26 +0200
Subject: [PATCH 3/4] libvncserver/auth: don't keep security handlers from
previous runs
Whyohsoever security handlers are stored in a variable global to the
application, not in the rfbScreen struct. This meant that security
handlers registered once would stick around forever before this commit.
---
libvncserver/auth.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/libvncserver/auth.c b/libvncserver/auth.c
index 55e0b3c9..fc74c800 100644
--- a/libvncserver/auth.c
+++ b/libvncserver/auth.c
@@ -264,9 +264,11 @@ rfbSendSecurityTypeList(rfbClientPtr cl,
primaryType = determinePrimarySecurityType(cl);
switch (primaryType) {
case rfbSecTypeNone:
+ rfbUnregisterSecurityHandler(&VncSecurityHandlerVncAuth);
rfbRegisterSecurityHandler(&VncSecurityHandlerNone);
break;
case rfbSecTypeVncAuth:
+ rfbUnregisterSecurityHandler(&VncSecurityHandlerNone);
rfbRegisterSecurityHandler(&VncSecurityHandlerVncAuth);
break;
}
--
2.28.0

View File

@ -0,0 +1,45 @@
From 641610b961a732bb68f111536ebf8c42be20f05b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Wed, 16 Sep 2020 17:35:49 +0200
Subject: [PATCH 4/4] zlib: Clear buffer pointers on cleanup (#444)
The pointers to the buffers were freed, and the size fields were set to
0, but the buffer pointers themsef was not set to NULL, when shutting
down, meaning the next time used, NULL checks would not tell whether the
pointer is valid. This caused crashes ending with
#0 0x00007ffff73729e5 in raise () from /lib64/libc.so.6
#1 0x00007ffff735b895 in abort () from /lib64/libc.so.6
#2 0x00007ffff73b6857 in __libc_message () from /lib64/libc.so.6
#3 0x00007ffff73bdd7c in malloc_printerr () from /lib64/libc.so.6
#4 0x00007ffff73c2f1a in realloc () from /lib64/libc.so.6
#5 0x00007ffff78b558e in rfbSendOneRectEncodingZlib (cl=0x4a4b80, x=0, y=0, w=800, h=40) at /home/jonas/Dev/gnome/libvncserver/libvncserver/zlib.c:106
#6 0x00007ffff78b5dec in rfbSendRectEncodingZlib (cl=0x4a4b80, x=0, y=0, w=800, h=600) at /home/jonas/Dev/gnome/libvncserver/libvncserver/zlib.c:308
#7 0x00007ffff7899453 in rfbSendFramebufferUpdate (cl=0x4a4b80, givenUpdateRegion=0x49ef70) at /home/jonas/Dev/gnome/libvncserver/libvncserver/rfbserver.c:3264
#8 0x00007ffff789079d in rfbUpdateClient (cl=0x4a4b80) at /home/jonas/Dev/gnome/libvncserver/libvncserver/main.c:1275
#9 0x00007ffff78905f5 in rfbProcessEvents (screen=0x4d5790, usec=0) at /home/jonas/Dev/gnome/libvncserver/libvncserver/main.c:1251
---
libvncserver/zlib.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/libvncserver/zlib.c b/libvncserver/zlib.c
index d24d7d15..5c3a8236 100644
--- a/libvncserver/zlib.c
+++ b/libvncserver/zlib.c
@@ -64,11 +64,13 @@ void rfbZlibCleanup(rfbScreenInfoPtr screen)
{
if (zlibBeforeBufSize) {
free(zlibBeforeBuf);
+ zlibBeforeBuf = NULL;
zlibBeforeBufSize=0;
}
if (zlibAfterBufSize) {
zlibAfterBufSize=0;
free(zlibAfterBuf);
+ zlibAfterBuf = NULL;
}
}
--
2.28.0

View File

@ -1,127 +0,0 @@
From f97b689c5c67cee36025a7b0a9210deb8b373b03 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Fri, 3 Jul 2020 17:03:52 +0200
Subject: [PATCH 1/3] session-vnc: Add API to flush
When no damage is to be reported, but e.g. cursor moved, we need to
flush, so add API to make this possible.
(cherry picked from commit 25e61a7ed3631687aed4310824e7810088e63b37)
---
src/grd-session-vnc.c | 6 ++++++
src/grd-session-vnc.h | 2 ++
2 files changed, 8 insertions(+)
diff --git a/src/grd-session-vnc.c b/src/grd-session-vnc.c
index 9fcbb69..7950d1e 100644
--- a/src/grd-session-vnc.c
+++ b/src/grd-session-vnc.c
@@ -179,6 +179,12 @@ grd_session_vnc_take_buffer (GrdSessionVnc *session_vnc,
rfbProcessEvents (session_vnc->rfb_screen, 0);
}
+void
+grd_session_vnc_flush (GrdSessionVnc *session_vnc)
+{
+ rfbProcessEvents (session_vnc->rfb_screen, 0);
+}
+
void
grd_session_vnc_set_cursor (GrdSessionVnc *session_vnc,
rfbCursorPtr rfb_cursor)
diff --git a/src/grd-session-vnc.h b/src/grd-session-vnc.h
index 294860e..a065857 100644
--- a/src/grd-session-vnc.h
+++ b/src/grd-session-vnc.h
@@ -49,6 +49,8 @@ void grd_session_vnc_queue_resize_framebuffer (GrdSessionVnc *session_vnc,
void grd_session_vnc_take_buffer (GrdSessionVnc *session_vnc,
void *data);
+void grd_session_vnc_flush (GrdSessionVnc *session_vnc);
+
void grd_session_vnc_set_cursor (GrdSessionVnc *session_vnc,
rfbCursorPtr rfb_cursor);
--
2.26.2
From 8a050b66be76d73725ac7665295160ab6c40b0f5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Fri, 3 Jul 2020 17:12:58 +0200
Subject: [PATCH 2/3] vnc-pipewire-stream: Properly process cursor-change-only
frames
Such frames will have the buffer data size set to 0, as it is empty, but
may contain metadata carrying the cursor update.
(cherry picked from commit c04762a450ea9a21730db26c296c1283e121dc08)
---
src/grd-vnc-pipewire-stream.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/grd-vnc-pipewire-stream.c b/src/grd-vnc-pipewire-stream.c
index a3f5fb6..7519377 100644
--- a/src/grd-vnc-pipewire-stream.c
+++ b/src/grd-vnc-pipewire-stream.c
@@ -312,7 +312,6 @@ process_buffer (GrdVncPipeWireStream *stream,
size_t size;
uint8_t *map;
void *src_data;
- int y;
struct spa_meta_cursor *spa_meta_cursor;
g_autofree GrdVncFrame *frame = NULL;
@@ -320,8 +319,8 @@ process_buffer (GrdVncPipeWireStream *stream,
if (buffer->datas[0].chunk->size == 0)
{
- g_warning ("Received empty buffer");
- return NULL;
+ map = NULL;
+ src_data = NULL;
}
else if (buffer->datas[0].type == SPA_DATA_MemFd)
{
@@ -367,6 +366,7 @@ process_buffer (GrdVncPipeWireStream *stream,
int src_stride;
int dst_stride;
int height;
+ int y;
src_stride = buffer->datas[0].chunk->stride;
dst_stride = grd_session_vnc_get_framebuffer_stride (stream->session);
--
2.26.2
From eac6368d8411c586007df8b1a2d85df3da1b55c5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Fri, 3 Jul 2020 17:13:58 +0200
Subject: [PATCH 3/3] vnc-pipewire-stream: Flush connection if no new pixel
buffer
Otherwise we'll wait on input until we flush out our new cursor move
only output.
(cherry picked from commit 3394e34c3c502d63636bb852c062855c46736a6f)
---
src/grd-vnc-pipewire-stream.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/grd-vnc-pipewire-stream.c b/src/grd-vnc-pipewire-stream.c
index 7519377..791b71d 100644
--- a/src/grd-vnc-pipewire-stream.c
+++ b/src/grd-vnc-pipewire-stream.c
@@ -299,6 +299,8 @@ do_render (struct spa_loop *loop,
if (frame->data)
grd_session_vnc_take_buffer (stream->session, frame->data);
+ else
+ grd_session_vnc_flush (stream->session);
g_free (frame);
--
2.26.2

View File

@ -1,4 +1,4 @@
From 10843a1f3edffbb475c01835451d39ebe6153e44 Mon Sep 17 00:00:00 2001
From 8676ef6c32557234d08acb13d7524df5fa1f4bb2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Thu, 14 Jun 2018 12:21:37 +0200
Subject: [PATCH 1/7] vnc: Add anonymous TLS encryption support
@ -11,31 +11,31 @@ VNC connection.
---
meson.build | 1 +
src/grd-enums.h | 6 +
src/grd-session-vnc.c | 98 +++-
src/grd-session-vnc.h | 15 +
src/grd-session-vnc.c | 120 ++++-
src/grd-session-vnc.h | 17 +
src/grd-settings.c | 28 ++
src/grd-settings.h | 2 +
src/grd-vnc-server.c | 45 ++
src/grd-vnc-tls.c | 444 ++++++++++++++++++
src/grd-vnc-tls.h | 28 ++
src/meson.build | 5 +-
src/meson.build | 3 +
...nome.desktop.remote-desktop.gschema.xml.in | 10 +
11 files changed, 666 insertions(+), 16 deletions(-)
11 files changed, 678 insertions(+), 26 deletions(-)
create mode 100644 src/grd-vnc-tls.c
create mode 100644 src/grd-vnc-tls.h
diff --git a/meson.build b/meson.build
index 1c96849..a24acfd 100644
index 5e9ad04..9bbd5fc 100644
--- a/meson.build
+++ b/meson.build
@@ -15,6 +15,7 @@ libvncserver_dep = dependency('libvncserver')
libvncclient_dep = dependency('libvncclient')
libsecret_dep = dependency('libsecret-1')
libnotify_dep = dependency('libnotify')
+gnutls_dep = dependency('gnutls')
@@ -40,6 +40,7 @@ endif
if have_vnc
libvncserver_dep = dependency('libvncserver')
libvncclient_dep = dependency('libvncclient')
+ gnutls_dep = dependency('gnutls')
endif
cdata = configuration_data()
cdata.set_quoted('GETTEXT_PACKAGE', 'gnome-remote-desktop')
diff --git a/src/grd-enums.h b/src/grd-enums.h
index ffab821..4333863 100644
--- a/src/grd-enums.h
@ -52,10 +52,10 @@ index ffab821..4333863 100644
+
#endif /* GRD_ENUMS_H */
diff --git a/src/grd-session-vnc.c b/src/grd-session-vnc.c
index 1f3f0e2..0cc2ea2 100644
index 0e520dc..0c189fd 100644
--- a/src/grd-session-vnc.c
+++ b/src/grd-session-vnc.c
@@ -44,7 +44,9 @@ struct _GrdSessionVnc
@@ -45,7 +45,9 @@ struct _GrdSessionVnc
{
GrdSession parent;
@ -65,7 +65,7 @@ index 1f3f0e2..0cc2ea2 100644
GSource *source;
rfbScreenInfoPtr rfb_screen;
rfbClientPtr rfb_client;
@@ -505,12 +507,30 @@ check_rfb_password (rfbClientPtr rfb_client,
@@ -540,6 +542,12 @@ check_rfb_password (rfbClientPtr rfb_client,
}
}
@ -76,9 +76,10 @@ index 1f3f0e2..0cc2ea2 100644
+}
+
int
grd_session_vnc_get_framebuffer_stride (GrdSessionVnc *session_vnc)
{
return session_vnc->rfb_screen->paddedWidthInBytes;
grd_session_vnc_get_stride_for_width (GrdSessionVnc *session_vnc,
int width)
@@ -547,6 +555,18 @@ grd_session_vnc_get_stride_for_width (GrdSessionVnc *session_vnc,
return width * BGRX_BYTES_PER_PIXEL;
}
+rfbClientPtr
@ -96,7 +97,7 @@ index 1f3f0e2..0cc2ea2 100644
static void
init_vnc_session (GrdSessionVnc *session_vnc)
{
@@ -551,33 +571,74 @@ init_vnc_session (GrdSessionVnc *session_vnc)
@@ -590,44 +610,85 @@ init_vnc_session (GrdSessionVnc *session_vnc)
rfbProcessEvents (rfb_screen, 0);
}
@ -131,6 +132,17 @@ index 1f3f0e2..0cc2ea2 100644
+ session_vnc->pending_framebuffer_width,
+ session_vnc->pending_framebuffer_height);
+ session_vnc->pending_framebuffer_resize = FALSE;
+
+ /**
+ * This is a workaround. libvncserver is unable to handle clipboard
+ * changes early and either disconnects the client or crashes g-r-d
+ * if it receives rfbSendServerCutText too early altough the
+ * authentification process is already done.
+ * Doing this after resizing the framebuffer, seems to work fine,
+ * so enable the clipboard here and not when the remote desktop
+ * session proxy is acquired.
+ */
+ grd_clipboard_vnc_maybe_enable_clipboard (session_vnc->clipboard_vnc);
+ }
+ }
+
@ -172,6 +184,17 @@ index 1f3f0e2..0cc2ea2 100644
- session_vnc->pending_framebuffer_width,
- session_vnc->pending_framebuffer_height);
- session_vnc->pending_framebuffer_resize = FALSE;
-
- /**
- * This is a workaround. libvncserver is unable to handle clipboard
- * changes early and either disconnects the client or crashes g-r-d
- * if it receives rfbSendServerCutText too early altough the
- * authentification process is already done.
- * Doing this after resizing the framebuffer, seems to work fine,
- * so enable the clipboard here and not when the remote desktop
- * session proxy is acquired.
- */
- grd_clipboard_vnc_maybe_enable_clipboard (session_vnc->clipboard_vnc);
- }
+ grd_session_stop (session);
}
@ -185,7 +208,7 @@ index 1f3f0e2..0cc2ea2 100644
}
return G_SOURCE_CONTINUE;
@@ -590,7 +651,10 @@ grd_session_vnc_attach_source (GrdSessionVnc *session_vnc)
@@ -640,7 +701,10 @@ grd_session_vnc_attach_source (GrdSessionVnc *session_vnc)
socket = g_socket_connection_get_socket (session_vnc->connection);
session_vnc->source = g_socket_create_source (socket,
@ -197,7 +220,7 @@ index 1f3f0e2..0cc2ea2 100644
NULL);
g_source_set_callback (session_vnc->source,
(GSourceFunc) handle_socket_data,
@@ -616,8 +680,10 @@ grd_session_vnc_new (GrdVncServer *vnc_server,
@@ -666,8 +730,10 @@ grd_session_vnc_new (GrdVncServer *vnc_server,
"context", context,
NULL);
@ -208,7 +231,7 @@ index 1f3f0e2..0cc2ea2 100644
grd_session_vnc_attach_source (session_vnc);
init_vnc_session (session_vnc);
@@ -632,6 +698,8 @@ grd_session_vnc_dispose (GObject *object)
@@ -682,6 +748,8 @@ grd_session_vnc_dispose (GObject *object)
g_assert (!session_vnc->rfb_screen);
@ -218,7 +241,7 @@ index 1f3f0e2..0cc2ea2 100644
G_OBJECT_CLASS (grd_session_vnc_parent_class)->dispose (object);
diff --git a/src/grd-session-vnc.h b/src/grd-session-vnc.h
index 14b5d12..46a8579 100644
index a532567..4e7b33d 100644
--- a/src/grd-session-vnc.h
+++ b/src/grd-session-vnc.h
@@ -36,6 +36,9 @@ G_DECLARE_FINAL_TYPE (GrdSessionVnc,
@ -231,13 +254,15 @@ index 14b5d12..46a8579 100644
GrdSessionVnc *grd_session_vnc_new (GrdVncServer *vnc_server,
GSocketConnection *connection);
@@ -53,6 +56,18 @@ void grd_session_vnc_move_cursor (GrdSessionVnc *session_vnc,
int x,
int y);
@@ -62,6 +65,20 @@ void grd_session_vnc_set_client_clipboard_text (GrdSessionVnc *session_vnc,
int grd_session_vnc_get_stride_for_width (GrdSessionVnc *session_vnc,
int width);
+int grd_session_vnc_get_fd (GrdSessionVnc *session_vnc);
+
int grd_session_vnc_get_framebuffer_stride (GrdSessionVnc *session_vnc);
+int grd_session_vnc_get_framebuffer_stride (GrdSessionVnc *session_vnc);
+
gboolean grd_session_vnc_is_client_gone (GrdSessionVnc *session_vnc);
+rfbClientPtr grd_session_vnc_get_rfb_client (GrdSessionVnc *session_vnc);
+
@ -251,10 +276,10 @@ index 14b5d12..46a8579 100644
+
#endif /* GRD_SESSION_VNC_H */
diff --git a/src/grd-settings.c b/src/grd-settings.c
index bdf8211..7324310 100644
index d2f31d2..12d8693 100644
--- a/src/grd-settings.c
+++ b/src/grd-settings.c
@@ -48,6 +48,7 @@ struct _GrdSettings
@@ -60,6 +60,7 @@ struct _GrdSettings
gboolean view_only;
GrdVncAuthMethod auth_method;
int port;
@ -262,7 +287,7 @@ index bdf8211..7324310 100644
} vnc;
};
@@ -120,6 +121,12 @@ grd_settings_get_vnc_auth_method (GrdSettings *settings)
@@ -242,6 +243,12 @@ grd_settings_get_vnc_auth_method (GrdSettings *settings)
return settings->vnc.auth_method;
}
@ -273,9 +298,9 @@ index bdf8211..7324310 100644
+}
+
static void
update_vnc_view_only (GrdSettings *settings)
update_rdp_tls_cert (GrdSettings *settings)
{
@@ -134,6 +141,13 @@ update_vnc_auth_method (GrdSettings *settings)
@@ -277,6 +284,13 @@ update_vnc_auth_method (GrdSettings *settings)
"auth-method");
}
@ -287,9 +312,9 @@ index bdf8211..7324310 100644
+}
+
static void
on_vnc_settings_changed (GSettings *vnc_settings,
on_rdp_settings_changed (GSettings *rdp_settings,
const char *key,
@@ -149,6 +163,11 @@ on_vnc_settings_changed (GSettings *vnc_settings,
@@ -314,6 +328,11 @@ on_vnc_settings_changed (GSettings *vnc_settings,
update_vnc_auth_method (settings);
g_signal_emit (settings, signals[VNC_AUTH_METHOD_CHANGED], 0);
}
@ -301,16 +326,16 @@ index bdf8211..7324310 100644
}
static void
@@ -172,6 +191,8 @@ grd_settings_init (GrdSettings *settings)
update_vnc_auth_method (settings);
@@ -345,6 +364,8 @@ grd_settings_init (GrdSettings *settings)
settings->rdp.port = GRD_RDP_SERVER_PORT;
settings->vnc.port = GRD_VNC_SERVER_PORT;
+
+ update_vnc_encryption (settings);
}
static void
@@ -195,4 +216,11 @@ grd_settings_class_init (GrdSettingsClass *klass)
@@ -389,4 +410,11 @@ grd_settings_class_init (GrdSettingsClass *klass)
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
@ -323,10 +348,10 @@ index bdf8211..7324310 100644
+ G_TYPE_NONE, 0);
}
diff --git a/src/grd-settings.h b/src/grd-settings.h
index e4e0c09..0575ec1 100644
index e12e47e..b940fdb 100644
--- a/src/grd-settings.h
+++ b/src/grd-settings.h
@@ -45,4 +45,6 @@ gboolean grd_settings_get_vnc_view_only (GrdSettings *settings);
@@ -64,4 +64,6 @@ gboolean grd_settings_get_vnc_view_only (GrdSettings *settings);
GrdVncAuthMethod grd_settings_get_vnc_auth_method (GrdSettings *settings);
@ -899,33 +924,28 @@ index 0000000..135ef8c
+
+#endif /* GRD_VNC_TLS_H */
diff --git a/src/meson.build b/src/meson.build
index 0f76fab..9d2f1ce 100644
index 843746d..133cc60 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -21,6 +21,8 @@ daemon_sources = files([
'grd-vnc-pipewire-stream.h',
'grd-vnc-server.c',
'grd-vnc-server.h',
+ 'grd-vnc-tls.c',
+ 'grd-vnc-tls.h',
])
@@ -72,10 +72,13 @@ if have_vnc
'grd-vnc-pipewire-stream.h',
'grd-vnc-server.c',
'grd-vnc-server.h',
+ 'grd-vnc-tls.c',
+ 'grd-vnc-tls.h',
])
deps += [
libvncserver_dep,
+ gnutls_dep,
]
endif
gen_daemon_sources = []
@@ -51,7 +53,8 @@ executable('gnome-remote-desktop-daemon',
pipewire_dep,
libvncserver_dep,
libsecret_dep,
- libnotify_dep],
+ libnotify_dep,
+ gnutls_dep],
include_directories: [configinc],
install: true,
install_dir: libexecdir)
diff --git a/src/org.gnome.desktop.remote-desktop.gschema.xml.in b/src/org.gnome.desktop.remote-desktop.gschema.xml.in
index a5c2022..846e65b 100644
index 4b6e593..0086d99 100644
--- a/src/org.gnome.desktop.remote-desktop.gschema.xml.in
+++ b/src/org.gnome.desktop.remote-desktop.gschema.xml.in
@@ -23,5 +23,15 @@
@@ -49,5 +49,15 @@
* password - by requiring the remote client to provide a known password
</description>
</key>
@ -942,10 +962,10 @@ index a5c2022..846e65b 100644
</schema>
</schemalist>
--
2.26.2
2.29.2
From aa54aeb43938250a4d27a99e62eb5628d3b55076 Mon Sep 17 00:00:00 2001
From 552e9c9add722e953a8da22bd54ba0fef7a9d6af Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Wed, 27 Nov 2019 11:02:09 +0100
Subject: [PATCH 2/7] session-vnc: Add paused/resumed signals
@ -958,10 +978,10 @@ out-of-socket source.
1 file changed, 65 insertions(+), 7 deletions(-)
diff --git a/src/grd-session-vnc.c b/src/grd-session-vnc.c
index 0cc2ea2..076e25f 100644
index 0c189fd..596896d 100644
--- a/src/grd-session-vnc.c
+++ b/src/grd-session-vnc.c
@@ -40,14 +40,27 @@
@@ -41,14 +41,27 @@
#define BGRX_SAMPLES_PER_PIXEL 3
#define BGRX_BYTES_PER_PIXEL 4
@ -989,7 +1009,7 @@ index 0cc2ea2..076e25f 100644
rfbScreenInfoPtr rfb_screen;
rfbClientPtr rfb_client;
@@ -73,7 +86,7 @@ struct _GrdSessionVnc
@@ -76,7 +89,7 @@ struct _GrdSessionVnc
G_DEFINE_TYPE (GrdSessionVnc, grd_session_vnc, GRD_TYPE_SESSION);
static void
@ -998,7 +1018,7 @@ index 0cc2ea2..076e25f 100644
static gboolean
close_session_idle (gpointer user_data);
@@ -212,7 +225,8 @@ handle_client_gone (rfbClientPtr rfb_client)
@@ -235,7 +248,8 @@ handle_client_gone (rfbClientPtr rfb_client)
g_debug ("VNC client gone");
@ -1006,9 +1026,9 @@ index 0cc2ea2..076e25f 100644
+ grd_session_vnc_pause (session_vnc);
+
maybe_queue_close_session_idle (session_vnc);
session_vnc->rfb_client = NULL;
}
@@ -280,7 +294,7 @@ handle_new_client (rfbClientPtr rfb_client)
@@ -304,7 +318,7 @@ handle_new_client (rfbClientPtr rfb_client)
session_vnc->prompt_cancellable,
prompt_response_callback,
session_vnc);
@ -1017,7 +1037,7 @@ index 0cc2ea2..076e25f 100644
return RFB_CLIENT_ON_HOLD;
case GRD_VNC_AUTH_METHOD_PASSWORD:
session_vnc->rfb_screen->passwordCheck = check_rfb_password;
@@ -498,7 +512,7 @@ check_rfb_password (rfbClientPtr rfb_client,
@@ -533,7 +547,7 @@ check_rfb_password (rfbClientPtr rfb_client,
if (memcmp (challenge_encrypted, response_encrypted, len) == 0)
{
grd_session_start (GRD_SESSION (session_vnc));
@ -1026,7 +1046,7 @@ index 0cc2ea2..076e25f 100644
return TRUE;
}
else
@@ -668,6 +682,36 @@ grd_session_vnc_detach_source (GrdSessionVnc *session_vnc)
@@ -718,6 +732,36 @@ grd_session_vnc_detach_source (GrdSessionVnc *session_vnc)
g_clear_pointer (&session_vnc->source, g_source_destroy);
}
@ -1063,7 +1083,7 @@ index 0cc2ea2..076e25f 100644
GrdSessionVnc *
grd_session_vnc_new (GrdVncServer *vnc_server,
GSocketConnection *connection)
@@ -685,6 +729,7 @@ grd_session_vnc_new (GrdVncServer *vnc_server,
@@ -735,6 +779,7 @@ grd_session_vnc_new (GrdVncServer *vnc_server,
grd_session_vnc_grab_socket (session_vnc, vnc_socket_grab_func);
grd_session_vnc_attach_source (session_vnc);
@ -1071,7 +1091,7 @@ index 0cc2ea2..076e25f 100644
init_vnc_session (session_vnc);
@@ -714,7 +759,7 @@ grd_session_vnc_stop (GrdSession *session)
@@ -764,7 +809,7 @@ grd_session_vnc_stop (GrdSession *session)
g_clear_object (&session_vnc->pipewire_stream);
@ -1079,9 +1099,9 @@ index 0cc2ea2..076e25f 100644
+ grd_session_vnc_pause (session_vnc);
g_clear_object (&session_vnc->connection);
g_clear_pointer (&session_vnc->rfb_screen->frameBuffer, g_free);
@@ -770,8 +815,8 @@ grd_session_vnc_stream_ready (GrdSession *session,
G_CALLBACK (on_pipwire_stream_closed),
g_clear_object (&session_vnc->clipboard_vnc);
@@ -817,8 +862,8 @@ grd_session_vnc_stream_ready (GrdSession *session,
G_CALLBACK (on_pipewire_stream_closed),
session_vnc);
- if (!session_vnc->source)
@ -1091,7 +1111,7 @@ index 0cc2ea2..076e25f 100644
}
static void
@@ -790,4 +835,17 @@ grd_session_vnc_class_init (GrdSessionVncClass *klass)
@@ -837,4 +882,17 @@ grd_session_vnc_class_init (GrdSessionVncClass *klass)
session_class->stop = grd_session_vnc_stop;
session_class->stream_ready = grd_session_vnc_stream_ready;
@ -1110,10 +1130,10 @@ index 0cc2ea2..076e25f 100644
+ G_TYPE_NONE, 0);
}
--
2.26.2
2.29.2
From ed3d72cb8d08192831397903f0ba92f439751988 Mon Sep 17 00:00:00 2001
From 3b33524046d299111cc150cc8d6d100f1e516485 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Wed, 27 Nov 2019 11:03:46 +0100
Subject: [PATCH 3/7] session-vnc: Add grd_session_vnc_dispatch() helper
@ -1126,10 +1146,10 @@ available that is not visible to the socket source.
2 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/src/grd-session-vnc.c b/src/grd-session-vnc.c
index 076e25f..8b8ce1b 100644
index 596896d..06b2cf7 100644
--- a/src/grd-session-vnc.c
+++ b/src/grd-session-vnc.c
@@ -622,6 +622,21 @@ vnc_socket_grab_func (GrdSessionVnc *session_vnc,
@@ -672,6 +672,21 @@ vnc_socket_grab_func (GrdSessionVnc *session_vnc,
return TRUE;
}
@ -1151,7 +1171,7 @@ index 076e25f..8b8ce1b 100644
static gboolean
handle_socket_data (GSocket *socket,
GIOCondition condition,
@@ -638,16 +653,7 @@ handle_socket_data (GSocket *socket,
@@ -688,16 +703,7 @@ handle_socket_data (GSocket *socket,
}
else if (condition & G_IO_IN)
{
@ -1170,10 +1190,10 @@ index 076e25f..8b8ce1b 100644
else
{
diff --git a/src/grd-session-vnc.h b/src/grd-session-vnc.h
index 46a8579..910b00c 100644
index 4e7b33d..cf275af 100644
--- a/src/grd-session-vnc.h
+++ b/src/grd-session-vnc.h
@@ -68,6 +68,8 @@ void grd_session_vnc_grab_socket (GrdSessionVnc *session_vnc,
@@ -79,6 +79,8 @@ void grd_session_vnc_grab_socket (GrdSessionVnc *session_vnc,
void grd_session_vnc_ungrab_socket (GrdSessionVnc *session_vnc,
GrdVncSocketGrabFunc grab_func);
@ -1183,10 +1203,10 @@ index 46a8579..910b00c 100644
#endif /* GRD_SESSION_VNC_H */
--
2.26.2
2.29.2
From 44e6bec84a86064a7b3abbcbbcd07ebb525aca9f Mon Sep 17 00:00:00 2001
From 3945af78cea858033d954bb1b071269687bdea85 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Wed, 27 Nov 2019 11:05:13 +0100
Subject: [PATCH 4/7] vnc/tls: Add some logging
@ -1260,10 +1280,10 @@ index ec4758e..ac6c35f 100644
{
g_warning ("TLS handshake failed: %s", error->message);
--
2.26.2
2.29.2
From fc07db3b6fafec47e02ff81f0f893dcaf64ba988 Mon Sep 17 00:00:00 2001
From f5330797678f4c4db4a3fa19cebd30dd4d6bbb8c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Wed, 27 Nov 2019 11:07:40 +0100
Subject: [PATCH 5/7] vnc/tls: Dispatch also when data is pending outside of
@ -1276,14 +1296,14 @@ epoll(). Deal with this by adding a custom source that dispatches as
long as there is data to read in those buffers.
---
src/grd-session-vnc.h | 2 +
src/grd-vnc-tls.c | 92 ++++++++++++++++++++++++++++++++++++++++---
2 files changed, 88 insertions(+), 6 deletions(-)
src/grd-vnc-tls.c | 90 ++++++++++++++++++++++++++++++++++++++++---
2 files changed, 86 insertions(+), 6 deletions(-)
diff --git a/src/grd-session-vnc.h b/src/grd-session-vnc.h
index 910b00c..294860e 100644
index cf275af..efc0038 100644
--- a/src/grd-session-vnc.h
+++ b/src/grd-session-vnc.h
@@ -68,6 +68,8 @@ void grd_session_vnc_grab_socket (GrdSessionVnc *session_vnc,
@@ -79,6 +79,8 @@ void grd_session_vnc_grab_socket (GrdSessionVnc *session_vnc,
void grd_session_vnc_ungrab_socket (GrdSessionVnc *session_vnc,
GrdVncSocketGrabFunc grab_func);
@ -1293,7 +1313,7 @@ index 910b00c..294860e 100644
GrdVncServer * grd_session_vnc_get_vnc_server (GrdSessionVnc *session_vnc);
diff --git a/src/grd-vnc-tls.c b/src/grd-vnc-tls.c
index ac6c35f..8f65225 100644
index ac6c35f..312b6b9 100644
--- a/src/grd-vnc-tls.c
+++ b/src/grd-vnc-tls.c
@@ -41,6 +41,12 @@ typedef enum _GrdTlsHandshakeState
@ -1318,12 +1338,7 @@ index ac6c35f..8f65225 100644
} GrdVncTlsSession;
static gboolean
@@ -296,16 +304,14 @@ grd_vnc_tls_peek_at_socket (rfbClientPtr rfb_client,
peekable_len = MIN (len, tls_session->peek_buffer_len);
memcpy (buf, tls_session->peek_buffer, peekable_len);
+ fprintf(stderr, ":::: %s:%d %s() - peeked %d bytes, can peek %d bytes\n", __FILE__, __LINE__, __func__,
+ peekable_len, tls_session->peek_buffer_len);
@@ -299,13 +307,9 @@ grd_vnc_tls_peek_at_socket (rfbClientPtr rfb_client,
return peekable_len;
}
@ -1339,7 +1354,7 @@ index ac6c35f..8f65225 100644
if (tls_session->peek_buffer_len > 0)
return TRUE;
@@ -315,6 +321,16 @@ grd_vnc_tls_has_pending_on_socket (rfbClientPtr rfb_client)
@@ -315,6 +319,16 @@ grd_vnc_tls_has_pending_on_socket (rfbClientPtr rfb_client)
return FALSE;
}
@ -1356,7 +1371,7 @@ index ac6c35f..8f65225 100644
static int
grd_vnc_tls_write_to_socket (rfbClientPtr rfb_client,
const char *buf,
@@ -403,6 +419,62 @@ tls_handshake_grab_func (GrdSessionVnc *session_vnc,
@@ -403,6 +417,62 @@ tls_handshake_grab_func (GrdSessionVnc *session_vnc,
return TRUE;
}
@ -1419,7 +1434,7 @@ index ac6c35f..8f65225 100644
static void
rfb_tls_security_handler (rfbClientPtr rfb_client)
{
@@ -429,6 +501,14 @@ rfb_tls_security_handler (rfbClientPtr rfb_client)
@@ -429,6 +499,14 @@ rfb_tls_security_handler (rfbClientPtr rfb_client)
rfb_client->hasPendingOnSocket = grd_vnc_tls_has_pending_on_socket;
rfb_client->writeToSocket = grd_vnc_tls_write_to_socket;
@ -1435,10 +1450,10 @@ index ac6c35f..8f65225 100644
}
--
2.26.2
2.29.2
From c582baab12c1e2dd2b512329da42880c40993df6 Mon Sep 17 00:00:00 2001
From fae9653965ddcc3d5684a056d9bdf46ef439d649 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Wed, 27 Nov 2019 16:48:00 +0100
Subject: [PATCH 6/7] session-vnc: Set our own password handling function up
@ -1457,10 +1472,10 @@ password prompt.
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/src/grd-session-vnc.c b/src/grd-session-vnc.c
index 8b8ce1b..a93a2e3 100644
index 06b2cf7..7a4c6b3 100644
--- a/src/grd-session-vnc.c
+++ b/src/grd-session-vnc.c
@@ -91,11 +91,6 @@ grd_session_vnc_pause (GrdSessionVnc *session_vnc);
@@ -94,11 +94,6 @@ grd_session_vnc_pause (GrdSessionVnc *session_vnc);
static gboolean
close_session_idle (gpointer user_data);
@ -1472,7 +1487,7 @@ index 8b8ce1b..a93a2e3 100644
static void
swap_uint8 (uint8_t *a,
uint8_t *b)
@@ -297,7 +292,6 @@ handle_new_client (rfbClientPtr rfb_client)
@@ -321,7 +316,6 @@ handle_new_client (rfbClientPtr rfb_client)
grd_session_vnc_pause (session_vnc);
return RFB_CLIENT_ON_HOLD;
case GRD_VNC_AUTH_METHOD_PASSWORD:
@ -1480,7 +1495,7 @@ index 8b8ce1b..a93a2e3 100644
/*
* authPasswdData needs to be non NULL in libvncserver to trigger
* password authentication.
@@ -581,6 +575,8 @@ init_vnc_session (GrdSessionVnc *session_vnc)
@@ -620,6 +614,8 @@ init_vnc_session (GrdSessionVnc *session_vnc)
rfb_screen->frameBuffer = g_malloc0 (screen_width * screen_height * 4);
memset (rfb_screen->frameBuffer, 0x1f, screen_width * screen_height * 4);
@ -1490,43 +1505,40 @@ index 8b8ce1b..a93a2e3 100644
rfbProcessEvents (rfb_screen, 0);
}
--
2.26.2
2.29.2
From b7fc232ee5272b430f28c33ebaacd501ff63a4dc Mon Sep 17 00:00:00 2001
From 1ae1286b2cc868045f93c02b7a990638ca94b26d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Wed, 27 Nov 2019 16:53:42 +0100
Subject: [PATCH 7/7] vnc: Unregister previously set security handlers on init
Date: Mon, 12 Oct 2020 17:34:30 +0200
Subject: [PATCH 7/7] vnc: Copy pixels using the right destination stride
When we're starting a session, we're going to handle a new client
connection. However, any previous client that was ever run on in a
previous session would still have their "security handler" registered,
as such is a global permanent change in libvncserver right now.
We're copying the pixels in a separate thread managed by PipeWire, and
in this thread, accessing the VNC framebuffer dimension and stride is
racy. Instead of fetching the dimension directly, pass the expected
width and get the stride it will eventually have.
To work around this, unregister all primary security handler (i.e.
'none' and 'password') when initializing the RFB screen. We'll set up
the preferred one when handling the new client.
Already before this patch, when the copied pixel end up on the main
thread and the dimension still doesn't match up, the frame will be
dropped.
---
src/grd-session-vnc.c | 6 ++++++
1 file changed, 6 insertions(+)
src/grd-session-vnc.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/grd-session-vnc.c b/src/grd-session-vnc.c
index a93a2e3..9fcbb69 100644
--- a/src/grd-session-vnc.c
+++ b/src/grd-session-vnc.c
@@ -555,6 +555,12 @@ init_vnc_session (GrdSessionVnc *session_vnc)
8, 3, 4);
session_vnc->rfb_screen = rfb_screen;
diff --git a/src/grd-session-vnc.h b/src/grd-session-vnc.h
index efc0038..f3a6314 100644
--- a/src/grd-session-vnc.h
+++ b/src/grd-session-vnc.h
@@ -67,7 +67,8 @@ int grd_session_vnc_get_stride_for_width (GrdSessionVnc *session_vnc,
+ /*
+ * Unregister whatever security handler was used the last time; we'll set
+ * up new ones when authorizing the new client anyway.
+ */
+ rfbUnregisterPrimarySecurityHandlers ();
+
update_server_format (session_vnc);
int grd_session_vnc_get_fd (GrdSessionVnc *session_vnc);
-int grd_session_vnc_get_framebuffer_stride (GrdSessionVnc *session_vnc);
+int grd_session_vnc_get_stride_for_width (GrdSessionVnc *session_vnc,
+ int width);
gboolean grd_session_vnc_is_client_gone (GrdSessionVnc *session_vnc);
socket = g_socket_connection_get_socket (session_vnc->connection);
--
2.26.2
2.29.2

View File

@ -0,0 +1,47 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0b6228a..20fec85 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -495,7 +495,7 @@ if(WIN32)
endif(WITH_TIGHTVNC_FILETRANSFER)
endif(WIN32)
-target_link_libraries(vncclient
+target_link_libraries(vncclient PUBLIC
${ADDITIONAL_LIBS}
${ZLIB_LIBRARIES}
${LZO_LIBRARIES}
@@ -504,7 +504,7 @@ target_link_libraries(vncclient
${GNUTLS_LIBRARIES}
${OPENSSL_LIBRARIES}
)
-target_link_libraries(vncserver
+target_link_libraries(vncserver PUBLIC
${ADDITIONAL_LIBS}
${ZLIB_LIBRARIES}
${LZO_LIBRARIES}
diff --git a/libvncclient.pc.cmakein b/libvncclient.pc.cmakein
index ceeda39..f131dca 100644
--- a/libvncclient.pc.cmakein
+++ b/libvncclient.pc.cmakein
@@ -8,7 +8,6 @@ Description: A library for easy implementation of a VNC client.
Version: @LibVNCServer_VERSION@
Requires:
Requires.private:
-Libs: -L${libdir} -lvncclient
-Libs.private: @PRIVATE_LIBS@
+Libs: -L${libdir} -lvncclient @PRIVATE_LIBS@
Cflags: -I${includedir}
diff --git a/libvncserver.pc.cmakein b/libvncserver.pc.cmakein
index 33ec668..5ae98c9 100644
--- a/libvncserver.pc.cmakein
+++ b/libvncserver.pc.cmakein
@@ -8,6 +8,5 @@ Description: A library for easy implementation of a VNC server.
Version: @LibVNCServer_VERSION@
Requires:
Requires.private:
-Libs: -L${libdir} -lvncserver
-Libs.private: @PRIVATE_LIBS@
+Libs: -L${libdir} -lvncserver @PRIVATE_LIBS@
Cflags: -I${includedir}

View File

@ -0,0 +1,15 @@
diff -up libvncserver-LibVNCServer-0.9.13/libvncclient/tls_gnutls.c.crypto_policy libvncserver-LibVNCServer-0.9.13/libvncclient/tls_gnutls.c
--- libvncserver-LibVNCServer-0.9.13/libvncclient/tls_gnutls.c.crypto_policy 2020-06-13 13:49:53.000000000 -0500
+++ libvncserver-LibVNCServer-0.9.13/libvncclient/tls_gnutls.c 2020-07-02 08:00:54.304902893 -0500
@@ -29,8 +29,8 @@
#include "tls.h"
-static const char *rfbTLSPriority = "NORMAL:+DHE-DSS:+RSA:+DHE-RSA:+SRP";
-static const char *rfbAnonTLSPriority= "NORMAL:+ANON-DH";
+static const char *rfbTLSPriority = "@SYSTEM";
+static const char *rfbAnonTLSPriority= "@SYSTEM:+ANON-DH";
#define DH_BITS 1024
static gnutls_dh_params_t rfbDHParams;
diff -up libvncserver-LibVNCServer-0.9.13/libvncserver/rfbssl_gnutls.c.crypto_policy libvncserver-LibVNCServer-0.9.13/libvncserver/rfbssl_gnutls.c

View File

@ -1,45 +1,93 @@
%global systemd_unit gnome-remote-desktop.service
%global tarball_version %%(echo %{version} | tr '~' '.')
%if 0%{?rhel} >= 9
%global bundle_libvncserver 1
%global enable_rdp 0
%else
%global bundle_libvncserver 0
%global enable_rdp 1
%endif
%global libvncserver_name LibVNCServer
%global libvncserver_version 0.9.13
Name: gnome-remote-desktop
Version: 0.1.8
Release: 3%{?dist}
Version: 40.0
Release: 10%{?dist}
Summary: GNOME Remote Desktop screen share service
License: GPLv2+
URL: https://gitlab.gnome.org/jadahl/gnome-remote-desktop
Source0: https://gitlab.gnome.org/jadahl/gnome-remote-desktop/uploads/20e4965351cdbd8dc32ff9801e884b91/gnome-remote-desktop-0.1.8.tar.xz
Source0: https://download.gnome.org/sources/gnome-remote-desktop/40/%{name}-%{tarball_version}.tar.xz
Source1: https://github.com/LibVNC/libvncserver/archive/refs/tags/%{libvncserver_name}-%{libvncserver_version}.tar.gz
# Fix black screen on Wayland
Patch1: 0001-vnc-pipewire-stream-Handle-stride-mismatch.patch
### gnome-remote-desktop patches
# Adds encryption support (requires patched LibVNCServer)
Patch0: gnutls-anontls.patch
# Anon TLS encryption support
Patch2: anon-tls-support.patch
# Backport upstream leak fix (rhbz#1951129)
Patch1: 0001-pipewire-stream-Don-t-leak-GSource-s.patch
# Don't crash on metadata only buffers (#1847062)
Patch3: 0001-stream-log-a-warning-on-error.patch
Patch4: 0002-vnc-pipewire-stream-Only-try-to-copy-frame-pixels-if.patch
Patch5: 0001-vnc-pipewire-stream-Remove-assert.patch
### LibVNCServer patches
## TLS security type enablement patches
# https://github.com/LibVNC/libvncserver/pull/234
Patch1000: 0001-libvncserver-Add-API-to-add-custom-I-O-entry-points.patch
Patch1001: 0002-libvncserver-Add-channel-security-handlers.patch
# https://github.com/LibVNC/libvncserver/commit/87c52ee0551b7c4e76855d270d475b9e3039fe08
Patch1002: 0003-libvncserver-auth-don-t-keep-security-handlers-from-.patch
# Fix crash on all runs after the first
# https://github.com/LibVNC/libvncserver/pull/444
# https://bugzilla.redhat.com/show_bug.cgi?id=1882718
Patch1003: 0004-zlib-Clear-buffer-pointers-on-cleanup-444.patch
# Fix another crasher
# https://gitlab.gnome.org/GNOME/gnome-remote-desktop/-/issues/45
# https://bugzilla.redhat.com/show_bug.cgi?id=1882718
Patch1004: 0001-libvncserver-don-t-NULL-out-internal-of-the-default-.patch
## downstream patches
Patch2000: libvncserver-LibVNCServer-0.9.13-system-crypto-policy.patch
Patch2001: libvncserver-LibVNCServer-0.9.13-static-library-link.patch
## Don't compile SHA1 support
Patch2100: 0001-crypto-Don-t-compile-SHA1-support-when-Websockets-ar.patch
# Cursor only frame fixes (#1837406)
Patch6: cursor-only-frame-fixes.patch
BuildRequires: git
BuildRequires: gcc
BuildRequires: meson >= 0.36.0
BuildRequires: pkgconfig
BuildRequires: pkgconfig(cairo)
BuildRequires: pkgconfig(glib-2.0) >= 2.32
BuildRequires: pkgconfig(gio-unix-2.0) >= 2.32
BuildRequires: pkgconfig(libpipewire-0.3) >= 0.3.4
BuildRequires: pkgconfig(libvncserver) >= 0.9.11-7
BuildRequires: pkgconfig(libpipewire-0.3) >= 0.3.0
%if 0%{?enable_rdp}
BuildRequires: pkgconfig(freerdp2)
BuildRequires: pkgconfig(winpr2)
BuildRequires: pkgconfig(fuse3)
%endif
BuildRequires: pkgconfig(xkbcommon)
BuildRequires: pkgconfig(libsecret-1)
BuildRequires: pkgconfig(libnotify)
BuildRequires: pkgconfig(gnutls)
BuildRequires: python3-devel
%if 0%{?bundle_libvncserver}
BuildRequires: cmake
BuildRequires: lzo-devel
BuildRequires: lzo-minilzo
%else
BuildRequires: pkgconfig(libvncserver) >= 0.9.11-7
%endif
%{?systemd_requires}
BuildRequires: systemd
Requires: pipewire >= 0.3.4
Requires: pipewire >= 0.3.0
Obsoletes: vino < 3.22.0-21
%if 0%{?bundle_libvncserver}
Provides: bundled(libvncserver) = %{libvncserver_version}
%endif
%description
GNOME Remote Desktop is a remote desktop and screen sharing service for the
@ -47,17 +95,84 @@ GNOME desktop environment.
%prep
%autosetup -S git
## Setup libvncserver
%if 0%{?bundle_libvncserver}
%setup -b 1 -n libvncserver-%{libvncserver_name}-%{libvncserver_version}
%patch1000 -p1 -b .tls-1
%patch1001 -p1 -b .tls-2
%patch1002 -p1 -b .handlers
%patch1003 -p1 -b .pointers
%patch1004 -p1 -b .cursor_null
%patch2000 -p1 -b .crypto_policy
%patch2001 -p1 -b .static
%patch2100 -p1 -b .no-sha1
# Nuke bundled minilzo
rm -fv common/lzodefs.h common/lzoconf.h commmon/minilzo.h common/minilzo.c
# Fix encoding
for file in ChangeLog ; do
mv ${file} ${file}.OLD && \
iconv -f ISO_8859-1 -t UTF8 ${file}.OLD > ${file} && \
touch --reference ${file}.OLD $file
done
%endif
## Setup gnome-remote-desktop
%setup -n %{name}-%{tarball_version}
%patch0 -p1
%patch1 -p1
%build
%meson
## Build libvncserver
%if 0%{?bundle_libvncserver}
pushd ../libvncserver-%{libvncserver_name}-%{libvncserver_version}
mkdir -p %{_builddir}/libvncserver/
%global libvncserver_install_dir %{buildroot}%{_builddir}/libvncserver
%cmake \
-DCMAKE_INSTALL_PREFIX=%{libvncserver_install_dir} \
-DINCLUDE_INSTALL_DIR=%{libvncserver_install_dir}/include \
-DLIB_INSTALL_DIR:PATH=%{libvncserver_install_dir}/%{_lib} \
-DSYSCONF_INSTALL_DIR=%{libvncserver_install_dir}/etc \
-DWITH_FFMPEG=OFF -DWITH_GTK=OFF -DWITH_OPENSSL=OFF -DWITH_GNUTLS=ON \
-DWITH_SDL=OFF -DWITH_X11=OFF -DWITH_WEBSOCKETS=OFF \
-DLIBVNCSERVER_WITH_WEBSOCKETS=OFF -DBUILD_SHARED_LIBS=OFF
%cmake_build
%__cmake --install "%{__cmake_builddir}"
popd
%endif
## Build gnome-remote-desktop
%if 0%{?bundle_libvncserver}
%global pkg_config_path_override --pkg-config-path %{buildroot}/%{_builddir}/libvncserver/%{_lib}/pkgconfig
%endif
%if 0%{?enable_rdp}
%global rdp_configuration -Drdp=true
%else
%global rdp_configuration -Drdp=false
%endif
%meson %{?pkg_config_path_override} %{rdp_configuration}
%meson_build
%install
%meson_install
%if 0%{?bundle_libvncserver}
pushd ../libvncserver-%{libvncserver_name}-%{libvncserver_version}
cp COPYING %{_builddir}/%{name}-%{tarball_version}/COPYING.libvncserver
popd
%endif
%post
%systemd_user_post %{systemd_unit}
@ -73,6 +188,9 @@ GNOME desktop environment.
%files
%license COPYING
%if 0%{?bundle_libvncserver}
%license COPYING.libvncserver
%endif
%doc README
%{_libexecdir}/gnome-remote-desktop-daemon
%{_userunitdir}/gnome-remote-desktop.service
@ -81,48 +199,105 @@ GNOME desktop environment.
%changelog
* Wed Jul 15 2020 Jonas Ådahl <jadahl@redhat.com> - 0.1.8-3
- Backport cursor only frame fixes
Related: #1837406
* Wed Jul 19 2023 Jonas Ådahl <jadahl@redhat.com> - 40.0-10
- Don't compile in SHA1 support again
Resolves: #2223925
* Thu Jun 18 2020 Jonas Ådahl <jadahl@redhat.com> - 0.1.8-2
- Don't crash on metadata only buffers
Resolves: #1847062
* Wed Jul 19 2023 Jonas Ådahl <jadahl@redhat.com> - 40.0-9
- Bump version number
Related: rhbz#2188174
* Wed May 20 2020 Jonas Ådahl <jadahl@redhat.com> - 0.1.8-1
- Rebase to 0.1.8
Resolves: #1837406
* Wed Apr 19 2023 Yaakov Selkowitz <yselkowi@redhat.com> - 40.0-8
- Do not provide libvncserver.so.1
Resolves: rhbz#2188174
* Wed Nov 27 2019 Jonas Ådahl <jadahl@redhat.com> - 0.1.6-8
- Update patch to handle older libvncserver at build time
Resolves: #1684729
* Mon Oct 25 2021 Jonas Ådahl <jadahl@redhat.com> - 40.0-7
- Don't compile in SHA1 support
Resolves: #1936594
* Wed Nov 27 2019 Jonas Ådahl <jadahl@redhat.com> - 0.1.6-7
- Handle auth settings changes
Resolves: #1684729
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 40.0-6
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
* Wed Nov 27 2019 Jonas Ådahl <jadahl@redhat.com> - 0.1.6-6
- Fix initial black content issue
Resolves: #1765448
* Tue Jun 15 2021 Jonas Ådahl <jadahl@redhat.com> - 40.0-5
- Backport leak fix
Resolves: #1951129
* Thu May 30 2019 Tomáš Popela <tpopela@redhat.com> - 0.1.6-5
- Bump the version to make gating happy - that's bug 1681618
- Resolves: rhbz#1713330
* Mon May 17 2021 Ondrej Holy <oholy@redhat.com> - 40.0-4
- Rebuild for updated FreeRDP (#1951123).
* Fri May 24 2019 Jonas Ådahl <jadahl@redhat.com> - 0.1.6-4
- Backport password override test helper (rhbz#1713330)
* Thu Apr 22 2021 Jonas Ådahl <jadahl@redhat.com> - 40.0-3
- Bundle libvncserver
- Disable RDP support
* Thu Jan 3 2019 Jonas Ådahl <jadahl@redhat.com> - 0.1.6-3
- Backport various fixes (rhbz#1659118)
* Thu Apr 15 2021 Mohan Boddu <mboddu@redhat.com> - 40.0-2
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
* Mon Oct 1 2018 Jonas Ådahl <jadahl@redhat.com> - 0.1.6-2
- Don't crash when PipeWire disconnects (rhbz#1627469)
* Mon Mar 22 2021 Kalev Lember <klember@redhat.com> - 40.0-1
- Update to 40.0
* Thu Mar 18 2021 Michael Catanzaro <mcatanzaro@redhat.com> - 40.0~rc-2
- Add Obsoletes: vino
* Mon Mar 15 2021 Kalev Lember <klember@redhat.com> - 40.0~rc-1
- Update to 40.rc
* Thu Mar 04 2021 Jonas Ådahl <jadahl@redhat.com> - 40.0~beta-1
- Bump to 40.beta
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 0.1.9-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Mon Sep 14 2020 Jonas Ådahl <jadahl@redhat.com> - 0.1.9-2
- Copy using the right destination stride
* Mon Sep 14 2020 Jonas Ådahl <jadahl@redhat.com> - 0.1.9-1
- Update to 0.1.9
- Backport race condition crash fix
- Rebase anon-tls patches
* Thu Aug 27 2020 Ray Strode <rstrode@redhat.com> - 0.1.8-3
- Fix crash
Related: #1844993
* Mon Jun 1 2020 Felipe Borges <feborges@redhat.com> - 0.1.8-2
- Fix black screen issue in remote connections on Wayland
* Wed Mar 11 2020 Jonas Ådahl <jadahl@redhat.com> - 0.1.8-1
- Update to 0.1.8
* Tue Jan 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 0.1.7-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 0.1.7-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Mon Mar 4 2019 Jonas Ådahl <jadahl@redhat.com> - 0.1.7-1
- Update to 0.1.7
* Thu Jan 31 2019 Fedora Release Engineering <releng@fedoraproject.org> - 0.1.6-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Tue Oct 2 2018 Jonas Ådahl <jadahl@redhat.com> - 0.1.6-2
- Don't crash when PipeWire disconnects (rhbz#1632781)
* Tue Aug 7 2018 Jonas Ådahl <jadahl@redhat.com> - 0.1.6
- Update to 0.1.6
- Apply ANON-TLS patch
- Depend on pipewire 0.2.2
* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 0.1.4-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Wed May 30 2018 Jonas Ådahl <jadahl@redhat.com> - 0.1.4-1
- Update to new version
* Fri Feb 09 2018 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 0.1.2-5
- Escape macros in %%changelog
* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 0.1.2-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
* Tue Aug 29 2017 Jonas Ådahl <jadahl@redhat.com> - 0.1.2-3
- Use %%autosetup
- Install licence file