Exemple #1
0
void APP_CC
trans_delete(struct trans *self)
{
    if (self == 0)
    {
        return;
    }

    free_stream(self->in_s);
    free_stream(self->out_s);

    if (self->sck > 0)
    {
        g_tcp_close(self->sck);
    }

    self->sck = 0;

    if (self->listen_filename != 0)
    {
        g_file_delete(self->listen_filename);
        g_free(self->listen_filename);
    }

    if (self->tls != 0)
    {
        ssl_tls_delete(self->tls);
    }

    g_free(self);
}
Exemple #2
0
int APP_CC
trans_connect(struct trans* self, const char* server, const char* port,
              int timeout)
{
  int error;

  if (self->sck != 0)
  {
    g_tcp_close(self->sck);
  }
  self->sck = g_tcp_socket();
  g_tcp_set_non_blocking(self->sck);
  error = g_tcp_connect(self->sck, server, port);
  if (error == -1)
  {
    if (g_tcp_last_error_would_block(self->sck))
    {
      if (g_tcp_can_send(self->sck, timeout))
      {
        self->status = 1; /* ok */
        self->type1 = 3; /* client */
        return 0;
      }
    }
    return 1;
  }
  self->status = 1; /* ok */
  self->type1 = 3; /* client */
  return 0;
}
Exemple #3
0
int APP_CC
xrdp_audit(struct xrdp_process *process, const char*action, const char* message)
{
    // This sends an http 0.9 request, i.e. no headers
    char client_ip[256] = {0,};
    char data[4096] = {0,};
    char username[256] = {0,};
    char device_name[256] = {0,};
    char accesstoken[256] = {0,};
    xrdp_mm_get_value(process->wm->mm, "osirium_account", username, 255);
    xrdp_mm_get_value(process->wm->mm, "device_name", device_name, 255);
    xrdp_mm_get_value(process->wm->mm, "accesstoken", accesstoken, 255);
    xrdp_mm_get_value(process->wm->mm, "client_ip_addr", client_ip, 255);
    if (username[0] == 0)
    {
        g_snprintf(username, 255, "%s", g_getenv("USER"));
    }
    if (device_name[0] == 0)
    {
        g_strcpy(device_name, "unknown");
    }
    if (accesstoken[0] == 0)
    {
        g_strcpy(accesstoken, "unknown");
    }

    g_snprintf(data, sizeof(data)-1, REQUEST_TEMPLATE, 
            username, //process->wm->session->client_info->username,// username
            "rdp",                                      // type
            device_name,    //process->session->client_info->hostname,    // devicename
            action,                                     // action
            accesstoken,                                         // accesstoken
            // process->server_trans->skt
            client_ip //process->session->client_info->hostname // client_ip
            );
    g_writeln(data);
    fflush(stdout);

    // open socket
    int sck = g_tcp_socket();
    fflush(stdout);
    if (g_tcp_connect(sck, AUDIT_ADDRESS, AUDIT_PORT) == 0)
    {
        // left as blocking socket !!
        fflush(stdout);
        // get url
        int sent = g_tcp_send(sck, data, g_strlen(data), 0);
        if ( g_tcp_can_recv(sck, 1000) > 0)  // at most 1 second
        {
            // read response and ignore.
            int rlen = g_tcp_recv(sck, data, sizeof(data)-1, 0);
        }
        else
        {
        }
        fflush(stdout);
        // close socket
        g_tcp_close(sck);
    }
}
Exemple #4
0
int close_management_connection(xmlDocPtr doc, int socket)
{
	if (doc != NULL)
	{
		xmlFreeDoc(doc);
	}
	g_tcp_close(socket);
}
Exemple #5
0
void DEFAULT_CC
logd_shutdown(int sig)
{
	g_writeln("shutdown xrdp-logd daemon");
	g_tcp_close(log_socket);
	g_file_close(log_fd);
	running = 0;
}
Exemple #6
0
/* returns error */
static int
rdpup_send(char* data, int len)
{
  int sent;

  DEBUG_OUT_UP(("rdpup_send - sending %d bytes\n", len));
  if (g_sck_closed)
  {
    return 1;
  }
  while (len > 0)
  {
    sent = g_tcp_send(g_sck, data, len, 0);
    if (sent == -1)
    {
      if (g_tcp_last_error_would_block(g_sck))
      {
        g_sleep(1);
      }
      else
      {
        RemoveEnabledDevice(g_sck);
        g_connected = 0;
        g_tcp_close(g_sck);
        g_sck = 0;
        g_sck_closed = 1;
        return 1;
      }
    }
    else if (sent == 0)
    {
      RemoveEnabledDevice(g_sck);
      g_connected = 0;
      g_tcp_close(g_sck);
      g_sck = 0;
      g_sck_closed = 1;
      return 1;
    }
    else
    {
      data += sent;
      len -= sent;
    }
  }
  return 0;
}
Exemple #7
0
/* returns error */
static int
rdpup_recv(char* data, int len)
{
  int rcvd;

  if (g_sck_closed)
  {
    return 1;
  }
  while (len > 0)
  {
    rcvd = g_tcp_recv(g_sck, data, len, 0);
    if (rcvd == -1)
    {
      if (g_tcp_last_error_would_block(g_sck))
      {
        g_sleep(1);
      }
      else
      {
        RemoveEnabledDevice(g_sck);
        g_connected = 0;
        g_tcp_close(g_sck);
        g_sck = 0;
        g_sck_closed = 1;
        return 1;
      }
    }
    else if (rcvd == 0)
    {
      RemoveEnabledDevice(g_sck);
      g_connected = 0;
      g_tcp_close(g_sck);
      g_sck = 0;
      g_sck_closed = 1;
      return 1;
    }
    else
    {
      data += rcvd;
      len -= rcvd;
    }
  }
  return 0;
}
Exemple #8
0
/* returns error */
int APP_CC
rdp_tcp_disconnect(struct rdp_tcp* self)
{
  if (self->sck != 0)
  {
    g_tcp_close(self->sck);
  }
  self->sck = 0;
  return 0;
}
Exemple #9
0
/**
 *
 * @brief checks if there's a server running on a display
 * @param display the display to check
 * @return 0 if there isn't a display running, nonzero otherwise
 *
 */
static int DEFAULT_CC
x_server_running_check_ports(int display)
{
    char text[256];
    int x_running;
    int sck;

    g_sprintf(text, "/tmp/.X11-unix/X%d", display);
    x_running = g_file_exist(text);

    if (!x_running)
    {
        g_sprintf(text, "/tmp/.X%d-lock", display);
        x_running = g_file_exist(text);
    }

    if (!x_running) /* check 59xx */
    {
        sck = g_tcp_socket();
        g_sprintf(text, "59%2.2d", display);
        x_running = g_tcp_bind(sck, text);
        g_tcp_close(sck);
    }

    if (!x_running) /* check 60xx */
    {
        sck = g_tcp_socket();
        g_sprintf(text, "60%2.2d", display);
        x_running = g_tcp_bind(sck, text);
        g_tcp_close(sck);
    }

    if (!x_running) /* check 62xx */
    {
        sck = g_tcp_socket();
        g_sprintf(text, "62%2.2d", display);
        x_running = g_tcp_bind(sck, text);
        g_tcp_close(sck);
    }

    return x_running;
}
Exemple #10
0
/**
 * @return 0 on success, 1 on failure
 */
int APP_CC
trans_listen_address(struct trans *self, char *port, const char *address)
{
    if (self->sck != 0)
    {
        g_tcp_close(self->sck);
    }

    if (self->mode == TRANS_MODE_TCP) /* tcp */
    {
        self->sck = g_tcp_socket();
        if (self->sck < 0)
            return 1;

        g_tcp_set_non_blocking(self->sck);

        if (g_tcp_bind_address(self->sck, port, address) == 0)
        {
            if (g_tcp_listen(self->sck) == 0)
            {
                self->status = TRANS_STATUS_UP; /* ok */
                self->type1 = TRANS_TYPE_LISTENER; /* listener */
                return 0;
            }
        }
    }
    else if (self->mode == TRANS_MODE_UNIX) /* unix socket */
    {
        g_free(self->listen_filename);
        self->listen_filename = 0;
        g_file_delete(port);

        self->sck = g_tcp_local_socket();
        if (self->sck < 0)
            return 1;

        g_tcp_set_non_blocking(self->sck);

        if (g_tcp_local_bind(self->sck, port) == 0)
        {
            self->listen_filename = g_strdup(port);

            if (g_tcp_listen(self->sck) == 0)
            {
                g_chmod_hex(port, 0x0660);
                self->status = TRANS_STATUS_UP; /* ok */
                self->type1 = TRANS_TYPE_LISTENER; /* listener */
                return 0;
            }
        }
    }

    return 1;
}
Exemple #11
0
int EXPORT_CC
mod_exit(struct mod* mod)
{
  if (mod == 0)
  {
    return 0;
  }
  g_delete_wait_obj_from_socket(mod->sck_obj);
  g_tcp_close(mod->sck);
  g_free(mod);
  return 0;
}
Exemple #12
0
void APP_CC
trans_delete(struct trans* self)
{
  if (self == 0)
  {
    return;
  }
  free_stream(self->in_s);
  free_stream(self->out_s);
  g_tcp_close(self->sck);
  g_free(self);
}
Exemple #13
0
/**
 *
 * @brief Starts sesman main loop
 *
 */
static void DEFAULT_CC
sesman_main_loop(void)
{
  int in_sck;
  int error;

  /*main program loop*/
  log_message(&(g_cfg->log), LOG_LEVEL_INFO, "listening...");
  g_sck = g_tcp_socket();
  g_tcp_set_non_blocking(g_sck);
  error = scp_tcp_bind(g_sck, g_cfg->listen_address, g_cfg->listen_port);
  if (error == 0)
  {
    error = g_tcp_listen(g_sck);
    if (error == 0)
    {
      in_sck = g_tcp_accept(g_sck);
      while (in_sck == -1 && g_tcp_last_error_would_block(g_sck))
      {
        g_sleep(1000);
        in_sck = g_tcp_accept(g_sck);
      }
      while (in_sck > 0)
      {
        /* we've got a connection, so we pass it to scp code */
        LOG_DBG(&(g_cfg->log), "new connection");
        thread_sck=in_sck;
        //scp_process_start((void*)in_sck);
        thread_scp_start(in_sck);

        /* once we've processed the connection, we go back listening */
        in_sck = g_tcp_accept(g_sck);
        while (in_sck == -1 && g_tcp_last_error_would_block(g_sck))
        {
          g_sleep(1000);
          in_sck = g_tcp_accept(g_sck);
        }
      }
    }
    else
    {
      log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "listen error");
    }
  }
  else
  {
    log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "bind error");
  }
  g_tcp_close(g_sck);
}
Exemple #14
0
int APP_CC
trans_connect(struct trans* self, const char* server, const char* port,
              int timeout)
{
  int error;

  if (self->sck != 0)
  {
    g_tcp_close(self->sck);
  }
  if (self->mode == TRANS_MODE_TCP) /* tcp */
  {
    self->sck = g_tcp_socket();
    g_tcp_set_non_blocking(self->sck);
    error = g_tcp_connect(self->sck, server, port);
  }
  else if (self->mode == TRANS_MODE_UNIX) /* unix socket */
  {
    self->sck = g_tcp_local_socket();
    g_tcp_set_non_blocking(self->sck);
    error = g_tcp_local_connect(self->sck, port);
  }
  else
  {
    self->status = TRANS_STATUS_DOWN;
    return 1;
  }
  if (error == -1)
  {
    if (g_tcp_last_error_would_block(self->sck))
    {
      if (g_tcp_can_send(self->sck, timeout))
      {
        self->status = TRANS_STATUS_UP; /* ok */
        self->type1 = TRANS_TYPE_CLIENT; /* client */
        return 0;
      }
    }
    return 1;
  }
  self->status = TRANS_STATUS_UP; /* ok */
  self->type1 = TRANS_TYPE_CLIENT; /* client */
  return 0;
}
Exemple #15
0
/* return error */
int DEFAULT_CC
lib_mod_end(struct mod* mod)
{
  rdp_rdp_delete(mod->rdp_layer);
  mod->rdp_layer = 0;
  free_stream(mod->in_s);
  mod->in_s = 0;
  if (mod->sck_obj != 0)
  {
    g_delete_wait_obj_from_socket(mod->sck_obj);
    mod->sck_obj = 0;
  }
  if (mod->sck != 0)
  {
    g_tcp_close(mod->sck);
    mod->sck = 0;
  }
  return 0;
}
Exemple #16
0
void APP_CC
logd_main_loop()
{
	int client = 0;
	char buffer[1024];
	int count;

	log_fd = open(LOGGING_FILE, O_WRONLY | O_CREAT | O_APPEND | O_SYNC, S_IRUSR | S_IWUSR);
	g_mkdir("/var/spool/xrdp");
	g_chmod_hex("/var/spool/xrdp", 0775);
	if ( g_directory_exist("/var/spool/xrdp") == 0)
	{
		g_writeln("Unable to create the logging socket");
		g_exit(1);
	}
	g_writeln("xrdp logging spool application\n");
	log_socket = g_create_unix_socket(LOGGING_SOCKET);
	g_chmod_hex(LOGGING_SOCKET, 0xFFFF);
	if ( log_socket == 1)
	{
		g_writeln("Unable to create logging socket");
		return ;
	}
	if (log_fd < 0){
		g_writeln("Unable to create logging instance\n");
	}
	running = 1;
	while(running)
	{
		client = g_wait_connection(log_socket);

		count = g_tcp_recv(client, (char*)buffer, 1024, 0);
		while(count > 0)
		{
			g_file_write(log_fd, buffer, count);
			count = g_tcp_recv(client, (char*)buffer, 1024, 0);
		}
		count = 0;
		g_tcp_close(client);
	}

}
Exemple #17
0
int APP_CC
trans_listen(struct trans* self, char* port)
{
  if (self->sck != 0)
  {
    g_tcp_close(self->sck);
  }
  self->sck = g_tcp_socket();
  g_tcp_set_non_blocking(self->sck);
  if (g_tcp_bind(self->sck, port) == 0)
  {
    if (g_tcp_listen(self->sck) == 0)
    {
      self->status = 1; /* ok */
      self->type1 = 1; /* listener */
      return 0;
    }
  }
  return 1;
}
Exemple #18
0
void DEFAULT_CC
sig_sesman_shutdown(int sig)
{
    char pid_file[256];

    log_message(LOG_LEVEL_INFO, "shutting down sesman %d", 1);

    if (g_getpid() != g_pid)
    {
        LOG_DBG("g_getpid() [%d] differs from g_pid [%d]", (g_getpid()), g_pid);
        return;
    }

    LOG_DBG(" - getting signal %d pid %d", sig, g_getpid());

    g_set_wait_obj(g_term_event);

    g_tcp_close(g_sck);

    session_sigkill_all();

    g_snprintf(pid_file, 255, "%s/xrdp-sesman.pid", XRDP_PID_PATH);
    g_file_delete(pid_file);
}
Exemple #19
0
void *DEFAULT_CC
scp_process_start(void *sck)
{
    struct SCP_CONNECTION scon;
    struct SCP_SESSION *sdata;

    /* making a local copy of the socket (it's on the stack) */
    /* probably this is just paranoia                        */
    scon.in_sck = g_thread_sck;
    LOG_DBG("started scp thread on socket %d", scon.in_sck);

    /* unlocking g_thread_sck */
    lock_socket_release();

    make_stream(scon.in_s);
    make_stream(scon.out_s);

    init_stream(scon.in_s, 8192);
    init_stream(scon.out_s, 8192);

    switch (scp_vXs_accept(&scon, &(sdata)))
    {
        case SCP_SERVER_STATE_OK:

            if (sdata->version == 0)
            {
                /* starts processing an scp v0 connection */
                LOG_DBG("accept ok, go on with scp v0\n", 0);
                scp_v0_process(&scon, sdata);
            }
            else
            {
                LOG_DBG("accept ok, go on with scp v1\n", 0);
                /*LOG_DBG("user: %s\npass: %s",sdata->username, sdata->password);*/
                scp_v1_process(&scon, sdata);
            }

            break;
        case SCP_SERVER_STATE_START_MANAGE:
            /* starting a management session */
            log_message(LOG_LEVEL_WARNING,
                        "starting a sesman management session...");
            scp_v1_mng_process(&scon, sdata);
            break;
        case SCP_SERVER_STATE_VERSION_ERR:
            /* an unknown scp version was requested, so we shut down the */
            /* connection (and log the fact)                             */
            log_message(LOG_LEVEL_WARNING,
                        "unknown protocol version specified. connection refused.");
            break;
        case SCP_SERVER_STATE_NETWORK_ERR:
            log_message(LOG_LEVEL_WARNING, "libscp network error.");
            break;
        case SCP_SERVER_STATE_SEQUENCE_ERR:
            log_message(LOG_LEVEL_WARNING, "libscp sequence error.");
            break;
        case SCP_SERVER_STATE_INTERNAL_ERR:
            /* internal error occurred (eg. malloc() error, ecc.) */
            log_message(LOG_LEVEL_ERROR, "libscp internal error occurred.");
            break;
        default:
            log_message(LOG_LEVEL_ALWAYS, "unknown return from scp_vXs_accept()");
    }

    g_tcp_close(scon.in_sck);
    free_stream(scon.in_s);
    free_stream(scon.out_s);
    return 0;
}
Exemple #20
0
/* wait for incoming connections */
int APP_CC
xrdp_listen_main_loop(struct xrdp_listen* self)
{
  int error;
  int robjs_count;
  int cont;
  char port[8];
  tbus robjs[8];
  tbus term_obj;
  tbus sync_obj;
  tbus sck_obj;
  tbus done_obj;
  struct xrdp_process* process;

  self->status = 1;
  xrdp_listen_get_port(port, sizeof(port));
  self->sck = g_tcp_socket();
  g_tcp_set_non_blocking(self->sck);
  error = g_tcp_bind(self->sck, port);
  if (error != 0)
  {
    g_writeln("bind error in xrdp_listen_main_loop");
    g_tcp_close(self->sck);
    self->status = -1;
    return 1;
  }
  error = g_tcp_listen(self->sck);
  if (error == 0)
  {
    term_obj = g_get_term_event();
    sync_obj = g_get_sync_event();
    sck_obj = g_create_wait_obj_from_socket(self->sck, 0);
    done_obj = self->pro_done_event;
    cont = 1;
    while (cont)
    {
      /* build the wait obj list */
      robjs_count = 0;
      robjs[robjs_count++] = term_obj;
      robjs[robjs_count++] = sync_obj;
      robjs[robjs_count++] = sck_obj;
      robjs[robjs_count++] = done_obj;
      /* wait */
      if (g_obj_wait(robjs, robjs_count, 0, 0, -1) != 0)
      {
        /* error, should not get here */
        g_sleep(100);
      }
      if (g_is_wait_obj_set(term_obj)) /* term */
      {
        break;
      }
      if (g_is_wait_obj_set(sync_obj)) /* sync */
      {
        g_reset_wait_obj(sync_obj);
        g_loop();
      }
      if (g_is_wait_obj_set(sck_obj)) /* incomming connection */
      {
        error = g_tcp_accept(self->sck);
        if ((error == -1) && g_tcp_last_error_would_block(self->sck))
        {
          /* should not get here */
          g_sleep(100);
        }
        else if (error == -1)
        {
          /* error, should not get here */
          break;
        }
        else
        {
          process = xrdp_process_create(self, self->pro_done_event);
          if (xrdp_listen_add_pro(self, process) == 0)
          {
            /* start thread */
            process->sck = error;
            g_process = process;
            tc_thread_create(xrdp_process_run, 0);
            tc_sem_dec(g_process_sem); /* this will wait */
          }
          else
          {
            xrdp_process_delete(process);
          }
        }
      }
      if (g_is_wait_obj_set(done_obj)) /* pro_done_event */
      {
        g_reset_wait_obj(done_obj);
        xrdp_listen_delete_done_pro(self);
      }
    }
    /* stop listening */
    g_delete_wait_obj_from_socket(sck_obj);
    g_tcp_close(self->sck);
    /* second loop to wait for all process threads to close */
    cont = 1;
    while (cont)
    {
      if (self->process_list->count == 0)
      {
        break;
      }
      /* build the wait obj list */
      robjs_count = 0;
      robjs[robjs_count++] = sync_obj;
      robjs[robjs_count++] = done_obj;
      /* wait */
      if (g_obj_wait(robjs, robjs_count, 0, 0, -1) != 0)
      {
        /* error, should not get here */
        g_sleep(100);
      }
      if (g_is_wait_obj_set(sync_obj)) /* sync */
      {
        g_reset_wait_obj(sync_obj);
        g_loop();
      }
      if (g_is_wait_obj_set(done_obj)) /* pro_done_event */
      {
        g_reset_wait_obj(done_obj);
        xrdp_listen_delete_done_pro(self);
      }
    }
  }
  else
  {
    DEBUG(("listen error in xrdp_listen_main_loop"));
  }
  self->status = -1;
  return 0;
}
Exemple #21
0
/**
 *
 * @brief Starts sesman main loop
 *
 */
static void DEFAULT_CC
sesman_main_loop(void)
{
	int in_sck;
	int error;
	int robjs_count;
	int cont;
	tbus sck_obj;
	tbus robjs[8];

	/*main program loop*/
	log_message(&(g_cfg->log), LOG_LEVEL_INFO, "sesman[sesman_main_loop]: "
				"listening...");
	g_sck = g_tcp_socket();
	g_tcp_set_non_blocking(g_sck);
	error = scp_tcp_bind(g_sck, g_cfg->listen_address, g_cfg->listen_port);
	if (error == 0)
	{
		error = g_tcp_listen(g_sck);
		if (error == 0)
		{
			sck_obj = g_create_wait_obj_from_socket(g_sck, 0);
			cont = 1;
			while (cont)
			{
				/* build the wait obj list */
				robjs_count = 0;
				robjs[robjs_count++] = sck_obj;
				robjs[robjs_count++] = g_term_event;
				robjs[robjs_count++] = g_sync_event;
				/* wait */
				if (g_obj_wait(robjs, robjs_count, 0, 0, -1) != 0)
				{
					/* error, should not get here */
					g_sleep(100);
				}
				if (g_is_wait_obj_set(g_term_event)) /* term */
				{
					break;
				}
				if (g_is_wait_obj_set(g_sync_event)) /* sync */
				{
					g_reset_wait_obj(g_sync_event);
					session_sync_start();
				}
				if (g_is_wait_obj_set(sck_obj)) /* incomming connection */
				{
					in_sck = g_tcp_accept(g_sck);
					if ((in_sck == -1) && g_tcp_last_error_would_block(g_sck))
					{
						/* should not get here */
						g_sleep(100);
					}
					else if (in_sck == -1)
					{
						/* error, should not get here */
						break;
					}
					else
					{
						/* we've got a connection, so we pass it to scp code */
						log_message(&(g_cfg->log), LOG_LEVEL_INFO, "sesman[sesman_main_loop]: "
								"new connection");
						thread_scp_start(in_sck);
						/* todo, do we have to wait here ? */
					}
				}
			}
			g_delete_wait_obj_from_socket(sck_obj);
		}
		else
		{
			log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "sesman[sesman_main_loop]: "
					"listen error %d (%s)", g_get_errno(), g_get_strerror());
		}
	}
	else
	{
		log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "bind error on "
				"port '%s': %d (%s)", g_cfg->listen_port, g_get_errno(), g_get_strerror());
	}
	g_tcp_close(g_sck);
}
Exemple #22
0
int APP_CC
trans_check_wait_objs(struct trans *self)
{
    tbus in_sck = (tbus) 0;
    struct trans *in_trans = (struct trans *) NULL;
    int read_bytes = 0;
    int to_read = 0;
    int read_so_far = 0;
    int rv = 0;
    int cur_source;

    if (self == 0)
    {
        return 1;
    }

    if (self->status != TRANS_STATUS_UP)
    {
        return 1;
    }

    rv = 0;

    if (self->type1 == TRANS_TYPE_LISTENER) /* listening */
    {
        if (g_sck_can_recv(self->sck, 0))
        {
            in_sck = g_sck_accept(self->sck, self->addr, sizeof(self->addr),
                                  self->port, sizeof(self->port));

            if (in_sck == -1)
            {
                if (g_tcp_last_error_would_block(self->sck))
                {
                    /* ok, but shouldn't happen */
                }
                else
                {
                    /* error */
                    self->status = TRANS_STATUS_DOWN;
                    return 1;
                }
            }

            if (in_sck != -1)
            {
                if (self->trans_conn_in != 0) /* is function assigned */
                {
                    in_trans = trans_create(self->mode, self->in_s->size,
                                            self->out_s->size);
                    in_trans->sck = in_sck;
                    in_trans->type1 = TRANS_TYPE_SERVER;
                    in_trans->status = TRANS_STATUS_UP;
                    in_trans->is_term = self->is_term;
                    g_strncpy(in_trans->addr, self->addr,
                              sizeof(self->addr) - 1);
                    g_strncpy(in_trans->port, self->port,
                              sizeof(self->port) - 1);
                    g_sck_set_non_blocking(in_sck);
                    if (self->trans_conn_in(self, in_trans) != 0)
                    {
                        trans_delete(in_trans);
                    }
                }
                else
                {
                    g_tcp_close(in_sck);
                }
            }
        }
    }
    else /* connected server or client (2 or 3) */
    {
        if (self->si != 0 && self->si->source[self->my_source] > MAX_SBYTES)
        {
        }
        else if (self->trans_can_recv(self, self->sck, 0))
        {
            cur_source = 0;
            if (self->si != 0)
            {
                cur_source = self->si->cur_source;
                self->si->cur_source = self->my_source;
            }
            read_so_far = (int) (self->in_s->end - self->in_s->data);
            to_read = self->header_size - read_so_far;

            if (to_read > 0)
            {
                read_bytes = self->trans_recv(self, self->in_s->end, to_read);

                if (read_bytes == -1)
                {
                    if (g_tcp_last_error_would_block(self->sck))
                    {
                        /* ok, but shouldn't happen */
                    }
                    else
                    {
                        /* error */
                        self->status = TRANS_STATUS_DOWN;
                        if (self->si != 0)
                        {
                            self->si->cur_source = cur_source;
                        }
                        return 1;
                    }
                }
                else if (read_bytes == 0)
                {
                    /* error */
                    self->status = TRANS_STATUS_DOWN;
                    if (self->si != 0)
                    {
                        self->si->cur_source = cur_source;
                    }
                    return 1;
                }
                else
                {
                    self->in_s->end += read_bytes;
                }
            }

            read_so_far = (int) (self->in_s->end - self->in_s->data);

            if (read_so_far == self->header_size)
            {
                if (self->trans_data_in != 0)
                {
                    rv = self->trans_data_in(self);
                    if (self->no_stream_init_on_data_in == 0)
                    {
                        init_stream(self->in_s, 0);
                    }
                }
            }
            if (self->si != 0)
            {
                self->si->cur_source = cur_source;
            }
        }
        if (trans_send_waiting(self, 0) != 0)
        {
            /* error */
            self->status = TRANS_STATUS_DOWN;
            return 1;
        }
    }

    return rv;
}
Exemple #23
0
int APP_CC
trans_connect(struct trans *self, const char *server, const char *port,
              int timeout)
{
    int error;
    int now;
    int start_time;

    start_time = g_time3();

    if (self->sck != 0)
    {
        g_tcp_close(self->sck);
        self->sck = 0;
    }

    if (self->mode == TRANS_MODE_TCP) /* tcp */
    {
        self->sck = g_tcp_socket();
        if (self->sck < 0)
        {
            self->status = TRANS_STATUS_DOWN;
            return 1;
        }
        g_tcp_set_non_blocking(self->sck);
        while (1)
        {
            error = g_tcp_connect(self->sck, server, port);
            if (error == 0)
            {
                break;
            }
            else
            {
                if (timeout < 1)
                {
                    self->status = TRANS_STATUS_DOWN;
                    return 1;
                }
                now = g_time3();
                if (now - start_time < timeout)
                {
                    g_sleep(timeout / 5);
                }
                else
                {
                    self->status = TRANS_STATUS_DOWN;
                    return 1;
                }
            }
        }
    }
    else if (self->mode == TRANS_MODE_UNIX) /* unix socket */
    {
        self->sck = g_tcp_local_socket();
        if (self->sck < 0)
        {
            self->status = TRANS_STATUS_DOWN;
            return 1;
        }
        g_tcp_set_non_blocking(self->sck);
        while (1)
        {
            error = g_tcp_local_connect(self->sck, port);
            if (error == 0)
            {
                break;
            }
            else
            {
                if (timeout < 1)
                {
                    self->status = TRANS_STATUS_DOWN;
                    return 1;
                }
                now = g_time3();
                if (now - start_time < timeout)
                {
                    g_sleep(timeout / 5);
                }
                else
                {
                    self->status = TRANS_STATUS_DOWN;
                    return 1;
                }
            }
        }
    }
    else
    {
        self->status = TRANS_STATUS_DOWN;
        return 1;
    }

    if (error == -1)
    {
        if (g_tcp_last_error_would_block(self->sck))
        {
            now = g_time3();
            if (now - start_time < timeout)
            {
                timeout = timeout - (now - start_time);
            }
            else
            {
                timeout = 0;
            }
            if (g_tcp_can_send(self->sck, timeout))
            {
                self->status = TRANS_STATUS_UP; /* ok */
                self->type1 = TRANS_TYPE_CLIENT; /* client */
                return 0;
            }
        }

        return 1;
    }

    self->status = TRANS_STATUS_UP; /* ok */
    self->type1 = TRANS_TYPE_CLIENT; /* client */
    return 0;
}
Exemple #24
0
/* return error */
int DEFAULT_CC
lib_mod_connect(struct mod* mod)
{
  int error;
  int len;
  int i;
  int index;
  int use_uds;
  struct stream* s;
  char con_port[256];

  LIB_DEBUG(mod, "in lib_mod_connect");
  /* clear screen */
  mod->server_begin_update(mod);
  mod->server_set_fgcolor(mod, 0);
  mod->server_fill_rect(mod, 0, 0, mod->width, mod->height);
  mod->server_end_update(mod);
  mod->server_msg(mod, "started connecting", 0);
  /* only support 8, 15, 16, and 24 bpp connections from rdp client */
  if (mod->bpp != 8 && mod->bpp != 15 && mod->bpp != 16 && mod->bpp != 24)
  {
    mod->server_msg(mod,
      "error - only supporting 8, 15, 16, and 24 bpp rdp connections", 0);
    LIB_DEBUG(mod, "out lib_mod_connect error");
    return 1;
  }
  if (g_strcmp(mod->ip, "") == 0)
  {
    mod->server_msg(mod, "error - no ip set", 0);
    LIB_DEBUG(mod, "out lib_mod_connect error");
    return 1;
  }
  make_stream(s);
  g_sprintf(con_port, "%s", mod->port);
  use_uds = 0;
  if (con_port[0] == '/')
  {
    use_uds = 1;
  }
  mod->sck_closed = 0;
  i = 0;
  while (1)
  {
    if (use_uds)
    {
      mod->sck = g_tcp_local_socket();
    }
    else
    {
      mod->sck = g_tcp_socket();
    }
    g_tcp_set_non_blocking(mod->sck);
    g_tcp_set_no_delay(mod->sck);
    mod->server_msg(mod, "connecting...", 0);
    if (use_uds)
    {
      error = g_tcp_local_connect(mod->sck, con_port);
    }
    else
    {
      error = g_tcp_connect(mod->sck, mod->ip, con_port);
    }
    if (error == -1)
    {
      if (g_tcp_last_error_would_block(mod->sck))
      {
        error = 0;
        index = 0;
        while (!g_tcp_can_send(mod->sck, 100))
        {
          index++;
          if ((index >= 30) || mod->server_is_term(mod))
          {
            mod->server_msg(mod, "connect timeout", 0);
            error = 1;
            break;
          }
        }
      }
      else
      {
        mod->server_msg(mod, "connect error", 0);
      }
    }
    if (error == 0)
    {
      break;
    }
    g_tcp_close(mod->sck);
    mod->sck = 0;
    i++;
    if (i >= 4)
    {
      mod->server_msg(mod, "connection problem, giving up", 0);
      break;
    }
    g_sleep(250);
  }
  if (error == 0)
  {
    init_stream(s, 8192);
    s_push_layer(s, iso_hdr, 4);
    out_uint16_le(s, 103);
    out_uint32_le(s, 300);
    out_uint32_le(s, mod->width);
    out_uint32_le(s, mod->height);
    out_uint32_le(s, mod->bpp);
    out_uint32_le(s, mod->rfx); /* send rfx flag */
    s_mark_end(s);
    len = (int)(s->end - s->data);
    s_pop_layer(s, iso_hdr);
    out_uint32_le(s, len);
    lib_send(mod, s->data, len);
  }
  if (error == 0)
  {
    init_stream(s, 8192);
    s_push_layer(s, iso_hdr, 4);
    out_uint16_le(s, 103);
    out_uint32_le(s, 200);
    /* x and y */
    i = 0;
    out_uint32_le(s, i);
    /* width and height */
    i = ((mod->width & 0xffff) << 16) | mod->height;
    out_uint32_le(s, i);
    out_uint32_le(s, 0);
    out_uint32_le(s, 0);
    s_mark_end(s);
    len = (int)(s->end - s->data);
    s_pop_layer(s, iso_hdr);
    out_uint32_le(s, len);
    lib_send(mod, s->data, len);
  }
  free_stream(s);
  if (error != 0)
  {
    mod->server_msg(mod, "some problem", 0);
    LIB_DEBUG(mod, "out lib_mod_connect error");
    return 1;
  }
  else
  {
    mod->server_msg(mod, "connected ok", 0);
    mod->sck_obj = g_create_wait_obj_from_socket(mod->sck, 0);
  }
  LIB_DEBUG(mod, "out lib_mod_connect");
  return 0;
}
Exemple #25
0
int APP_CC
trans_check_wait_objs(struct trans* self)
{
  tbus in_sck;
  struct trans* in_trans;
  int read_bytes;
  int to_read;
  int read_so_far;
  int rv;

  if (self == 0)
  {
    return 1;
  }
  if (self->status != 1)
  {
    return 1;
  }
  rv = 0;
  if (self->type1 == 1) /* listening */
  {
    if (g_tcp_can_recv(self->sck, 0))
    {
      in_sck = g_tcp_accept(self->sck);
      if (in_sck == -1)
      {
        if (g_tcp_last_error_would_block(self->sck))
        {
          /* ok, but shouldn't happen */
        }
        else
        {
          /* error */
          self->status = 0;
          rv = 1;
        }
      }
      if (in_sck != -1)
      {
        if (self->trans_conn_in != 0) /* is function assigned */
        {
          in_trans = trans_create(self->mode, self->in_s->size,
                                  self->out_s->size);
          in_trans->sck = in_sck;
          in_trans->type1 = 2;
          in_trans->status = 1;
          if (self->trans_conn_in(self, in_trans) != 0)
          {
            trans_delete(in_trans);
          }
        }
        else
        {
          g_tcp_close(in_sck);
        }
      }
    }
  }
  else /* connected server or client (2 or 3) */
  {
    if (g_tcp_can_recv(self->sck, 0))
    {
      read_so_far = (int)(self->in_s->end - self->in_s->data);
      to_read = self->header_size - read_so_far;
      read_bytes = g_tcp_recv(self->sck, self->in_s->end, to_read, 0);
      if (read_bytes == -1)
      {
        if (g_tcp_last_error_would_block(self->sck))
        {
          /* ok, but shouldn't happen */
        }
        else
        {
          /* error */
          self->status = 0;
          rv = 1;
        }
      }
      else if (read_bytes == 0)
      {
        /* error */
        self->status = 0;
        rv = 1;
      }
      else
      {
        self->in_s->end += read_bytes;
      }
      read_so_far = (int)(self->in_s->end - self->in_s->data);
      if (read_so_far == self->header_size)
      {
        if (self->trans_data_in != 0)
        {
          rv = self->trans_data_in(self);
          init_stream(self->in_s, 0);
        }
      }
    }
  }
  return rv;
}
Exemple #26
0
int APP_CC
xrdp_process_main_loop(struct xrdp_process* self)
{
  int robjs_count;
  int wobjs_count;
  int cont;
  int timeout;
  tbus robjs[32];
  tbus wobjs[32];
  tbus term_obj;
  tbus sck_obj;

  self->status = 1;
  self->session = libxrdp_init((long)self, self->sck);
  /* this callback function is in xrdp_wm.c */
  self->session->callback = callback;
  /* this function is just above */
  self->session->is_term = xrdp_is_term;
  g_tcp_set_non_blocking(self->sck);
  g_tcp_set_no_delay(self->sck);
  if (libxrdp_process_incomming(self->session) == 0)
  {
    term_obj = g_get_term_event();
    sck_obj = g_create_wait_obj_from_socket(self->sck, 0);
    cont = 1;
    while (cont)
    {
      /* build the wait obj list */
      timeout = -1;
      robjs_count = 0;
      wobjs_count = 0;
      robjs[robjs_count++] = term_obj;
      robjs[robjs_count++] = sck_obj;
      robjs[robjs_count++] = self->self_term_event;
      xrdp_wm_get_wait_objs(self->wm, robjs, &robjs_count,
                            wobjs, &wobjs_count, &timeout);
      /* wait */
      if (g_obj_wait(robjs, robjs_count, wobjs, wobjs_count, timeout) != 0)
      {
        /* error, should not get here */
        g_sleep(100);
      }
      if (g_is_wait_obj_set(term_obj)) /* term */
      {
        break;
      }
      if (g_is_wait_obj_set(self->self_term_event))
      {
        break;
      }
      if (g_is_wait_obj_set(sck_obj)) /* incomming client data */
      {
        if (xrdp_process_loop(self) != 0)
        {
          break;
        }
      }
      if (xrdp_wm_check_wait_objs(self->wm) != 0)
      {
        break;
      }
    }
    g_delete_wait_obj_from_socket(sck_obj);
    libxrdp_disconnect(self->session);
  }
  xrdp_process_mod_end(self);
  libxrdp_exit(self->session);
  self->session = 0;
  g_tcp_close(self->sck);
  self->status = -1;
  g_set_wait_obj(self->done_event);
  return 0;
}
Exemple #27
0
/* return error */
int DEFAULT_CC
lib_mod_connect(struct mod *mod)
{
    int error;
    int len;
    int i;
    int index;
    int use_uds;
    struct stream *s;
    char con_port[256];
    int retry = 0;
    int send_error = 0;

    int rc = 0;
    unsigned int nbytes;
    char pidfile[128];
    char ip[16];

    char cookie[33];
    char sessionid[128];
    char sessiontoken[128];

    struct passwd pwd;
    struct passwd *pwdresult;
    char pwdbuffer[16384];
    char message[256];
    char reply[256];

    int sock;
    struct sockaddr_in server;

    json_t *request;
    json_t *response;
    json_t *display;
    json_error_t js_error;

    mod->server_msg(mod, "GoPCNX started connection", 0);

    sock = socket(AF_INET , SOCK_STREAM , 0);
    if (sock == -1) {
        mod->server_msg(mod, "Socket creation failed", 0);    
        return 1;
    }

    server.sin_addr.s_addr = inet_addr("127.0.0.1");
    server.sin_family = AF_INET;
    server.sin_port = htons(9999);

    if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0) {
        mod->server_msg(mod, "Server connection failed", 0);
        return 1;
    }

    request = json_object();
    json_object_set(request, "username", json_string(mod->username));
    json_object_set(request, "password", json_string(mod->password));
    json_object_set(request, "ip", json_string("127.0.0.1"));
    json_object_set(request, "link", json_string("lan"));
    display = json_object();
    json_object_set(display, "width", json_integer(mod->width));
    json_object_set(display, "height", json_integer(mod->height));
    json_object_set(request, "display", display);
    json_decref(display);

    g_snprintf(message, sizeof(message)-1, "%s\n", json_dumps(request, 0));
    json_decref(request);

    if (send(sock, message, strlen(message), 0) < 0) {
        mod->server_msg(mod, "Server request failed", 0);
        return 1;
    }

    if (recv(sock, reply, sizeof(reply), 0) < 0) {
        mod->server_msg(mod, "Server reply failed", 0);
        return 1;
    }

    response = json_loads(reply, 0, &js_error);
        
    if (response == NULL) {
        mod->server_msg(mod, "Decoding response failed", 0);
        return 1;
    } else {
        json_t *nxsession = json_object_get(response, "session");
        json_t *err = json_object_get(response, "err");
        int resume = json_is_true(json_object_get(response, "resume"));

        if (err) {
            mod->server_msg(mod, json_string_value(err), 0);
            return 1;
        } else if (resume) {
            resize_nxproxy(mod);
        } else {
            char sessionstash[512];
            const char *cookie = json_string_value(json_object_get(nxsession, "cookie"));
            const char *host = json_string_value(json_object_get(nxsession, "host"));
            json_int_t port = json_integer_value(json_object_get(nxsession, "port"));            

            getpwnam_r(mod->username, &pwd, pwdbuffer, sizeof(pwdbuffer), &pwdresult);
            if (pwdresult == NULL) {
                mod->server_msg(mod, "Uid lookup failed", 0);
                return 1;
            }

            if (!start_nxproxy(mod, cookie, (int)port)) {
                mod->server_msg(mod, "nxproxy failed to start", 0);
                return 1;
            }

            json_decref(nxsession);
        }
    }

    json_decref(response);

    LIB_DEBUG(mod, "in lib_mod_connect");
    /* clear screen */
    mod->server_begin_update(mod);
    mod->server_set_fgcolor(mod, 0);
    mod->server_fill_rect(mod, 0, 0, mod->width, mod->height);
    mod->server_end_update(mod);
    mod->server_msg(mod, "started connecting", 0);

    /* only support 8, 15, 16, and 24 bpp connections from rdp client */
    if (mod->bpp != 8 && mod->bpp != 15 && mod->bpp != 16 && mod->bpp != 24)
    {
        mod->server_msg(mod,
                        "error - only supporting 8, 15, 16, and 24 bpp rdp connections", 0);
        LIB_DEBUG(mod, "out lib_mod_connect error");
        return 1;
    }

    if (g_strcmp(mod->ip, "") == 0)
    {
        mod->server_msg(mod, "error - no ip set", 0);
        LIB_DEBUG(mod, "out lib_mod_connect error");
        return 1;
    }

    make_stream(s);

    g_snprintf(con_port, 255, "%s", mod->port);
    use_uds = 0;

    if (con_port[0] == '/')
    {
        use_uds = 1;
    }

    mod->sck_closed = 0;
    i = 0;

RECONNECT:
    while (1)
    {
        if (use_uds)
        {
            mod->sck = g_tcp_local_socket();
        }
        else
        {
            mod->sck = g_tcp_socket();
            g_tcp_set_non_blocking(mod->sck);
            g_tcp_set_no_delay(mod->sck);
        }

        /* mod->server_msg(mod, "connecting...", 0); */

        if (use_uds)
        {
            error = g_tcp_local_connect(mod->sck, con_port);
        }
        else
        {
            error = g_tcp_connect(mod->sck, mod->ip, con_port);
        }

        if (error == -1)
        {
            if (g_tcp_last_error_would_block(mod->sck))
            {
                error = 0;
                index = 0;

                while (!g_tcp_can_send(mod->sck, 100))
                {
                    index++;

                    if ((index >= 30) || mod->server_is_term(mod))
                    {
                        mod->server_msg(mod, "connect timeout", 0);
                        error = 1;
                        break;
                    }
                }
            }
            else
            {
                /* mod->server_msg(mod, "connect error", 0); */
            }
        }

        if (error == 0)
        {
            break;
        }

        g_tcp_close(mod->sck);
        mod->sck = 0;
        i++;

        if (i >= 20)
        {
            mod->server_msg(mod, "connection problem, giving up", 0);
            break;
        }

        g_sleep(500);
    }

    if (error == 0)
    {
        if (use_uds)
        {
            lib_mod_log_peer(mod);
        }
    }

    if (error == 0)
    {
        /* send version message */
        init_stream(s, 8192);
        s_push_layer(s, iso_hdr, 4);
        out_uint16_le(s, 103);
        out_uint32_le(s, 301);
        out_uint32_le(s, 0);
        out_uint32_le(s, 0);
        out_uint32_le(s, 0);
        out_uint32_le(s, 1);
        s_mark_end(s);
        len = (int)(s->end - s->data);
        s_pop_layer(s, iso_hdr);
        out_uint32_le(s, len);
        lib_send(mod, s->data, len);
    }

    if (error == 0)
    {
        /* send screen size message */
        init_stream(s, 8192);
        s_push_layer(s, iso_hdr, 4);
        out_uint16_le(s, 103);
        out_uint32_le(s, 300);
        out_uint32_le(s, mod->width);
        out_uint32_le(s, mod->height);
        out_uint32_le(s, mod->bpp);
        out_uint32_le(s, 0);
        s_mark_end(s);
        len = (int)(s->end - s->data);
        s_pop_layer(s, iso_hdr);
        out_uint32_le(s, len);
        lib_send(mod, s->data, len);
    }

    if (error == 0)
    {
        /* send invalidate message */
        init_stream(s, 8192);
        s_push_layer(s, iso_hdr, 4);
        out_uint16_le(s, 103);
        out_uint32_le(s, 200);
        /* x and y */
        i = 0;
        out_uint32_le(s, i);
        /* width and height */
        i = ((mod->width & 0xffff) << 16) | mod->height;
        out_uint32_le(s, i);
        out_uint32_le(s, 0);
        out_uint32_le(s, 0);
        s_mark_end(s);
        len = (int)(s->end - s->data);
        s_pop_layer(s, iso_hdr);
        out_uint32_le(s, len);
        send_error = lib_send(mod, s->data, len);
    }

    if (send_error) {
        if (retry < 50) {
            g_tcp_close(mod->sck);
            mod->server_msg(mod, "Doing a retry", 0);
            retry++;
            g_sleep(1000);
            goto RECONNECT;
        }

        error = send_error;
    }

    free_stream(s);

    if (error != 0)
    {
        mod->server_msg(mod, "some problem", 0);
        LIB_DEBUG(mod, "out lib_mod_connect error");
        return 1;
    }
    else
    {
        mod->server_msg(mod, "connected ok", 0);
        mod->sck_obj = g_create_wait_obj_from_socket(mod->sck, 0);
    }

    LIB_DEBUG(mod, "out lib_mod_connect");
    return 0;
}
Exemple #28
0
int DEFAULT_CC
main(int argc, char** argv)
{
  int sck;
  int code;
  int i;
  int size;
  int version;
  int width;
  int height;
  int bpp;
  int keylayout;
  int display;
  struct stream* in_s;
  struct stream* out_s;
  char* username;
  char* password;
  char* exec;
  long data;

  if (0 != config_read(&g_cfg))
  {
    g_printf("sesrun: error reading config. quitting.\n");
    return 1;
  }

  g_pid = g_getpid();
  if (argc == 1)
  {
    g_printf("xrdp session starter v0.2\n");
    g_printf("\nusage:\n");
    g_printf("sesrun <server> <username> <password> <exec> <width> <height> <bpp> <keylayout>\n");
  }
  else if (argc == 9)
  {
    username = argv[2];
    password = argv[3];
    exec = argv[4];
    width = g_atoi(argv[5]);
    height = g_atoi(argv[6]);
    bpp = g_atoi(argv[7]);
    keylayout = g_atoi(argv[8]);
    make_stream(in_s);
    init_stream(in_s, 8192);
    make_stream(out_s);
    init_stream(out_s, 8192);
    sck = g_tcp_socket();
    if (g_tcp_connect(sck, argv[1], "3350") == 0)
    {
      s_push_layer(out_s, channel_hdr, 8);
      out_uint16_be(out_s, 20); /* code */
      i = g_strlen(username);
      out_uint16_be(out_s, i);
      out_uint8a(out_s, username, i);
      i = g_strlen(password);
      out_uint16_be(out_s, i);
      out_uint8a(out_s, password, i);
      i = g_strlen(exec);
      out_uint16_be(out_s, i);
      out_uint8a(out_s, exec, i);
      out_uint16_be(out_s, width);
      out_uint16_be(out_s, height);
      out_uint16_be(out_s, bpp);
      out_uint16_be(out_s, keylayout);
      s_mark_end(out_s);
      s_pop_layer(out_s, channel_hdr);
      out_uint32_be(out_s, 0); /* version */
      out_uint32_be(out_s, out_s->end - out_s->data); /* size */
      tcp_force_send(sck, out_s->data, out_s->end - out_s->data);
      if (tcp_force_recv(sck, in_s->data, 8) == 0)
      {
        in_uint32_be(in_s, version);
        in_uint32_be(in_s, size);
        init_stream(in_s, 8192);
        if (tcp_force_recv(sck, in_s->data, size - 8) == 0)
        {
          if (version == 0)
          {
            in_uint16_be(in_s, code);
            if (code == 3)
            {
              in_uint16_be(in_s, data);
              in_uint16_be(in_s, display);
              g_printf("ok %d display %d\n", data, display);
            }
          }
        }
      }
    }
    else
    {
      g_printf("connect error\n");
    }
    g_tcp_close(sck);
    free_stream(in_s);
    free_stream(out_s);
  }
  return 0;
}
Exemple #29
0
/* called with the main thread */
static int APP_CC
session_start_fork(int width, int height, int bpp, char *username,
                   char *password, tbus data, tui8 type, char *domain,
                   char *program, char *directory, char *client_ip)
{
    int display = 0;
    int pid = 0;
    int wmpid = 0;
    int xpid = 0;
    int i = 0;
    char geometry[32];
    char depth[32];
    char screen[32];
    char text[256];
    char passwd_file[256];
    char **pp1 = (char **)NULL;
    struct session_chain *temp = (struct session_chain *)NULL;
    struct list *xserver_params = (struct list *)NULL;
    time_t ltime;
    struct tm stime;
    char execvpparams[2048];

    /* initialize (zero out) local variables: */
    g_memset(&ltime, 0, sizeof(time_t));
    g_memset(&stime, 0, sizeof(struct tm));
    g_memset(geometry, 0, sizeof(char) * 32);
    g_memset(depth, 0, sizeof(char) * 32);
    g_memset(screen, 0, sizeof(char) * 32);
    g_memset(text, 0, sizeof(char) * 256);
    g_memset(passwd_file, 0, sizeof(char) * 256);

    /* check to limit concurrent sessions */
    if (g_session_count >= g_cfg->sess.max_sessions)
    {
        log_message(LOG_LEVEL_INFO, "max concurrent session limit "
                    "exceeded. login for user %s denied", username);
        return 0;
    }

    temp = (struct session_chain *)g_malloc(sizeof(struct session_chain), 0);

    if (temp == 0)
    {
        log_message(LOG_LEVEL_ERROR, "cannot create new chain "
                    "element - user %s", username);
        return 0;
    }

    temp->item = (struct session_item *)g_malloc(sizeof(struct session_item), 0);

    if (temp->item == 0)
    {
        g_free(temp);
        log_message(LOG_LEVEL_ERROR, "cannot create new session "
                    "item - user %s", username);
        return 0;
    }

    display = session_get_aval_display_from_chain();

    if (display == 0)
    {
        g_free(temp->item);
        g_free(temp);
        return 0;
    }

    pid = g_fork();

    if (pid == -1)
    {
    }
    else if (pid == 0) /* child sesman */
    {
        g_tcp_close(g_sck);
        g_tcp_close(g_thread_sck);
        auth_start_session(data, display);
        g_sprintf(geometry, "%dx%d", width, height);
        g_sprintf(depth, "%d", bpp);
        g_sprintf(screen, ":%d", display);
        wmpid = g_fork();

        if (wmpid == -1)
        {
        }
        else if (wmpid == 0) /* child (child sesman) xserver */
        {
            wait_for_xserver(display);
            env_set_user(username, 0, display);

            if (x_server_running(display))
            {
                auth_set_env(data);

                if (directory != 0)
                {
                    if (directory[0] != 0)
                    {
                        g_set_current_dir(directory);
                    }
                }

                if (program != 0)
                {
                    if (program[0] != 0)
                    {
                        g_execlp3(program, program, 0);
                        log_message(LOG_LEVEL_ALWAYS,
                                    "error starting program %s for user %s - pid %d",
                                    program, username, g_getpid());
                    }
                }

                /* try to execute user window manager if enabled */
                if (g_cfg->enable_user_wm)
                {
                    g_sprintf(text, "%s/%s", g_getenv("HOME"), g_cfg->user_wm);

                    if (g_file_exist(text))
                    {
                        g_execlp3(text, g_cfg->user_wm, 0);
                        log_message(LOG_LEVEL_ALWAYS, "error starting user "
                                    "wm for user %s - pid %d", username, g_getpid());
                        /* logging parameters */
                        log_message(LOG_LEVEL_DEBUG, "errno: %d, "
                                    "description: %s", errno, g_get_strerror());
                        log_message(LOG_LEVEL_DEBUG, "execlp3 parameter "
                                    "list:");
                        log_message(LOG_LEVEL_DEBUG, "        argv[0] = %s",
                                    text);
                        log_message(LOG_LEVEL_DEBUG, "        argv[1] = %s",
                                    g_cfg->user_wm);
                    }
                }

                /* if we're here something happened to g_execlp3
                   so we try running the default window manager */
                g_sprintf(text, "%s/%s", XRDP_CFG_PATH, g_cfg->default_wm);
                g_execlp3(text, g_cfg->default_wm, 0);

                log_message( LOG_LEVEL_ALWAYS, "error starting default "
                             "wm for user %s - pid %d", username, g_getpid());
                /* logging parameters */
                log_message( LOG_LEVEL_DEBUG, "errno: %d, description: "
                             "%s", errno, g_get_strerror());
                log_message(LOG_LEVEL_DEBUG, "execlp3 parameter list:");
                log_message(LOG_LEVEL_DEBUG, "        argv[0] = %s",
                            text);
                log_message(LOG_LEVEL_DEBUG, "        argv[1] = %s",
                            g_cfg->default_wm);

                /* still a problem starting window manager just start xterm */
                g_execlp3("xterm", "xterm", 0);

                /* should not get here */
                log_message(LOG_LEVEL_ALWAYS, "error starting xterm "
                            "for user %s - pid %d", username, g_getpid());
                /* logging parameters */
                log_message(LOG_LEVEL_DEBUG, "errno: %d, description: "
                            "%s", errno, g_get_strerror());
            }
            else
            {
                log_message(LOG_LEVEL_ERROR, "another Xserver might "
                            "already be active on display %d - see log", display);
            }

            log_message(LOG_LEVEL_DEBUG, "aborting connection...");
            g_exit(0);
        }
        else /* parent (child sesman) */
        {
            xpid = g_fork();

            if (xpid == -1)
            {
            }
            else if (xpid == 0) /* child */
            {
                env_set_user(username, passwd_file, display);
                env_check_password_file(passwd_file, password);

                if (type == SESMAN_SESSION_TYPE_XVNC)
                {
                    xserver_params = list_create();
                    xserver_params->auto_free = 1;
                    /* these are the must have parameters */
                    list_add_item(xserver_params, (long)g_strdup("Xvnc"));
                    list_add_item(xserver_params, (long)g_strdup(screen));
                    list_add_item(xserver_params, (long)g_strdup("-geometry"));
                    list_add_item(xserver_params, (long)g_strdup(geometry));
                    list_add_item(xserver_params, (long)g_strdup("-depth"));
                    list_add_item(xserver_params, (long)g_strdup(depth));
                    list_add_item(xserver_params, (long)g_strdup("-rfbauth"));
                    list_add_item(xserver_params, (long)g_strdup(passwd_file));

                    /* additional parameters from sesman.ini file */
                    //config_read_xserver_params(SESMAN_SESSION_TYPE_XVNC,
                    //                           xserver_params);
                    list_append_list_strdup(g_cfg->vnc_params, xserver_params, 0);

                    /* make sure it ends with a zero */
                    list_add_item(xserver_params, 0);
                    pp1 = (char **)xserver_params->items;
                    log_message(LOG_LEVEL_INFO, "Xvnc start:%s", dumpItemsToString(xserver_params, execvpparams, 2048));
                    g_execvp("Xvnc", pp1);
                }
                else if (type == SESMAN_SESSION_TYPE_XRDP)
                {
                    xserver_params = list_create();
                    xserver_params->auto_free = 1;
                    /* these are the must have parameters */
                    list_add_item(xserver_params, (long)g_strdup("X11rdp"));
                    list_add_item(xserver_params, (long)g_strdup(screen));
                    list_add_item(xserver_params, (long)g_strdup("-geometry"));
                    list_add_item(xserver_params, (long)g_strdup(geometry));
                    list_add_item(xserver_params, (long)g_strdup("-depth"));
                    list_add_item(xserver_params, (long)g_strdup(depth));

                    /* additional parameters from sesman.ini file */
                    //config_read_xserver_params(SESMAN_SESSION_TYPE_XRDP,
                    //                           xserver_params);
                    list_append_list_strdup(g_cfg->rdp_params, xserver_params, 0);

                    /* make sure it ends with a zero */
                    list_add_item(xserver_params, 0);
                    pp1 = (char **)xserver_params->items;
                    log_message(LOG_LEVEL_INFO, "X11rdp start:%s", dumpItemsToString(xserver_params, execvpparams, 2048));
                    g_execvp("X11rdp", pp1);
                }
                else
                {
                    log_message(LOG_LEVEL_ALWAYS, "bad session type - "
                                "user %s - pid %d", username, g_getpid());
                    g_exit(1);
                }

                /* should not get here */
                log_message(LOG_LEVEL_ALWAYS, "error starting X server "
                            "- user %s - pid %d", username, g_getpid());

                /* logging parameters */
                log_message(LOG_LEVEL_DEBUG, "errno: %d, description: "
                            "%s", errno, g_get_strerror());
                log_message(LOG_LEVEL_DEBUG, "execve parameter list size: "
                            "%d", (xserver_params)->count);

                for (i = 0; i < (xserver_params->count); i++)
                {
                    log_message(LOG_LEVEL_DEBUG, "        argv[%d] = %s",
                                i, (char *)list_get_item(xserver_params, i));
                }

                list_delete(xserver_params);
                g_exit(1);
            }
            else /* parent (child sesman)*/
            {
                wait_for_xserver(display);
                g_snprintf(text, 255, "%d", display);
                g_setenv("XRDP_SESSVC_DISPLAY", text, 1);
                g_snprintf(text, 255, ":%d.0", display);
                g_setenv("DISPLAY", text, 1);
                /* new style waiting for clients */
                session_start_sessvc(xpid, wmpid, data, username, display);
            }
        }
    }
    else /* parent sesman process */
    {
        temp->item->pid = pid;
        temp->item->display = display;
        temp->item->width = width;
        temp->item->height = height;
        temp->item->bpp = bpp;
        temp->item->data = data;
        g_strncpy(temp->item->client_ip, client_ip, 255);   /* store client ip data */
        g_strncpy(temp->item->name, username, 255);

        ltime = g_time1();
        localtime_r(&ltime, &stime);
        temp->item->connect_time.year = (tui16)(stime.tm_year + 1900);
        temp->item->connect_time.month = (tui8)stime.tm_mon;
        temp->item->connect_time.day = (tui8)stime.tm_mday;
        temp->item->connect_time.hour = (tui8)stime.tm_hour;
        temp->item->connect_time.minute = (tui8)stime.tm_min;
        zero_time(&(temp->item->disconnect_time));
        zero_time(&(temp->item->idle_time));

        temp->item->type = type;
        temp->item->status = SESMAN_SESSION_STATUS_ACTIVE;

        temp->next = g_sessions;
        g_sessions = temp;
        g_session_count++;
    }

    return display;
}
Exemple #30
0
/**
 *
 * @brief Starts sesman main loop
 *
 */
static void DEFAULT_CC
sesman_main_loop(void)
{
    int in_sck;
    int error;
    int robjs_count;
    int cont;
    tbus sck_obj;
    tbus robjs[8];

    g_sck = g_tcp_socket();
    if (g_sck < 0)
    {
        log_message(LOG_LEVEL_ERROR, "error opening socket, g_tcp_socket() failed...");
        return;
    }

    g_tcp_set_non_blocking(g_sck);
    error = scp_tcp_bind(g_sck, g_cfg->listen_address, g_cfg->listen_port);

    if (error == 0)
    {
        error = g_tcp_listen(g_sck);

        if (error == 0)
        {
            log_message(LOG_LEVEL_INFO, "listening to port %s on %s",
                        g_cfg->listen_port, g_cfg->listen_address);
            sck_obj = g_create_wait_obj_from_socket(g_sck, 0);
            cont = 1;

            while (cont)
            {
                /* build the wait obj list */
                robjs_count = 0;
                robjs[robjs_count++] = sck_obj;
                robjs[robjs_count++] = g_term_event;

                /* wait */
                if (g_obj_wait(robjs, robjs_count, 0, 0, -1) != 0)
                {
                    /* error, should not get here */
                    g_sleep(100);
                }

                if (g_is_wait_obj_set(g_term_event)) /* term */
                {
                    break;
                }

                if (g_is_wait_obj_set(sck_obj)) /* incoming connection */
                {
                    in_sck = g_tcp_accept(g_sck);

                    if ((in_sck == -1) && g_tcp_last_error_would_block(g_sck))
                    {
                        /* should not get here */
                        g_sleep(100);
                    }
                    else if (in_sck == -1)
                    {
                        /* error, should not get here */
                        break;
                    }
                    else
                    {
                        /* we've got a connection, so we pass it to scp code */
                        LOG_DBG("new connection");
                        scp_process_start((void*)(tintptr)in_sck);
                        g_sck_close(in_sck);
                    }
                }
            }

            g_delete_wait_obj_from_socket(sck_obj);
        }
        else
        {
            log_message(LOG_LEVEL_ERROR, "listen error %d (%s)",
                        g_get_errno(), g_get_strerror());
        }
    }
    else
    {
        log_message(LOG_LEVEL_ERROR, "bind error on "
                    "port '%s': %d (%s)", g_cfg->listen_port,
                    g_get_errno(), g_get_strerror());
    }
    g_tcp_close(g_sck);
}