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:
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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 */
|
||||||
|
|||||||
@@ -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 \
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+67
-30
@@ -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,36 +3801,45 @@ 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->sesman_trans_is_ccp)
|
||||||
|
{
|
||||||
|
/* 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)
|
if (self->mmcs_expecting_msg)
|
||||||
{
|
{
|
||||||
/* The sesman transport has failed with an
|
/* The sesman transport has failed with an
|
||||||
* outstanding message */
|
* outstanding message while connecting */
|
||||||
xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR,
|
xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR, "Unexpected"
|
||||||
"Unexpected sesman failure - check sesman log");
|
" sesman failure - check sesman log");
|
||||||
xrdp_wm_mod_connect_done(self->wm, 1);
|
xrdp_wm_mod_connect_done(self->wm, 1);
|
||||||
}
|
}
|
||||||
self->delete_sesman_trans = 1;
|
|
||||||
if (self->wm->hide_log_window)
|
if (self->wm->hide_log_window)
|
||||||
{
|
{
|
||||||
/* if hide_log_window, this is fatal */
|
/* if hide_log_window, this is fatal */
|
||||||
rv = 1;
|
rv = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self->delete_sesman_trans = 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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);
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
Reference in New Issue
Block a user