summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/os_calls.c70
-rw-r--r--common/os_calls.h1
-rw-r--r--sesman/Makefile16
-rw-r--r--sesman/sesman.c484
-rw-r--r--sesman/sesman.ini5
-rw-r--r--vnc/vnc.c103
-rw-r--r--xrdp/xrdp.ini23
-rw-r--r--xrdp/xrdp_listen.c20
-rw-r--r--xrdp/xrdp_login_wnd.c4
-rw-r--r--xrdp/xrdp_mcs.c13
-rw-r--r--xrdp/xrdp_process.c340
-rw-r--r--xrdp/xrdp_rdp.c63
12 files changed, 914 insertions, 228 deletions
diff --git a/common/os_calls.c b/common/os_calls.c
index 9b3a9e31..6d6acaef 100644
--- a/common/os_calls.c
+++ b/common/os_calls.c
@@ -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;
}
@@ -248,6 +268,16 @@ int g_getchar(void)
}
/*****************************************************************************/
+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)
{
int rv;
@@ -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
diff --git a/common/os_calls.h b/common/os_calls.h
index 7766563d..009ed4a4 100644
--- a/common/os_calls.h
+++ b/common/os_calls.h
@@ -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);
diff --git a/sesman/Makefile b/sesman/Makefile
new file mode 100644
index 00000000..7844495d
--- /dev/null
+++ b/sesman/Makefile
@@ -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
diff --git a/sesman/sesman.c b/sesman/sesman.c
new file mode 100644
index 00000000..d18096bb
--- /dev/null
+++ b/sesman/sesman.c
@@ -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;
+}
diff --git a/sesman/sesman.ini b/sesman/sesman.ini
new file mode 100644
index 00000000..d01e8d2f
--- /dev/null
+++ b/sesman/sesman.ini
@@ -0,0 +1,5 @@
+
+[globals]
+auth=pam
+xserver=Xvnc :%d -geometry %dx%d -depth %d -bs
+wm=startkde
diff --git a/vnc/vnc.c b/vnc/vnc.c
index a8514c7b..94c39ae8 100644
--- a/vnc/vnc.c
+++ b/vnc/vnc.c
@@ -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;
}
diff --git a/xrdp/xrdp.ini b/xrdp/xrdp.ini
index f46acb9c..9a682181 100644
--- a/xrdp/xrdp.ini
+++ b/xrdp/xrdp.ini
@@ -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
diff --git a/xrdp/xrdp_listen.c b/xrdp/xrdp_listen.c
index 492466ee..f46cb187 100644
--- a/xrdp/xrdp_listen.c
+++ b/xrdp/xrdp_listen.c
@@ -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);
+ }
}
}
}
diff --git a/xrdp/xrdp_login_wnd.c b/xrdp/xrdp_login_wnd.c
index 38b58d99..b6fa0d19 100644
--- a/xrdp/xrdp_login_wnd.c
+++ b/xrdp/xrdp_login_wnd.c
@@ -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 */
{
diff --git a/xrdp/xrdp_mcs.c b/xrdp/xrdp_mcs.c
index 82eeff0f..41197cfa 100644
--- a/xrdp/xrdp_mcs.c
+++ b/xrdp/xrdp_mcs.c
@@ -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);
diff --git a/xrdp/xrdp_process.c b/xrdp/xrdp_process.c
index aa9acfa1..91531688 100644
--- a/xrdp/xrdp_process.c
+++ b/xrdp/xrdp_process.c
@@ -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;
+}
diff --git a/xrdp/xrdp_rdp.c b/xrdp/xrdp_rdp.c
index bed3e833..a36aeac6 100644
--- a/xrdp/xrdp_rdp.c
+++ b/xrdp/xrdp_rdp.c
@@ -778,6 +778,53 @@ int xrdp_rdp_process_data_font(struct xrdp_rdp* self, struct stream* s)
}
/*****************************************************************************/
+/* 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);