Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix v0.10.x regressions in standalone chansrv #3243

Merged
merged 7 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions docs/man/xrdp.ini.5.in
Original file line number Diff line number Diff line change
Expand Up @@ -381,14 +381,17 @@ Specifies the session type. The default, \fI0\fR, is Xvnc,
and \fI20\fR is Xorg with xorgxrdp modules.

.TP
\fBchansrvport\fR=\fBDISPLAY(\fR\fIn\fR\fB)\fR|\fI/path/to/domain-socket\fR
\fBchansrvport\fR=\fBDISPLAY(\fR\fIn\fR\fB)\fR|\fBDISPLAY(\fR\fIn,u\fR\fB)\fR||\fI/path/to/domain-socket\fR
Asks xrdp to connect to a manually started \fBxrdp-chansrv\fR instance.
This can be useful if you wish to use to use xrdp to connect to a VNC session
which has been started other than by \fBxrdp-sesman\fR, as you can then make
use of \fBxrdp\-chansrv\fR facilities in the VNC session.

The first form of this setting is recommended, replacing \fIn\fR with the
X11 display number of the session.
Either the first or second form of this setting is recommended. Replace
\fIn\fR with the X11 display number of the session, and (if applicable)
\fIu\fR with the numeric ID of the session. The second form is only
required if \fBxrdp\fR is unable to determine the session uid from the
other values in the connection block.

.TP
\fBkeycode_set\fR=\fI<string>\fR
Expand Down
2 changes: 2 additions & 0 deletions libipm/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ libipm_la_SOURCES = \
ercp.c \
scp.h \
scp.c \
scp_sync.h \
scp_sync.c \
scp_application_types.h \
scp_application_types.c

Expand Down
40 changes: 40 additions & 0 deletions libipm/scp.c
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,46 @@ scp_get_list_sessions_response(

/*****************************************************************************/

int
scp_send_create_sockdir_request(struct trans *trans)
{
return libipm_msg_out_simple_send(
trans,
(int)E_SCP_CREATE_SOCKDIR_REQUEST,
NULL);
}


/*****************************************************************************/

int
scp_send_create_sockdir_response(struct trans *trans,
enum scp_create_sockdir_status status)
{
return libipm_msg_out_simple_send(
trans,
(int)E_SCP_CREATE_SOCKDIR_RESPONSE,
"i", status);
}

/*****************************************************************************/

int
scp_get_create_sockdir_response(struct trans *trans,
enum scp_create_sockdir_status *status)
{
int32_t i_status = 0;
int rv = libipm_msg_in_parse(trans, "i", &i_status);
if (rv == 0)
{
*status = (enum scp_create_sockdir_status)i_status;
}

return rv;
}

/*****************************************************************************/

int
scp_send_close_connection_request(struct trans *trans)
{
Expand Down
46 changes: 43 additions & 3 deletions libipm/scp.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ enum scp_msg_code
E_SCP_LIST_SESSIONS_REQUEST,
E_SCP_LIST_SESSIONS_RESPONSE,

E_SCP_CREATE_SOCKDIR_REQUEST,
E_SCP_CREATE_SOCKDIR_RESPONSE,

E_SCP_CLOSE_CONNECTION_REQUEST
// No E_SCP_CLOSE_CONNECTION_RESPONSE
};
Expand Down Expand Up @@ -411,7 +414,7 @@ scp_get_create_session_response(struct trans *trans,
struct guid *guid);

/**
* Send an E_LIST_SESSIONS_REQUEST (SCP client)
* Send an E_SCP_LIST_SESSIONS_REQUEST (SCP client)
*
* @param trans SCP transport
* @return != 0 for error
Expand All @@ -422,7 +425,7 @@ int
scp_send_list_sessions_request(struct trans *trans);

/**
* Send an E_LIST_SESSIONS_RESPONSE (SCP server)
* Send an E_SCP_LIST_SESSIONS_RESPONSE (SCP server)
*
* @param trans SCP transport
* @param status Status of request
Expand All @@ -436,7 +439,7 @@ scp_send_list_sessions_response(
const struct scp_session_info *info);

/**
* Parse an incoming E_LIST_SESSIONS_RESPONSE (SCP client)
* Parse an incoming E_SCP_LIST_SESSIONS_RESPONSE (SCP client)
*
* @param trans SCP transport
* @param[out] status Status of request
Expand All @@ -456,6 +459,43 @@ scp_get_list_sessions_response(
enum scp_list_sessions_status *status,
struct scp_session_info **info);

/**
* Send an E_SCP_CREATE_SOCKDIR_REQUEST (SCP client)
*
* @param trans SCP transport
* @return != 0 for error
*
* In some configurations, chansrv is not started by sesman. In this
* instance, it may be necessary for the unprivileged sesman process to
* ask sesman to create the sockets dir so sesman can populate it.
*
* Server replies with E_SCP_CREATE_SOCKDIR_RESPONSE
*/
int
scp_send_create_sockdir_request(struct trans *trans);

/**
* Send an E_SCP_CREATE_SOCKDIR_RESPONSE (SCP server)
*
* @param trans SCP transport
* @param status Status of request
* @return != 0 for error
*/
int
scp_send_create_sockdir_response(struct trans *trans,
enum scp_create_sockdir_status status);

/**
* Parse an incoming E_SCP_CREATE_SOCKDIR_RESPONSE (SCP client)
*
* @param trans SCP transport
* @param[out] status Status of request
* @return != 0 for error
*/
int
scp_get_create_sockdir_response(struct trans *trans,
enum scp_create_sockdir_status *status);

/**
* Send an E_CLOSE_CONNECTION_REQUEST (SCP client)
*
Expand Down
18 changes: 18 additions & 0 deletions libipm/scp_application_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,5 +136,23 @@ enum scp_list_sessions_status
E_SCP_LS_NO_MEMORY
};

/**
* Status of a create sockdir message
*/
enum scp_create_sockdir_status
{
E_SCP_CS_OK = 0,

/**
* Client hasn't logged in yet
*/
E_SCP_CS_NOT_LOGGED_IN = 100,

/**
* sesman failed to create the directory
*/
E_SCP_CS_OTHER_ERROR
};


#endif /* SCP_APPLICATION_TYPES_H */
210 changes: 210 additions & 0 deletions libipm/scp_sync.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2022
*
* 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.
*/

/**
*
* @file scp_sync.c
* @brief scp definitions (synchronous calls)
* @author Matt Burt
*
*/

#if defined(HAVE_CONFIG_H)
#include "config_ac.h"
#endif

//nclude "tools_common.h"
//nclude "trans.h"
#include "os_calls.h"
#include "log.h"
#include "scp.h"
#include "scp_sync.h"

/*****************************************************************************/
int
scp_sync_wait_specific(struct trans *t, enum scp_msg_code wait_msgno)
{

int rv = 0;
int available = 0;

while (rv == 0 && !available)
{
if ((rv = scp_msg_in_wait_available(t)) != 0)
{
LOG(LOG_LEVEL_ERROR, "Error waiting on sesman transport");
}
else
{
enum scp_msg_code reply_msgno = scp_msg_in_get_msgno(t);

available = 1;
if (reply_msgno != wait_msgno)
{
char buff[64];
scp_msgno_to_str(reply_msgno, buff, sizeof(buff));

LOG(LOG_LEVEL_WARNING,
"Ignoring unexpected message %s", buff);
scp_msg_in_reset(t);
available = 0;
}
}
}

return rv;
}

/*****************************************************************************/
int
scp_sync_uds_login_request(struct trans *t)
{
int rv = scp_send_uds_login_request(t);
if (rv == 0)
{
if ((rv = scp_sync_wait_specific(t, E_SCP_LOGIN_RESPONSE)) == 0)
{
enum scp_login_status login_result;
int server_closed;
rv = scp_get_login_response(t, &login_result, &server_closed, NULL);
if (rv == 0 && login_result != E_SCP_LOGIN_OK)
{
char msg[256];
scp_login_status_to_str(login_result, msg, sizeof(msg));
g_printf("Login failed; %s\n", msg);
rv = 1;
if (!server_closed)
{
(void)scp_send_close_connection_request(t);
}
}
scp_msg_in_reset(t); // Done with this message
}

}
return rv;
}

/*****************************************************************************/
struct list *
scp_sync_list_sessions_request(struct trans *t)
{
struct list *sessions = list_create();
if (sessions == NULL)
{
LOG(LOG_LEVEL_ERROR, "Out of memory for sessions list");
}
else
{
int end_of_list = 0;

enum scp_list_sessions_status status;
struct scp_session_info *p;

int rv = scp_send_list_sessions_request(t);

sessions->auto_free = 1;

while (rv == 0 && !end_of_list)
{
rv = scp_sync_wait_specific(t, E_SCP_LIST_SESSIONS_RESPONSE);
if (rv != 0)
{
break;
}

rv = scp_get_list_sessions_response(t, &status, &p);
if (rv != 0)
{
break;
}

switch (status)
{
case E_SCP_LS_SESSION_INFO:
if (!list_add_item(sessions, (tintptr)p))
{
g_free(p);
LOG(LOG_LEVEL_ERROR, "Out of memory for session item");
rv = 1;
}
break;

case E_SCP_LS_END_OF_LIST:
end_of_list = 1;
break;

default:
LOG(LOG_LEVEL_ERROR,
"Unexpected return code %d for session item", status);
rv = 1;
}
scp_msg_in_reset(t);
}

if (rv != 0)
{
list_delete(sessions);
sessions = NULL;
}
}

return sessions;
}

/*****************************************************************************/
int
scp_sync_create_sockdir_request(struct trans *t)
{
int rv = scp_send_create_sockdir_request(t);
if (rv == 0)
{
rv = scp_sync_wait_specific(t, E_SCP_CREATE_SOCKDIR_RESPONSE);
if (rv == 0)
{
enum scp_create_sockdir_status status;
rv = scp_get_create_sockdir_response(t, &status);
if (rv == 0)
{
switch (status)
{
case E_SCP_CS_OK:
break;

case E_SCP_CS_NOT_LOGGED_IN:
LOG(LOG_LEVEL_ERROR, "sesman reported not-logged-in");
rv = 1;
break;

case E_SCP_CS_OTHER_ERROR:
LOG(LOG_LEVEL_ERROR,
"sesman reported fail on create directory");
rv = 1;
break;
}
}
scp_msg_in_reset(t); // Done with this message
if (!rv)
{
(void)scp_send_close_connection_request(t);
}
}

}
return rv;
}
Loading