summaryrefslogtreecommitdiff
path: root/src/core/exports.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/exports.c')
-rw-r--r--src/core/exports.c396
1 files changed, 396 insertions, 0 deletions
diff --git a/src/core/exports.c b/src/core/exports.c
new file mode 100644
index 0000000..2f336be
--- /dev/null
+++ b/src/core/exports.c
@@ -0,0 +1,396 @@
+/* BSD-2-Clause license
+ *
+ * Copyright (c) 2018-2023 NST <www.newinfosec.ru>, sss <sss at dark-alexandr dot net>.
+ *
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdbool.h>
+
+#include <ev.h>
+#include <wslay/wslay.h>
+
+#include "ws_session.h"
+#include "ws_protocol.h"
+#include "webrdp_module_api.h"
+#include "wrdp_thpool_internals.h"
+#include "globals.h"
+#include "task.h"
+
+#include "thread_impl.h"
+
+#include "utilities.h"
+#include "log.h"
+
+void
+send_text_msg(const char *msg, void *_task_info)
+{
+ ws_send_text((uint8_t *)msg, strlen(msg), _task_info);
+}
+
+static void
+send_typed_text_msg(const char *type, const char *msg, void *_task_info)
+{
+ size_t len = strlen(msg) + strlen(type);
+ uint8_t *buf = malloc(len);
+#ifdef DEBUG
+ log_msg((const uint8_t *)msg, strlen(msg), wrdp_log_level_trace, 0);
+#endif
+ if (!buf)
+ {
+ perror("malloc");
+ return;
+ }
+ memset(buf, 0, len);
+ memcpy(buf, type, strlen(type));
+ memcpy(buf + strlen(type), msg, len - strlen(type));
+ ws_send_text(buf, len, _task_info);
+ free(buf);
+}
+
+void
+send_text_info_msg(const char *msg, void *task_info)
+{
+ send_typed_text_msg("I:", msg, task_info);
+}
+
+void
+send_text_warning_msg(const char *msg, void *task_info)
+{
+ send_typed_text_msg("W:", msg, task_info);
+}
+
+void
+send_text_debug_msg(const char *msg, void *task_info)
+{
+ send_typed_text_msg("D:", msg, task_info);
+}
+
+void
+send_error_msg(const char *msg, void *task_info)
+{
+ send_typed_text_msg("E:", msg, task_info);
+}
+
+void
+send_ctl_msg(const char *msg, void *task_info)
+{
+ send_typed_text_msg("0:", msg, task_info);
+}
+
+static void
+send_termination_msg(void *task_info)
+{
+ ws_send_text((uint8_t *)"T:", 2, task_info);
+}
+
+static void
+send_typed_proto_msg(
+ uint8_t *buf, size_t size, ws_output_codes type, void *task_info)
+{
+ uint8_t *msg = ws_pack_msg(buf, size, type);
+ ws_send_binary(msg, size + 4, task_info);
+ free(msg);
+}
+
+static void
+send_begin_paint(void *task_info)
+{
+ send_typed_proto_msg(0, 0, ws_out_beginpaint, task_info);
+}
+
+static void
+send_end_paint(void *task_info)
+{
+ send_typed_proto_msg(0, 0, ws_out_endpaint, task_info);
+}
+
+static void
+send_bitmap(
+ const wrdp_core_display_bmp *bmp, uint8_t *bmp_data, void *task_info)
+{
+ size_t buf_size = sizeof(wrdp_core_display_bmp) + bmp->size;
+ uint8_t *buf = malloc(buf_size);
+ if (!buf)
+ {
+ perror("malloc");
+ return;
+ }
+ memcpy(buf, bmp, sizeof(wrdp_core_display_bmp));
+ memcpy(buf + sizeof(wrdp_core_display_bmp), bmp_data, bmp->size);
+ send_typed_proto_msg(buf, buf_size, ws_out_bitmap, task_info);
+ free(buf);
+}
+
+static void
+send_opaque_rect_order(
+ const wrdp_core_display_opaque_rect_order *oro, void *task_info)
+{
+ send_typed_proto_msg((uint8_t *)oro,
+ sizeof(wrdp_core_display_opaque_rect_order), ws_out_opaquerect,
+ task_info);
+}
+
+static void
+send_set_bounds(const wrdp_core_display_bounds *bounds, void *task_info)
+{
+ send_typed_proto_msg((uint8_t *)bounds,
+ sizeof(wrdp_core_display_bounds), ws_out_setbounds, task_info);
+}
+
+static void
+send_pat_blt(const wrdp_core_display_patblt_order *patblt, void *task_info)
+{
+ send_typed_proto_msg((uint8_t *)patblt,
+ sizeof(wrdp_core_display_patblt_order), ws_out_patblt, task_info);
+}
+
+static void
+send_multi_opaque_rect(
+ const wrdp_core_display_m_opaque_rect *mrect, void *task_info)
+{
+ size_t buf_size
+ = (sizeof(uint32_t) * 2)
+ + (sizeof(wrdp_core_display_delta_rect) * mrect->num_rect);
+ uint8_t *buf = malloc(buf_size);
+ if (!buf)
+ {
+ perror("malloc");
+ return;
+ }
+ memcpy(buf, (uint8_t *)&(mrect->color), 4);
+ memcpy(buf + 4, (uint8_t *)&(mrect->num_rect), 4);
+ memcpy(buf + 4 + 4, (uint8_t *)mrect->rects,
+ mrect->num_rect * sizeof(wrdp_core_display_delta_rect));
+
+ send_typed_proto_msg(buf, buf_size, ws_out_multi_opaquerect, task_info);
+ free(buf);
+}
+
+static void
+send_scr_blt(const wrdp_core_display_scr_blt *scr_blt, void *task_info)
+{
+ send_typed_proto_msg((uint8_t *)&scr_blt,
+ sizeof(wrdp_core_display_scr_blt), ws_out_scr_btl, task_info);
+}
+
+static void
+send_ptr_new(const wrdp_core_display_cursor_info *ptr, void *task_info)
+{
+ size_t buf_size = sizeof(wrdp_core_display_cursor) - sizeof(uint8_t *)
+ + sizeof(wrdp_core_display_cursor_info)
+ - sizeof(uint32_t)
+ - sizeof(wrdp_core_display_cursor *) + ptr->data_size;
+ uint8_t *buf = malloc(buf_size);
+ if (!buf)
+ {
+ perror("malloc");
+ return;
+ }
+ memcpy(buf, ptr,
+ sizeof(wrdp_core_display_cursor_info) - sizeof(uint32_t)
+ - sizeof(wrdp_core_display_cursor *));
+ memcpy(buf + sizeof(wrdp_core_display_cursor_info) - sizeof(uint32_t)
+ - sizeof(wrdp_core_display_cursor *),
+ ptr->cur, sizeof(wrdp_core_display_cursor) - sizeof(uint8_t *));
+ memcpy(buf + sizeof(wrdp_core_display_cursor_info) - sizeof(uint32_t)
+ - sizeof(wrdp_core_display_cursor *)
+ + sizeof(wrdp_core_display_cursor) - sizeof(uint8_t *),
+ ptr->cur->data, ptr->data_size);
+ send_typed_proto_msg(buf, buf_size, ws_out_ptr_new, task_info);
+ free(buf);
+}
+
+static void
+send_ptr_free(uint32_t ptr_id, void *task_info)
+{
+ send_typed_proto_msg(
+ (uint8_t *)&ptr_id, sizeof(uint32_t), ws_out_ptr_free, task_info);
+}
+
+static void
+send_ptr_set(uint32_t ptr_id, void *task_info)
+{
+ send_typed_proto_msg(
+ (uint8_t *)&ptr_id, sizeof(uint32_t), ws_out_ptr_set, task_info);
+}
+
+static void
+send_ptr_set_null(void *task_info)
+{
+ send_typed_proto_msg(0, 0, ws_out_ptr_set_null, task_info);
+}
+
+static void
+send_ptr_set_default(void *task_info)
+{
+ send_typed_proto_msg(0, 0, ws_out_ptr_set_default, task_info);
+}
+
+static void
+clipboard_changed(uint8_t *fmts, size_t fmts_count, void *task_info)
+{
+ send_typed_proto_msg(
+ fmts, fmts_count, ws_out_clpbrd_changed, task_info);
+}
+
+static void
+clipboard_send_data(uint8_t *buf, size_t buf_size, void *task_info)
+{
+ send_typed_proto_msg(buf, buf_size, ws_out_clpbrd_data, task_info);
+}
+
+static void
+clipboard_request_data(uint8_t data_fmt, void *task_info)
+{
+ send_typed_proto_msg(
+ &data_fmt, 1, ws_out_clpbrd_request_data, task_info);
+}
+
+static void
+ft_request(const wrdp_backend_ft_file_request *req, void *task_info)
+{
+ send_typed_proto_msg((uint8_t *)req,
+ sizeof(wrdp_backend_ft_file_request), ws_out_ft_request, task_info);
+}
+
+static void
+ft_send_chunk(
+ const wrdp_backend_ft_chunk *chunk, uint8_t *data, void *task_info)
+{
+ size_t buf_size = sizeof(wrdp_backend_ft_chunk) + chunk->size;
+ uint8_t *buf = malloc(buf_size);
+ if (!buf)
+ {
+ perror("malloc");
+ return;
+ }
+ memcpy(buf, chunk, sizeof(wrdp_backend_ft_chunk));
+ memcpy(buf + sizeof(wrdp_backend_ft_chunk), data, chunk->size);
+ send_typed_proto_msg(buf, buf_size, ws_out_ft_chunk, task_info);
+ free(buf);
+}
+
+static void
+ft_finish(const wrdp_backend_ft_status *status, void *task_info)
+{
+ send_typed_proto_msg((uint8_t *)status, sizeof(wrdp_backend_ft_status),
+ ws_out_ft_finish, task_info);
+}
+
+static void *
+get_libev_loop(void *_task_info)
+{
+ task_info *t = _task_info;
+ wrdp_thpool_task *pt = t->wrdp_thpool_task;
+ return pt->thread->ev_th_loop;
+}
+
+static void
+task_finished(bool success, void *_task_info)
+{
+ /* TODO: handle task failure */
+ destroy_task(_task_info);
+}
+
+static void
+reset_idle(void *_task_info)
+{
+ task_info *t = _task_info;
+ t->idle_time = 0;
+}
+
+bool
+init_exports()
+{
+ g_globals.exports = calloc(1, sizeof(wrdp_core_exports));
+ if (!g_globals.exports)
+ {
+ perror("calloc");
+ exit(EXIT_FAILURE);
+ }
+ g_globals.exports->api_core = calloc(1, sizeof(wrdp_core_cb_core));
+ if (!g_globals.exports->api_core)
+ {
+ perror("calloc");
+ exit(EXIT_FAILURE);
+ }
+ g_globals.exports->api_msgs = calloc(1, sizeof(wrdp_core_cb_msgs));
+ if (!g_globals.exports->api_msgs)
+ {
+ perror("calloc");
+ exit(EXIT_FAILURE);
+ }
+ g_globals.exports->api_paint = calloc(1, sizeof(wrdp_core_cb_paint));
+ if (!g_globals.exports->api_paint)
+ {
+ perror("calloc");
+ exit(EXIT_FAILURE);
+ }
+ g_globals.exports->api_clipboard
+ = calloc(1, sizeof(wrdp_core_cb_clipboard));
+ if (!g_globals.exports->api_clipboard)
+ {
+ perror("calloc");
+ exit(EXIT_FAILURE);
+ }
+ g_globals.exports->api_filetransfers
+ = calloc(1, sizeof(wrdp_core_cb_filetransfer));
+ if (!g_globals.exports->api_filetransfers)
+ {
+ perror("calloc");
+ exit(EXIT_FAILURE);
+ }
+ g_globals.exports->api_utils = calloc(1, sizeof(wrdp_core_cb_utils));
+ if (!g_globals.exports->api_utils)
+ {
+ perror("calloc");
+ exit(EXIT_FAILURE);
+ }
+
+ g_globals.exports->api_paint->send_begin_paint = send_begin_paint;
+ g_globals.exports->api_paint->send_bitmap = send_bitmap;
+ g_globals.exports->api_paint->send_end_paint = send_end_paint;
+ g_globals.exports->api_paint->send_multi_opaque_rect
+ = send_multi_opaque_rect;
+ g_globals.exports->api_paint->send_opaque_rect_order
+ = send_opaque_rect_order;
+ g_globals.exports->api_paint->send_pat_blt = send_pat_blt;
+ g_globals.exports->api_paint->send_ptr_free = send_ptr_free;
+ g_globals.exports->api_paint->send_ptr_new = send_ptr_new;
+ g_globals.exports->api_paint->send_ptr_set = send_ptr_set;
+ g_globals.exports->api_paint->send_ptr_set_default
+ = send_ptr_set_default;
+ g_globals.exports->api_paint->send_ptr_set_null = send_ptr_set_null;
+ g_globals.exports->api_paint->send_scr_blt = send_scr_blt;
+ g_globals.exports->api_paint->send_set_bounds = send_set_bounds;
+
+ g_globals.exports->api_msgs->send_text_msg = send_text_msg;
+ g_globals.exports->api_msgs->send_text_info_msg = send_text_info_msg;
+ g_globals.exports->api_msgs->send_text_warning_msg
+ = send_text_warning_msg;
+ g_globals.exports->api_msgs->send_text_debug_msg = send_text_debug_msg;
+ g_globals.exports->api_msgs->send_ctl_msg = send_ctl_msg;
+ g_globals.exports->api_msgs->send_error_msg = send_error_msg;
+ g_globals.exports->api_msgs->send_termination_msg
+ = send_termination_msg;
+ g_globals.exports->api_core->get_libev_loop = get_libev_loop;
+ g_globals.exports->api_core->task_finished = task_finished;
+ g_globals.exports->api_core->reset_idle = reset_idle;
+
+ g_globals.exports->api_clipboard->send_data = clipboard_send_data;
+ g_globals.exports->api_clipboard->clipboard_changed = clipboard_changed;
+ g_globals.exports->api_clipboard->request_data = clipboard_request_data;
+
+ g_globals.exports->api_filetransfers->ft_finish = ft_finish;
+ g_globals.exports->api_filetransfers->ft_request = ft_request;
+ g_globals.exports->api_filetransfers->ft_send_chunk = ft_send_chunk;
+
+ g_globals.exports->api_utils->hex_print = hex_print;
+ g_globals.exports->api_utils->log_msg = log_msg;
+ g_globals.exports->api_utils->log_msg_ex = log_msg_ex;
+ return true;
+}