summaryrefslogtreecommitdiff
path: root/src/rdp/rdp_module.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/rdp/rdp_module.c')
-rw-r--r--src/rdp/rdp_module.c168
1 files changed, 168 insertions, 0 deletions
diff --git a/src/rdp/rdp_module.c b/src/rdp/rdp_module.c
new file mode 100644
index 0000000..a315325
--- /dev/null
+++ b/src/rdp/rdp_module.c
@@ -0,0 +1,168 @@
+/* BSD-2-Clause license
+ *
+ * Copyright (c) 2018-2023 NST <www.newinfosec.ru>, sss <sss at dark-alexandr dot net>.
+ *
+ */
+
+#include <unistd.h>
+
+#include <freerdp/freerdp.h>
+#include <freerdp/gdi/gdi.h>
+
+#include <webrdp_core_api.h>
+#include <webrdp_module_api.h>
+
+#include "rdp_backend_api.h"
+#include "rdp_impl.h"
+#include "rdp_display_output.h"
+#include "rdp_user_input.h"
+#include "rdp_clipboard.h"
+#include "rdp_ft.h"
+#include "rdp_module.h"
+#include "rdp_settings.h"
+
+/* static void
+send_termination_message (rdp_internals* i)
+{
+ i->core->send_termination_msg (i->task_info);
+} */
+
+static bool
+rdp_init(void *internals)
+{
+ bool ret = true;
+ if (!rdp_init_internals(internals))
+ {
+ /* TODO: handle error */
+ return false;
+ }
+ if (!((rdp_internals *)internals)->instance)
+ {
+ /* TODO: handle error */
+ ret = false;
+ }
+ if (!rdp_init_settings(internals))
+ {
+ /* TODO: handle error */
+ ret = false;
+ }
+ if (!rdp_connect(internals))
+ {
+ /* TODO: handle error */
+ ret = false;
+ }
+ if (!ret)
+ {
+ rdp_internals *i = internals;
+ i->core->api_msgs->send_error_msg(
+ "rdp_module_internal_error", i->task_info);
+ /*send_termination_message (i);*/
+ i->core->api_core->task_finished(false, i->task_info);
+ }
+ return ret;
+}
+
+static void
+destroy_rdp(void *internals)
+{
+ rdp_internals *_i = internals;
+ /* stop all rdp fd's watchers */
+ int i;
+ for (i = 0; i < _i->rdp_fd_count; ++i)
+ {
+ if (ev_is_active(&(_i->rdp_fd[i])))
+ {
+ ev_io_stop(
+ _i->core->api_core->get_libev_loop(_i->task_info),
+ &(_i->rdp_fd[i]));
+ }
+ }
+ if (_i->conn_state == rdp_conn_state_connected)
+ {
+ freerdp_disconnect(_i->instance);
+ _i->conn_state = rdp_conn_state_offline;
+ }
+ _i->rdp_fd_count = 0;
+ if (_i->context)
+ {
+ if (_i->context->clipboard && _i->context->clipboard->srv_fmts
+ && _i->context->clipboard->srv_fmts_count)
+ {
+ for (i = 0; i < _i->context->clipboard->srv_fmts_count;
+ ++i)
+ {
+ if (_i->context->clipboard->srv_fmts[i]
+ .rdp_fmt.formatName)
+ {
+ free(_i->context->clipboard->srv_fmts[i]
+ .rdp_fmt.formatName);
+ }
+ }
+ free(_i->context->clipboard->srv_fmts);
+ }
+ if (_i->context->clipboard && _i->context->clipboard->clipboard)
+ {
+ ClipboardDestroy(_i->context->clipboard->clipboard);
+ }
+ if (_i->context->clipboard
+ && _i->context->clipboard->client_filelist_cache)
+ {
+ free(_i->context->clipboard->client_filelist_cache);
+ _i->context->clipboard->client_filelist_cache = 0;
+ }
+ free(_i->context->ft_to_client);
+ free(_i->context->ft_to_server);
+ }
+ if (_i->instance)
+ {
+ freerdp_context_free(_i->instance);
+ freerdp_free(_i->instance);
+ _i->instance = 0;
+ }
+ if (internals)
+ {
+ rdp_settings_free(internals);
+ internals = 0;
+ }
+}
+
+static void
+rdp_set_task_info(void *task_info, void *internals)
+{
+ rdp_internals *i = internals;
+ i->task_info = task_info;
+}
+
+bool
+rdp_create(wrdp_core_exports *core, wrdp_backend_module *module)
+{
+ wrdp_backend_module *backend = module;
+ if (!backend)
+ {
+ return false;
+ }
+ backend->callbacks_module->init = rdp_init;
+ backend->callbacks_module->destroy = destroy_rdp;
+ backend->callbacks_module->set_setting_int = rdp_set_setting_int;
+ backend->callbacks_module->set_setting_str = rdp_set_setting_str;
+ backend->callbacks_module->set_task_info = rdp_set_task_info;
+ register_input(backend);
+ register_clipboard(backend);
+ register_ft(backend);
+ backend->backend_internals = calloc(1, sizeof(rdp_internals));
+ if (!backend->backend_internals)
+ {
+ perror("calloc");
+ return false;
+ }
+ memset(&(((rdp_internals *)backend->backend_internals)->my_settings), 0,
+ sizeof(my_rdp_settings));
+ /* TODO: do we need to zero each option structure in settings ? */
+ {
+ rdp_internals *i = backend->backend_internals;
+ i->core = core;
+ i->backend = backend;
+ }
+
+ return true;
+}