added session manager and fixed disconnect problems
This commit is contained in:
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,11 +326,19 @@ 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,16 +513,22 @@ 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);
|
||||
|
16
sesman/Makefile
Normal file
16
sesman/Makefile
Normal file
@ -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
|
484
sesman/sesman.c
Normal file
484
sesman/sesman.c
Normal file
@ -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;
|
||||
}
|
5
sesman/sesman.ini
Normal file
5
sesman/sesman.ini
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
[globals]
|
||||
auth=pam
|
||||
xserver=Xvnc :%d -geometry %dx%d -depth %d -bs
|
||||
wm=startkde
|
103
vnc/vnc.c
103
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;
|
||||
}
|
||||
|
||||
|
@ -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,10 +165,12 @@ int xrdp_listen_main_loop(struct xrdp_listen* self)
|
||||
g_sleep(100);
|
||||
}
|
||||
else
|
||||
{
|
||||
xrdp_process_delete(g_process);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG(("error, listener done\n\r"));
|
||||
|
@ -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);
|
||||
|
@ -112,6 +112,7 @@ int xrdp_process_main_loop(struct xrdp_process* self)
|
||||
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)
|
||||
@ -158,6 +159,7 @@ int xrdp_process_main_loop(struct xrdp_process* self)
|
||||
}
|
||||
}
|
||||
xrdp_rdp_disconnect(self->rdp_layer);
|
||||
g_sleep(500);
|
||||
xrdp_rdp_delete(self->rdp_layer);
|
||||
self->rdp_layer = 0;
|
||||
g_tcp_close(self->sck);
|
||||
|
@ -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…
Reference in New Issue
Block a user