diff options
Diffstat (limited to 'src/core/exports.c')
-rw-r--r-- | src/core/exports.c | 396 |
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; +} |