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.
This commit is contained in:
matt335672
2025-07-08 12:32:34 +01:00
parent 7433ded30d
commit d015535065
15 changed files with 296 additions and 50 deletions
+4
View File
@@ -82,6 +82,7 @@
#define RNS_UD_32BPP_SUPPORT 0x0008 #define RNS_UD_32BPP_SUPPORT 0x0008
/* Client Core Data: earlyCapabilityFlags (2.2.1.3.2) */ /* 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_WANT_32BPP_SESSION 0x0002
#define RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU 0x0040 #define RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU 0x0040
#define RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL 0x0100 #define RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL 0x0100
@@ -280,7 +281,10 @@
#define ERRINFO_DISCONNECTED_BY_OTHERCONNECTION 0x0005 #define ERRINFO_DISCONNECTED_BY_OTHERCONNECTION 0x0005
#define ERRINFO_OUT_OF_MEMORY 0x0006 #define ERRINFO_OUT_OF_MEMORY 0x0006
#define ERRINFO_SERVER_DENIED_CONNECTION 0x0007 #define ERRINFO_SERVER_DENIED_CONNECTION 0x0007
#define ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES 0x0009
#define ERRINFO_LOGOFF_BY_USER 0x000c #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) */ /* Virtual channel PDU (2.2.6.1) */
#define CHANNEL_CHUNK_LENGTH 1600 #define CHANNEL_CHUNK_LENGTH 1600
+2
View File
@@ -43,6 +43,8 @@ ccp_close_reason_to_str(enum ccp_close_reason_type n,
? "Another connection was made to the session" : ? "Another connection was made to the session" :
(n == CCP_CLOSE_LOGOFF_BY_USER) (n == CCP_CLOSE_LOGOFF_BY_USER)
? "The user logged out of the session" : ? "The user logged out of the session" :
(n == CCP_CLOSE_SOFTWARE_FAILURE)
? "A software failure has occurred" :
/* Default */ NULL; /* Default */ NULL;
if (str == NULL) if (str == NULL)
+2 -1
View File
@@ -35,7 +35,8 @@ enum ccp_close_reason_type
{ {
CCP_CLOSE_RPC_INITIATED_DISCONNECT = 1, CCP_CLOSE_RPC_INITIATED_DISCONNECT = 1,
CCP_CLOSE_DISCONNECTED_BY_OTHERCONNECTION, CCP_CLOSE_DISCONNECTED_BY_OTHERCONNECTION,
CCP_CLOSE_LOGOFF_BY_USER CCP_CLOSE_LOGOFF_BY_USER,
CCP_CLOSE_SOFTWARE_FAILURE
}; };
/** /**
+39 -2
View File
@@ -73,9 +73,46 @@ libxrdp_exit(struct xrdp_session *session)
/******************************************************************************/ /******************************************************************************/
int EXPORT_CC 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;
} }
/******************************************************************************/ /******************************************************************************/
+12
View File
@@ -456,6 +456,18 @@ xrdp_rdp_send_deactivate(struct xrdp_rdp *self);
int int
xrdp_rdp_send_session_info(struct xrdp_rdp *self, const char *data, xrdp_rdp_send_session_info(struct xrdp_rdp *self, const char *data,
int data_bytes); 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 * Request output suppress or resume
* *
+11 -1
View File
@@ -104,8 +104,18 @@ struct xrdp_session *
libxrdp_init(tbus id, struct trans *trans, const char *xrdp_ini); libxrdp_init(tbus id, struct trans *trans, const char *xrdp_ini);
int int
libxrdp_exit(struct xrdp_session *session); 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 int
libxrdp_disconnect(struct xrdp_session *session); libxrdp_disconnect(struct xrdp_session *session, int errinfo);
int int
libxrdp_process_incoming(struct xrdp_session *session); libxrdp_process_incoming(struct xrdp_session *session);
int EXPORT_CC int EXPORT_CC
+3 -6
View File
@@ -1364,11 +1364,9 @@ xrdp_rdp_send_disconnect_query_response(struct xrdp_rdp *self)
return 0; return 0;
} }
#if 0 /* not used */
/*****************************************************************************/ /*****************************************************************************/
/* Send a [MS-RDPBCGR] TS_SET_ERROR_INFO_PDU message */ int
static int xrdp_rdp_send_set_error(struct xrdp_rdp *self, int reason)
xrdp_rdp_send_disconnect_reason(struct xrdp_rdp *self, int reason)
{ {
struct stream *s; 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) if (xrdp_rdp_init_data(self, s) != 0)
{ {
LOG(LOG_LEVEL_ERROR, 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); free_stream(s);
return 1; return 1;
} }
@@ -1399,7 +1397,6 @@ xrdp_rdp_send_disconnect_reason(struct xrdp_rdp *self, int reason)
free_stream(s); free_stream(s);
return 0; return 0;
} }
#endif
/*****************************************************************************/ /*****************************************************************************/
/* Process a [MS-RDPRFX] TS_FRAME_ACKNOWLEDGE_PDU message */ /* Process a [MS-RDPRFX] TS_FRAME_ACKNOWLEDGE_PDU message */
+1
View File
@@ -61,6 +61,7 @@ test_xrdp_LDADD = \
$(top_builddir)/libxrdp/libxrdp.la \ $(top_builddir)/libxrdp/libxrdp.la \
$(top_builddir)/xrdp/lang.o \ $(top_builddir)/xrdp/lang.o \
$(top_builddir)/xrdp/xrdp_mm.o \ $(top_builddir)/xrdp/xrdp_mm.o \
$(top_builddir)/xrdp/xrdp_mm_ccp.o \
$(top_builddir)/xrdp/xrdp_wm.o \ $(top_builddir)/xrdp/xrdp_wm.o \
$(top_builddir)/xrdp/xrdp_font.o \ $(top_builddir)/xrdp/xrdp_font.o \
$(top_builddir)/xrdp/xrdp_egfx.o \ $(top_builddir)/xrdp/xrdp_egfx.o \
+1
View File
@@ -71,6 +71,7 @@ xrdp_SOURCES = \
xrdp_listen.c \ xrdp_listen.c \
xrdp_login_wnd.c \ xrdp_login_wnd.c \
xrdp_mm.c \ xrdp_mm.c \
xrdp_mm_ccp.c \
xrdp_mm.h \ xrdp_mm.h \
xrdp_painter.c \ xrdp_painter.c \
xrdp_process.c \ xrdp_process.c \
+32
View File
@@ -503,6 +503,31 @@ xrdp_mm_suppress_output(struct xrdp_mm *self, int suppress,
int left, int top, int right, int bottom); int left, int top, int right, int bottom);
int int
xrdp_mm_up_and_running(struct xrdp_mm *self); 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 int
xrdp_mm_send_unicode_to_chansrv(struct xrdp_mm *self, xrdp_mm_send_unicode_to_chansrv(struct xrdp_mm *self,
int key_down, int key_down,
@@ -535,4 +560,11 @@ xrdp_mm_egfx_send_planar_bitmap(struct xrdp_mm *self,
struct xrdp_bitmap *bitmap, struct xrdp_bitmap *bitmap,
struct xrdp_rect *rect, struct xrdp_rect *rect,
int surface_id, int x, int y); 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 #endif
+2
View File
@@ -216,6 +216,8 @@ xrdp_wm_cancel_clicked(struct xrdp_bitmap *wnd)
{ {
if (wnd->wm->pro_layer != 0) 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); g_set_wait_obj(wnd->wm->pro_layer->self_term_event);
} }
} }
+75 -38
View File
@@ -28,6 +28,7 @@
#include "guid.h" #include "guid.h"
#include "ms-rdpedisp.h" #include "ms-rdpedisp.h"
#include "ms-rdpbcgr.h" #include "ms-rdpbcgr.h"
#include "ccp.h"
#include "scp.h" #include "scp.h"
#include <ctype.h> #include <ctype.h>
#include "xrdp_encoder.h" #include "xrdp_encoder.h"
@@ -1991,6 +1992,26 @@ xrdp_mm_up_and_running(struct xrdp_mm *self)
return 0; 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 */ /* open response from client going to channel server */
static int static int
@@ -2621,9 +2642,9 @@ xrdp_mm_process_login_response(struct xrdp_mm *self)
if (self->wm->client_info->require_credentials) if (self->wm->client_info->require_credentials)
{ {
/* Credentials had to be specified, but were invalid */ /* 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, " LOG(LOG_LEVEL_ERROR, "require_credentials is set, "
"but the user could not be logged in"); "but the user could not be logged in");
xrdp_mm_set_fatal(self, ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES);
} }
if (server_closed) 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", xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, "%s",
"Login retry limit reached"); "Login retry limit reached");
} }
xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, "%s", xrdp_mm_logwnd_fatal(self,
"Close the log window to exit."); ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES);
self->wm->fatal_error_in_log_window = 1;
/* Transport can be deleted now */ /* Transport can be deleted now */
self->delete_sesman_trans = 1; 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, rv = scp_get_connect_session_response(self->sesman_trans, &status,
&self->sesman_display_fd, &self->sesman_display_fd,
&self->sesman_chansrv_fd); &self->sesman_chansrv_fd);
/* Following this response, the sesman trans is closed */ if (rv != 0)
self->delete_sesman_trans = 1; {
self->delete_sesman_trans = 1;
if (rv == 0) }
else
{ {
if (status == E_SCP_SCONNECT_OK) if (status == E_SCP_SCONNECT_OK)
{ {
xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO,
"Got connection details for session"); "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 */ /* Carry on with the connect state machine */
xrdp_mm_connect_sm(self); 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, xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO,
"Can't create session for user %s - %s", "Can't create session for user %s - %s",
username, buff); username, buff);
xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, "%s", xrdp_mm_logwnd_fatal(self,
"Close the log window to exit."); ERRINFO_SERVER_DWM_CRASH);
self->wm->fatal_error_in_log_window = 1;
xrdp_wm_mod_connect_done(self->wm, 1); 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 static int
xrdp_mm_scp_data_in(struct trans *trans) 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) 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 any uncomsumed file descriptors from sesman */
close_sesman_file_descriptors(self); close_sesman_file_descriptors(self);
xrdp_wm_mod_connect_done(self->wm, status); xrdp_wm_mod_connect_done(self->wm, status);
/* Make sure the module is cleaned up if we weren't successful */ /* Make sure the module is cleaned up if we weren't successful */
if (status != 0) if (status != 0)
{ {
self->delete_sesman_trans = 1;
xrdp_mm_module_cleanup(self); xrdp_mm_module_cleanup(self);
} }
} }
@@ -3776,35 +3801,44 @@ xrdp_mm_draw_dirty(struct xrdp_mm *self)
int int
xrdp_mm_check_wait_objs(struct xrdp_mm *self) xrdp_mm_check_wait_objs(struct xrdp_mm *self)
{ {
int rv; int rv = 0;
if (self == 0) if (self == 0)
{ {
return 0; return 0;
} }
rv = 0;
if (self->sesman_trans != NULL && if (self->sesman_trans != NULL &&
!self->delete_sesman_trans && !self->delete_sesman_trans &&
self->sesman_trans->status == TRANS_STATUS_UP) self->sesman_trans->status == TRANS_STATUS_UP)
{ {
if (trans_check_wait_objs(self->sesman_trans) != 0) 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 /* Comms with the sesexec has failed - we have to assume
* outstanding message */ * the session has failed */
xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR, xrdp_mm_set_fatal(self, ERRINFO_LOGOFF_BY_USER);
"Unexpected sesman failure - check sesman log"); }
xrdp_wm_mod_connect_done(self->wm, 1); 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; 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) 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 != 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) if (self->egfx_up)
{ {
rv = xrdp_mm_draw_dirty(self); rv |= xrdp_mm_draw_dirty(self);
xrdp_region_delete(self->wm->screen_dirty_region); xrdp_region_delete(self->wm->screen_dirty_region);
self->wm->screen_dirty_region = NULL; self->wm->screen_dirty_region = NULL;
self->wm->last_screen_draw_time = now; 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->height,
self->wm->screen->bpp) != 0) 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, LOG(LOG_LEVEL_ERROR,
"Unexpected display value %d setting up module", self->display); "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) else if (self->code == XVNC_SESSION_CODE)
{ {
@@ -5285,7 +5322,7 @@ xrdp_mm_setup_mod2(struct xrdp_mm *self)
{ {
LOG(LOG_LEVEL_ERROR, LOG(LOG_LEVEL_ERROR,
"Unexpected session code %d setting up module", self->code); "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);
} }
} }
+107
View File
@@ -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 <config_ac.h>
#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;
}
+2 -2
View File
@@ -295,14 +295,14 @@ xrdp_process_main_loop(struct xrdp_process *self)
} }
} }
/* send disconnect message if possible */ /* send disconnect message if possible */
libxrdp_disconnect(self->session); libxrdp_disconnect(self->session, self->errinfo);
} }
else else
{ {
LOG(LOG_LEVEL_ERROR, "xrdp_process_main_loop: libxrdp_process_incoming failed"); LOG(LOG_LEVEL_ERROR, "xrdp_process_main_loop: libxrdp_process_incoming failed");
/* this will try to send a disconnect, /* this will try to send a disconnect,
maybe should check that connection got far enough */ maybe should check that connection got far enough */
libxrdp_disconnect(self->session); libxrdp_disconnect(self->session, self->errinfo);
} }
/* Run end in module */ /* Run end in module */
xrdp_process_mod_end(self); xrdp_process_mod_end(self);
+3
View File
@@ -464,6 +464,8 @@ struct xrdp_mm
int last_sync_saved; int last_sync_saved;
int last_sync_key_flags; int last_sync_key_flags;
int last_sync_device_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 struct xrdp_key_info
@@ -610,6 +612,7 @@ struct xrdp_process
int status; int status;
struct trans *server_trans; /* in tcp server mode */ struct trans *server_trans; /* in tcp server mode */
tbus self_term_event; tbus self_term_event;
int errinfo; /* Reason for self_term_event being set */
struct xrdp_listen *lis_layer; /* owner */ struct xrdp_listen *lis_layer; /* owner */
struct xrdp_session *session; struct xrdp_session *session;
/* create these when up and running */ /* create these when up and running */