Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ struct nvnc_client {

#ifdef HAVE_CRYPTO
struct crypto_key* apple_dh_secret;
struct crypto_cipher* apple_dh_cipher;

struct {
enum crypto_hash_type hash_type;
Expand Down
28 changes: 28 additions & 0 deletions include/rfb-proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#pragma once

#define RFB_VERSION_MESSAGE "RFB 003.008\n"
#define RFB_VERSION_MESSAGE_AAPL "RFB 003.889\n"

#include <stdint.h>
#include <unistd.h>
Expand Down Expand Up @@ -48,6 +49,9 @@ enum rfb_client_to_server_msg_type {
RFB_CLIENT_TO_SERVER_KEY_EVENT = 4,
RFB_CLIENT_TO_SERVER_POINTER_EVENT = 5,
RFB_CLIENT_TO_SERVER_CLIENT_CUT_TEXT = 6,
RFB_CLIENT_TO_SERVER_APPLE_CONTINUOUS_UPDATES = 9,
RFB_CLIENT_TO_SERVER_APPLE_SET_MODE = 10,
RFB_CLIENT_TO_SERVER_APPLE_ENCRYPTED_EVENT_MESSAGE = 16,
RFB_CLIENT_TO_SERVER_ENABLE_CONTINUOUS_UPDATES = 150,
RFB_CLIENT_TO_SERVER_NTP = 160,
RFB_CLIENT_TO_SERVER_FENCE = 248,
Expand Down Expand Up @@ -363,3 +367,27 @@ struct rfb_fence_msg {
uint8_t length;
uint8_t payload[0];
} RFB_PACKED;

struct rfb_apple_enc_event_msg {
uint8_t type;
uint8_t flags;
uint8_t keyboard;
uint8_t down_flag;
uint32_t key;
uint32_t delta;
uint8_t mouse;
uint8_t button_mask;
uint16_t x;
uint16_t y;
} RFB_PACKED;

struct rfb_apple_continuous_update_msg {
uint8_t type;
uint8_t padding;
uint16_t flag;
uint32_t ms_between_updates;
uint16_t x;
uint16_t y;
uint16_t width;
uint16_t height;
} RFB_PACKED;
4 changes: 3 additions & 1 deletion src/auth/apple-dh.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,18 +94,20 @@ int apple_dh_handle_response(struct nvnc_client* client)
msg->encrypted_credentials, sizeof(username), NULL, 0);
username[63] = '\0';
username[127] = '\0';
crypto_cipher_del(cipher);

update_min_rtt(client);

if (!server->auth_fn(username, password, server->auth_ud)) {
security_handshake_failed(client, username,
"Invalid username or password");
client->apple_dh_cipher = NULL;
crypto_cipher_del(cipher);
return -1;
}

security_handshake_ok(client, username);
client->state = VNC_CLIENT_STATE_WAITING_FOR_INIT;
client->apple_dh_cipher = cipher;

return sizeof(*msg) + key_len;
}
92 changes: 92 additions & 0 deletions src/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ static void client_close(struct nvnc_client* client)
bwe_destroy(client->bwe);

#ifdef HAVE_CRYPTO
crypto_cipher_del(client->apple_dh_cipher);
crypto_key_del(client->apple_dh_secret);
crypto_rsa_pub_key_del(client->rsa.pub);
#endif
Expand Down Expand Up @@ -1897,6 +1898,91 @@ static int on_client_fence(struct nvnc_client* client)
return sizeof(*msg) + length;
}

static int on_apple_client_continuous_updates(struct nvnc_client* client)
{
struct rfb_apple_continuous_update_msg *msg =
(struct rfb_apple_continuous_update_msg*)(
client->msg_buffer + client->buffer_index);

if (client->buffer_len - client->buffer_index < sizeof(*msg))
return 0;

if(msg->type != RFB_CLIENT_TO_SERVER_APPLE_CONTINUOUS_UPDATES)
return 0;

if (msg->flag) {
client->continuous_updates_enabled = true;
client->continuous_updates.x = ntohs(msg->x);
client->continuous_updates.y = ntohs(msg->y);
client->continuous_updates.width = ntohs(msg->width);
client->continuous_updates.height = ntohs(msg->height);

/* If there are any pending messages left, make sure they are processed */
process_fb_update_requests(client);
} else {
client->continuous_updates_enabled = false;
client->continuous_updates.x = 0;
client->continuous_updates.y = 0;
client->continuous_updates.width = 0;
client->continuous_updates.height = 0;

nvnc_send_end_of_continuous_updates(client);
}

return sizeof(*msg);
}

static int on_apple_client_set_mode(struct nvnc_client* client)
{
if (client->buffer_len - client->buffer_index < 4)
return 0;

uint16_t type = ntohs(*(client->msg_buffer + client->buffer_index + 2));

return 4;
}

static int on_apple_client_encrypted_event_message(struct nvnc_client* client)
{
struct rfb_apple_enc_event_msg *msg = (struct rfb_apple_enc_event_msg *)(
client->msg_buffer + client->buffer_index);

if (client->buffer_len - client->buffer_index < sizeof(*msg))
return 0;

assert(msg->type == RFB_CLIENT_TO_SERVER_APPLE_ENCRYPTED_EVENT_MESSAGE);

crypto_cipher_decrypt(client->apple_dh_cipher, &msg->keyboard, NULL,
&msg->keyboard,
sizeof(*msg) - offsetof(struct rfb_apple_enc_event_msg, keyboard),
NULL, 0);

struct nvnc* server = client->server;

if ((msg->keyboard != 0 && msg->keyboard != 0xff) ||
(msg->mouse != 0 && msg->mouse != 0xff))
return 0;

if (msg->keyboard == 0xff) {
int down_flag = msg->down_flag;
uint32_t keysym = ntohl(msg->key);
nvnc_key_fn fn = server->key_fn;
if (fn)
fn(client, keysym, !!down_flag);
}

if (msg->mouse == 0xff) {
int button_mask = msg->button_mask;
uint16_t x = ntohs(msg->x);
uint16_t y = ntohs(msg->y);
nvnc_pointer_fn fn = server->pointer_fn;
if (fn)
fn(client, x, y, button_mask);
}

return sizeof(*msg);
}

static int on_client_message(struct nvnc_client* client)
{
if (client->buffer_len - client->buffer_index < 1)
Expand Down Expand Up @@ -1928,6 +2014,12 @@ static int on_client_message(struct nvnc_client* client)
return on_client_ntp(client);
case RFB_CLIENT_TO_SERVER_FENCE:
return on_client_fence(client);
case RFB_CLIENT_TO_SERVER_APPLE_CONTINUOUS_UPDATES:
return on_apple_client_continuous_updates(client);
case RFB_CLIENT_TO_SERVER_APPLE_SET_MODE:
return on_apple_client_set_mode(client);
case RFB_CLIENT_TO_SERVER_APPLE_ENCRYPTED_EVENT_MESSAGE:
return on_apple_client_encrypted_event_message(client);
}

nvnc_log(NVNC_LOG_WARNING, "Got uninterpretable message from client: %p",
Expand Down