added session manager and fixed disconnect problems

ulab-original
jsorg71 20 years ago
parent f0c7bdb304
commit 0aff0efb52

@ -18,6 +18,8 @@
generic operating system calls
put all the os / arch define in here you want
*/
#ifdef _WIN32
@ -117,13 +119,17 @@ void* g_malloc(int size, int zero)
rv = (char*)malloc(size + sizeof(struct xrdp_mem));
if (zero)
{
memset(rv, 0, size + sizeof(struct xrdp_mem));
}
g_memsize += size;
p = (struct xrdp_mem*)rv;
p->size = size;
p->id = g_memid;
if (g_memlist != 0)
{
xrdp_list_add_item(g_memlist, (int)p);
}
g_memid++;
return rv + sizeof(struct xrdp_mem);
#else
@ -131,7 +137,9 @@ void* g_malloc(int size, int zero)
rv = (char*)malloc(size);
if (zero)
{
memset(rv, 0, size);
}
return rv;
#endif
}
@ -143,7 +151,9 @@ void* g_malloc1(int size, int zero)
rv = (char*)malloc(size);
if (zero)
{
memset(rv, 0, size);
}
return rv;
}
@ -160,7 +170,9 @@ void g_free(void* ptr)
g_memsize -= p->size;
i = xrdp_list_index_of(g_memlist, (int)p);
if (i >= 0)
{
xrdp_list_remove_item(g_memlist, i);
}
free(p);
}
#else
@ -216,14 +228,22 @@ void g_hexdump(char* p, int len)
printf("%04x ", offset);
thisline = len - offset;
if (thisline > 16)
{
thisline = 16;
}
for (i = 0; i < thisline; i++)
{
printf("%02x ", line[i]);
}
for (; i < 16; i++)
{
printf(" ");
}
for (i = 0; i < thisline; i++)
{
printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
printf("\n");
}
printf("\n\r");
offset += thisline;
line += thisline;
}
@ -247,6 +267,16 @@ int g_getchar(void)
return getchar();
}
/*****************************************************************************/
int g_tcp_set_no_delay(int sck)
{
int i;
i = 1;
setsockopt(sck, IPPROTO_TCP, TCP_NODELAY, (void*)&i, sizeof(i));
return 0;
}
/*****************************************************************************/
int g_tcp_socket(void)
{
@ -272,7 +302,9 @@ int g_tcp_local_socket(void)
void g_tcp_close(int sck)
{
if (sck == 0)
{
return;
}
#ifdef _WIN32
closesocket(sck);
#else
@ -294,10 +326,18 @@ int g_tcp_connect(int sck, char* address, char* port)
{
h = gethostbyname(address);
if (h != 0)
{
if (h->h_name != 0)
{
if (h->h_addr_list != 0)
{
if ((*(h->h_addr_list)) != 0)
{
s.sin_addr.s_addr = *((int*)(*(h->h_addr_list)));
}
}
}
}
}
return connect(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in));
}
@ -399,12 +439,18 @@ int g_tcp_force_recv(int sck, char* data, int len)
if (rcvd == -1)
{
if (g_tcp_last_error_would_block(sck))
{
g_sleep(1);
}
else
{
return 1;
}
}
else if (rcvd == 0)
{
return 1;
}
else
{
data += rcvd;
@ -431,12 +477,18 @@ int g_tcp_force_send(int sck, char* data, int len)
if (sent == -1)
{
if (g_tcp_last_error_would_block(sck))
{
g_sleep(1);
}
else
{
return 1;
}
}
else if (sent == 0)
{
return 1;
}
else
{
data += sent;
@ -461,15 +513,21 @@ int g_tcp_select(int sck1, int sck2)
FD_SET(((unsigned int)sck2), &rfds);
max = sck1;
if (sck2 > max)
{
max = sck2;
}
rv = select(max + 1, &rfds, 0, 0, &time);
if (rv > 0)
{
rv = 0;
if (FD_ISSET(((unsigned int)sck1), &rfds))
{
rv = rv | 1;
}
if (FD_ISSET(((unsigned int)sck2), &rfds))
{
rv = rv | 2;
}
}
return rv;
}
@ -653,7 +711,9 @@ void g_random(char* data, int len)
memset(data, 0x44, len);
fd = open("/dev/urandom", O_RDONLY);
if (fd == -1)
{
fd = open("/dev/random", O_RDONLY);
}
if (fd != -1)
{
read(fd, data, len);
@ -703,9 +763,13 @@ int g_file_read(int fd, char* ptr, int len)
{
#ifdef _WIN32
if (ReadFile((HANDLE)fd, (LPVOID)ptr, (DWORD)len, (LPDWORD)&len, 0))
{
return len;
}
else
{
return -1;
}
#else
return read(fd, ptr, len);
#endif
@ -717,9 +781,13 @@ int g_file_write(int fd, char* ptr, int len)
{
#ifdef _WIN32
if (WriteFile((HANDLE)fd, (LPVOID)ptr, (DWORD)len, (LPDWORD)&len, 0))
{
return len;
}
else
{
return -1;
}
#else
return write(fd, ptr, len);
#endif

@ -32,6 +32,7 @@ void g_free1(void* ptr);
void g_memset(void* ptr, int val, int size);
void g_memcpy(void* d_ptr, const void* s_ptr, int size);
int g_getchar(void);
int g_tcp_set_no_delay(int sck);
int g_tcp_socket(void);
int g_tcp_local_socket(void);
void g_tcp_close(int sck);

@ -0,0 +1,16 @@
SESMANOBJ = sesman.o ../common/os_calls.o
CFLAGS = -Wall -O2 -I../common
LDFLAGS = -L /usr/gnu/lib
LIBS = -lpam_userpass -lcrypto -lpthread
PAMLIB = /lib/libpam.so.0
CC = gcc
all: sesman
sesman: $(SESMANOBJ)
$(CC) $(LDFLAGS) -o sesman $(PAMLIB) $(SESMANOBJ) $(LIBS)
clean:
rm -f $(SESMANOBJ) sesman

@ -0,0 +1,484 @@
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
xrdp: A Remote Desktop Protocol server.
Copyright (C) Jay Sorg 2005
session manager
linux only
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pwd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
#include <security/pam_userpass.h>
#include "arch.h"
#include "parse.h"
#include "os_calls.h"
#define SERVICE "xrdp"
struct session_item
{
char name[256];
int pid; // pid of sesman waiting for wm to end
int display;
int width;
int height;
int bpp;
};
struct session_item session_items[100];
/******************************************************************************/
struct session_item* find_session_item(char* name, int width,
int height, int bpp)
{
int i;
for (i = 0; i < 100; i++)
{
if (g_strcmp(name, session_items[i].name) == 0 &&
session_items[i].width == width &&
session_items[i].height == height &&
session_items[i].bpp == bpp)
{
return session_items + i;
}
}
return 0;
}
/******************************************************************************/
struct session_item* find_session_item_by_name(char* name)
{
int i;
for (i = 0; i < 100; i++)
{
if (g_strcmp(name, session_items[i].name) == 0)
{
return session_items + i;
}
}
return 0;
}
/******************************************************************************/
struct session_item* find_session_item_by_display(int display)
{
int i;
for (i = 0; i < 100; i++)
{
if (session_items[i].display == display)
{
return session_items + i;
}
}
return 0;
}
/******************************************************************************/
int x_server_running(int display)
{
char text[256];
g_sprintf(text, "/tmp/.X11-unix/X%d", display);
return access(text, F_OK) == 0;
}
/******************************************************************************/
/* returns boolean */
int auth_pam_userpass(const char* user, const char* pass)
{
pam_handle_t* pamh;
pam_userpass_t userpass;
struct pam_conv conv = {pam_userpass_conv, &userpass};
const void* template1;
int status;
userpass.user = user;
userpass.pass = pass;
if (pam_start(SERVICE, user, &conv, &pamh) != PAM_SUCCESS)
{
return 0;
}
status = pam_authenticate(pamh, 0);
if (status != PAM_SUCCESS)
{
pam_end(pamh, status);
return 0;
}
status = pam_acct_mgmt(pamh, 0);
if (status != PAM_SUCCESS)
{
pam_end(pamh, status);
return 0;
}
status = pam_get_item(pamh, PAM_USER, &template1);
if (status != PAM_SUCCESS)
{
pam_end(pamh, status);
return 0;
}
if (pam_end(pamh, PAM_SUCCESS) != PAM_SUCCESS)
{
return 0;
}
return 1;
}
/******************************************************************************/
void cterm(int s)
{
int i;
int pid;
int wstat;
pid = waitpid(0, &wstat, WNOHANG);
if (pid > 0)
{
for (i = 0; i < 100; i++)
{
if (session_items[i].pid == pid)
{
g_memset(session_items + i, 0, sizeof(struct session_item));
}
}
}
}
/******************************************************************************/
/* ge the next available X display */
int get_next_display(void)
{
int i;
for (i = 10; i < 100; i++)
{
if (!x_server_running(i))
{
return i;
}
}
return -1;
}
/******************************************************************************/
int start_session(int width, int height, int bpp, char* username)
{
int display;
int pid;
int uid;
int wmpid;
int xpid;
struct passwd* pwd_1;
char text[256];
char geometry[32];
char depth[32];
char screen[32];
display = 10;
while (x_server_running(display) && display < 50)
{
display++;
}
if (display >= 50)
{
return 0;
}
wmpid = 0;
pid = fork();
if (pid == -1)
{
}
else if (pid == 0) // child
{
pwd_1 = getpwnam(username);
if (pwd_1 != 0)
{
uid = pwd_1->pw_uid;
if (setuid(uid) == 0)
{
setenv("USER", username, 1);
g_sprintf(text, "%d", uid);
setenv("UID", text, 1);
setenv("HOME", pwd_1->pw_dir, 1);
chdir(pwd_1->pw_dir);
if (access(".bash_profile", F_OK) == 0)
{
system("sh .bash_profile");
}
g_sprintf(text, ":%d.0", display);
setenv("DISPLAY", text, 1);
g_sprintf(geometry, "%dx%d", width, height);
g_sprintf(depth, "%d", bpp);
g_sprintf(screen, ":%d", display);
wmpid = fork();
if (wmpid == -1)
{
}
else if (wmpid == 0) // child
{
// give X a bit to start
g_sleep(500);
if (x_server_running(display))
{
execlp("startkde", NULL);
// should not get here
}
g_printf("error\n");
_exit(0);
}
else // parent
{
xpid = fork();
if (xpid == -1)
{
}
else if (xpid == 0) // child
{
g_sprintf(text, "%s/.vnc/passwd", pwd_1->pw_dir);
if (access(text, F_OK) == 0)
{
execlp("Xvnc", "Xvnc", screen, "-geometry", geometry,
"-depth", depth, "-bs", "-rfbauth", text, NULL);
}
else
{
execlp("Xvnc", "Xvnc", screen, "-geometry", geometry,
"-depth", depth, "-bs", NULL);
}
// should not get here
g_printf("error\n");
_exit(0);
}
else // parent
{
waitpid(wmpid, 0, 0);
kill(xpid, SIGTERM);
kill(wmpid, SIGTERM);
_exit(0);
}
}
}
}
}
else // parent
{
signal(SIGCHLD, cterm);
session_items[display].pid = pid;
g_strcpy(session_items[display].name, username);
session_items[display].display = display;
session_items[display].width = width;
session_items[display].height = height;
session_items[display].bpp = bpp;
g_sleep(1000);
}
return display;
}
/******************************************************************************/
int main(int argc, char** argv)
{
int sck;
int in_sck;
int code;
int i;
int size;
int version;
int ok;
int width;
int height;
int bpp;
int display;
struct stream* in_s;
struct stream* out_s;
char* username;
char* password;
char user[256];
char pass[256];
struct session_item* s_item;
g_memset(&session_items, 0, sizeof(session_items));
if (argc == 1)
{
g_printf("xrdp session manager v0.1\n");
g_printf("usage\n");
g_printf("sesman wait - wait for connection\n");
g_printf("sesman server username password width height bpp - \
start session\n");
}
else if (argc == 2 && g_strcmp(argv[1], "wait") == 0)
{
make_stream(in_s);
init_stream(in_s, 8192);
make_stream(out_s);
init_stream(out_s, 8192);
g_printf("listening\n");
sck = g_tcp_socket();
if (g_tcp_bind(sck, "3350") == 0)
{
if (g_tcp_listen(sck) == 0)
{
in_sck = g_tcp_accept(sck);
while (in_sck > 0)
{
init_stream(in_s, 8192);
if (g_tcp_force_recv(in_sck, in_s->data, 8) == 0)
{
in_uint32_be(in_s, version);
in_uint32_be(in_s, size);
init_stream(in_s, 8192);
if (g_tcp_force_recv(in_sck, in_s->data, size - 8) == 0)
{
if (version == 0)
{
in_uint16_be(in_s, code);
if (code == 0) // check username - password, start session
{
in_uint16_be(in_s, i);
in_uint8a(in_s, user, i);
user[i] = 0;
//g_printf("%s\n", user);
in_uint16_be(in_s, i);
in_uint8a(in_s, pass, i);
pass[i] = 0;
//g_printf("%s\n", pass);
in_uint16_be(in_s, width);
in_uint16_be(in_s, height);
in_uint16_be(in_s, bpp);
//g_printf("%d %d %d\n", width, height, bpp);
ok = auth_pam_userpass(user, pass);
display = 0;
if (ok)
{
s_item = find_session_item(user, width, height, bpp);
if (s_item != 0)
{
display = s_item->display;
}
else
{
display = start_session(width, height, bpp, user);
}
if (display == 0)
{
ok = 0;
}
}
init_stream(out_s, 8192);
out_uint32_be(out_s, 0); // version
out_uint32_be(out_s, 14); // size
out_uint16_be(out_s, 3); // cmd
out_uint16_be(out_s, ok); // data
out_uint16_be(out_s, display); // data
s_mark_end(out_s);
g_tcp_force_send(in_sck, out_s->data,
out_s->end - out_s->data);
}
}
}
}
close(in_sck);
in_sck = g_tcp_accept(sck);
}
}
else
{
g_printf("listen error\n");
}
}
else
{
g_printf("bind error\n");
}
g_tcp_close(sck);
free_stream(in_s);
free_stream(out_s);
}
else if (argc == 7)
{
username = argv[2];
password = argv[3];
width = atoi(argv[4]);
height = atoi(argv[5]);
bpp = atoi(argv[6]);
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, 0); // 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);
//g_printf("%d\n", width);
out_uint16_be(out_s, width);
out_uint16_be(out_s, height);
out_uint16_be(out_s, bpp);
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
g_tcp_force_send(sck, out_s->data, out_s->end - out_s->data);
if (g_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 (g_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, ok);
in_uint16_be(in_s, display);
g_printf("ok %d display %d\n", ok, display);
}
}
}
}
}
else
{
g_printf("connect error\n");
}
g_tcp_close(sck);
free_stream(in_s);
free_stream(out_s);
}
return 0;
}

@ -0,0 +1,5 @@
[globals]
auth=pam
xserver=Xvnc :%d -geometry %dx%d -depth %d -bs
wm=startkde

@ -22,11 +22,6 @@
#include "vnc.h"
char* vnc_start_command =
"su %s -c \"sh ../vnc/startvnc.sh :%d %d %d %d\"";
char* vnc_stop_command =
"";
/******************************************************************************/
int lib_mod_event(struct vnc* v, int msg, int param1, int param2)
{
@ -258,8 +253,12 @@ int lib_framebuffer_update(struct vnc* v)
int r;
int g;
int b;
int data_size;
int need_size;
struct stream* s;
data_size = 0;
data = 0;
Bpp = (v->mod_bpp + 7) / 8;
make_stream(s);
init_stream(s, 8192);
@ -287,7 +286,13 @@ int lib_framebuffer_update(struct vnc* v)
in_uint32_be(s, encoding);
if (encoding == 0) /* raw */
{
data = (char*)g_malloc(cx * cy * Bpp, 0);
need_size = cx * cy * Bpp;
if (need_size > data_size)
{
g_free(data);
data = (char*)g_malloc(need_size, 0);
data_size = need_size;
}
if (g_tcp_force_recv(v->sck, data, cx * cy * Bpp) != 0)
{
g_free(data);
@ -295,13 +300,13 @@ int lib_framebuffer_update(struct vnc* v)
return 1;
}
v->server_paint_rect(v, x, y, cx, cy, data);
g_free(data);
}
else if (encoding == 1) /* copy rect */
{
init_stream(s, 8192);
if (g_tcp_force_recv(v->sck, s->data, 4) != 0)
{
g_free(data);
free_stream(s);
return 1;
}
@ -317,6 +322,7 @@ int lib_framebuffer_update(struct vnc* v)
if (g_tcp_force_recv(v->sck, s->data,
cx * cy * Bpp + ((cx + 7) / 8) * cy) != 0)
{
g_free(data);
free_stream(s);
return 1;
}
@ -339,8 +345,13 @@ int lib_framebuffer_update(struct vnc* v)
}
v->server_set_cursor(v, x, y, cursor_data, cursor_mask);
}
else
{
g_printf("error in lib_framebuffer_update\n\r");
}
}
v->server_end_update(v);
g_free(data);
/* FrambufferUpdateRequest */
init_stream(s, 8192);
@ -491,34 +502,77 @@ int lib_mod_connect(struct vnc* v)
{
char cursor_data[32 * (32 * 3)];
char cursor_mask[32 * (32 / 8)];
char text[256];
char con_port[256];
struct stream* s;
struct stream* pixel_format;
int error;
int i;
int check_sec_result;
int sck;
int version;
int size;
int code;
int ok;
int display;
check_sec_result = 1;
if (g_strcmp(v->ip, "") == 0)
{
return 6;
}
make_stream(s);
if (g_strcmp(v->port, "-1") == 0)
{
i = 10;
g_sprintf(text, vnc_start_command, v->username, i, v->server_bpp,
v->server_width, v->server_height);
error = g_system(text);
while (error != 0 && i < 100)
i = 0;
error = 0;
init_stream(s, 8192);
sck = g_tcp_socket();
if (g_tcp_connect(sck, v->ip, "3350") == 0)
{
i++;
g_sprintf(text, vnc_start_command, v->username, i, v->server_bpp,
v->server_width, v->server_height);
error = g_system(text);
s_push_layer(s, channel_hdr, 8);
out_uint16_be(s, 0); // code
i = g_strlen(v->username);
out_uint16_be(s, i);
out_uint8a(s, v->username, i);
i = g_strlen(v->password);
out_uint16_be(s, i);
out_uint8a(s, v->password, i);
out_uint16_be(s, v->server_width);
out_uint16_be(s, v->server_height);
out_uint16_be(s, v->server_bpp);
s_mark_end(s);
s_pop_layer(s, channel_hdr);
out_uint32_be(s, 0); // version
out_uint32_be(s, s->end - s->data); // size
g_tcp_force_send(sck, s->data, s->end - s->data);
init_stream(s, 8192);
if (g_tcp_force_recv(sck, s->data, 8) == 0)
{
in_uint32_be(s, version);
in_uint32_be(s, size);
init_stream(s, 8192);
if (g_tcp_force_recv(sck, s->data, size - 8) == 0)
{
if (version == 0)
{
in_uint16_be(s, code);
if (code == 3)
{
in_uint16_be(s, ok);
in_uint16_be(s, display);
if (ok)
{
i = display;
}
}
}
}
}
}
if (error != 0)
g_tcp_close(sck);
if (error != 0 || i == 0)
{
free_stream(s);
return 5;
}
g_sprintf(con_port, "%d", 5900 + i);
@ -528,7 +582,6 @@ int lib_mod_connect(struct vnc* v)
{
g_sprintf(con_port, "%s", v->port);
}
make_stream(s);
make_stream(pixel_format);
v->sck = g_tcp_socket();
error = g_tcp_connect(v->sck, v->ip, con_port);
@ -681,12 +734,8 @@ int lib_mod_invalidate(struct vnc* v, int x, int y, int cx, int cy)
/******************************************************************************/
int lib_mod_end(struct vnc* v)
{
char text[256];
if (v->vnc_desktop != 0)
{
g_sprintf(text, vnc_stop_command, v->username, v->vnc_desktop);
g_system(text);
}
return 0;
}
@ -695,13 +744,21 @@ int lib_mod_end(struct vnc* v)
int lib_mod_set_param(struct vnc* v, char* name, char* value)
{
if (g_strcmp(name, "username") == 0)
{
g_strncpy(v->username, value, 255);
}
else if (g_strcmp(name, "password") == 0)
{
g_strncpy(v->password, value, 255);
}
else if (g_strcmp(name, "ip") == 0)
{
g_strncpy(v->ip, value, 255);
}
else if (g_strcmp(name, "port") == 0)
{
g_strncpy(v->port, value, 255);
}
return 0;
}

@ -4,28 +4,19 @@ bitmap_cache=yes
bitmap_compression=yes
[vnc1]
name=self:2
name=sesman
lib=../vnc/libvnc.so
auth=local
ip=127.0.0.1
port=5902
port=-1
username=ask
password=master
password=ask
[vnc2]
name=self:3
name=console
lib=../vnc/libvnc.so
auth=local
ip=127.0.0.1
port=5903
username=n/a
password=master
[vnc3]
name=playback
lib=../vnc/libvnc.so
auth=local
ip=127.0.0.1
port=5910
username=n/a
password=tucker
port=5900
username=ask
password=ask

@ -47,17 +47,31 @@ int xrdp_listen_term_processes(struct xrdp_listen* self)
/* tell all xrdp processes to end */
for (i = 0; i < self->process_list_count; i++)
{
if (self->process_list[i] != 0)
{
self->process_list[i]->term = 1;
}
}
/* make sure they are done */
for (i = 0; i < self->process_list_count; i++)
{
if (self->process_list[i] != 0)
{
while (self->process_list[i]->status > 0)
{
g_sleep(10);
}
}
}
/* free them all */
for (i = 0; i < self->process_list_count; i++)
{
if (self->process_list[i] != 0)
{
xrdp_process_delete(self->process_list[i]);
}
}
return 0;
}
@ -133,9 +147,13 @@ int xrdp_listen_main_loop(struct xrdp_listen* self)
{
error = g_tcp_accept(self->sck);
if (error == -1 && g_tcp_last_error_would_block(self->sck))
{
g_sleep(100);
}
else if (error == -1)
{
break;
}
else
{
g_process = xrdp_process_create(self);
@ -147,7 +165,9 @@ int xrdp_listen_main_loop(struct xrdp_listen* self)
g_sleep(100);
}
else
{
xrdp_process_delete(g_process);
}
}
}
}

@ -187,10 +187,10 @@ int xrdp_wm_login_notify(struct xrdp_bitmap* wnd,
}
else if (sender->id == 2) /* cancel button */
{
/*if (wnd != 0)
if (wnd != 0)
if (wnd->wm != 0)
if (wnd->wm->pro_layer != 0)
wnd->wm->pro_layer->term = 1;*/
wnd->wm->pro_layer->term = 1;
}
else if (sender->id == 3) /* ok button */
{

@ -584,25 +584,18 @@ int xrdp_mcs_send(struct xrdp_mcs* self, struct stream* s)
/* returns error */
int xrdp_mcs_disconnect(struct xrdp_mcs* self)
{
int len;
struct stream* s;
make_stream(s);
init_stream(s, 8192);
if (xrdp_mcs_init(self, s) != 0)
if (xrdp_iso_init(self->iso_layer, s) != 0)
{
free_stream(s);
return 1;
}
out_uint8(s, (MCS_DPUM << 2) | 1);
out_uint8(s, 0x80);
s_mark_end(s);
s_pop_layer(s, mcs_hdr);
len = (s->end - s->p) - 8;
len = len | 0x8000;
out_uint8(s, MCS_DPUM << 2);
out_uint16_be(s, self->userid);
out_uint16_be(s, MCS_GLOBAL_CHANNEL);
out_uint8(s, 0x70);
out_uint16_be(s, len);
if (xrdp_iso_send(self->iso_layer, s) != 0)
{
free_stream(s);

@ -1,169 +1,171 @@
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
xrdp: A Remote Desktop Protocol server.
Copyright (C) Jay Sorg 2004-2005
main rdp process
*/
#include "xrdp.h"
/*****************************************************************************/
struct xrdp_process* xrdp_process_create(struct xrdp_listen* owner)
{
struct xrdp_process* self;
self = (struct xrdp_process*)g_malloc(sizeof(struct xrdp_process), 1);
self->lis_layer = owner;
return self;
}
/*****************************************************************************/
void xrdp_process_delete(struct xrdp_process* self)
{
if (self == 0)
{
return;
}
xrdp_rdp_delete(self->rdp_layer);
xrdp_orders_delete(self->orders);
xrdp_wm_delete(self->wm);
g_free(self);
}
/*****************************************************************************/
int xrdp_process_loop(struct xrdp_process* self, struct stream* s)
{
int cont;
int rv;
int code;
code = 0;
rv = 0;
cont = 1;
while (cont && !self->term)
{
if (xrdp_rdp_recv(self->rdp_layer, s, &code) != 0)
{
rv = 1;
break;
}
DEBUG(("xrdp_process_main_loop code %d\n\r", code));
switch (code)
{
case -1:
xrdp_rdp_send_demand_active(self->rdp_layer);
break;
case 0:
break;
case RDP_PDU_CONFIRM_ACTIVE: /* 3 */
xrdp_rdp_process_confirm_active(self->rdp_layer, s);
break;
case RDP_PDU_DATA: /* 7 */
if (xrdp_rdp_process_data(self->rdp_layer, s) != 0)
{
DEBUG(("xrdp_rdp_process_data returned non zero\n\r"));
cont = 0;
self->term = 1;
}
break;
default:
g_printf("unknown in xrdp_process_main_loop\n\r");
break;
}
if (cont)
{
cont = s->next_packet < s->end;
}
}
if (self->rdp_layer->up_and_running && self->wm == 0 && rv == 0)
{
/* only do this once */
DEBUG(("xrdp_process_main_loop up and running\n\r"));
self->orders = xrdp_orders_create(self, self->rdp_layer);
self->wm = xrdp_wm_create(self, &self->rdp_layer->client_info);
xrdp_wm_init(self->wm);
}
return rv;
}
/*****************************************************************************/
int xrdp_process_main_loop(struct xrdp_process* self)
{
#ifndef XRDP_LIB
int i;
struct stream* s;
make_stream(s);
self->status = 1;
self->rdp_layer = xrdp_rdp_create(self, self->sck);
g_tcp_set_non_blocking(self->sck);
if (xrdp_rdp_incoming(self->rdp_layer) == 0)
{
while (!g_is_term() && !self->term)
{
i = g_tcp_select(self->sck, self->app_sck);
if (i & 1)
{
init_stream(s, 8192);
if (xrdp_process_loop(self, s) != 0)
{
break;
}
}
if (i & 2) /* mod socket fired */
{
if (self->wm->mod == 0)
{
break;
}
if (self->wm->mod->mod_signal == 0)
{
break;
}
if (self->wm->mod->mod_signal(self->wm->mod) != 0)
{
break;
}
}
if (i == 0) /* no data on any stream */
{
g_sleep(10);
}
else if (i < 0)
{
break;
}
}
}
if (self->wm->mod != 0)
{
if (self->wm->mod->mod_end != 0)
{
self->wm->mod->mod_end(self->wm->mod);
}
}
xrdp_rdp_disconnect(self->rdp_layer);
xrdp_rdp_delete(self->rdp_layer);
self->rdp_layer = 0;
g_tcp_close(self->sck);
self->status = -1;
xrdp_listen_delete_pro(self->lis_layer, self);
free_stream(s);
#endif
return 0;
}
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
xrdp: A Remote Desktop Protocol server.
Copyright (C) Jay Sorg 2004-2005
main rdp process
*/
#include "xrdp.h"
/*****************************************************************************/
struct xrdp_process* xrdp_process_create(struct xrdp_listen* owner)
{
struct xrdp_process* self;
self = (struct xrdp_process*)g_malloc(sizeof(struct xrdp_process), 1);
self->lis_layer = owner;
return self;
}
/*****************************************************************************/
void xrdp_process_delete(struct xrdp_process* self)
{
if (self == 0)
{
return;
}
xrdp_rdp_delete(self->rdp_layer);
xrdp_orders_delete(self->orders);
xrdp_wm_delete(self->wm);
g_free(self);
}
/*****************************************************************************/
int xrdp_process_loop(struct xrdp_process* self, struct stream* s)
{
int cont;
int rv;
int code;
code = 0;
rv = 0;
cont = 1;
while (cont && !self->term)
{
if (xrdp_rdp_recv(self->rdp_layer, s, &code) != 0)
{
rv = 1;
break;
}
DEBUG(("xrdp_process_main_loop code %d\n\r", code));
switch (code)
{
case -1:
xrdp_rdp_send_demand_active(self->rdp_layer);
break;
case 0:
break;
case RDP_PDU_CONFIRM_ACTIVE: /* 3 */
xrdp_rdp_process_confirm_active(self->rdp_layer, s);
break;
case RDP_PDU_DATA: /* 7 */
if (xrdp_rdp_process_data(self->rdp_layer, s) != 0)
{
DEBUG(("xrdp_rdp_process_data returned non zero\n\r"));
cont = 0;
self->term = 1;
}
break;
default:
g_printf("unknown in xrdp_process_main_loop\n\r");
break;
}
if (cont)
{
cont = s->next_packet < s->end;
}
}
if (self->rdp_layer->up_and_running && self->wm == 0 && rv == 0)
{
/* only do this once */
DEBUG(("xrdp_process_main_loop up and running\n\r"));
self->orders = xrdp_orders_create(self, self->rdp_layer);
self->wm = xrdp_wm_create(self, &self->rdp_layer->client_info);
xrdp_wm_init(self->wm);
}
return rv;
}
/*****************************************************************************/
int xrdp_process_main_loop(struct xrdp_process* self)
{
#ifndef XRDP_LIB
int i;
struct stream* s;
make_stream(s);
self->status = 1;
self->rdp_layer = xrdp_rdp_create(self, self->sck);
g_tcp_set_non_blocking(self->sck);
g_tcp_set_no_delay(self->sck);
if (xrdp_rdp_incoming(self->rdp_layer) == 0)
{
while (!g_is_term() && !self->term)
{
i = g_tcp_select(self->sck, self->app_sck);
if (i & 1)
{
init_stream(s, 8192);
if (xrdp_process_loop(self, s) != 0)
{
break;
}
}
if (i & 2) /* mod socket fired */
{
if (self->wm->mod == 0)
{
break;
}
if (self->wm->mod->mod_signal == 0)
{
break;
}
if (self->wm->mod->mod_signal(self->wm->mod) != 0)
{
break;
}
}
if (i == 0) /* no data on any stream */
{
g_sleep(10);
}
else if (i < 0)
{
break;
}
}
}
if (self->wm->mod != 0)
{
if (self->wm->mod->mod_end != 0)
{
self->wm->mod->mod_end(self->wm->mod);
}
}
xrdp_rdp_disconnect(self->rdp_layer);
g_sleep(500);
xrdp_rdp_delete(self->rdp_layer);
self->rdp_layer = 0;
g_tcp_close(self->sck);
self->status = -1;
xrdp_listen_delete_pro(self->lis_layer, self);
free_stream(s);
#endif
return 0;
}

@ -777,6 +777,53 @@ int xrdp_rdp_process_data_font(struct xrdp_rdp* self, struct stream* s)
return 0;
}
/*****************************************************************************/
/* sent 37 pdu */
int xrdp_rdp_send_disconnect_query_response(struct xrdp_rdp* self)
{
struct stream* s;
make_stream(s);
init_stream(s, 8192);
if (xrdp_rdp_init_data(self, s) != 0)
{
free_stream(s);
return 1;
}
s_mark_end(s);
if (xrdp_rdp_send_data(self, s, 37) != 0)
{
free_stream(s);
return 1;
}
free_stream(s);
return 0;
}
/*****************************************************************************/
/* sent RDP_DATA_PDU_DISCONNECT 47 pdu */
int xrdp_rdp_send_disconnect_reason(struct xrdp_rdp* self, int reason)
{
struct stream* s;
make_stream(s);
init_stream(s, 8192);
if (xrdp_rdp_init_data(self, s) != 0)
{
free_stream(s);
return 1;
}
out_uint32_le(s, reason);
s_mark_end(s);
if (xrdp_rdp_send_data(self, s, RDP_DATA_PDU_DISCONNECT) != 0)
{
free_stream(s);
return 1;
}
free_stream(s);
return 0;
}
/*****************************************************************************/
/* RDP_PDU_DATA */
int xrdp_rdp_process_data(struct xrdp_rdp* self, struct stream* s)
@ -806,18 +853,20 @@ int xrdp_rdp_process_data(struct xrdp_rdp* self, struct stream* s)
case RDP_DATA_PDU_SYNCHRONISE: /* 31 */
xrdp_rdp_process_data_sync(self);
break;
case 33: /* 33 ?? */
case 33: /* 33 ?? Invalidate an area I think */
xrdp_rdp_process_screen_update(self, s);
break;
/*case 35:*/
case 35:
/* 35 ?? this comes when minimuzing a full screen mstsc.exe 2600 */
/* I think this is saying the client no longer wants screen */
/* updates and it will issue a 33 above to catch up */
/* so minumized apps don't take bandwidth */
case 36: /* 36 ?? disconnect? */
return 1;
/* so minimized apps don't take bandwidth */
break;
case 36: /* 36 ?? disconnect query? */
/* when this message comes, send a 37 back so the client */
/* is sure the connection is alive and it can ask if user */
/* really wants to disconnect */
xrdp_rdp_send_disconnect_query_response(self); /* send a 37 back */
break;
case RDP_DATA_PDU_FONT2: /* 39 */
xrdp_rdp_process_data_font(self, s);

Loading…
Cancel
Save