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 |
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 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 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 |
193 |
" 'PRIMARYCLIPBOARD' looks at both PRIMARY and CLIPBOARD\n"); |
" 'PRIMARYCLIPBOARD' looks at both PRIMARY and CLIPBOARD\n"); |
194 |
fprintf(stderr, " when sending data to server.\n"); |
fprintf(stderr, " when sending data to server.\n"); |
195 |
fprintf(stderr, " 'CLIPBOARD' looks at only CLIPBOARD.\n"); |
fprintf(stderr, " 'CLIPBOARD' looks at only CLIPBOARD.\n"); |
196 |
|
#ifdef WITH_SCARD |
197 |
|
fprintf(stderr, " '-r scard[:\"Scard Name\"=\"Alias Name[;Vendor Name]\"[,...]]\n"); |
198 |
|
fprintf(stderr, " example: -r scard:\"eToken PRO 00 00\"=\"AKS ifdh 0\"\n"); |
199 |
|
fprintf(stderr, |
200 |
|
" \"eToken PRO 00 00\" -> Device in Linux/Unix enviroment\n"); |
201 |
|
fprintf(stderr, |
202 |
|
" \"AKS ifdh 0\" -> Device shown in Windows enviroment \n"); |
203 |
|
fprintf(stderr, " example: -r scard:\"eToken PRO 00 00\"=\"AKS ifdh 0;AKS\"\n"); |
204 |
|
fprintf(stderr, |
205 |
|
" \"eToken PRO 00 00\" -> Device in Linux/Unix enviroment\n"); |
206 |
|
fprintf(stderr, |
207 |
|
" \"AKS ifdh 0\" -> Device shown in Windows enviroment \n"); |
208 |
|
fprintf(stderr, |
209 |
|
" \"AKS\" -> Device vendor name \n"); |
210 |
|
#endif |
211 |
fprintf(stderr, " -0: attach to console\n"); |
fprintf(stderr, " -0: attach to console\n"); |
212 |
fprintf(stderr, " -4: use RDP version 4\n"); |
fprintf(stderr, " -4: use RDP version 4\n"); |
213 |
fprintf(stderr, " -5: use RDP version 5 (default)\n"); |
fprintf(stderr, " -5: use RDP version 5 (default)\n"); |
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 |
427 |
|
char *rdpsnd_optarg = NULL; |
428 |
|
#endif |
429 |
|
|
430 |
#ifdef HAVE_LOCALE_H |
#ifdef HAVE_LOCALE_H |
431 |
/* Set locale according to environment */ |
/* Set locale according to environment */ |
687 |
if (str_startswith(optarg, "local")) |
if (str_startswith(optarg, "local")) |
688 |
#ifdef WITH_RDPSND |
#ifdef WITH_RDPSND |
689 |
{ |
{ |
690 |
char *driver = NULL, *options = |
rdpsnd_optarg = |
691 |
NULL; |
next_arg(optarg, ':'); |
692 |
|
g_rdpsnd = True; |
|
if ((driver = |
|
|
next_arg(optarg, ':'))) |
|
|
{ |
|
|
if (!strlen(driver)) |
|
|
{ |
|
|
driver = NULL; |
|
|
} |
|
|
else if ((options = |
|
|
next_arg(driver, |
|
|
':'))) |
|
|
{ |
|
|
if (!strlen |
|
|
(options)) |
|
|
options = |
|
|
NULL; |
|
|
} |
|
|
} |
|
|
|
|
|
if (!rdpsnd_select_driver |
|
|
(driver, options)) |
|
|
{ |
|
|
warning("Driver not available\n"); |
|
|
} |
|
|
else |
|
|
{ |
|
|
g_rdpsnd = True; |
|
|
} |
|
693 |
} |
} |
694 |
|
|
695 |
#else |
#else |
709 |
else |
else |
710 |
{ |
{ |
711 |
#ifdef WITH_RDPSND |
#ifdef WITH_RDPSND |
712 |
if (!rdpsnd_select_driver(NULL, NULL)) |
g_rdpsnd = True; |
|
{ |
|
|
warning("No sound-driver available\n"); |
|
|
} |
|
|
else |
|
|
{ |
|
|
g_rdpsnd = True; |
|
|
} |
|
713 |
#else |
#else |
714 |
warning("Not compiled with sound support\n"); |
warning("Not compiled with sound support\n"); |
715 |
#endif |
#endif |
757 |
else |
else |
758 |
g_rdpclip = True; |
g_rdpclip = True; |
759 |
} |
} |
760 |
|
else if (strncmp("scard", optarg, 5) == 0) |
761 |
|
{ |
762 |
|
#ifdef WITH_SCARD |
763 |
|
scard_enum_devices(&g_num_devices, optarg + 5); |
764 |
|
#else |
765 |
|
warning("Not compiled with smartcard support\n"); |
766 |
|
#endif |
767 |
|
} |
768 |
else |
else |
769 |
{ |
{ |
770 |
warning("Unknown -r argument\n\n\tPossible arguments are: comport, disk, lptport, printer, sound, clipboard\n"); |
warning("Unknown -r argument\n\n\tPossible arguments are: comport, disk, lptport, printer, sound, clipboard, scard\n"); |
771 |
} |
} |
772 |
break; |
break; |
773 |
|
|
912 |
|
|
913 |
#ifdef WITH_RDPSND |
#ifdef WITH_RDPSND |
914 |
if (g_rdpsnd) |
if (g_rdpsnd) |
915 |
rdpsnd_init(); |
{ |
916 |
|
if (!rdpsnd_init(rdpsnd_optarg)) |
917 |
|
{ |
918 |
|
warning("Initializing sound-support failed!\n"); |
919 |
|
} |
920 |
|
} |
921 |
#endif |
#endif |
922 |
|
|
923 |
if (lspci_enabled) |
if (lspci_enabled) |
1010 |
|
|
1011 |
#ifdef EGD_SOCKET |
#ifdef EGD_SOCKET |
1012 |
/* 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) */ |
1013 |
static BOOL |
static RD_BOOL |
1014 |
generate_random_egd(uint8 * buf) |
generate_random_egd(uint8 * buf) |
1015 |
{ |
{ |
1016 |
struct sockaddr_un addr; |
struct sockaddr_un addr; |
1017 |
BOOL ret = False; |
RD_BOOL ret = False; |
1018 |
int fd; |
int fd; |
1019 |
|
|
1020 |
fd = socket(AF_UNIX, SOCK_STREAM, 0); |
fd = socket(AF_UNIX, SOCK_STREAM, 0); |
1104 |
return mem; |
return mem; |
1105 |
} |
} |
1106 |
|
|
1107 |
|
/* Exit on NULL pointer. Use to verify result from XGetImage etc */ |
1108 |
|
void |
1109 |
|
exit_if_null(void *ptr) |
1110 |
|
{ |
1111 |
|
if (ptr == NULL) |
1112 |
|
{ |
1113 |
|
error("unexpected null pointer. Out of memory?\n"); |
1114 |
|
exit(1); |
1115 |
|
} |
1116 |
|
} |
1117 |
|
|
1118 |
/* strdup */ |
/* strdup */ |
1119 |
char * |
char * |
1120 |
xstrdup(const char *s) |
xstrdup(const char *s) |
1301 |
} |
} |
1302 |
|
|
1303 |
|
|
1304 |
BOOL |
RD_BOOL |
1305 |
str_startswith(const char *s, const char *prefix) |
str_startswith(const char *s, const char *prefix) |
1306 |
{ |
{ |
1307 |
return (strncmp(s, prefix, strlen(prefix)) == 0); |
return (strncmp(s, prefix, strlen(prefix)) == 0); |
1312 |
line. Incomplete lines are saved in the rest variable, which should |
line. Incomplete lines are saved in the rest variable, which should |
1313 |
initially point to NULL. When linehandler returns False, stop and |
initially point to NULL. When linehandler returns False, stop and |
1314 |
return False. Otherwise, return True. */ |
return False. Otherwise, return True. */ |
1315 |
BOOL |
RD_BOOL |
1316 |
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) |
1317 |
{ |
{ |
1318 |
char *buf, *p; |
char *buf, *p; |
1320 |
size_t inputlen; |
size_t inputlen; |
1321 |
size_t buflen; |
size_t buflen; |
1322 |
size_t restlen = 0; |
size_t restlen = 0; |
1323 |
BOOL ret = True; |
RD_BOOL ret = True; |
1324 |
|
|
1325 |
/* Copy data to buffer */ |
/* Copy data to buffer */ |
1326 |
inputlen = strlen(input); |
inputlen = strlen(input); |
1368 |
|
|
1369 |
/* Execute the program specified by argv. For each line in |
/* Execute the program specified by argv. For each line in |
1370 |
stdout/stderr output, call linehandler. Returns false on failure. */ |
stdout/stderr output, call linehandler. Returns false on failure. */ |
1371 |
BOOL |
RD_BOOL |
1372 |
subprocess(char *const argv[], str_handle_lines_t linehandler, void *data) |
subprocess(char *const argv[], str_handle_lines_t linehandler, void *data) |
1373 |
{ |
{ |
1374 |
pid_t child; |
pid_t child; |
1534 |
} |
} |
1535 |
|
|
1536 |
/* Create the bitmap cache directory */ |
/* Create the bitmap cache directory */ |
1537 |
BOOL |
RD_BOOL |
1538 |
rd_pstcache_mkdir(void) |
rd_pstcache_mkdir(void) |
1539 |
{ |
{ |
1540 |
char *home; |
char *home; |
1611 |
} |
} |
1612 |
|
|
1613 |
/* do a write lock on a file */ |
/* do a write lock on a file */ |
1614 |
BOOL |
RD_BOOL |
1615 |
rd_lock_file(int fd, int start, int len) |
rd_lock_file(int fd, int start, int len) |
1616 |
{ |
{ |
1617 |
struct flock lock; |
struct flock lock; |