@ -42,6 +42,16 @@
# include "xauth.h"
# include "xrdp_sockets.h"
# include <string.h>
# include <arpa/inet.h>
# include <sys/types.h>
# include <netinet/in.h>
# include <sys/socket.h>
# include <sys/types.h>
# include <unistd.h>
# include <fcntl.h>
# include <netdb.h>
# include "libraptorsmiface.h"
# ifndef PR_SET_NO_NEW_PRIVS
@ -158,6 +168,82 @@ session_get_bydata(const char *name, int width, int height, int bpp, int type,
return 0 ;
}
/******************************************************************************/
/**
*
* @ brief checks if there ' s a server running on a host and port
* @ param display the display to check
* @ return 0 if the port is closed , 1 if it is open
*
*/
static int
check_port_status ( const char * host , const char * port )
{
char text [ 256 ] ;
int x_running ;
int sck ;
struct sockaddr_in servaddr ;
int soc = socket ( PF_INET , SOCK_STREAM , IPPROTO_TCP ) ;
g_memset ( & servaddr , 0 , sizeof ( servaddr ) ) ;
servaddr . sin_family = AF_INET ;
servaddr . sin_port = htons ( atoi ( port ) ) ;
struct hostent * hostaddr ;
hostaddr = gethostbyname ( host ) ;
g_memcpy ( & servaddr . sin_addr , hostaddr - > h_addr , hostaddr - > h_length ) ;
int res = connect ( soc , ( struct sockaddr * ) & servaddr , sizeof ( servaddr ) ) ;
close ( soc ) ;
if ( res = = - 1 )
{
// Port is closed, no server there!
return 0 ;
}
else {
// Port is open
return 1 ;
}
}
/******************************************************************************/
/**
*
* @ brief checks if there ' s a server running on a remote display
* @ param display the display to check
* @ return 0 if there isn ' t a display running , nonzero otherwise
*
*/
static int
x_server_running_check_remote_ports ( const char * host , int display )
{
char text [ 256 ] ;
int x_running ;
int sck ;
x_running = 0 ;
/* check 59xx */
{
g_sprintf ( text , " 59%2.2d " , display ) ;
x_running + = check_port_status ( host , text ) ;
}
/* check 60xx */
{
g_sprintf ( text , " 60%2.2d " , display ) ;
x_running + = check_port_status ( host , text ) ;
}
/* check 62xx */
{
g_sprintf ( text , " 62%2.2d " , display ) ;
x_running + = check_port_status ( host , text ) ;
}
return x_running ;
}
/******************************************************************************/
/**
*
@ -330,14 +416,14 @@ wait_for_xserver(int display)
int i ;
/* give X a bit to start */
/* wait up to 1 0 secs for x server to start */
/* wait up to 1 5 secs for x server to start */
i = 0 ;
while ( ! x_server_running ( display ) )
while ( ! x_server_running _check_ports ( display ) )
{
i + + ;
if ( i > 4 0)
if ( i > 6 0)
{
log_message ( LOG_LEVEL_ERROR ,
" X server for display %d startup timeout " ,
@ -387,6 +473,57 @@ session_start_chansrv(char *username, int display)
return chansrv_pid ;
}
/******************************************************************************/
static int
wait_for_remote_xserver ( const char * host , int display )
{
int i ;
/* give X a bit to start */
/* wait up to 15 secs for x server to start */
i = 0 ;
//while (!x_server_running(display))
while ( ! x_server_running_check_remote_ports ( host , display ) )
{
i + + ;
if ( i > 60 )
{
log_message ( LOG_LEVEL_ERROR ,
" X server for host %s and display %d startup timeout " ,
host , display ) ;
break ;
}
g_sleep ( 250 ) ;
}
return 0 ;
}
/******************************************************************************/
static const char *
wait_for_remote_hostname ( char * username )
{
int i ;
/* wait up to 5 secs for hostname to appear */
i = 0 ;
const char * hostname = raptor_sm_get_hostname_for_username ( username , false ) ;
while ( strcmp ( hostname , " " ) = = 0 )
{
g_free ( hostname ) ;
hostname = raptor_sm_get_hostname_for_username ( username , false ) ;
i + + ;
if ( i > 20 )
{
log_message ( LOG_LEVEL_ERROR ,
" Hostname allocation timeout " ) ;
break ;
}
g_sleep ( 250 ) ;
}
return hostname ;
}
/******************************************************************************/
/* called with the main thread */
static int
@ -468,6 +605,7 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
if ( display = = 0 )
{
log_message ( LOG_LEVEL_ALWAYS , " Unable to allocate display for user %s " , s - > username ) ;
g_free ( temp - > item ) ;
g_free ( temp ) ;
return 0 ;
@ -543,17 +681,25 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
}
else if ( window_manager_pid = = 0 )
{
wait_for_xserver ( display ) ;
if ( session_was_already_running ) {
g_exit ( 0 ) ;
}
char * remote_server = wait_for_remote_hostname ( s - > username ) ;
wait_for_remote_xserver ( remote_server , display ) ;
env_set_user ( s - > username ,
0 ,
display ,
g_cfg - > env_names ,
g_cfg - > env_values ) ;
if ( session_was_already_running ) {
g_exit ( 0 ) ;
}
if ( x_server_running ( display ) )
if ( x_server_running_check_remote_ports ( remote_server , display ) )
{
g_free ( remote_server ) ;
// RAPTOR session management
raptor_sm_run_remote_desktop ( s - > username , display , " /opt/trinity/bin/starttde " ) ;
g_exit ( 0 ) ;
auth_set_env ( data ) ;
if ( s - > directory ! = 0 )
{
@ -619,6 +765,7 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
}
else
{
g_free ( remote_server ) ;
log_message ( LOG_LEVEL_ERROR , " another Xserver might "
" already be active on display %d - see log " , display ) ;
}
@ -726,6 +873,7 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
/* fire up Xorg */
pid_t serverpid ;
serverpid = raptor_sm_run_remote_server ( s - > username , pp1 ) ;
log_message ( LOG_LEVEL_ALWAYS , " new server pid code was %d during login for user %s " , serverpid , s - > username ) ;
if ( serverpid > = 0 ) {
if ( ! session_was_already_running ) {
@ -841,7 +989,9 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
}
else
{
wait_for_xserver ( display ) ;
char * remote_server = wait_for_remote_hostname ( s - > username ) ;
wait_for_remote_xserver ( remote_server , display ) ;
free ( remote_server ) ;
chansrv_pid = session_start_chansrv ( s - > username , display ) ;
log_message ( LOG_LEVEL_ALWAYS , " waiting for window manager "
" (pid %d) to exit " , window_manager_pid ) ;