|
|
|
@ -285,7 +285,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm* self)
|
|
|
|
|
}
|
|
|
|
|
if (self->mod_handle == 0)
|
|
|
|
|
{
|
|
|
|
|
/* Let the main thread load the lib,*/
|
|
|
|
|
/* Let the main thread load the lib,*/
|
|
|
|
|
self->mod_handle = g_xrdp_sync(xrdp_mm_sync_load, (long)lib, 0);
|
|
|
|
|
if (self->mod_handle != 0)
|
|
|
|
|
{
|
|
|
|
@ -330,7 +330,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm* self)
|
|
|
|
|
g_snprintf(text, 255, "error loading %s specified in xrdp.ini, please "
|
|
|
|
|
"add a valid entry like lib=libxrdp-vnc.so or similar", lib);
|
|
|
|
|
xrdp_wm_log_msg(self->wm, text);
|
|
|
|
|
return 1 ;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
if (self->mod != 0)
|
|
|
|
|
{
|
|
|
|
@ -808,7 +808,7 @@ xrdp_mm_process_login_response(struct xrdp_mm* self, struct stream* s)
|
|
|
|
|
xrdp_wm_log_msg(self->wm, "xrdp_mm_process_login_response: "
|
|
|
|
|
"login failed");
|
|
|
|
|
}
|
|
|
|
|
cleanup_sesman_connection(self);
|
|
|
|
|
cleanup_sesman_connection(self);
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -942,14 +942,14 @@ xrdp_mm_sesman_data_in(struct trans* trans)
|
|
|
|
|
in_uint16_be(s, code);
|
|
|
|
|
switch (code)
|
|
|
|
|
{
|
|
|
|
|
/* even when the request is denied the reply will hold 3 as the command. */
|
|
|
|
|
/* even when the request is denied the reply will hold 3 as the command. */
|
|
|
|
|
case 3:
|
|
|
|
|
error = xrdp_mm_process_login_response(self, s);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
xrdp_wm_log_msg(self->wm, "An undefined reply code was received from sesman");
|
|
|
|
|
xrdp_wm_log_msg(self->wm, "An undefined reply code was received from sesman");
|
|
|
|
|
g_writeln("Fatal xrdp_mm_sesman_data_in: unknown cmd code %d", code);
|
|
|
|
|
cleanup_sesman_connection(self);
|
|
|
|
|
cleanup_sesman_connection(self);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -960,117 +960,120 @@ xrdp_mm_sesman_data_in(struct trans* trans)
|
|
|
|
|
#ifdef ACCESS
|
|
|
|
|
/*********************************************************************/
|
|
|
|
|
/* return 0 on success */
|
|
|
|
|
int access_control(char *username, char *password, char *srv){
|
|
|
|
|
int reply ;
|
|
|
|
|
int rec = 1 ; // failure
|
|
|
|
|
int access_control(char *username, char *password, char *srv)
|
|
|
|
|
{
|
|
|
|
|
int reply;
|
|
|
|
|
int rec = 1; // failure
|
|
|
|
|
struct stream* in_s;
|
|
|
|
|
struct stream* out_s;
|
|
|
|
|
unsigned long version ;
|
|
|
|
|
struct stream* out_s;
|
|
|
|
|
unsigned long version;
|
|
|
|
|
unsigned short int dummy;
|
|
|
|
|
unsigned short int ok;
|
|
|
|
|
unsigned short int code;
|
|
|
|
|
unsigned long size ;
|
|
|
|
|
int index ;
|
|
|
|
|
unsigned long size;
|
|
|
|
|
int index;
|
|
|
|
|
int socket = g_tcp_socket();
|
|
|
|
|
if (socket > 0) {
|
|
|
|
|
if (socket > 0)
|
|
|
|
|
{
|
|
|
|
|
/* we use a blocking socket here */
|
|
|
|
|
reply = g_tcp_connect(socket, srv, "3350");
|
|
|
|
|
if (reply == 0)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
make_stream(in_s);
|
|
|
|
|
init_stream(in_s, 500);
|
|
|
|
|
make_stream(out_s);
|
|
|
|
|
init_stream(out_s, 500);
|
|
|
|
|
s_push_layer(out_s, channel_hdr, 8);
|
|
|
|
|
init_stream(out_s, 500);
|
|
|
|
|
s_push_layer(out_s, channel_hdr, 8);
|
|
|
|
|
out_uint16_be(out_s, 4); /*0x04 means SCP_GW_AUTHENTICATION*/
|
|
|
|
|
index = g_strlen(username);
|
|
|
|
|
out_uint16_be(out_s, index);
|
|
|
|
|
out_uint8a(out_s, username, index);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
index = g_strlen(password);
|
|
|
|
|
out_uint16_be(out_s, index);
|
|
|
|
|
out_uint8a(out_s, password, index);
|
|
|
|
|
out_uint8a(out_s, password, index);
|
|
|
|
|
s_mark_end(out_s);
|
|
|
|
|
s_pop_layer(out_s, channel_hdr);
|
|
|
|
|
out_uint32_be(out_s, 0); /* version */
|
|
|
|
|
index = (int)(out_s->end - out_s->data);
|
|
|
|
|
out_uint32_be(out_s, index); /* size */
|
|
|
|
|
/* g_writeln("Number of data to send : %d",index); */
|
|
|
|
|
reply = g_tcp_send(socket, out_s->data, index, 0);
|
|
|
|
|
free_stream(out_s);
|
|
|
|
|
reply = g_tcp_send(socket, out_s->data, index, 0);
|
|
|
|
|
free_stream(out_s);
|
|
|
|
|
if (reply > 0)
|
|
|
|
|
{
|
|
|
|
|
/* We wait in 5 sec for a reply from sesman*/
|
|
|
|
|
if(g_tcp_can_recv(socket,5000)){
|
|
|
|
|
if (g_tcp_can_recv(socket, 5000))
|
|
|
|
|
{
|
|
|
|
|
reply = g_tcp_recv(socket, in_s->end, 500, 0);
|
|
|
|
|
if (reply > 0)
|
|
|
|
|
{
|
|
|
|
|
in_s->end = in_s->end + reply ;
|
|
|
|
|
in_s->end = in_s->end + reply;
|
|
|
|
|
in_uint32_be(in_s, version);
|
|
|
|
|
/*g_writeln("Version number in reply from sesman: %d",version) ; */
|
|
|
|
|
in_uint32_be(in_s, size);
|
|
|
|
|
if((size==14) && (version==0))
|
|
|
|
|
if ((size == 14) && (version == 0))
|
|
|
|
|
{
|
|
|
|
|
in_uint16_be(in_s, code);
|
|
|
|
|
in_uint16_be(in_s, ok);
|
|
|
|
|
in_uint16_be(in_s, dummy);
|
|
|
|
|
if(code!=4)
|
|
|
|
|
if (code != 4)
|
|
|
|
|
{
|
|
|
|
|
log_message(LOG_LEVEL_ERROR,"Returned cmd code from "
|
|
|
|
|
log_message(LOG_LEVEL_ERROR, "Returned cmd code from "
|
|
|
|
|
"sesman is corrupt");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
rec = ok; /* here we read the reply from the access control */
|
|
|
|
|
rec = ok; /* here we read the reply from the access control */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
log_message(LOG_LEVEL_ERROR,"Corrupt reply size or "
|
|
|
|
|
"version from sesman: %d",size);
|
|
|
|
|
log_message(LOG_LEVEL_ERROR, "Corrupt reply size or "
|
|
|
|
|
"version from sesman: %d", size);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
log_message(LOG_LEVEL_ERROR,"No data received from sesman");
|
|
|
|
|
log_message(LOG_LEVEL_ERROR, "No data received from sesman");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
log_message(LOG_LEVEL_ERROR,"Timeout when waiting for sesman");
|
|
|
|
|
log_message(LOG_LEVEL_ERROR, "Timeout when waiting for sesman");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
log_message(LOG_LEVEL_ERROR,"No success sending to sesman");
|
|
|
|
|
log_message(LOG_LEVEL_ERROR, "No success sending to sesman");
|
|
|
|
|
}
|
|
|
|
|
free_stream(in_s);
|
|
|
|
|
g_tcp_close(socket);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
log_message(LOG_LEVEL_ERROR,"Failure connecting to socket sesman");
|
|
|
|
|
}
|
|
|
|
|
log_message(LOG_LEVEL_ERROR, "Failure connecting to socket sesman");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
log_message(LOG_LEVEL_ERROR,"Failure creating socket - for access control");
|
|
|
|
|
}
|
|
|
|
|
log_message(LOG_LEVEL_ERROR, "Failure creating socket - for access control");
|
|
|
|
|
}
|
|
|
|
|
return rec;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/* This routine clears all states to make sure that our next login will be
|
|
|
|
|
* as expected. If the user does not press ok on the log window and try to
|
|
|
|
|
* as expected. If the user does not press ok on the log window and try to
|
|
|
|
|
* connect again we must make sure that no previous information is stored.*/
|
|
|
|
|
void cleanup_states(struct xrdp_mm* self)
|
|
|
|
|
{
|
|
|
|
|
if(self != NULL)
|
|
|
|
|
if (self != NULL)
|
|
|
|
|
{
|
|
|
|
|
self-> connected_state = 0; /* true if connected to sesman else false */
|
|
|
|
|
self-> sesman_trans = NULL; /* connection to sesman */
|
|
|
|
|
self-> sesman_trans_up = 0 ; /* true once connected to sesman */
|
|
|
|
|
self-> sesman_trans_up = 0; /* true once connected to sesman */
|
|
|
|
|
self-> delete_sesman_trans = 0; /* boolean set when done with sesman connection */
|
|
|
|
|
self-> display = 0; /* 10 for :10.0, 11 for :11.0, etc */
|
|
|
|
|
self-> code = 0; /* 0 Xvnc session 10 X11rdp session */
|
|
|
|
@ -1099,8 +1102,8 @@ xrdp_mm_connect(struct xrdp_mm* self)
|
|
|
|
|
char port[8];
|
|
|
|
|
char chansrvport[256];
|
|
|
|
|
#ifdef ACCESS
|
|
|
|
|
int use_pam_auth = 0 ;
|
|
|
|
|
char pam_auth_sessionIP[256] ;
|
|
|
|
|
int use_pam_auth = 0;
|
|
|
|
|
char pam_auth_sessionIP[256];
|
|
|
|
|
char pam_auth_password[256];
|
|
|
|
|
char pam_auth_username[256];
|
|
|
|
|
char username[256];
|
|
|
|
@ -1134,28 +1137,28 @@ xrdp_mm_connect(struct xrdp_mm* self)
|
|
|
|
|
self->sesman_controlled = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#ifdef ACCESS
|
|
|
|
|
#ifdef ACCESS
|
|
|
|
|
else if (g_strcasecmp(name, "pamusername") == 0)
|
|
|
|
|
{
|
|
|
|
|
use_pam_auth = 1;
|
|
|
|
|
g_strncpy(pam_auth_username, value, 255);
|
|
|
|
|
use_pam_auth = 1;
|
|
|
|
|
g_strncpy(pam_auth_username, value, 255);
|
|
|
|
|
}
|
|
|
|
|
else if (g_strcasecmp(name, "pamsessionmng") == 0)
|
|
|
|
|
{
|
|
|
|
|
g_strncpy(pam_auth_sessionIP, value, 255);
|
|
|
|
|
g_strncpy(pam_auth_sessionIP, value, 255);
|
|
|
|
|
}
|
|
|
|
|
else if (g_strcasecmp(name, "pampassword") == 0)
|
|
|
|
|
{
|
|
|
|
|
g_strncpy(pam_auth_password, value, 255);
|
|
|
|
|
g_strncpy(pam_auth_password, value, 255);
|
|
|
|
|
}
|
|
|
|
|
else if (g_strcasecmp(name, "password") == 0)
|
|
|
|
|
{
|
|
|
|
|
g_strncpy(password, value, 255);
|
|
|
|
|
}
|
|
|
|
|
g_strncpy(password, value, 255);
|
|
|
|
|
}
|
|
|
|
|
else if (g_strcasecmp(name, "username") == 0)
|
|
|
|
|
{
|
|
|
|
|
g_strncpy(username, value, 255);
|
|
|
|
|
}
|
|
|
|
|
g_strncpy(username, value, 255);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
else if (g_strcasecmp(name, "chansrvport") == 0)
|
|
|
|
|
{
|
|
|
|
@ -1163,28 +1166,29 @@ xrdp_mm_connect(struct xrdp_mm* self)
|
|
|
|
|
self->usechansrv = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#ifdef ACCESS
|
|
|
|
|
if(use_pam_auth){
|
|
|
|
|
int reply;
|
|
|
|
|
#ifdef ACCESS
|
|
|
|
|
if (use_pam_auth)
|
|
|
|
|
{
|
|
|
|
|
int reply;
|
|
|
|
|
char replytxt[80];
|
|
|
|
|
char replymessage[4][80] = {"Ok","Sesman connect failure","User or password error","Privilege group error"};
|
|
|
|
|
xrdp_wm_log_msg(self->wm, "Please wait, we now perform access control...");
|
|
|
|
|
/* g_writeln("we use pam modules to check if we can approve this user"); */
|
|
|
|
|
if(!g_strncmp(pam_auth_username,"same",255))
|
|
|
|
|
if (!g_strncmp(pam_auth_username, "same", 255))
|
|
|
|
|
{
|
|
|
|
|
log_message(LOG_LEVEL_DEBUG,"pamusername copied from username - same: %s",username);
|
|
|
|
|
g_strncpy(pam_auth_username,username,255);
|
|
|
|
|
log_message(LOG_LEVEL_DEBUG, "pamusername copied from username - same: %s", username);
|
|
|
|
|
g_strncpy(pam_auth_username,username, 255);
|
|
|
|
|
}
|
|
|
|
|
if(!g_strncmp(pam_auth_password,"same",255))
|
|
|
|
|
if (!g_strncmp(pam_auth_password, "same", 255))
|
|
|
|
|
{
|
|
|
|
|
log_message(LOG_LEVEL_DEBUG,"pam_auth_password copied from username - same: %s",password);
|
|
|
|
|
g_strncpy(pam_auth_password,password,255);
|
|
|
|
|
log_message(LOG_LEVEL_DEBUG,"pam_auth_password copied from username - same: %s", password);
|
|
|
|
|
g_strncpy(pam_auth_password, password, 255);
|
|
|
|
|
}
|
|
|
|
|
/* access_control return 0 on success */
|
|
|
|
|
reply = access_control(pam_auth_username, pam_auth_password, pam_auth_sessionIP);
|
|
|
|
|
if(reply>=0 && reply<4)
|
|
|
|
|
reply = access_control(pam_auth_username, pam_auth_password, pam_auth_sessionIP);
|
|
|
|
|
if (reply >= 0 && reply < 4)
|
|
|
|
|
{
|
|
|
|
|
g_sprintf(replytxt,"Reply from access control: %s",replymessage[reply]);
|
|
|
|
|
g_sprintf(replytxt,"Reply from access control: %s", replymessage[reply]);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
@ -1192,12 +1196,12 @@ xrdp_mm_connect(struct xrdp_mm* self)
|
|
|
|
|
}
|
|
|
|
|
xrdp_wm_log_msg(self->wm,replytxt);
|
|
|
|
|
log_message(LOG_LEVEL_INFO,replytxt);
|
|
|
|
|
if(reply!=0)
|
|
|
|
|
{
|
|
|
|
|
rv = 1 ;
|
|
|
|
|
return rv ;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (reply != 0)
|
|
|
|
|
{
|
|
|
|
|
rv = 1;
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
if (self->sesman_controlled)
|
|
|
|
|
{
|
|
|
|
@ -1234,7 +1238,7 @@ xrdp_mm_connect(struct xrdp_mm* self)
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
g_snprintf(errstr, 255, "Failure to connect to sesman: %s port: %s",
|
|
|
|
|
ip, port);
|
|
|
|
|
ip, port);
|
|
|
|
|
xrdp_wm_log_msg(self->wm, errstr);
|
|
|
|
|
trans_delete(self->sesman_trans);
|
|
|
|
|
self->sesman_trans = 0;
|
|
|
|
@ -1249,12 +1253,12 @@ xrdp_mm_connect(struct xrdp_mm* self)
|
|
|
|
|
if (xrdp_mm_setup_mod2(self) == 0)
|
|
|
|
|
{
|
|
|
|
|
xrdp_wm_set_login_mode(self->wm, 10);
|
|
|
|
|
rv = 0 ; /*sucess*/
|
|
|
|
|
rv = 0; /*sucess*/
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* connect error */
|
|
|
|
|
g_snprintf(errstr, 255, "Failure to connect to: %s",ip);
|
|
|
|
|
g_snprintf(errstr, 255, "Failure to connect to: %s", ip);
|
|
|
|
|
xrdp_wm_log_msg(self->wm, errstr);
|
|
|
|
|
rv = 1; /* failure */
|
|
|
|
|
}
|
|
|
|
@ -1267,7 +1271,7 @@ xrdp_mm_connect(struct xrdp_mm* self)
|
|
|
|
|
{
|
|
|
|
|
xrdp_wm_set_login_mode(self->wm, 11);
|
|
|
|
|
xrdp_mm_module_cleanup(self);
|
|
|
|
|
rv = 1 ; /* failure */
|
|
|
|
|
rv = 1; /* failure */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1277,7 +1281,7 @@ xrdp_mm_connect(struct xrdp_mm* self)
|
|
|
|
|
/* if sesman controlled, this will connect later */
|
|
|
|
|
xrdp_mm_connect_chansrv(self, "", chansrvport);
|
|
|
|
|
}
|
|
|
|
|
g_writeln("returnvalue from xrdp_mm_connect %d",rv);
|
|
|
|
|
g_writeln("returnvalue from xrdp_mm_connect %d", rv);
|
|
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
@ -1760,154 +1764,161 @@ server_reset(struct xrdp_mod* mod, int width, int height, int bpp)
|
|
|
|
|
* return 1 on success 0 on failure */
|
|
|
|
|
int read_allowed_channel_names(struct list* names, struct list* values)
|
|
|
|
|
{
|
|
|
|
|
int fd;
|
|
|
|
|
int ret = 0 ;
|
|
|
|
|
char cfg_file[256];
|
|
|
|
|
int fd;
|
|
|
|
|
int ret = 0;
|
|
|
|
|
char cfg_file[256];
|
|
|
|
|
int pos;
|
|
|
|
|
g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
|
|
|
|
|
fd = g_file_open(cfg_file);
|
|
|
|
|
if (fd > 0)
|
|
|
|
|
{
|
|
|
|
|
names->auto_free = 1;
|
|
|
|
|
{
|
|
|
|
|
names->auto_free = 1;
|
|
|
|
|
values->auto_free = 1;
|
|
|
|
|
pos = 0 ;
|
|
|
|
|
pos = 0;
|
|
|
|
|
/* all values in this section can be valid channel names */
|
|
|
|
|
if (file_read_section(fd, "channels", names, values) == 0)
|
|
|
|
|
{
|
|
|
|
|
ret = 1 ;
|
|
|
|
|
ret = 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
g_writeln("Failure reading channel section of configuration") ;
|
|
|
|
|
}
|
|
|
|
|
g_writeln("Failure reading channel section of configuration");
|
|
|
|
|
}
|
|
|
|
|
g_file_close(fd);
|
|
|
|
|
return ret ;
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* internal function return 1 if name is in list of channels
|
|
|
|
|
/* internal function return 1 if name is in list of channels
|
|
|
|
|
* and if the value is allowed */
|
|
|
|
|
int DEFAULT_CC is_name_in_lists(char *inName, struct list* names, struct list* values)
|
|
|
|
|
int DEFAULT_CC
|
|
|
|
|
is_name_in_lists(char* inName, struct list* names, struct list* values)
|
|
|
|
|
{
|
|
|
|
|
int reply = 0 ; /*means not in the list*/
|
|
|
|
|
int index ;
|
|
|
|
|
int reply = 0; /*means not in the list*/
|
|
|
|
|
int index;
|
|
|
|
|
char* val;
|
|
|
|
|
char* name ;
|
|
|
|
|
char* name;
|
|
|
|
|
for (index = 0; index < names->count; index++)
|
|
|
|
|
{
|
|
|
|
|
name = (char*)list_get_item(names, index);
|
|
|
|
|
if (name != 0)
|
|
|
|
|
{
|
|
|
|
|
/* ex rdpdr ;rdpsnd ; drdynvc ; cliprdr */
|
|
|
|
|
if(!g_strncmp(name,inName,MAX_CHANNEL_NAME)){
|
|
|
|
|
if (!g_strncmp(name, inName, MAX_CHANNEL_NAME))
|
|
|
|
|
{
|
|
|
|
|
val = (char*)list_get_item(values, index);
|
|
|
|
|
if ((g_strcasecmp(val, "yes") == 0) ||
|
|
|
|
|
(g_strcasecmp(val, "on") == 0) ||
|
|
|
|
|
(g_strcasecmp(val, "true") == 0) ||
|
|
|
|
|
(g_atoi(val) != 0))
|
|
|
|
|
{
|
|
|
|
|
reply = 1 ;
|
|
|
|
|
reply = 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
g_writeln("This channel is disabled: %s",name);
|
|
|
|
|
g_writeln("This channel is disabled: %s", name);
|
|
|
|
|
}
|
|
|
|
|
break ; /* stop loop - item found*/
|
|
|
|
|
break; /* stop loop - item found*/
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return reply ;
|
|
|
|
|
return reply;
|
|
|
|
|
}
|
|
|
|
|
/* internal function only used once per session
|
|
|
|
|
* creates the list of allowed channels and store the information
|
|
|
|
|
* creates the list of allowed channels and store the information
|
|
|
|
|
* in wm struct */
|
|
|
|
|
void init_channel_allowed(struct xrdp_wm* wm)
|
|
|
|
|
{
|
|
|
|
|
int error ;
|
|
|
|
|
int i ;
|
|
|
|
|
char channelname[MAX_CHANNEL_NAME];
|
|
|
|
|
int index = 0 ;
|
|
|
|
|
int allowindex = 0 ;
|
|
|
|
|
{
|
|
|
|
|
int error;
|
|
|
|
|
int i;
|
|
|
|
|
char channelname[MAX_CHANNEL_NAME];
|
|
|
|
|
int index = 0;
|
|
|
|
|
int allowindex = 0;
|
|
|
|
|
struct list* names;
|
|
|
|
|
struct list* values;
|
|
|
|
|
struct list* values;
|
|
|
|
|
/* first reset allowedchannels */
|
|
|
|
|
for(i = 0 ; i<MAX_NR_CHANNELS;i++)
|
|
|
|
|
for (i = 0; i < MAX_NR_CHANNELS; i++)
|
|
|
|
|
{
|
|
|
|
|
/* 0 is a valid channel so we use -1 to mark the index as unused */
|
|
|
|
|
wm->allowedchannels[i] = -1 ;
|
|
|
|
|
wm->allowedchannels[i] = -1;
|
|
|
|
|
}
|
|
|
|
|
names = list_create();
|
|
|
|
|
names = list_create();
|
|
|
|
|
values = list_create();
|
|
|
|
|
if(read_allowed_channel_names(names,values)){
|
|
|
|
|
do{
|
|
|
|
|
if (read_allowed_channel_names(names, values))
|
|
|
|
|
{
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
/* libxrdp_query_channel return 1 on error*/
|
|
|
|
|
error = libxrdp_query_channel(wm->session, index, channelname,NULL);
|
|
|
|
|
if(error==0){
|
|
|
|
|
/* examples of channel names: rdpdr ;rdpsnd ; drdynvc ; cliprdr */
|
|
|
|
|
if(is_name_in_lists(channelname,names,values)){
|
|
|
|
|
g_writeln("The following channel is allowed: %s",channelname) ;
|
|
|
|
|
wm->allowedchannels[allowindex] = index ;
|
|
|
|
|
allowindex ++ ;
|
|
|
|
|
if(allowindex>=MAX_NR_CHANNELS)
|
|
|
|
|
error = libxrdp_query_channel(wm->session, index, channelname,NULL);
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
/* examples of channel names: rdpdr ; rdpsnd ; drdynvc ; cliprdr */
|
|
|
|
|
if (is_name_in_lists(channelname, names, values))
|
|
|
|
|
{
|
|
|
|
|
g_writeln("The following channel is allowed: %s", channelname);
|
|
|
|
|
wm->allowedchannels[allowindex] = index;
|
|
|
|
|
allowindex++;
|
|
|
|
|
if (allowindex >= MAX_NR_CHANNELS)
|
|
|
|
|
{
|
|
|
|
|
g_writeln("Programming error in is_channel_allowed");
|
|
|
|
|
error = 1 ; /* end loop */
|
|
|
|
|
error = 1; /* end loop */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
g_writeln("The following channel is not allowed: %s",channelname) ;
|
|
|
|
|
g_writeln("The following channel is not allowed: %s",channelname);
|
|
|
|
|
}
|
|
|
|
|
index ++ ;
|
|
|
|
|
index++;
|
|
|
|
|
}
|
|
|
|
|
}while((error==0) && (index<MAX_NR_CHANNELS)) ;
|
|
|
|
|
} while ((error == 0) && (index < MAX_NR_CHANNELS));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
g_writeln("Error reading channel section in inifile") ;
|
|
|
|
|
}
|
|
|
|
|
g_writeln("Error reading channel section in inifile");
|
|
|
|
|
}
|
|
|
|
|
list_delete(names);
|
|
|
|
|
list_delete(values);
|
|
|
|
|
list_delete(values);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/* This function returns 1 if the channelID is allowed by rule set
|
|
|
|
|
* returns 0 if not allowed */
|
|
|
|
|
int DEFAULT_CC is_channel_allowed(struct xrdp_wm* wm, int channel_id)
|
|
|
|
|
{
|
|
|
|
|
int i ;
|
|
|
|
|
int reply = 0 ; /* not allowed */
|
|
|
|
|
/* The first time each client is using this function we have to
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
int reply = 0; /* not allowed */
|
|
|
|
|
/* The first time each client is using this function we have to
|
|
|
|
|
* define the list of allowed channels */
|
|
|
|
|
if(wm->allowedinitialized==0)
|
|
|
|
|
if (wm->allowedinitialized == 0)
|
|
|
|
|
{
|
|
|
|
|
init_channel_allowed(wm);
|
|
|
|
|
g_writeln("allow channel list initialized");
|
|
|
|
|
wm->allowedinitialized = 1 ;
|
|
|
|
|
wm->allowedinitialized = 1;
|
|
|
|
|
}
|
|
|
|
|
for(i = 0 ; i<MAX_NR_CHANNELS;i++)
|
|
|
|
|
for(i = 0; i < MAX_NR_CHANNELS; i++)
|
|
|
|
|
{
|
|
|
|
|
if(channel_id == wm->allowedchannels[i])
|
|
|
|
|
if (channel_id == wm->allowedchannels[i])
|
|
|
|
|
{
|
|
|
|
|
/*g_writeln("Channel allowed: %d",channel_id);*/
|
|
|
|
|
reply = 1 ; /*channel allowed*/
|
|
|
|
|
break ;
|
|
|
|
|
reply = 1; /*channel allowed*/
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else if(wm->allowedchannels[i]==-1)
|
|
|
|
|
else if (wm->allowedchannels[i] == -1)
|
|
|
|
|
{
|
|
|
|
|
/* We are in the unused space of the allowedchannels list
|
|
|
|
|
/* We are in the unused space of the allowedchannels list
|
|
|
|
|
* We can end the loop */
|
|
|
|
|
break ;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/*if(reply==0)
|
|
|
|
|
/*if (reply == 0)
|
|
|
|
|
{
|
|
|
|
|
g_writeln("This channel is NOT allowed: %d",channel_id) ;
|
|
|
|
|
}*/
|
|
|
|
|
return reply ;
|
|
|
|
|
return reply;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/*return 0 if the index is not found*/
|
|
|
|
|
int DEFAULT_CC
|
|
|
|
|
int DEFAULT_CC
|
|
|
|
|
server_query_channel(struct xrdp_mod* mod, int index, char* channel_name,
|
|
|
|
|
int* channel_flags)
|
|
|
|
|
{
|
|
|
|
@ -1946,14 +1957,14 @@ server_send_to_channel(struct xrdp_mod* mod, int channel_id,
|
|
|
|
|
struct xrdp_wm* wm;
|
|
|
|
|
|
|
|
|
|
wm = (struct xrdp_wm*)(mod->wm);
|
|
|
|
|
if(is_channel_allowed(wm,channel_id))
|
|
|
|
|
{
|
|
|
|
|
if (is_channel_allowed(wm, channel_id))
|
|
|
|
|
{
|
|
|
|
|
if (wm->mm->usechansrv)
|
|
|
|
|
{
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
return libxrdp_send_to_channel(wm->session, channel_id, data, data_len,
|
|
|
|
|
total_data_len, flags);
|
|
|
|
|
total_data_len, flags);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
@ -2101,3 +2112,89 @@ server_set_hints(struct xrdp_mod* mod, int hints, int mask)
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
int DEFAULT_CC
|
|
|
|
|
server_window_new_update(struct xrdp_mod* mod, int window_id,
|
|
|
|
|
struct rail_window_state_order* window_state,
|
|
|
|
|
int flags)
|
|
|
|
|
{
|
|
|
|
|
struct xrdp_wm* wm;
|
|
|
|
|
|
|
|
|
|
wm = (struct xrdp_wm*)(mod->wm);
|
|
|
|
|
return libxrdp_window_new_update(wm->session, window_id,
|
|
|
|
|
window_state, flags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
int DEFAULT_CC
|
|
|
|
|
server_window_delete(struct xrdp_mod* mod, int window_id)
|
|
|
|
|
{
|
|
|
|
|
struct xrdp_wm* wm;
|
|
|
|
|
|
|
|
|
|
wm = (struct xrdp_wm*)(mod->wm);
|
|
|
|
|
return libxrdp_window_delete(wm->session, window_id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
int DEFAULT_CC
|
|
|
|
|
server_window_icon(struct xrdp_mod* mod, int window_id, int cache_entry,
|
|
|
|
|
int cache_id, struct rail_icon_info* icon_info,
|
|
|
|
|
int flags)
|
|
|
|
|
{
|
|
|
|
|
struct xrdp_wm* wm;
|
|
|
|
|
|
|
|
|
|
wm = (struct xrdp_wm*)(mod->wm);
|
|
|
|
|
return libxrdp_window_icon(wm->session, window_id, cache_entry, cache_id,
|
|
|
|
|
icon_info, flags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
int DEFAULT_CC
|
|
|
|
|
server_window_cached_icon(struct xrdp_mod* mod,
|
|
|
|
|
int window_id, int cache_entry,
|
|
|
|
|
int cache_id, int flags)
|
|
|
|
|
{
|
|
|
|
|
struct xrdp_wm* wm;
|
|
|
|
|
|
|
|
|
|
wm = (struct xrdp_wm*)(mod->wm);
|
|
|
|
|
return libxrdp_window_cached_icon(wm->session, window_id, cache_entry,
|
|
|
|
|
cache_id, flags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
int DEFAULT_CC
|
|
|
|
|
server_notify_new_update(struct xrdp_mod* mod,
|
|
|
|
|
int window_id, int notify_id,
|
|
|
|
|
struct rail_notify_state_order* notify_state,
|
|
|
|
|
int flags)
|
|
|
|
|
{
|
|
|
|
|
struct xrdp_wm* wm;
|
|
|
|
|
|
|
|
|
|
wm = (struct xrdp_wm*)(mod->wm);
|
|
|
|
|
return libxrdp_notify_new_update(wm->session, window_id, notify_id,
|
|
|
|
|
notify_state, flags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
int DEFAULT_CC
|
|
|
|
|
server_notify_delete(struct xrdp_mod* mod, int window_id,
|
|
|
|
|
int notify_id)
|
|
|
|
|
{
|
|
|
|
|
struct xrdp_wm* wm;
|
|
|
|
|
|
|
|
|
|
wm = (struct xrdp_wm*)(mod->wm);
|
|
|
|
|
return libxrdp_notify_delete(wm->session, window_id, notify_id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
int DEFAULT_CC
|
|
|
|
|
server_monitored_desktop(struct xrdp_mod* mod,
|
|
|
|
|
struct rail_monitored_desktop_order* mdo,
|
|
|
|
|
int flags)
|
|
|
|
|
{
|
|
|
|
|
struct xrdp_wm* wm;
|
|
|
|
|
|
|
|
|
|
wm = (struct xrdp_wm*)(mod->wm);
|
|
|
|
|
return libxrdp_monitored_desktop(wm->session, mdo, flags);
|
|
|
|
|
}
|
|
|
|
|