1 |
/* -*- c-basic-offset: 8 -*- |
/* -*- c-basic-offset: 8 -*- |
2 |
rdesktop: A Remote Desktop Protocol client. |
rdesktop: A Remote Desktop Protocol client. |
3 |
Entrypoint and utility functions |
Entrypoint and utility functions |
4 |
Copyright (C) Matthew Chapman 1999-2005 |
Copyright (C) Matthew Chapman 1999-2007 |
5 |
|
|
6 |
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
7 |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
45 |
#include <sys/un.h> /* sockaddr_un */ |
#include <sys/un.h> /* sockaddr_un */ |
46 |
#endif |
#endif |
47 |
|
|
48 |
#include <openssl/md5.h> |
#include "ssl.h" |
49 |
|
|
50 |
char g_title[64] = ""; |
char g_title[64] = ""; |
51 |
char g_username[64]; |
char g_username[64]; |
71 |
extern int g_tcp_port_rdp; |
extern int g_tcp_port_rdp; |
72 |
int g_server_depth = -1; |
int g_server_depth = -1; |
73 |
int g_win_button_size = 0; /* If zero, disable single app mode */ |
int g_win_button_size = 0; /* If zero, disable single app mode */ |
74 |
BOOL g_bitmap_compression = True; |
RD_BOOL g_bitmap_compression = True; |
75 |
BOOL g_sendmotion = True; |
RD_BOOL g_sendmotion = True; |
76 |
BOOL g_bitmap_cache = True; |
RD_BOOL g_bitmap_cache = True; |
77 |
BOOL g_bitmap_cache_persist_enable = False; |
RD_BOOL g_bitmap_cache_persist_enable = False; |
78 |
BOOL g_bitmap_cache_precache = True; |
RD_BOOL g_bitmap_cache_precache = True; |
79 |
BOOL g_encryption = True; |
RD_BOOL g_encryption = True; |
80 |
BOOL packet_encryption = True; |
RD_BOOL g_packet_encryption = True; |
81 |
BOOL g_desktop_save = True; /* desktop save order */ |
RD_BOOL g_desktop_save = True; /* desktop save order */ |
82 |
BOOL g_polygon_ellipse_orders = True; /* polygon / ellipse orders */ |
RD_BOOL g_polygon_ellipse_orders = True; /* polygon / ellipse orders */ |
83 |
BOOL g_fullscreen = False; |
RD_BOOL g_fullscreen = False; |
84 |
BOOL g_grab_keyboard = True; |
RD_BOOL g_grab_keyboard = True; |
85 |
BOOL g_hide_decorations = False; |
RD_BOOL g_hide_decorations = False; |
86 |
BOOL g_use_rdp5 = True; |
RD_BOOL g_use_rdp5 = True; |
87 |
BOOL g_rdpclip = True; |
RD_BOOL g_rdpclip = True; |
88 |
BOOL g_console_session = False; |
RD_BOOL g_console_session = False; |
89 |
BOOL g_numlock_sync = False; |
RD_BOOL g_numlock_sync = False; |
90 |
BOOL lspci_enabled = False; |
RD_BOOL g_lspci_enabled = False; |
91 |
BOOL g_owncolmap = False; |
RD_BOOL g_owncolmap = False; |
92 |
BOOL g_ownbackstore = True; /* We can't rely on external BackingStore */ |
RD_BOOL g_ownbackstore = True; /* We can't rely on external BackingStore */ |
93 |
BOOL g_seamless_rdp = False; |
RD_BOOL g_seamless_rdp = False; |
94 |
uint32 g_embed_wnd; |
uint32 g_embed_wnd; |
95 |
uint32 g_rdp5_performanceflags = |
uint32 g_rdp5_performanceflags = |
96 |
RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS; |
RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS; |
97 |
/* Session Directory redirection */ |
/* Session Directory redirection */ |
98 |
BOOL g_redirect = False; |
RD_BOOL g_redirect = False; |
99 |
char g_redirect_server[64]; |
char g_redirect_server[64]; |
100 |
char g_redirect_domain[16]; |
char g_redirect_domain[16]; |
101 |
char g_redirect_password[64]; |
char g_redirect_password[64]; |
104 |
uint32 g_redirect_flags = 0; |
uint32 g_redirect_flags = 0; |
105 |
|
|
106 |
#ifdef WITH_RDPSND |
#ifdef WITH_RDPSND |
107 |
BOOL g_rdpsnd = False; |
RD_BOOL g_rdpsnd = False; |
108 |
#endif |
#endif |
109 |
|
|
110 |
#ifdef HAVE_ICONV |
#ifdef HAVE_ICONV |
127 |
usage(char *program) |
usage(char *program) |
128 |
{ |
{ |
129 |
fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n"); |
fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n"); |
130 |
fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2005 Matt Chapman.\n"); |
fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2007 Matt Chapman.\n"); |
131 |
fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n"); |
fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n"); |
132 |
|
|
133 |
fprintf(stderr, "Usage: %s [options] server[:port]\n", program); |
fprintf(stderr, "Usage: %s [options] server[:port]\n", program); |
319 |
rdp_reset_state(); |
rdp_reset_state(); |
320 |
} |
} |
321 |
|
|
322 |
static BOOL |
static RD_BOOL |
323 |
read_password(char *password, int size) |
read_password(char *password, int size) |
324 |
{ |
{ |
325 |
struct termios tios; |
struct termios tios; |
326 |
BOOL ret = False; |
RD_BOOL ret = False; |
327 |
int istty = 0; |
int istty = 0; |
328 |
char *p; |
char *p; |
329 |
|
|
413 |
char password[64]; |
char password[64]; |
414 |
char shell[256]; |
char shell[256]; |
415 |
char directory[256]; |
char directory[256]; |
416 |
BOOL prompt_password, deactivated; |
RD_BOOL prompt_password, deactivated; |
417 |
struct passwd *pw; |
struct passwd *pw; |
418 |
uint32 flags, ext_disc_reason = 0; |
uint32 flags, ext_disc_reason = 0; |
419 |
char *p; |
char *p; |
420 |
int c; |
int c; |
421 |
char *locale = NULL; |
char *locale = NULL; |
422 |
int username_option = 0; |
int username_option = 0; |
423 |
BOOL geometry_option = False; |
RD_BOOL geometry_option = False; |
424 |
int run_count = 0; /* Session Directory support */ |
int run_count = 0; /* Session Directory support */ |
425 |
BOOL continue_connect = True; /* Session Directory support */ |
RD_BOOL continue_connect = True; /* Session Directory support */ |
426 |
#ifdef WITH_RDPSND |
#ifdef WITH_RDPSND |
427 |
char *rdpsnd_optarg = NULL; |
char *rdpsnd_optarg = NULL; |
428 |
#endif |
#endif |
582 |
g_encryption = False; |
g_encryption = False; |
583 |
break; |
break; |
584 |
case 'E': |
case 'E': |
585 |
packet_encryption = False; |
g_packet_encryption = False; |
586 |
break; |
break; |
587 |
case 'm': |
case 'm': |
588 |
g_sendmotion = False; |
g_sendmotion = False; |
633 |
g_server_depth = strtol(optarg, NULL, 10); |
g_server_depth = strtol(optarg, NULL, 10); |
634 |
if (g_server_depth != 8 && |
if (g_server_depth != 8 && |
635 |
g_server_depth != 16 && |
g_server_depth != 16 && |
636 |
g_server_depth != 15 && g_server_depth != 24) |
g_server_depth != 15 && g_server_depth != 24 |
637 |
|
&& g_server_depth != 32) |
638 |
{ |
{ |
639 |
error("Invalid server colour depth.\n"); |
error("Invalid server colour depth.\n"); |
640 |
return 1; |
return 1; |
727 |
} |
} |
728 |
else if (str_startswith(optarg, "lspci")) |
else if (str_startswith(optarg, "lspci")) |
729 |
{ |
{ |
730 |
lspci_enabled = True; |
g_lspci_enabled = True; |
731 |
} |
} |
732 |
else if (str_startswith(optarg, "lptport")) |
else if (str_startswith(optarg, "lptport")) |
733 |
{ |
{ |
921 |
} |
} |
922 |
#endif |
#endif |
923 |
|
|
924 |
if (lspci_enabled) |
if (g_lspci_enabled) |
925 |
lspci_init(); |
lspci_init(); |
926 |
|
|
927 |
rdpdr_init(); |
rdpdr_init(); |
939 |
|
|
940 |
/* By setting encryption to False here, we have an encrypted login |
/* By setting encryption to False here, we have an encrypted login |
941 |
packet but unencrypted transfer of other packets */ |
packet but unencrypted transfer of other packets */ |
942 |
if (!packet_encryption) |
if (!g_packet_encryption) |
943 |
g_encryption = False; |
g_encryption = False; |
944 |
|
|
945 |
|
|
1011 |
|
|
1012 |
#ifdef EGD_SOCKET |
#ifdef EGD_SOCKET |
1013 |
/* Read 32 random bytes from PRNGD or EGD socket (based on OpenSSL RAND_egd) */ |
/* Read 32 random bytes from PRNGD or EGD socket (based on OpenSSL RAND_egd) */ |
1014 |
static BOOL |
static RD_BOOL |
1015 |
generate_random_egd(uint8 * buf) |
generate_random_egd(uint8 * buf) |
1016 |
{ |
{ |
1017 |
struct sockaddr_un addr; |
struct sockaddr_un addr; |
1018 |
BOOL ret = False; |
RD_BOOL ret = False; |
1019 |
int fd; |
int fd; |
1020 |
|
|
1021 |
fd = socket(AF_UNIX, SOCK_STREAM, 0); |
fd = socket(AF_UNIX, SOCK_STREAM, 0); |
1053 |
{ |
{ |
1054 |
struct stat st; |
struct stat st; |
1055 |
struct tms tmsbuf; |
struct tms tmsbuf; |
1056 |
MD5_CTX md5; |
SSL_MD5 md5; |
1057 |
uint32 *r; |
uint32 *r; |
1058 |
int fd, n; |
int fd, n; |
1059 |
|
|
1085 |
r[7] = st.st_ctime; |
r[7] = st.st_ctime; |
1086 |
|
|
1087 |
/* Hash both halves with MD5 to obscure possible patterns */ |
/* Hash both halves with MD5 to obscure possible patterns */ |
1088 |
MD5_Init(&md5); |
ssl_md5_init(&md5); |
1089 |
MD5_Update(&md5, random, 16); |
ssl_md5_update(&md5, random, 16); |
1090 |
MD5_Final(random, &md5); |
ssl_md5_final(&md5, random); |
1091 |
MD5_Update(&md5, random + 16, 16); |
ssl_md5_update(&md5, random + 16, 16); |
1092 |
MD5_Final(random + 16, &md5); |
ssl_md5_final(&md5, random + 16); |
1093 |
} |
} |
1094 |
|
|
1095 |
/* malloc; exit if out of memory */ |
/* malloc; exit if out of memory */ |
1302 |
} |
} |
1303 |
|
|
1304 |
|
|
1305 |
BOOL |
RD_BOOL |
1306 |
str_startswith(const char *s, const char *prefix) |
str_startswith(const char *s, const char *prefix) |
1307 |
{ |
{ |
1308 |
return (strncmp(s, prefix, strlen(prefix)) == 0); |
return (strncmp(s, prefix, strlen(prefix)) == 0); |
1313 |
line. Incomplete lines are saved in the rest variable, which should |
line. Incomplete lines are saved in the rest variable, which should |
1314 |
initially point to NULL. When linehandler returns False, stop and |
initially point to NULL. When linehandler returns False, stop and |
1315 |
return False. Otherwise, return True. */ |
return False. Otherwise, return True. */ |
1316 |
BOOL |
RD_BOOL |
1317 |
str_handle_lines(const char *input, char **rest, str_handle_lines_t linehandler, void *data) |
str_handle_lines(const char *input, char **rest, str_handle_lines_t linehandler, void *data) |
1318 |
{ |
{ |
1319 |
char *buf, *p; |
char *buf, *p; |
1321 |
size_t inputlen; |
size_t inputlen; |
1322 |
size_t buflen; |
size_t buflen; |
1323 |
size_t restlen = 0; |
size_t restlen = 0; |
1324 |
BOOL ret = True; |
RD_BOOL ret = True; |
1325 |
|
|
1326 |
/* Copy data to buffer */ |
/* Copy data to buffer */ |
1327 |
inputlen = strlen(input); |
inputlen = strlen(input); |
1369 |
|
|
1370 |
/* Execute the program specified by argv. For each line in |
/* Execute the program specified by argv. For each line in |
1371 |
stdout/stderr output, call linehandler. Returns false on failure. */ |
stdout/stderr output, call linehandler. Returns false on failure. */ |
1372 |
BOOL |
RD_BOOL |
1373 |
subprocess(char *const argv[], str_handle_lines_t linehandler, void *data) |
subprocess(char *const argv[], str_handle_lines_t linehandler, void *data) |
1374 |
{ |
{ |
1375 |
pid_t child; |
pid_t child; |
1535 |
} |
} |
1536 |
|
|
1537 |
/* Create the bitmap cache directory */ |
/* Create the bitmap cache directory */ |
1538 |
BOOL |
RD_BOOL |
1539 |
rd_pstcache_mkdir(void) |
rd_pstcache_mkdir(void) |
1540 |
{ |
{ |
1541 |
char *home; |
char *home; |
1612 |
} |
} |
1613 |
|
|
1614 |
/* do a write lock on a file */ |
/* do a write lock on a file */ |
1615 |
BOOL |
RD_BOOL |
1616 |
rd_lock_file(int fd, int start, int len) |
rd_lock_file(int fd, int start, int len) |
1617 |
{ |
{ |
1618 |
struct flock lock; |
struct flock lock; |