1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
|
/*
* Copyright (c) 2019 - 2024 Andri Yngvason
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include <stdbool.h>
#include <pixman.h>
#include <zlib.h>
#include "rfb-proto.h"
#include "sys/queue.h"
#include "stream/stream.h"
#include "neatvnc.h"
#include "config.h"
#ifdef HAVE_CRYPTO
#include "crypto.h"
#endif
#ifdef ENABLE_TLS
#include <gnutls/gnutls.h>
#endif
#define MAX_ENCODINGS 32
#define MAX_OUTGOING_FRAMES 4
#define MSG_BUFFER_SIZE 4096
#define MAX_CUT_TEXT_SIZE 10000000
#define MAX_CLIENT_UNSOLICITED_TEXT_SIZE 20971520
#define MAX_SECURITY_TYPES 32
enum nvnc_client_state {
VNC_CLIENT_STATE_ERROR = -1,
VNC_CLIENT_STATE_WAITING_FOR_VERSION = 0,
VNC_CLIENT_STATE_WAITING_FOR_SECURITY,
#ifdef ENABLE_TLS
VNC_CLIENT_STATE_WAITING_FOR_VENCRYPT_VERSION,
VNC_CLIENT_STATE_WAITING_FOR_VENCRYPT_SUBTYPE,
VNC_CLIENT_STATE_WAITING_FOR_VENCRYPT_PLAIN_AUTH,
#endif
#ifdef HAVE_CRYPTO
VNC_CLIENT_STATE_WAITING_FOR_APPLE_DH_RESPONSE,
VNC_CLIENT_STATE_WAITING_FOR_RSA_AES_PUBLIC_KEY,
VNC_CLIENT_STATE_WAITING_FOR_RSA_AES_CHALLENGE,
VNC_CLIENT_STATE_WAITING_FOR_RSA_AES_CLIENT_HASH,
VNC_CLIENT_STATE_WAITING_FOR_RSA_AES_CREDENTIALS,
#endif
VNC_CLIENT_STATE_WAITING_FOR_INIT,
VNC_CLIENT_STATE_READY,
};
struct nvnc;
struct stream;
struct aml_handler;
struct aml_idle;
struct nvnc_display;
struct crypto_key;
struct crypto_rsa_pub_key;
struct crypto_rsa_priv_key;
struct bwe;
struct nvnc_common {
void* userdata;
nvnc_cleanup_fn cleanup_fn;
};
struct cut_text {
char* buffer;
size_t length;
size_t index;
bool is_zlib;
bool is_provide;
};
struct nvnc_client {
struct nvnc_common common;
struct stream* net_stream;
char username[256];
struct nvnc* server;
enum nvnc_client_state state;
struct rfb_pixel_format pixfmt;
enum rfb_encodings encodings[MAX_ENCODINGS + 1];
size_t n_encodings;
LIST_ENTRY(nvnc_client) link;
struct pixman_region16 damage;
int n_pending_requests;
bool is_updating;
nvnc_client_fn cleanup_fn;
size_t buffer_index;
size_t buffer_len;
uint8_t msg_buffer[MSG_BUFFER_SIZE];
uint32_t known_width;
uint32_t known_height;
struct cut_text cut_text;
uint32_t ext_clipboard_caps;
uint32_t ext_clipboard_max_unsolicited_text_size;
bool is_ext_notified;
bool is_continuous_updates_notified;
bool continuous_updates_enabled;
struct {
int x, y;
unsigned int width, height;
} continuous_updates;
struct encoder* encoder;
struct encoder* zrle_encoder;
struct encoder* tight_encoder;
uint32_t cursor_seq;
int quality;
bool formats_changed;
enum nvnc_keyboard_led_state led_state;
enum nvnc_keyboard_led_state pending_led_state;
bool is_blocked_by_fence;
bool must_block_after_next_message;
struct {
int n_pending_requests;
enum rfb_fence_flags flags;
uint8_t payload[64];
size_t length;
} pending_fence;
int32_t last_ping_time;
int32_t min_rtt;
struct bwe* bwe;
int32_t inflight_bytes;
#ifdef HAVE_CRYPTO
struct crypto_key* apple_dh_secret;
struct {
enum crypto_hash_type hash_type;
enum crypto_cipher_type cipher_type;
size_t challenge_len;
uint8_t challenge[32];
struct crypto_rsa_pub_key* pub;
} rsa;
#endif
};
LIST_HEAD(nvnc_client_list, nvnc_client);
enum nvnc__socket_type {
NVNC__SOCKET_TCP,
NVNC__SOCKET_UNIX,
NVNC__SOCKET_WEBSOCKET,
NVNC__SOCKET_FROM_FD,
};
struct nvnc {
struct nvnc_common common;
bool is_closing;
int fd;
enum nvnc__socket_type socket_type;
struct aml_handler* poll_handle;
struct nvnc_client_list clients;
char name[256];
void* userdata;
nvnc_key_fn key_fn;
nvnc_key_fn key_code_fn;
nvnc_pointer_fn pointer_fn;
nvnc_fb_req_fn fb_req_fn;
nvnc_client_fn new_client_fn;
nvnc_cut_text_fn cut_text_fn;
struct cut_text ext_clipboard_provide_msg;
nvnc_desktop_layout_fn desktop_layout_fn;
struct nvnc_display* display;
struct {
struct nvnc_fb* buffer;
uint32_t width, height;
uint32_t hotspot_x, hotspot_y;
} cursor;
uint32_t cursor_seq;
enum nvnc_auth_flags auth_flags;
nvnc_auth_fn auth_fn;
void* auth_ud;
#ifdef ENABLE_TLS
gnutls_certificate_credentials_t tls_creds;
#endif
#ifdef HAVE_CRYPTO
struct crypto_rsa_pub_key* rsa_pub;
struct crypto_rsa_priv_key* rsa_priv;
#endif
int n_security_types;
enum rfb_security_type security_types[MAX_SECURITY_TYPES];
uint32_t n_damage_clients;
};
void nvnc__damage_region(struct nvnc* self,
const struct pixman_region16* damage);
void close_after_write(void* userdata, enum stream_req_status status);
void update_min_rtt(struct nvnc_client* client);
|