202 changes: 129 additions & 73 deletions CMakeLists.txt

Large diffs are not rendered by default.

1,630 changes: 1,630 additions & 0 deletions ChangeLog

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -598,9 +598,12 @@ INPUT = rfb \
client_examples/vnc2mpg.c \
examples/camera.c \
examples/example.c \
examples/blooptest.c \
examples/filetransfer.c \
examples/fontsel.c \
examples/pnmshow.c \
examples/pnmshow24.c \
examples/storepasswd.c \
examples/vncev.c

# This tag can be used to specify the character encoding of the source files
Expand Down
54 changes: 54 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
This is the original author Dscho's account on the project's initial history.
If you want to know what happened afterwards, have a look at [NEWS](NEWS.md).

History
=======

LibVNCServer is based on Tridia VNC and OSXvnc, which in turn are based on
the original code from ORL/AT&T.

When I began hacking with computers, my first interest was speed. So, when I
got around assembler, I programmed the floppy to do much of the work, because
its clock rate was higher than that of my C64. This was my first experience
with client/server techniques.

When I came around Xwindows (much later), I was at once intrigued by the
elegance of such connectedness between the different computers. I used it
a lot - not the least priority lay on games. However, when I tried it over
modem from home, it was no longer that much fun.

When I started working with ASP (Application Service Provider) programs, I
tumbled across Tarantella and Citrix. Being a security fanatic, the idea of
running a server on windows didn't appeal to me, so Citrix went down the
basket. However, Tarantella has its own problems (security as well as the
high price). But at the same time somebody told me about this "great little
administrator's tool" named VNC. Being used to windows programs' sizes, the
surprise was reciprocal inverse to the size of VNC!

At the same time, the program "rdesktop" (a native Linux client for the
Terminal Services of Windows servers) came to my attention. There where even
works under way to make a protocol converter "rdp2vnc" out of this. However,
my primary goal was a slow connection and rdp2vnc could only speak RRE
encoding, which is not that funny with just 5kB/s. Tim Edmonds, the original
author of rdp2vnc, suggested that I adapt it to Hextile Encoding, which is
better. I first tried that, but had no success at all (crunchy pictures).

Also, I liked the idea of an HTTP server included and possibly other
encodings like the Tight Encodings from Const Kaplinsky. So I started looking
for libraries implementing a VNC server where I could steal what I can't make.
I found some programs based on the demo server from AT&T, which was also the
basis for rdp2vnc (can only speak Raw and RRE encoding). There were some
rumors that GGI has a VNC backend, but I didn't find any code, so probably
there wasn't a working version anyway.

All of a sudden, everything changed: I read on freshmeat that "OSXvnc" was
released. I looked at the code and it was not much of a problem to work out
a simple server - using every functionality there is in Xvnc. It became clear
to me that I *had* to build a library out of it, so everybody can use it.
Every change, every new feature can propagate to every user of it.

It also makes everything easier:
You don't care about the cursor, once set (or use the standard cursor).
You don't care about those sockets. You don't care about encodings.
You just change your frame buffer and inform the library about it. Every once
in a while you call rfbProcessEvents and that's it.
321 changes: 0 additions & 321 deletions NEWS

This file was deleted.

580 changes: 580 additions & 0 deletions NEWS.md

Large diffs are not rendered by default.

520 changes: 133 additions & 387 deletions README.md

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Security Policy

## Supported Versions

We fix security problems on the master branch. Downstream packagers are
advised to cherry-pick those onto release versions. Currently, no point
releases of already-released versions are made due to low development
team head count.

## Reporting a Vulnerability

Mail in to dontmind@sdf.org.
30 changes: 0 additions & 30 deletions TODO

This file was deleted.

26 changes: 26 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
high-prio:
----------
- [Merge MulticastVNC](https://github.com/LibVNC/libvncserver/issues/394)
- [style fixes: use Linux' coding guidelines & ANSIfy tightvnc-filetransfer](https://github.com/LibVNC/libvncserver/issues/395)
- [Implement encryption in libvncserver](https://github.com/LibVNC/libvncserver/issues/396)


maybe-later:
------------

- selectbox: scroll bars
- authentification schemes (secure vnc)
- IO function ptr exists; now explain how to tunnel and implement a
- client address restriction scheme.

- make SDLvncviewer more versatile
- test for missing keys (especially "[]{}" with ./examples/mac),
- map Apple/Linux/Windows keys onto each other,
- handle selection
- handle scroll wheel
- LibVNCClient cleanup: prefix with "rfbClient", and make sure it does
not deliberately die() or exit() anywhere!
- make corre work again (libvncclient or libvncserver?)
- teach SDLvncviewer about CopyRect...
- implement "-record" in libvncclient
- implement QoS for Windows in libvncclient
1 change: 1 addition & 0 deletions client_examples/SDLvncviewer.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/**
* @example SDLvncviewer.c
* Once built, you can run it via `SDLvncviewer <remote-host>`.
*/

#include <SDL.h>
Expand Down
2 changes: 2 additions & 0 deletions client_examples/vnc2mpg.c
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,9 @@ int main(int argc, char **argv)
client->format.blueShift=0; client->format.blueMax=31;

/* Initialize libavcodec, and register all codecs and formats. */
#if LIBAVUTIL_VERSION_MAJOR < 56 /* deprecrated in FFMPEG 4.0 */
av_register_all();
#endif

/* Parse command line. */
for(i=1;i<argc;i++) {
Expand Down
422 changes: 195 additions & 227 deletions cmake/Modules/FindFFMPEG.cmake

Large diffs are not rendered by default.

36 changes: 36 additions & 0 deletions cmake/Toolchain-cross-mingw32-linux.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# the name of the target operating system
SET(CMAKE_SYSTEM_NAME Windows)

# Choose an appropriate compiler prefix

# for classical mingw32
# see http://www.mingw.org/
#set(COMPILER_PREFIX "i586-mingw32msvc")

# for 32 or 64 bits mingw-w64
# see http://mingw-w64.sourceforge.net/
set(COMPILER_PREFIX "i686-w64-mingw32")
#set(COMPILER_PREFIX "x86_64-w64-mingw32"

# which compilers to use for C and C++
find_program(CMAKE_RC_COMPILER NAMES ${COMPILER_PREFIX}-windres)
#SET(CMAKE_RC_COMPILER ${COMPILER_PREFIX}-windres)
find_program(CMAKE_C_COMPILER NAMES ${COMPILER_PREFIX}-gcc)
#SET(CMAKE_C_COMPILER ${COMPILER_PREFIX}-gcc)
find_program(CMAKE_CXX_COMPILER NAMES ${COMPILER_PREFIX}-g++)
#SET(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-g++)


# here is the target environment located
SET(USER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/deps)
SET(CMAKE_FIND_ROOT_PATH /usr/${COMPILER_PREFIX} ${USER_ROOT_PATH})

# adjust the default behaviour of the FIND_XXX() commands:
# search headers and libraries in the target environment, search
# programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

# use wine for runnings tests
set(CMAKE_CROSSCOMPILING_EMULATOR wine)
46 changes: 46 additions & 0 deletions common/crypto.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#ifndef _RFB_CRYPTO_H
#define _RFB_CRYPTO_H 1

#include <stdint.h>
#include "rfb/rfbconfig.h"

#define SHA1_HASH_SIZE 20
#define MD5_HASH_SIZE 16

/* Generates an MD5 hash of 'in' and writes it to 'out', which must be 16 bytes in size. */
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. */
int hash_sha1(void *out, const void *in, const size_t in_len);

/* Fill 'out' with 'len' random bytes. */
void random_bytes(void *out, size_t len);

/*
Takes the 8-byte key in 'key', reverses the bits in each byte of key as required by the RFB protocol,
encrypts 'in' with the resulting key using single-key 56-bit DES and writes the result to 'out'.
*/
int encrypt_rfbdes(void *out, int *out_len, const unsigned char key[8], const void *in, const size_t in_len);

/*
Takes the 8-byte key in 'key', reverses the bits in each byte of key as required by the RFB protocol,
decrypts 'in' with the resulting key using single-key 56-bit DES and writes the result to 'out'.
*/
int decrypt_rfbdes(void *out, int *out_len, const unsigned char key[8], const void *in, const size_t in_len);

/* Encrypts 'in' with the the 16-byte key in 'key' using AES-128-ECB and writes the result to 'out'. */
int encrypt_aes128ecb(void *out, int *out_len, const unsigned char key[16], const void *in, const size_t in_len);

/*
Generates a Diffie-Hellman public-private keypair using the generator value 'gen' and prime modulo
'prime', writing the result to 'pub_out' and 'priv_out', which must be 'keylen' in size.
*/
int dh_generate_keypair(uint8_t *priv_out, uint8_t *pub_out, const uint8_t *gen, const size_t gen_len, const uint8_t *prime, const size_t keylen);

/*
Computes the shared Diffie-Hellman secret using the private key 'priv', the other side's public
key 'pub' and the modulo prime 'prime' and writes it to 'shared_out', which must be 'keylen' in size.
*/
int dh_compute_shared_key(uint8_t *shared_out, const uint8_t *priv, const uint8_t *pub, const uint8_t *prime, const size_t keylen);

#endif
93 changes: 93 additions & 0 deletions common/crypto_included.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* crypto_included.c - Crypto wrapper (included version)
*/

/*
* Copyright (C) 2011 Gernot Tenchio
* Copyright (C) 2019 Christian Beier
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/

#include <string.h>
#include "sha.h"
#include "d3des.h"
#include "crypto.h"


int hash_md5(void *out, const void *in, const size_t in_len)
{
return 0;
}

int hash_sha1(void *out, const void *in, const size_t in_len)
{
SHA1Context sha1;
if(SHA1Reset(&sha1) != shaSuccess)
return 0;
if(SHA1Input(&sha1, in, in_len) != shaSuccess)
return 0;
if(SHA1Result(&sha1, out) != shaSuccess)
return 0;

return 1;
}

void random_bytes(void *out, size_t len)
{

}

int encrypt_rfbdes(void *out, int *out_len, const unsigned char key[8], const void *in, const size_t in_len)
{
int eightbyteblocks = in_len/8;
int i;
rfbDesKey((unsigned char*)key, EN0);
for(i = 0; i < eightbyteblocks; ++i)
rfbDes((unsigned char*)in + i*8, (unsigned char*)out + i*8);

*out_len = in_len;

return 1;
}

int decrypt_rfbdes(void *out, int *out_len, const unsigned char key[8], const void *in, const size_t in_len)
{
int eightbyteblocks = in_len/8;
int i;
rfbDesKey((unsigned char*)key, DE1);
for(i = 0; i < eightbyteblocks; ++i)
rfbDes((unsigned char*)in + i*8, (unsigned char*)out + i*8);

*out_len = in_len;

return 1;
}

int encrypt_aes128ecb(void *out, int *out_len, const unsigned char key[16], const void *in, const size_t in_len)
{
return 0;
}

int dh_generate_keypair(uint8_t *priv_out, uint8_t *pub_out, const uint8_t *gen, const size_t gen_len, const uint8_t *prime, const size_t keylen)
{
return 0;
}

int dh_compute_shared_key(uint8_t *shared_out, const uint8_t *priv, const uint8_t *pub, const uint8_t *prime, const size_t keylen)
{
return 0;
}
271 changes: 271 additions & 0 deletions common/crypto_libgcrypt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,271 @@
/*
* crypto_gnutls.c - Crypto wrapper (libgcrypt version)
*/

/*
* Copyright (C) 2011 Gernot Tenchio
* Copyright (C) 2019 Christian Beier
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/

#include <string.h>
#include <gcrypt.h>
#include "crypto.h"

static int mpiToBytes(const gcry_mpi_t value, uint8_t *result, size_t size)
{
gcry_error_t error;
size_t len;
int i;

error = gcry_mpi_print(GCRYMPI_FMT_USG, result, size, &len, value);
if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
return 0;
for (i=size-1;i>(int)size-1-(int)len;--i)
result[i] = result[i-size+len];
for (;i>=0;--i)
result[i] = 0;
return 1;
}

static unsigned char reverseByte(unsigned char b) {
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
return b;
}

int hash_md5(void *out, const void *in, const size_t in_len)
{
int result = 0;
gcry_error_t error;
gcry_md_hd_t md5 = NULL;
void *digest;

error = gcry_md_open(&md5, GCRY_MD_MD5, 0);
if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
goto out;

gcry_md_write(md5, in, in_len);

if(!(digest = gcry_md_read(md5, GCRY_MD_MD5)))
goto out;

memcpy(out, digest, gcry_md_get_algo_dlen(GCRY_MD_MD5));

result = 1;

out:
gcry_md_close(md5);
return result;
}

int hash_sha1(void *out, const void *in, const size_t in_len)
{
int result = 0;
gcry_error_t error;
gcry_md_hd_t sha1 = NULL;
void *digest;

error = gcry_md_open(&sha1, GCRY_MD_SHA1, 0);
if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
goto out;

gcry_md_write(sha1, in, in_len);

if(!(digest = gcry_md_read(sha1, GCRY_MD_SHA1)))
goto out;

memcpy(out, digest, gcry_md_get_algo_dlen(GCRY_MD_SHA1));

result = 1;

out:
gcry_md_close(sha1);
return result;
}

void random_bytes(void *out, size_t len)
{
gcry_randomize(out, len, GCRY_STRONG_RANDOM);
}

int encrypt_rfbdes(void *out, int *out_len, const unsigned char key[8], const void *in, const size_t in_len)
{
int result = 0;
gcry_error_t error;
gcry_cipher_hd_t des = NULL;
unsigned char mungedkey[8];
int i;

for (i = 0; i < 8; i++)
mungedkey[i] = reverseByte(key[i]);

error = gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
goto out;

error = gcry_cipher_setkey(des, mungedkey, 8);
if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
goto out;

error = gcry_cipher_encrypt(des, out, in_len, in, in_len);
if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
goto out;

*out_len = in_len;

result = 1;

out:
gcry_cipher_close(des);
return result;
}

int decrypt_rfbdes(void *out, int *out_len, const unsigned char key[8], const void *in, const size_t in_len)
{
int result = 0;
gcry_error_t error;
gcry_cipher_hd_t des = NULL;
unsigned char mungedkey[8];
int i;

for (i = 0; i < 8; i++)
mungedkey[i] = reverseByte(key[i]);

error = gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
goto out;

error = gcry_cipher_setkey(des, mungedkey, 8);
if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
goto out;

error = gcry_cipher_decrypt(des, out, in_len, in, in_len);
if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
goto out;

*out_len = in_len;

result = 1;

out:
gcry_cipher_close(des);
return result;
}


int encrypt_aes128ecb(void *out, int *out_len, const unsigned char key[16], const void *in, const size_t in_len)
{
int result = 0;
gcry_error_t error;
gcry_cipher_hd_t aes = NULL;

error = gcry_cipher_open(&aes, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB, 0);
if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
goto out;

error = gcry_cipher_setkey(aes, key, 16);
if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
goto out;

error = gcry_cipher_encrypt(aes, out, in_len, in, in_len);
if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
goto out;
*out_len = in_len;

result = 1;

out:
gcry_cipher_close(aes);
return result;
}

int dh_generate_keypair(uint8_t *priv_out, uint8_t *pub_out, const uint8_t *gen, const size_t gen_len, const uint8_t *prime, const size_t keylen)
{
int result = 0;
gcry_error_t error;
gcry_mpi_t genmpi = NULL, modmpi = NULL, privmpi = NULL, pubmpi = NULL;

error = gcry_mpi_scan(&genmpi, GCRYMPI_FMT_USG, gen, gen_len, NULL);
if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
goto out;
error = gcry_mpi_scan(&modmpi, GCRYMPI_FMT_USG, prime, keylen, NULL);
if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
goto out;

privmpi = gcry_mpi_new(keylen);
if (!privmpi)
goto out;
gcry_mpi_randomize(privmpi, (keylen/8)*8, GCRY_STRONG_RANDOM);

pubmpi = gcry_mpi_new(keylen);
if (!pubmpi)
goto out;

gcry_mpi_powm(pubmpi, genmpi, privmpi, modmpi);

if (!mpiToBytes(pubmpi, pub_out, keylen))
goto out;
if (!mpiToBytes(privmpi, priv_out, keylen))
goto out;

result = 1;

out:
gcry_mpi_release(genmpi);
gcry_mpi_release(modmpi);
gcry_mpi_release(privmpi);
gcry_mpi_release(pubmpi);
return result;
}

int dh_compute_shared_key(uint8_t *shared_out, const uint8_t *priv, const uint8_t *pub, const uint8_t *prime, const size_t keylen)
{
int result = 1;
gcry_error_t error;
gcry_mpi_t keympi = NULL, modmpi = NULL, privmpi = NULL, pubmpi = NULL;

error = gcry_mpi_scan(&privmpi, GCRYMPI_FMT_USG, priv, keylen, NULL);
if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
goto out;
error = gcry_mpi_scan(&pubmpi, GCRYMPI_FMT_USG, pub, keylen, NULL);
if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
goto out;
error = gcry_mpi_scan(&modmpi, GCRYMPI_FMT_USG, prime, keylen, NULL);
if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
goto out;

keympi = gcry_mpi_new(keylen);
if (!keympi)
goto out;

gcry_mpi_powm(keympi, pubmpi, privmpi, modmpi);

if (!mpiToBytes(keympi, shared_out, keylen))
goto out;

result = 1;

out:
gcry_mpi_release(keympi);
gcry_mpi_release(modmpi);
gcry_mpi_release(privmpi);
gcry_mpi_release(pubmpi);

return result;
}
201 changes: 201 additions & 0 deletions common/crypto_openssl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
/*
* crypto_openssl.c - Crypto wrapper (openssl version)
*/

/*
* Copyright (C) 2011 Gernot Tenchio
* Copyright (C) 2019 Christian Beier
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/

#include <string.h>
#include <openssl/sha.h>
#include <openssl/md5.h>
#include <openssl/dh.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include "crypto.h"

static unsigned char reverseByte(unsigned char b) {
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
return b;
}

int hash_md5(void *out, const void *in, const size_t in_len)
{
MD5_CTX md5;
if(!MD5_Init(&md5))
return 0;
if(!MD5_Update(&md5, in, in_len))
return 0;
if(!MD5_Final(out, &md5))
return 0;
return 1;
}

int hash_sha1(void *out, const void *in, const size_t in_len)
{
SHA_CTX sha1;
if(!SHA1_Init(&sha1))
return 0;
if(!SHA1_Update(&sha1, in, in_len))
return 0;
if(!SHA1_Final(out, &sha1))
return 0;
return 1;
}

void random_bytes(void *out, size_t len)
{
RAND_bytes(out, len);
}

int encrypt_rfbdes(void *out, int *out_len, const unsigned char key[8], const void *in, const size_t in_len)
{
int result = 0;
EVP_CIPHER_CTX *des;
unsigned char mungedkey[8];
int i;

for (i = 0; i < 8; i++)
mungedkey[i] = reverseByte(key[i]);

if(!(des = EVP_CIPHER_CTX_new()))
goto out;
if(!EVP_EncryptInit_ex(des, EVP_des_ecb(), NULL, mungedkey, NULL))
goto out;
if(!EVP_EncryptUpdate(des, out, out_len, in, in_len))
goto out;

result = 1;

out:
EVP_CIPHER_CTX_free(des);
return result;
}

int decrypt_rfbdes(void *out, int *out_len, const unsigned char key[8], const void *in, const size_t in_len)
{
int result = 0;
EVP_CIPHER_CTX *des;
unsigned char mungedkey[8];
int i;

for (i = 0; i < 8; i++)
mungedkey[i] = reverseByte(key[i]);

if(!(des = EVP_CIPHER_CTX_new()))
goto out;
if(!EVP_DecryptInit_ex(des, EVP_des_ecb(), NULL, mungedkey, NULL))
goto out;
if(!EVP_DecryptUpdate(des, out, out_len, in, in_len))
goto out;

result = 1;

out:
EVP_CIPHER_CTX_free(des);
return result;
}

int encrypt_aes128ecb(void *out, int *out_len, const unsigned char key[16], const void *in, const size_t in_len)
{
int result = 0;
EVP_CIPHER_CTX *aes;

if(!(aes = EVP_CIPHER_CTX_new()))
goto out;
EVP_CIPHER_CTX_set_padding(aes, 0);
if(!EVP_EncryptInit_ex(aes, EVP_aes_128_ecb(), NULL, key, NULL))
goto out;
if(!EVP_EncryptUpdate(aes, out, out_len, in, in_len))
goto out;

result = 1;

out:
EVP_CIPHER_CTX_free(aes);
return result;
}

int dh_generate_keypair(uint8_t *priv_out, uint8_t *pub_out, const uint8_t *gen, const size_t gen_len, const uint8_t *prime, const size_t keylen)
{
int result = 0;
DH *dh;
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
const BIGNUM *pub_key = NULL;
const BIGNUM *priv_key = NULL;
#endif

if(!(dh = DH_new()))
goto out;
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined LIBRESSL_VERSION_NUMBER
dh->p = BN_bin2bn(prime, keylen, NULL);
dh->g = BN_bin2bn(gen, gen_len, NULL);
#else
if(!DH_set0_pqg(dh, BN_bin2bn(prime, keylen, NULL), NULL, BN_bin2bn(gen, gen_len, NULL)))
goto out;
#endif
if(!DH_generate_key(dh))
goto out;
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined LIBRESSL_VERSION_NUMBER
if(BN_bn2bin(dh->priv_key, priv_out) == 0)
goto out;
if(BN_bn2bin(dh->pub_key, pub_out) == 0)
goto out;
#else
DH_get0_key(dh, &pub_key, &priv_key);
if(BN_bn2binpad(priv_key, priv_out, keylen) == -1)
goto out;
if(BN_bn2binpad(pub_key, pub_out, keylen) == -1)
goto out;
#endif

result = 1;

out:
DH_free(dh);
return result;
}

int dh_compute_shared_key(uint8_t *shared_out, const uint8_t *priv, const uint8_t *pub, const uint8_t *prime, const size_t keylen)
{
int result = 0;
DH *dh;

if(!(dh = DH_new()))
goto out;
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined LIBRESSL_VERSION_NUMBER
dh->p = BN_bin2bn(prime, keylen, NULL);
dh->priv_key = BN_bin2bn(priv, keylen, NULL);
#else
if(!DH_set0_pqg(dh, BN_bin2bn(prime, keylen, NULL), NULL, BN_new()))
goto out;
if(!DH_set0_key(dh, NULL, BN_bin2bn(priv, keylen, NULL)))
goto out;
#endif
if(DH_compute_key(shared_out, BN_bin2bn(pub, keylen, NULL), dh) == -1)
goto out;

result = 1;

out:
DH_free(dh);
return result;
}
19 changes: 10 additions & 9 deletions common/d3des.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,16 @@ void rfbDesKey(unsigned char *key,
return;
}

static void rfbUseKey(register unsigned long *from)
{
register unsigned long *to, *endp;

to = KnL, endp = &KnL[32];
while( to < endp ) *to++ = *from++;
return;
}


static void cookey(register unsigned long *raw1)
{
register unsigned long *cook, *raw0;
Expand All @@ -138,15 +148,6 @@ static void cookey(register unsigned long *raw1)
}


void rfbUseKey(register unsigned long *from)
{
register unsigned long *to, *endp;

to = KnL, endp = &KnL[32];
while( to < endp ) *to++ = *from++;
return;
}

void rfbDes(unsigned char *inblock,
unsigned char *outblock)
{
Expand Down
4 changes: 0 additions & 4 deletions common/d3des.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,6 @@ extern void rfbDesKey(unsigned char *, int);
* for encryption or decryption according to MODE.
*/

extern void rfbUseKey(unsigned long *);
/* cookedkey[32]
* Loads the internal key register with the data in cookedkey.
*/

extern void rfbDes(unsigned char *, unsigned char *);
/* from[8] to[8]
Expand Down
451 changes: 0 additions & 451 deletions common/md5.c

This file was deleted.

152 changes: 0 additions & 152 deletions common/md5.h

This file was deleted.

16 changes: 0 additions & 16 deletions common/rfbcrypto.h

This file was deleted.

50 changes: 0 additions & 50 deletions common/rfbcrypto_gnutls.c

This file was deleted.

49 changes: 0 additions & 49 deletions common/rfbcrypto_included.c

This file was deleted.

49 changes: 0 additions & 49 deletions common/rfbcrypto_openssl.c

This file was deleted.

66 changes: 66 additions & 0 deletions common/sockets.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* LibVNCServer/LibVNCClient common platform socket defines and includes.
*
* Copyright (C) 2020 Christian Beier <dontmind@freeshell.org>
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/

#ifndef _RFB_COMMON_SOCKETS_H
#define _RFB_COMMON_SOCKETS_H

#ifdef WIN32
/*
Windows sockets
*/
#include <winsock2.h>
#include <ws2tcpip.h>

#undef EWOULDBLOCK
#define EWOULDBLOCK WSAEWOULDBLOCK

#undef ETIMEDOUT
#define ETIMEDOUT WSAETIMEDOUT

#undef EINTR
#define EINTR WSAEINTR

#undef EINVAL
#define EINVAL WSAEINVAL

/* MinGW has those, but MSVC not */
#ifdef _MSC_VER
#define SHUT_RD SD_RECEIVE
#define SHUT_WR SD_SEND
#define SHUT_RDWR SD_BOTH
#endif

#define read(sock,buf,len) recv(sock,buf,len,0)
#define write(sock,buf,len) send(sock,buf,len,0)

#else
/*
Unix sockets
*/
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <netdb.h>
#endif

#endif /* _RFB_COMMON_SOCKETS_H */
4 changes: 3 additions & 1 deletion common/turbojpeg.c
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ DLLEXPORT int DLLCALL tjCompress(tjhandle handle, unsigned char *srcBuf,
int width, int pitch, int height, int pixelSize, unsigned char *jpegBuf,
unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags)
{
int retval=0; unsigned long size;
int retval=0; unsigned long size = 0;
retval=tjCompress2(handle, srcBuf, width, pitch, height,
getPixelFormat(pixelSize, flags), &jpegBuf, &size, jpegSubsamp, jpegQual,
flags);
Expand Down Expand Up @@ -797,7 +797,9 @@ DLLEXPORT int DLLCALL tjDecompress2(tjhandle handle, unsigned char *jpegBuf,
}
if(scaledw>width || scaledh>height)
_throw("tjDecompress2(): Could not scale down to desired image dimensions");
#ifndef JCS_EXTENSIONS
width=scaledw; height=scaledh;
#endif
dinfo->scale_num=sf[i].num;
dinfo->scale_denom=sf[i].denom;

Expand Down
5 changes: 5 additions & 0 deletions common/turbojpeg.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

/*
* Copyright (C)2009-2012 D. R. Commander. All Rights Reserved.
*
Expand Down Expand Up @@ -36,6 +37,10 @@
#endif
#define DLLCALL

#ifdef _MSC_VER
#pragma warning(disable:4996)
#endif


/**
* @addtogroup TurboJPEG Lite
Expand Down
34 changes: 17 additions & 17 deletions common/vncauth.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
* vncauth.c - Functions for VNC password management and authentication.
*/

#include <rfb/rfbproto.h>
#ifdef __STRICT_ANSI__
#define _BSD_SOURCE
#define _POSIX_SOURCE
Expand All @@ -34,8 +35,7 @@
#ifdef LIBVNCSERVER_HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <rfb/rfbproto.h>
#include "d3des.h"
#include "crypto.h"

#include <string.h>
#include <math.h>
Expand All @@ -49,6 +49,10 @@
#ifdef WIN32
#define srandom srand
#define random rand
#include <process.h>
#ifdef _MSC_VER
#pragma warning(disable:4996)
#endif
#else
#include <sys/time.h>
#endif
Expand Down Expand Up @@ -77,6 +81,7 @@ rfbEncryptAndStorePasswd(char *passwd, char *fname)
FILE *fp;
unsigned int i;
unsigned char encryptedPasswd[8];
int out_len;

if ((fp = fopen(fname,"w")) == NULL) return 1;

Expand All @@ -97,9 +102,7 @@ rfbEncryptAndStorePasswd(char *passwd, char *fname)

/* Do encryption in-place - this way we overwrite our copy of the plaintext
password */

rfbDesKey(fixedkey, EN0);
rfbDes(encryptedPasswd, encryptedPasswd);
encrypt_rfbdes(encryptedPasswd, &out_len, fixedkey, encryptedPasswd, sizeof(encryptedPasswd));

for (i = 0; i < 8; i++) {
putc(encryptedPasswd[i], fp);
Expand All @@ -122,8 +125,9 @@ rfbDecryptPasswdFromFile(char *fname)
FILE *fp;
int i, ch;
unsigned char *passwd = (unsigned char *)malloc(9);
int out_len;

if ((fp = fopen(fname,"r")) == NULL) {
if (!passwd || (fp = fopen(fname,"r")) == NULL) {
free(passwd);
return NULL;
}
Expand All @@ -140,8 +144,8 @@ rfbDecryptPasswdFromFile(char *fname)

fclose(fp);

rfbDesKey(fixedkey, DE1);
rfbDes(passwd, passwd);
if(!decrypt_rfbdes(passwd, &out_len, fixedkey, passwd, 8))
return NULL;

passwd[8] = 0;

Expand Down Expand Up @@ -181,6 +185,7 @@ rfbEncryptBytes(unsigned char *bytes, char *passwd)
{
unsigned char key[8];
unsigned int i;
int out_len;

/* key is simply password padded with nulls */

Expand All @@ -192,24 +197,19 @@ rfbEncryptBytes(unsigned char *bytes, char *passwd)
}
}

rfbDesKey(key, EN0);

for (i = 0; i < CHALLENGESIZE; i += 8) {
rfbDes(bytes+i, bytes+i);
}
encrypt_rfbdes(bytes, &out_len, key, bytes, CHALLENGESIZE);
}

void
rfbEncryptBytes2(unsigned char *where, const int length, unsigned char *key) {
int i, j;
rfbDesKey(key, EN0);
int i, j, out_len;
for (i = 0; i< 8; i++)
where[i] ^= key[i];
rfbDes(where, where);
encrypt_rfbdes(where, &out_len, key, where, 8);
for (i = 8; i < length; i += 8) {
for (j = 0; j < 8; j++) {
where[i + j] ^= where[i + j - 8];
}
rfbDes(where + i, where + i);
encrypt_rfbdes(where + i, &out_len, key, where + i, 8);
}
}
247 changes: 0 additions & 247 deletions compat/msvc/stdint.h

This file was deleted.

64 changes: 0 additions & 64 deletions compat/msvc/sys/time.h

This file was deleted.

3 changes: 0 additions & 3 deletions compat/msvc/unistd.h

This file was deleted.

2 changes: 1 addition & 1 deletion examples/backchannel.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ int main(int argc,char** argv)

server=rfbGetScreen(&argc,argv,400,300,8,3,4);
if(!server)
return 0;
return 1;
server->frameBuffer=(char*)malloc(400*300*4);
rfbInitServer(server);
rfbRunEventLoop(server,-1,FALSE);
Expand Down
5 changes: 5 additions & 0 deletions examples/blooptest.c
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
/**
@example blooptest.c
blooptest is a test of pthreads. It is just the example, but with a background
loop to hunt down thread lockups.
*/
#define BACKGROUND_LOOP_TEST
#include "example.c"
19 changes: 18 additions & 1 deletion examples/camera.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,23 @@
#include <stdlib.h>
#include <string.h>
#include <rfb/rfb.h>
#ifdef LIBVNCSERVER_HAVE_GETTIMEOFDAY
/* if we have gettimeofday(), it is in this header */
#include <sys/time.h>
#endif
#if !defined LIBVNCSERVER_HAVE_GETTIMEOFDAY && defined WIN32
#include <fcntl.h>
#include <conio.h>
#include <sys/timeb.h>

static void gettimeofday(struct timeval* tv,char* dummy)
{
SYSTEMTIME t;
GetSystemTime(&t);
tv->tv_sec=t.wHour*3600+t.wMinute*60+t.wSecond;
tv->tv_usec=t.wMilliseconds*1000;
}
#endif


#define WIDTH 640
Expand Down Expand Up @@ -134,7 +151,7 @@ int main(int argc,char** argv)

rfbScreenInfoPtr server=rfbGetScreen(&argc,argv,WIDTH,HEIGHT,8,3,BPP);
if(!server)
return 0;
return 1;
server->desktopName = "Live Video Feed Example";
server->frameBuffer=(char*)malloc(WIDTH*HEIGHT*BPP);
server->alwaysShared=(1==1);
Expand Down
5 changes: 4 additions & 1 deletion examples/colourmaptest.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ int main(int argc,char** argv)

rfbScreenInfoPtr server=rfbGetScreen(&argc,argv,256,256,8,1,1);
if(!server)
return 0;
return 1;
server->serverFormat.trueColour=FALSE;
server->colourMap.count=256;
server->colourMap.is16=FALSE;
Expand All @@ -23,6 +23,9 @@ int main(int argc,char** argv)
server->colourMap.data.bytes=bytes;

server->frameBuffer=(char*)malloc(256*256);
if(!server->frameBuffer)
return 1;

for(i=0;i<256*256;i++)
server->frameBuffer[i]=(i/256);

Expand Down
16 changes: 11 additions & 5 deletions test/cursortest.c → examples/cursors.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,9 @@ static void SetRichCursor(rfbScreenInfoPtr rfbScreen)
c=rfbMakeXCursor(w,h,bitmap,bitmap);
c->xhot = 16; c->yhot = 24;

c->richSource = (char*)malloc(w*h*bpp);
c->richSource = (unsigned char*)malloc(w*h*bpp);
if (!c->richSource) return;

for(j=0;j<h;j++) {
for(i=0;i<w;i++) {
c->richSource[j*w*bpp+i*bpp+0]=i*0xff/w;
Expand Down Expand Up @@ -218,7 +220,8 @@ static void SetRichCursor2(rfbScreenInfoPtr rfbScreen)
c=rfbMakeXCursor(w,h,bitmap,bitmap);
c->xhot = 5; c->yhot = 7;

c->richSource = (char*)malloc(w*h*bpp);
c->richSource = (unsigned char*)malloc(w*h*bpp);
if(!c->richSource) return;
for(j=0;j<h;j++) {
for(i=0;i<w;i++) {
c->richSource[j*w*bpp+i*bpp+0]=0xff;
Expand All @@ -236,11 +239,13 @@ static void SetAlphaCursor(rfbScreenInfoPtr screen,int mode)
{
int i,j;
rfbCursorPtr c = screen->cursor;
int maskStride=(c->width+7)/8;
int maskStride;

if(!c)
return;

maskStride = (c->width+7)/8;

if(c->alphaSource) {
free(c->alphaSource);
c->alphaSource=NULL;
Expand All @@ -250,6 +255,7 @@ static void SetAlphaCursor(rfbScreenInfoPtr screen,int mode)
return;

c->alphaSource = (unsigned char*)malloc(c->width*c->height);
if (!c->alphaSource) return;

for(j=0;j<c->height;j++)
for(i=0;i<c->width;i++) {
Expand All @@ -259,7 +265,7 @@ static void SetAlphaCursor(rfbScreenInfoPtr screen,int mode)
}
if(c->cleanupMask)
free(c->mask);
c->mask=rfbMakeMaskFromAlphaSource(c->width,c->height,c->alphaSource);
c->mask=(unsigned char*)rfbMakeMaskFromAlphaSource(c->width,c->height,c->alphaSource);
c->cleanupMask=TRUE;
}

Expand Down Expand Up @@ -324,7 +330,7 @@ int main(int argc,char** argv)
{
rfbScreenInfoPtr rfbScreen = rfbGetScreen(&argc,argv,maxx,maxy,8,3,bpp);
if(!rfbScreen)
return 0;
return 1;

rfbScreen->desktopName = "Cursor Test";
rfbScreen->frameBuffer = (char*)malloc(maxx*maxy*bpp);
Expand Down
13 changes: 7 additions & 6 deletions examples/example.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,7 @@ static void doptr(int buttonMask,int x,int y,rfbClientPtr cl)
/* we could get a selection like that:
rfbGotXCutText(cl->screen,"Hallo",5);
*/
} else
cd->oldButton=0;
}

cd->oldx=x; cd->oldy=y; cd->oldButton=buttonMask;
}
Expand Down Expand Up @@ -227,7 +226,7 @@ static char exampleXCursor[]=
static void MakeRichCursor(rfbScreenInfoPtr rfbScreen)
{
int i,j,w=32,h=32;
rfbCursorPtr c = rfbScreen->cursor;
rfbCursorPtr c;
char bitmap[]=
" "
" xxxxxx "
Expand Down Expand Up @@ -265,6 +264,8 @@ static void MakeRichCursor(rfbScreenInfoPtr rfbScreen)
c->xhot = 16; c->yhot = 24;

c->richSource = (unsigned char*)malloc(w*h*bpp);
if(!c->richSource)
return;
c->cleanupRichSource = TRUE;
for(j=0;j<h;j++) {
for(i=0;i<w;i++) {
Expand All @@ -282,7 +283,7 @@ int main(int argc,char** argv)
{
rfbScreenInfoPtr rfbScreen = rfbGetScreen(&argc,argv,maxx,maxy,8,3,bpp);
if(!rfbScreen)
return 0;
return 1;
rfbScreen->desktopName = "LibVNCServer Example";
rfbScreen->frameBuffer = (char*)malloc(maxx*maxy*bpp);
rfbScreen->alwaysShared = TRUE;
Expand Down Expand Up @@ -320,8 +321,8 @@ int main(int argc,char** argv)
rfbRunEventLoop(rfbScreen,40000,FALSE);
#endif /* OWN LOOP */
#else
#if !defined(LIBVNCSERVER_HAVE_LIBPTHREAD)
#error "I need pthreads for that."
#if !defined(LIBVNCSERVER_HAVE_LIBPTHREAD) && !defined(LIBVNCSERVER_HAVE_WIN32THREADS)
#error "I need pthreads or win32 threads for that."
#endif

/* this is the non-blocking event loop; a background thread is started */
Expand Down
2 changes: 1 addition & 1 deletion examples/filetransfer.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ int main(int argc,char** argv)
{
rfbScreenInfoPtr server=rfbGetScreen(&argc,argv,400,300,8,3,4);
if(!server)
return 0;
return 1;
server->frameBuffer=(char*)malloc(400*300*4);
rfbRegisterTightVNCFileTransferExtension();
rfbInitServer(server);
Expand Down
14 changes: 12 additions & 2 deletions examples/fontsel.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
/**
@example fontsel.c
fontsel is a test for rfbSelectBox and rfbLoadConsoleFont. If you have Linux
console fonts, you can browse them via VNC. Directory browsing not implemented
yet :-(
*/

#include <rfb/rfb.h>

#define FONTDIR "/usr/lib/kbd/consolefonts/"
Expand Down Expand Up @@ -42,9 +49,12 @@ int main(int argc,char** argv)
int i,j;

if(!s)
return 0;
return 1;

s->frameBuffer=(char*)malloc(640*480*3);
if(!s->frameBuffer)
return 1;

rfbInitServer(s);

for(j=0;j<480;j++)
Expand All @@ -61,7 +71,7 @@ int main(int argc,char** argv)
exit(1);
}

for(j=0;j<0 && rfbIsActive(s);j++)
for(j=0;j<10 && rfbIsActive(s);j++)
rfbProcessEvents(s,900000);

i = rfbSelectBox(s,font,fontlist,10,20,200,300,0xffdfdf,0x602040,2,showFont);
Expand Down
713 changes: 443 additions & 270 deletions examples/mac.c

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion examples/pnmshow.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ int main(int argc,char** argv)
/* initialize data for vnc server */
rfbScreen = rfbGetScreen(&argc,argv,paddedWidth,height,8,(bitsPerPixelInFile+7)/8,bytesPerPixel);
if(!rfbScreen)
return 0;
return 1;
if(argc>1)
rfbScreen->desktopName = argv[1];
else
Expand All @@ -79,6 +79,8 @@ int main(int argc,char** argv)

/* allocate picture and read it */
rfbScreen->frameBuffer = (char*)malloc(paddedWidth*bytesPerPixel*height);
if(!rfbScreen->frameBuffer)
exit(1);
fread(rfbScreen->frameBuffer,width*bitsPerPixelInFile/8,height,in);
fclose(in);

Expand All @@ -87,6 +89,8 @@ int main(int argc,char** argv)
rfbScreen->colourMap.count=256;
rfbScreen->colourMap.is16=FALSE;
rfbScreen->colourMap.data.bytes=malloc(256*3);
if(!rfbScreen->colourMap.data.bytes)
exit(1);
for(i=0;i<256;i++)
memset(rfbScreen->colourMap.data.bytes+3*i,i,3);
}
Expand Down
10 changes: 8 additions & 2 deletions examples/pnmshow24.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
/**
* @example pnmshow24.c
@example pnmshow24.c
pnmshow24 is like pnmshow, but it uses 3 bytes/pixel internally, which is not
as efficient as 4 bytes/pixel for translation, because there is no native data
type of that size, so you have to memcpy pixels and be real cautious with
endianness. Anyway, it works.
*/

#include <stdio.h>
Expand Down Expand Up @@ -61,7 +65,7 @@ int main(int argc,char** argv)
/* initialize data for vnc server */
rfbScreen = rfbGetScreen(&argc,argv,paddedWidth,height,8,3,3);
if(!rfbScreen)
return 0;
return 1;
if(argc>1)
rfbScreen->desktopName = argv[1];
else
Expand All @@ -74,6 +78,8 @@ int main(int argc,char** argv)

/* allocate picture and read it */
rfbScreen->frameBuffer = (char*)malloc(paddedWidth*3*height);
if(!rfbScreen->frameBuffer)
return 1;
fread(rfbScreen->frameBuffer,width*3,height,in);
fclose(in);

Expand Down
19 changes: 10 additions & 9 deletions examples/repeater.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ int main(int argc,char** argv)
char *repeaterHost;
int repeaterPort, sock;
char id[250];
int idlen;
rfbClientPtr cl;

int i,j;
Expand All @@ -24,37 +23,39 @@ int main(int argc,char** argv)
"Usage: %s <id> <repeater-host> [<repeater-port>]\n", argv[0]);
exit(1);
}
idlen = snprintf(id, sizeof(id) - 1, "ID:%s", argv[1]);
if(idlen < 0 || idlen >= (int)sizeof(id)) {
fprintf(stderr, "Error, given ID is probably too long.\n");
memset(id, 0, sizeof(id));
if(snprintf(id, sizeof(id), "ID:%s", argv[1]) >= (int)sizeof(id)) {
/* truncated! */
fprintf(stderr, "Error, given ID is too long.\n");
return 1;
}

repeaterHost = argv[2];
repeaterPort = argc < 4 ? 5500 : atoi(argv[3]);

/* The initialization is identical to simple15.c */
rfbScreenInfoPtr server=rfbGetScreen(&argc,argv,400,300,5,3,2);
if(!server)
return 0;
return 1;
server->frameBuffer=(char*)malloc(400*300*2);
if(!server->frameBuffer)
return 1;
f=(uint16_t*)server->frameBuffer;
for(j=0;j<300;j++)
for(i=0;i<400;i++)
f[j*400+i]=/* red */ ((j*32/300) << 10) |
/* green */ (((j+400-i)*32/700) << 5) |
/* blue */ ((i*32/400));
/* blue */ (i*32/400);

/* Now for the repeater-specific part: */
server->port = -1; /* do not listen on any port */
server->ipv6port = -1; /* do not listen on any port */

sock = rfbConnectToTcpAddr(repeaterHost, repeaterPort);
if (sock < 0) {
if (sock == RFB_INVALID_SOCKET) {
perror("connect to repeater");
return 1;
}
if (write(sock, id, idlen+1) != idlen+1) {
if (send(sock, id, sizeof(id),0) != sizeof(id)) {
perror("writing id");
return 1;
}
Expand Down
1 change: 1 addition & 0 deletions examples/rotatetemplate.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ static void FUNCTION(rfbScreenInfoPtr screen)
OUT_T* buffer = (OUT_T*)screen->frameBuffer;
int i, j, w = screen->width, h = screen->height;
OUT_T* newBuffer = (OUT_T*)malloc(w * h * sizeof(OUT_T));
if (!newBuffer) return;

for (j = 0; j < h; j++)
for (i = 0; i < w; i++)
Expand Down
2 changes: 1 addition & 1 deletion examples/simple.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ int main(int argc,char** argv)
{
rfbScreenInfoPtr server=rfbGetScreen(&argc,argv,400,300,8,3,4);
if(!server)
return 0;
return 1;
server->frameBuffer=(char*)malloc(400*300*4);
rfbInitServer(server);
rfbRunEventLoop(server,-1,FALSE);
Expand Down
6 changes: 4 additions & 2 deletions examples/simple15.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ int main(int argc,char** argv)

rfbScreenInfoPtr server=rfbGetScreen(&argc,argv,400,300,5,3,2);
if(!server)
return 0;
return 1;
server->frameBuffer=(char*)malloc(400*300*2);
if(!server->frameBuffer)
return 1;
f=(uint16_t*)server->frameBuffer;
for(j=0;j<300;j++)
for(i=0;i<400;i++)
f[j*400+i]=/* red */ ((j*32/300) << 10) |
/* green */ (((j+400-i)*32/700) << 5) |
/* blue */ ((i*32/400));
/* blue */ (i*32/400);

rfbInitServer(server);
rfbRunEventLoop(server,-1,FALSE);
Expand Down
8 changes: 8 additions & 0 deletions examples/storepasswd.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@
* USA.
*/

/**
@example storepasswd.c
storepasswd is the original program to save a vnc style password in a file.
Unfortunately, authentication as every vncviewer speaks it means the server
has to know the plain password. You really should tunnel via ssh or use
your own PasswordCheck to build a PIN/TAN system.
*/

#include <stdio.h>
#include <rfb/rfb.h>

Expand Down
7 changes: 6 additions & 1 deletion examples/vncev.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ static void read_keys(void)
j=j*16+k;
if(keys[j&0x3ff]) {
char* x=(char*)malloc(1+strlen(keys[j&0x3ff])+1+strlen(buffer+strlen("#define ")));
if(!x) {
memset(keys,0,0x400*sizeof(char*));
fclose(keysyms);
return;
}
strcpy(x,keys[j&0x3ff]);
strcat(x,",");
strcat(x,buffer+strlen("#define "));
Expand Down Expand Up @@ -115,7 +120,7 @@ int main(int argc,char** argv)
{
rfbScreenInfoPtr s=rfbGetScreen(&argc,argv,width,height,8,1,1);
if(!s)
return 0;
return 1;
s->colourMap.is16=FALSE;
s->colourMap.count=2;
s->colourMap.data.bytes=(unsigned char*)"\xd0\xd0\xd0\x30\x01\xe0";
Expand Down
2 changes: 1 addition & 1 deletion examples/zippy.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ int main (int argc, char **argv)

server = rfbGetScreen (&argc, argv, maxx, maxy, 8, 3, bpp);
if(!server)
return 0;
return 1;
server->desktopName = "Zippy das wundersquirrel\'s VNC server";
server->frameBuffer = (char*)malloc(maxx*maxy*bpp);
server->alwaysShared = TRUE;
Expand Down
6 changes: 3 additions & 3 deletions libvncclient.pc.cmakein
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=@CMAKE_INSTALL_PREFIX@
libdir=@CMAKE_INSTALL_PREFIX@/lib
libdir=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@
includedir=@CMAKE_INSTALL_PREFIX@/include

Name: LibVNCClient
Description: A library for easy implementation of a VNC client.
Version: @PACKAGE_VERSION@
Version: @LibVNCServer_VERSION@
Requires:
Requires.private: zlib
Requires.private:
Libs: -L${libdir} -lvncclient
Libs.private: @PRIVATE_LIBS@
Cflags: -I${includedir}
Expand Down
5 changes: 5 additions & 0 deletions libvncclient/cursor.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#define OPER_SAVE 0
#define OPER_RESTORE 1

#define MAX_CURSOR_SIZE 1024

#define RGB24_TO_PIXEL(bpp,r,g,b) \
((((uint##bpp##_t)(r) & 0xFF) * client->format.redMax + 127) / 255 \
<< client->format.redShift | \
Expand All @@ -54,6 +56,9 @@ rfbBool HandleCursorShape(rfbClient* client,int xhot, int yhot, int width, int h
if (width * height == 0)
return TRUE;

if (width >= MAX_CURSOR_SIZE || height >= MAX_CURSOR_SIZE)
return FALSE;

/* Allocate memory for pixel data and temporary mask data. */
if(client->rcSource)
free(client->rcSource);
Expand Down
2 changes: 1 addition & 1 deletion libvncclient/hextile.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
static rfbBool
HandleHextileBPP (rfbClient* client, int rx, int ry, int rw, int rh)
{
CARDBPP bg, fg;
CARDBPP bg = 0, fg;
int i;
uint8_t *ptr;
int x, y, w, h;
Expand Down
47 changes: 23 additions & 24 deletions libvncclient/listen.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
#endif
#include <sys/types.h>
#ifdef WIN32
#define close closesocket
#include <winsock2.h>
#else // #ifdef WIN32
#include <sys/wait.h>
Expand All @@ -54,14 +53,14 @@ listenForIncomingConnections(rfbClient* client)
rfbClientErr("listenForIncomingConnections on MinGW32 NOT IMPLEMENTED\n");
return;
#else
int listenSocket, listen6Socket = -1;
int listenSocket = RFB_INVALID_SOCKET, listen6Socket = RFB_INVALID_SOCKET;
fd_set fds;

client->listenSpecified = TRUE;

listenSocket = ListenAtTcpPortAndAddress(client->listenPort, client->listenAddress);

if ((listenSocket < 0))
if (listenSocket == RFB_INVALID_SOCKET)
return;

rfbClientLog("%s -listen: Listening on port %d\n",
Expand All @@ -71,11 +70,11 @@ listenForIncomingConnections(rfbClient* client)

#ifdef LIBVNCSERVER_IPv6 /* only try that if we're IPv6-capable, otherwise we may try to bind to the same port which would make all that listening fail */
/* only do IPv6 listen of listen6Port is set */
if (client->listen6Port > 0)
if (client->listen6Port != RFB_INVALID_SOCKET)
{
listen6Socket = ListenAtTcpPortAndAddress(client->listen6Port, client->listen6Address);

if (listen6Socket < 0)
if (listen6Socket == RFB_INVALID_SOCKET)
return;

rfbClientLog("%s -listen: Listening on IPV6 port %d\n",
Expand All @@ -95,9 +94,9 @@ listenForIncomingConnections(rfbClient* client)

FD_ZERO(&fds);

if(listenSocket >= 0)
if(listenSocket != RFB_INVALID_SOCKET)
FD_SET(listenSocket, &fds);
if(listen6Socket >= 0)
if(listen6Socket != RFB_INVALID_SOCKET)
FD_SET(listen6Socket, &fds);

r = select(rfbMax(listenSocket, listen6Socket)+1, &fds, NULL, NULL, NULL);
Expand All @@ -108,7 +107,7 @@ listenForIncomingConnections(rfbClient* client)
else if (FD_ISSET(listen6Socket, &fds))
client->sock = AcceptTcpConnection(client->listen6Sock);

if (client->sock < 0)
if (client->sock == RFB_INVALID_SOCKET)
return;
if (!SetNonBlocking(client->sock))
return;
Expand All @@ -123,13 +122,13 @@ listenForIncomingConnections(rfbClient* client)

case 0:
/* child - return to caller */
close(listenSocket);
close(listen6Socket);
rfbCloseSocket(listenSocket);
rfbCloseSocket(listen6Socket);
return;

default:
/* parent - go round and listen again */
close(client->sock);
rfbCloseSocket(client->sock);
break;
}
}
Expand Down Expand Up @@ -159,11 +158,11 @@ listenForIncomingConnectionsNoFork(rfbClient* client, int timeout)

client->listenSpecified = TRUE;

if (client->listenSock < 0)
if (client->listenSock == RFB_INVALID_SOCKET)
{
client->listenSock = ListenAtTcpPortAndAddress(client->listenPort, client->listenAddress);

if (client->listenSock < 0)
if (client->listenSock == RFB_INVALID_SOCKET)
return -1;

rfbClientLog("%s -listennofork: Listening on port %d\n",
Expand All @@ -174,11 +173,11 @@ listenForIncomingConnectionsNoFork(rfbClient* client, int timeout)

#ifdef LIBVNCSERVER_IPv6 /* only try that if we're IPv6-capable, otherwise we may try to bind to the same port which would make all that listening fail */
/* only do IPv6 listen of listen6Port is set */
if (client->listen6Port > 0 && client->listen6Sock < 0)
if (client->listen6Port != RFB_INVALID_SOCKET && client->listen6Sock == RFB_INVALID_SOCKET)
{
client->listen6Sock = ListenAtTcpPortAndAddress(client->listen6Port, client->listen6Address);

if (client->listen6Sock < 0)
if (client->listen6Sock == RFB_INVALID_SOCKET)
return -1;

rfbClientLog("%s -listennofork: Listening on IPV6 port %d\n",
Expand All @@ -190,9 +189,9 @@ listenForIncomingConnectionsNoFork(rfbClient* client, int timeout)

FD_ZERO(&fds);

if(client->listenSock >= 0)
if(client->listenSock != RFB_INVALID_SOCKET)
FD_SET(client->listenSock, &fds);
if(client->listen6Sock >= 0)
if(client->listen6Sock != RFB_INVALID_SOCKET)
FD_SET(client->listen6Sock, &fds);

if (timeout < 0)
Expand All @@ -207,18 +206,18 @@ listenForIncomingConnectionsNoFork(rfbClient* client, int timeout)
else if (FD_ISSET(client->listen6Sock, &fds))
client->sock = AcceptTcpConnection(client->listen6Sock);

if (client->sock < 0)
if (client->sock == RFB_INVALID_SOCKET)
return -1;
if (!SetNonBlocking(client->sock))
return -1;

if(client->listenSock >= 0) {
close(client->listenSock);
client->listenSock = -1;
if(client->listenSock != RFB_INVALID_SOCKET) {
rfbCloseSocket(client->listenSock);
client->listenSock = RFB_INVALID_SOCKET;
}
if(client->listen6Sock >= 0) {
close(client->listen6Sock);
client->listen6Sock = -1;
if(client->listen6Sock != RFB_INVALID_SOCKET) {
rfbCloseSocket(client->listen6Sock);
client->listen6Sock = RFB_INVALID_SOCKET;
}
return r;
}
Expand Down
Loading