From d015535065c76f1604bb8e875c971e5b56cc2a25 Mon Sep 17 00:00:00 2001 From: matt335672 <30179339+matt335672@users.noreply.github.com> Date: Tue, 8 Jul 2025 12:32:34 +0100 Subject: [PATCH] Add CCP support to xrdp This allows sesexec to send a reason for a connection close request to xrdp. xrdp is also updated to support server initiated disconnection sequences from [MS-RDPBCGR] 1.3.1.4, along with reporting a reason to the client for the disconnection. --- common/ms-rdpbcgr.h | 4 ++ libipm/ccp_application_types.c | 2 + libipm/ccp_application_types.h | 3 +- libxrdp/libxrdp.c | 41 +++++++++++- libxrdp/libxrdp.h | 12 ++++ libxrdp/libxrdpinc.h | 12 +++- libxrdp/xrdp_rdp.c | 9 +-- tests/xrdp/Makefile.am | 1 + xrdp/Makefile.am | 1 + xrdp/xrdp.h | 32 ++++++++++ xrdp/xrdp_login_wnd.c | 2 + xrdp/xrdp_mm.c | 113 ++++++++++++++++++++++----------- xrdp/xrdp_mm_ccp.c | 107 +++++++++++++++++++++++++++++++ xrdp/xrdp_process.c | 4 +- xrdp/xrdp_types.h | 3 + 15 files changed, 296 insertions(+), 50 deletions(-) create mode 100644 xrdp/xrdp_mm_ccp.c diff --git a/common/ms-rdpbcgr.h b/common/ms-rdpbcgr.h index 53f59065..52d32f64 100644 --- a/common/ms-rdpbcgr.h +++ b/common/ms-rdpbcgr.h @@ -82,6 +82,7 @@ #define RNS_UD_32BPP_SUPPORT 0x0008 /* Client Core Data: earlyCapabilityFlags (2.2.1.3.2) */ +#define RNS_UD_CS_SUPPORT_ERRINFO_PDU 0x0001 #define RNS_UD_CS_WANT_32BPP_SESSION 0x0002 #define RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU 0x0040 #define RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL 0x0100 @@ -280,7 +281,10 @@ #define ERRINFO_DISCONNECTED_BY_OTHERCONNECTION 0x0005 #define ERRINFO_OUT_OF_MEMORY 0x0006 #define ERRINFO_SERVER_DENIED_CONNECTION 0x0007 +#define ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES 0x0009 #define ERRINFO_LOGOFF_BY_USER 0x000c +#define ERRINFO_SERVER_DWM_CRASH 0x0010 +#define ERRINFO_SERVER_CSRSS_CRASH 0x0018 /* Virtual channel PDU (2.2.6.1) */ #define CHANNEL_CHUNK_LENGTH 1600 diff --git a/libipm/ccp_application_types.c b/libipm/ccp_application_types.c index b2518e44..b14f0977 100644 --- a/libipm/ccp_application_types.c +++ b/libipm/ccp_application_types.c @@ -43,6 +43,8 @@ ccp_close_reason_to_str(enum ccp_close_reason_type n, ? "Another connection was made to the session" : (n == CCP_CLOSE_LOGOFF_BY_USER) ? "The user logged out of the session" : + (n == CCP_CLOSE_SOFTWARE_FAILURE) + ? "A software failure has occurred" : /* Default */ NULL; if (str == NULL) diff --git a/libipm/ccp_application_types.h b/libipm/ccp_application_types.h index 55fe6c78..8e700d1f 100644 --- a/libipm/ccp_application_types.h +++ b/libipm/ccp_application_types.h @@ -35,7 +35,8 @@ enum ccp_close_reason_type { CCP_CLOSE_RPC_INITIATED_DISCONNECT = 1, CCP_CLOSE_DISCONNECTED_BY_OTHERCONNECTION, - CCP_CLOSE_LOGOFF_BY_USER + CCP_CLOSE_LOGOFF_BY_USER, + CCP_CLOSE_SOFTWARE_FAILURE }; /** diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c index 64ce2c12..fda20fca 100644 --- a/libxrdp/libxrdp.c +++ b/libxrdp/libxrdp.c @@ -73,9 +73,46 @@ libxrdp_exit(struct xrdp_session *session) /******************************************************************************/ int EXPORT_CC -libxrdp_disconnect(struct xrdp_session *session) +libxrdp_disconnect(struct xrdp_session *session, int errinfo) { - return xrdp_rdp_disconnect((struct xrdp_rdp *)session->rdp); + int rv = 0; + struct trans *trans = NULL; + struct xrdp_rdp *rdp = NULL; + int early_capability_flags = 0; + + if (session != NULL) + { + trans = session->trans; + rdp = (struct xrdp_rdp *)session->rdp; + if (session->client_info != NULL) + { + early_capability_flags = + session->client_info->mcs_early_capability_flags; + } + } + + if (trans != NULL && trans->status == TRANS_STATUS_UP && + trans->sck >= 0 && rdp != NULL) + { + /* Only send the error info PDU if the client has + * indicated it can receive it */ + if ((early_capability_flags & RNS_UD_CS_SUPPORT_ERRINFO_PDU) != 0) + { + rv = xrdp_rdp_send_set_error(rdp, errinfo); + } + + if (rv == 0) + { + rv = xrdp_rdp_send_deactivate(rdp); + } + + if (rv == 0) + { + rv = xrdp_rdp_disconnect(rdp); + } + } + + return rv; } /******************************************************************************/ diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h index b8b60136..1bac72ef 100644 --- a/libxrdp/libxrdp.h +++ b/libxrdp/libxrdp.h @@ -456,6 +456,18 @@ xrdp_rdp_send_deactivate(struct xrdp_rdp *self); int xrdp_rdp_send_session_info(struct xrdp_rdp *self, const char *data, int data_bytes); +/** + * Send a [MS-RDPBCGR] TS_SET_ERROR_INFO_PDU message + * @param self xrdp_rdp struct + * @param reason errinfo code ([MS-RDPBCGR] 2.2.5.1.1) + * @return != 0 for error + + * The caller is responsible for checking the client supports + * reception of this message (see 2.2.5.1) + */ +int +xrdp_rdp_send_set_error(struct xrdp_rdp *self, int reason); + /** * Request output suppress or resume * diff --git a/libxrdp/libxrdpinc.h b/libxrdp/libxrdpinc.h index b2d86adb..d5ca24eb 100644 --- a/libxrdp/libxrdpinc.h +++ b/libxrdp/libxrdpinc.h @@ -104,8 +104,18 @@ struct xrdp_session * libxrdp_init(tbus id, struct trans *trans, const char *xrdp_ini); int libxrdp_exit(struct xrdp_session *session); +/** + * Sends a disconnect sequence from the server ([MS-RDPBCGR] 1.3.1.4.x) + * @param session xrdp session + * @param errinfo Reason ([MS-RDPBCGR] 2.2.5.1.1) + * @return != 0 for an error + * + * After this call, the rdp channel is closed and cannot be re-used. This + * routine can be called more than once, but only the first call is + * effective. + */ int -libxrdp_disconnect(struct xrdp_session *session); +libxrdp_disconnect(struct xrdp_session *session, int errinfo); int libxrdp_process_incoming(struct xrdp_session *session); int EXPORT_CC diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index 97fe7ffd..f2397cf7 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -1364,11 +1364,9 @@ xrdp_rdp_send_disconnect_query_response(struct xrdp_rdp *self) return 0; } -#if 0 /* not used */ /*****************************************************************************/ -/* Send a [MS-RDPBCGR] TS_SET_ERROR_INFO_PDU message */ -static int -xrdp_rdp_send_disconnect_reason(struct xrdp_rdp *self, int reason) +int +xrdp_rdp_send_set_error(struct xrdp_rdp *self, int reason) { struct stream *s; @@ -1378,7 +1376,7 @@ xrdp_rdp_send_disconnect_reason(struct xrdp_rdp *self, int reason) if (xrdp_rdp_init_data(self, s) != 0) { LOG(LOG_LEVEL_ERROR, - "xrdp_rdp_send_disconnect_reason: xrdp_rdp_init_data failed"); + "xrdp_rdp_send_set_error_pdu: xrdp_rdp_init_data failed"); free_stream(s); return 1; } @@ -1399,7 +1397,6 @@ xrdp_rdp_send_disconnect_reason(struct xrdp_rdp *self, int reason) free_stream(s); return 0; } -#endif /*****************************************************************************/ /* Process a [MS-RDPRFX] TS_FRAME_ACKNOWLEDGE_PDU message */ diff --git a/tests/xrdp/Makefile.am b/tests/xrdp/Makefile.am index 505e4887..79e4d3bb 100644 --- a/tests/xrdp/Makefile.am +++ b/tests/xrdp/Makefile.am @@ -61,6 +61,7 @@ test_xrdp_LDADD = \ $(top_builddir)/libxrdp/libxrdp.la \ $(top_builddir)/xrdp/lang.o \ $(top_builddir)/xrdp/xrdp_mm.o \ + $(top_builddir)/xrdp/xrdp_mm_ccp.o \ $(top_builddir)/xrdp/xrdp_wm.o \ $(top_builddir)/xrdp/xrdp_font.o \ $(top_builddir)/xrdp/xrdp_egfx.o \ diff --git a/xrdp/Makefile.am b/xrdp/Makefile.am index 996eae92..685635dc 100644 --- a/xrdp/Makefile.am +++ b/xrdp/Makefile.am @@ -71,6 +71,7 @@ xrdp_SOURCES = \ xrdp_listen.c \ xrdp_login_wnd.c \ xrdp_mm.c \ + xrdp_mm_ccp.c \ xrdp_mm.h \ xrdp_painter.c \ xrdp_process.c \ diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h index 15f9770e..e4d4e88d 100644 --- a/xrdp/xrdp.h +++ b/xrdp/xrdp.h @@ -503,6 +503,31 @@ xrdp_mm_suppress_output(struct xrdp_mm *self, int suppress, int left, int top, int right, int bottom); int xrdp_mm_up_and_running(struct xrdp_mm *self); + +/** + * Ask the xrdp process (or thread) to terminate + * @param self xrdp_mm struct + * @param errinfo Error code to return to the client + * + * Execution continues after this call until the main process loop + * is reached. This routine could be called multiple times. In this + * instance the first code set is passed back to the client. + */ +void +xrdp_mm_set_fatal(struct xrdp_mm *self, int errinfo); + +/** + * Tell the user via the log window a fatal error has occurred + * @param self xrdp_mm struct + * @param errinfo Error code to return to the client + * + * The log window must already contain the fatal error. + * When the user presses OK in the log window, the xrdp process + * (or thread) is terminated. + */ +void +xrdp_mm_logwnd_fatal(struct xrdp_mm *self, int errinfo); + int xrdp_mm_send_unicode_to_chansrv(struct xrdp_mm *self, int key_down, @@ -535,4 +560,11 @@ xrdp_mm_egfx_send_planar_bitmap(struct xrdp_mm *self, struct xrdp_bitmap *bitmap, struct xrdp_rect *rect, int surface_id, int x, int y); + +/* xrdp_mm_cpp.c */ + +/* Callback registered for sesman communication replies over CCP */ +int +xrdp_mm_ccp_data_in(struct trans *trans); + #endif diff --git a/xrdp/xrdp_login_wnd.c b/xrdp/xrdp_login_wnd.c index 80d0a737..da1535e7 100644 --- a/xrdp/xrdp_login_wnd.c +++ b/xrdp/xrdp_login_wnd.c @@ -216,6 +216,8 @@ xrdp_wm_cancel_clicked(struct xrdp_bitmap *wnd) { if (wnd->wm->pro_layer != 0) { + wnd->wm->pro_layer->errinfo = + ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES; g_set_wait_obj(wnd->wm->pro_layer->self_term_event); } } diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index 2feb6060..536682d3 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -28,6 +28,7 @@ #include "guid.h" #include "ms-rdpedisp.h" #include "ms-rdpbcgr.h" +#include "ccp.h" #include "scp.h" #include #include "xrdp_encoder.h" @@ -1991,6 +1992,26 @@ xrdp_mm_up_and_running(struct xrdp_mm *self) return 0; } +/******************************************************************************/ +void +xrdp_mm_set_fatal(struct xrdp_mm *self, int errinfo) +{ + if (self->wm->pro_layer->errinfo == ERRINFO_NONE) + { + self->wm->pro_layer->errinfo = errinfo; + } + g_set_wait_obj(self->wm->pro_layer->self_term_event); +} + +/******************************************************************************/ +void +xrdp_mm_logwnd_fatal(struct xrdp_mm *self, int errinfo) +{ + xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, "Close the log window to exit."); + self->wm->pro_layer->errinfo = errinfo; + self->wm->fatal_error_in_log_window = 1; +} + /*****************************************************************************/ /* open response from client going to channel server */ static int @@ -2621,9 +2642,9 @@ xrdp_mm_process_login_response(struct xrdp_mm *self) if (self->wm->client_info->require_credentials) { /* Credentials had to be specified, but were invalid */ - g_set_wait_obj(self->wm->pro_layer->self_term_event); LOG(LOG_LEVEL_ERROR, "require_credentials is set, " "but the user could not be logged in"); + xrdp_mm_set_fatal(self, ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES); } if (server_closed) @@ -2633,9 +2654,8 @@ xrdp_mm_process_login_response(struct xrdp_mm *self) xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, "%s", "Login retry limit reached"); } - xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, "%s", - "Close the log window to exit."); - self->wm->fatal_error_in_log_window = 1; + xrdp_mm_logwnd_fatal(self, + ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES); /* Transport can be deleted now */ self->delete_sesman_trans = 1; } @@ -2717,16 +2737,24 @@ xrdp_mm_process_connect_session_response(struct xrdp_mm *self) rv = scp_get_connect_session_response(self->sesman_trans, &status, &self->sesman_display_fd, &self->sesman_chansrv_fd); - /* Following this response, the sesman trans is closed */ - self->delete_sesman_trans = 1; - - if (rv == 0) + if (rv != 0) + { + self->delete_sesman_trans = 1; + } + else { if (status == E_SCP_SCONNECT_OK) { xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, "Got connection details for session"); + /* Convert the sesman transport fron an SCP transport + * to a CCP transport */ + ccp_trans_from_scp_trans(self->sesman_trans, + xrdp_mm_ccp_data_in, + self); + self->sesman_trans_is_ccp = 1; + /* Carry on with the connect state machine */ xrdp_mm_connect_sm(self); } @@ -2745,10 +2773,11 @@ xrdp_mm_process_connect_session_response(struct xrdp_mm *self) xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, "Can't create session for user %s - %s", username, buff); - xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, "%s", - "Close the log window to exit."); - self->wm->fatal_error_in_log_window = 1; + xrdp_mm_logwnd_fatal(self, + ERRINFO_SERVER_DWM_CRASH); xrdp_wm_mod_connect_done(self->wm, 1); + // The sesman tranport is now useless to us. + self->delete_sesman_trans = 1; } } @@ -2756,7 +2785,7 @@ xrdp_mm_process_connect_session_response(struct xrdp_mm *self) } /*****************************************************************************/ -/* This is the callback registered for sesman communication replies. */ +/* This is the callback registered for sesman communication replies over SCP */ static int xrdp_mm_scp_data_in(struct trans *trans) { @@ -3389,19 +3418,15 @@ xrdp_mm_connect_sm(struct xrdp_mm *self) if (!self->mmcs_expecting_msg) { - /* We don't need the sesman transport anymore */ - if (self->sesman_trans != NULL) - { - self->delete_sesman_trans = 1; - } - /* Close any uncomsumed file descriptors from sesman */ close_sesman_file_descriptors(self); xrdp_wm_mod_connect_done(self->wm, status); + /* Make sure the module is cleaned up if we weren't successful */ if (status != 0) { + self->delete_sesman_trans = 1; xrdp_mm_module_cleanup(self); } } @@ -3776,35 +3801,44 @@ xrdp_mm_draw_dirty(struct xrdp_mm *self) int xrdp_mm_check_wait_objs(struct xrdp_mm *self) { - int rv; + int rv = 0; if (self == 0) { return 0; } - rv = 0; - if (self->sesman_trans != NULL && !self->delete_sesman_trans && self->sesman_trans->status == TRANS_STATUS_UP) { if (trans_check_wait_objs(self->sesman_trans) != 0) { - if (self->mmcs_expecting_msg) + if (self->sesman_trans_is_ccp) { - /* The sesman transport has failed with an - * outstanding message */ - xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR, - "Unexpected sesman failure - check sesman log"); - xrdp_wm_mod_connect_done(self->wm, 1); + /* Comms with the sesexec has failed - we have to assume + * the session has failed */ + xrdp_mm_set_fatal(self, ERRINFO_LOGOFF_BY_USER); + } + else + { + /* We're still using the SCP transport for + * pre-connection activities */ + if (self->mmcs_expecting_msg) + { + /* The sesman transport has failed with an + * outstanding message while connecting */ + xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR, "Unexpected" + " sesman failure - check sesman log"); + xrdp_wm_mod_connect_done(self->wm, 1); + } + if (self->wm->hide_log_window) + { + /* if hide_log_window, this is fatal */ + rv = 1; + } } self->delete_sesman_trans = 1; - if (self->wm->hide_log_window) - { - /* if hide_log_window, this is fatal */ - rv = 1; - } } } if (self->delete_sesman_trans) @@ -3827,9 +3861,12 @@ xrdp_mm_check_wait_objs(struct xrdp_mm *self) if (self->mod != NULL) { - if (self->mod->mod_check_wait_objs != NULL) + if (self->mod->mod_check_wait_objs != NULL && + self->mod->mod_check_wait_objs(self->mod) != 0) { - rv = self->mod->mod_check_wait_objs(self->mod); + /* Comms with the module has failed - we have to assume + * the display server, and hence the session has failed */ + xrdp_mm_set_fatal(self, ERRINFO_LOGOFF_BY_USER); } } @@ -3859,7 +3896,7 @@ xrdp_mm_check_wait_objs(struct xrdp_mm *self) { if (self->egfx_up) { - rv = xrdp_mm_draw_dirty(self); + rv |= xrdp_mm_draw_dirty(self); xrdp_region_delete(self->wm->screen_dirty_region); self->wm->screen_dirty_region = NULL; self->wm->last_screen_draw_time = now; @@ -5259,7 +5296,7 @@ xrdp_mm_setup_mod2(struct xrdp_mm *self) self->wm->screen->height, self->wm->screen->bpp) != 0) { - g_set_wait_obj(self->wm->pro_layer->self_term_event); /* kill session */ + xrdp_mm_set_fatal(self, ERRINFO_SERVER_DWM_CRASH); } } @@ -5269,7 +5306,7 @@ xrdp_mm_setup_mod2(struct xrdp_mm *self) { LOG(LOG_LEVEL_ERROR, "Unexpected display value %d setting up module", self->display); - g_set_wait_obj(self->wm->pro_layer->self_term_event); /* kill session */ + xrdp_mm_set_fatal(self, ERRINFO_SERVER_DWM_CRASH); } else if (self->code == XVNC_SESSION_CODE) { @@ -5285,7 +5322,7 @@ xrdp_mm_setup_mod2(struct xrdp_mm *self) { LOG(LOG_LEVEL_ERROR, "Unexpected session code %d setting up module", self->code); - g_set_wait_obj(self->wm->pro_layer->self_term_event); /* kill session */ + xrdp_mm_set_fatal(self, ERRINFO_SERVER_DWM_CRASH); } } diff --git a/xrdp/xrdp_mm_ccp.c b/xrdp/xrdp_mm_ccp.c new file mode 100644 index 00000000..8efa630c --- /dev/null +++ b/xrdp/xrdp_mm_ccp.c @@ -0,0 +1,107 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2014 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * module manager + */ + +#if defined(HAVE_CONFIG_H) +#include +#endif +#include "ccp.h" +#include "xrdp.h" +#include "log.h" + +/*****************************************************************************/ +/** + * We've been asked by sesman/sesexec to close the connection + */ +static int +xrdp_mm_process_close_ccp_connection_request(struct xrdp_mm *self) +{ + enum ccp_close_reason_type reason; + + int rv = ccp_get_close_connection_request(self->sesman_trans, &reason); + if (rv == 0) + { + int errinfo; + char buff[64]; + + switch (reason) + { + case CCP_CLOSE_RPC_INITIATED_DISCONNECT: + errinfo = ERRINFO_RPC_INITIATED_DISCONNECT; + break; + + case CCP_CLOSE_DISCONNECTED_BY_OTHERCONNECTION: + errinfo = ERRINFO_DISCONNECTED_BY_OTHERCONNECTION; + break; + + case CCP_CLOSE_LOGOFF_BY_USER: + errinfo = ERRINFO_LOGOFF_BY_USER; + break; + + case CCP_CLOSE_SOFTWARE_FAILURE: + errinfo = ERRINFO_SERVER_CSRSS_CRASH; + break; + + default: + LOG(LOG_LEVEL_WARNING, "Unexpected close connection reason %d", + (int)reason); + errinfo = ERRINFO_LOGOFF_BY_USER; + } + + LOG(LOG_LEVEL_INFO, "Request to close connection : '%s'", + ccp_close_reason_to_str(reason, buff, sizeof(buff))); + xrdp_mm_set_fatal(self, errinfo); + } + + return rv; +} + +/*****************************************************************************/ +int +xrdp_mm_ccp_data_in(struct trans *trans) +{ + int rv = 0; + int available; + + rv = ccp_msg_in_check_available(trans, &available); + if (rv == 0 && available) + { + struct xrdp_mm *self = (struct xrdp_mm *)(trans->callback_data); + enum ccp_msg_code msgno; + + switch ((msgno = ccp_msg_in_get_msgno(trans))) + { + case E_CCP_CLOSE_CONNECTION_REQUEST: + rv = xrdp_mm_process_close_ccp_connection_request(self); + break; + + default: + { + char buff[64]; + ccp_msgno_to_str(msgno, buff, sizeof(buff)); + LOG(LOG_LEVEL_ERROR, "Ignored CCP message %s from sesman", + buff); + } + } + + ccp_msg_in_reset(trans); + } + + return rv; +} diff --git a/xrdp/xrdp_process.c b/xrdp/xrdp_process.c index c40613dc..854f0427 100644 --- a/xrdp/xrdp_process.c +++ b/xrdp/xrdp_process.c @@ -295,14 +295,14 @@ xrdp_process_main_loop(struct xrdp_process *self) } } /* send disconnect message if possible */ - libxrdp_disconnect(self->session); + libxrdp_disconnect(self->session, self->errinfo); } else { LOG(LOG_LEVEL_ERROR, "xrdp_process_main_loop: libxrdp_process_incoming failed"); /* this will try to send a disconnect, maybe should check that connection got far enough */ - libxrdp_disconnect(self->session); + libxrdp_disconnect(self->session, self->errinfo); } /* Run end in module */ xrdp_process_mod_end(self); diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h index 271e9077..231db9fa 100644 --- a/xrdp/xrdp_types.h +++ b/xrdp/xrdp_types.h @@ -464,6 +464,8 @@ struct xrdp_mm int last_sync_saved; int last_sync_key_flags; int last_sync_device_flags; + /* Whether the sesman_trans is a CCP trans or not */ + int sesman_trans_is_ccp; }; struct xrdp_key_info @@ -610,6 +612,7 @@ struct xrdp_process int status; struct trans *server_trans; /* in tcp server mode */ tbus self_term_event; + int errinfo; /* Reason for self_term_event being set */ struct xrdp_listen *lis_layer; /* owner */ struct xrdp_session *session; /* create these when up and running */