📄 rdesktop.c
字号:
if (*p == '+' || *p == '-')
{
This->pos |= (*p == '-') ? 4 : 1;
This->ypos = strtol(p, NULL, 10);
}
break;
case 'f':
This->fullscreen = True;
break;
case 'b':
This->bitmap_cache = False;
break;
case 'B':
This->ownbackstore = False;
break;
case 'e':
This->encryption = False;
break;
case 'E':
This->packet_encryption = False;
break;
case 'm':
This->sendmotion = False;
break;
case 'C':
This->owncolmap = True;
break;
case 'D':
This->hide_decorations = True;
break;
case 'K':
This->grab_keyboard = False;
break;
case 'S':
if (!strcmp(optarg, "standard"))
{
This->win_button_size = 18;
break;
}
This->win_button_size = strtol(optarg, &p, 10);
if (*p)
{
error("invalid button size\n");
return 1;
}
break;
case 'T':
STRNCPY(This->title, optarg, sizeof(This->title));
break;
case 'N':
This->numlock_sync = True;
break;
case 'X':
This->embed_wnd = strtol(optarg, NULL, 0);
break;
case 'a':
This->server_depth = strtol(optarg, NULL, 10);
if (This->server_depth != 8 &&
This->server_depth != 16 &&
This->server_depth != 15 && This->server_depth != 24)
{
error("Invalid server colour depth.\n");
return 1;
}
break;
case 'z':
DEBUG(("rdp compression enabled\n"));
flags |= (RDP_LOGON_COMPRESSION | RDP_LOGON_COMPRESSION2);
break;
case 'x':
if (str_startswith(optarg, "m")) /* modem */
{
This->rdp5_performanceflags =
RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG |
RDP5_NO_MENUANIMATIONS | RDP5_NO_THEMING;
}
else if (str_startswith(optarg, "b")) /* broadband */
{
This->rdp5_performanceflags = RDP5_NO_WALLPAPER;
}
else if (str_startswith(optarg, "l")) /* lan */
{
This->rdp5_performanceflags = RDP5_DISABLE_NOTHING;
}
else
{
This->rdp5_performanceflags = strtol(optarg, NULL, 16);
}
break;
case 'P':
This->bitmap_cache_persist_enable = True;
break;
case 'r':
if (str_startswith(optarg, "sound"))
{
optarg += 5;
if (*optarg == ':')
{
optarg++;
while ((p = next_arg(optarg, ',')))
{
if (str_startswith(optarg, "remote"))
flags |= RDP_LOGON_LEAVE_AUDIO;
if (str_startswith(optarg, "local"))
#ifdef WITH_RDPSND
This->rdpsnd_enabled = True;
#else
warning("Not compiled with sound support\n");
#endif
if (str_startswith(optarg, "off"))
#ifdef WITH_RDPSND
This->rdpsnd_enabled = False;
#else
warning("Not compiled with sound support\n");
#endif
optarg = p;
}
}
else
{
#ifdef WITH_RDPSND
This->rdpsnd_enabled = True;
#else
warning("Not compiled with sound support\n");
#endif
}
}
else if (str_startswith(optarg, "disk"))
{
/* -r disk:h:=/mnt/floppy */
disk_enum_devices(This, &This->num_devices, optarg + 4);
}
else if (str_startswith(optarg, "comport"))
{
serial_enum_devices(This, &This->num_devices, optarg + 7);
}
else if (str_startswith(optarg, "lspci"))
{
This->lspci_enabled = True;
}
else if (str_startswith(optarg, "lptport"))
{
parallel_enum_devices(This, &This->num_devices, optarg + 7);
}
else if (str_startswith(optarg, "printer"))
{
printer_enum_devices(This, &This->num_devices, optarg + 7);
}
else if (str_startswith(optarg, "clientname"))
{
This->rdpdr_clientname = xmalloc(strlen(optarg + 11) + 1);
strcpy(This->rdpdr_clientname, optarg + 11);
}
else if (str_startswith(optarg, "clipboard"))
{
optarg += 9;
if (*optarg == ':')
{
optarg++;
if (str_startswith(optarg, "off"))
This->rdpclip = False;
else
cliprdr_set_mode(This, optarg);
}
else
This->rdpclip = True;
}
else
{
warning("Unknown -r argument\n\n\tPossible arguments are: comport, disk, lptport, printer, sound, clipboard\n");
}
break;
case '0':
This->console_session = True;
break;
case '4':
This->use_rdp5 = False;
break;
case '5':
This->use_rdp5 = True;
break;
case 'h':
case '?':
default:
usage(argv[0]);
return 1;
}
}
if (argc - optind != 1)
{
usage(argv[0]);
return 1;
}
STRNCPY(server, argv[optind], sizeof(server));
parse_server_and_port(This, server);
if (This->seamless_rdp)
{
if (This->win_button_size)
{
error("You cannot use -S and -A at the same time\n");
return 1;
}
This->rdp5_performanceflags &= ~RDP5_NO_FULLWINDOWDRAG;
if (geometry_option)
{
error("You cannot use -g and -A at the same time\n");
return 1;
}
if (This->fullscreen)
{
error("You cannot use -f and -A at the same time\n");
return 1;
}
if (This->hide_decorations)
{
error("You cannot use -D and -A at the same time\n");
return 1;
}
if (This->embed_wnd)
{
error("You cannot use -X and -A at the same time\n");
return 1;
}
if (!This->use_rdp5)
{
error("You cannot use -4 and -A at the same time\n");
return 1;
}
This->width = -100;
This->grab_keyboard = False;
}
if (!username_option)
{
pw = getpwuid(getuid());
if ((pw == NULL) || (pw->pw_name == NULL))
{
error("could not determine username, use -u\n");
return 1;
}
STRNCPY(This->username, pw->pw_name, sizeof(This->username));
}
#ifdef HAVE_ICONV
if (This->codepage[0] == 0)
{
if (setlocale(LC_CTYPE, ""))
{
STRNCPY(This->codepage, nl_langinfo(CODESET), sizeof(This->codepage));
}
else
{
STRNCPY(This->codepage, DEFAULT_CODEPAGE, sizeof(This->codepage));
}
}
#endif
if (This->hostname[0] == 0)
{
if (gethostname(fullhostname, sizeof(fullhostname)) == -1)
{
error("could not determine local hostname, use -n\n");
return 1;
}
p = strchr(fullhostname, '.');
if (p != NULL)
*p = 0;
STRNCPY(This->hostname, fullhostname, sizeof(This->hostname));
}
if (This->keymapname[0] == 0)
{
if (locale && xkeymap_from_locale(This, locale))
{
fprintf(stderr, "Autoselected keyboard map %s\n", This->keymapname);
}
else
{
STRNCPY(This->keymapname, "en-us", sizeof(This->keymapname));
}
}
if (locale)
xfree(locale);
if (prompt_password && read_password(password, sizeof(password)))
flags |= RDP_LOGON_AUTO;
if (This->title[0] == 0)
{
strcpy(This->title, "rdesktop - ");
strncat(This->title, server, sizeof(This->title) - sizeof("rdesktop - "));
}
#ifdef RDP2VNC
rdp2vnc_connect(server, flags, domain, password, shell, directory);
return 0;
#else
if (!ui_init(This))
return 1;
#ifdef WITH_RDPSND
if (This->rdpsnd_enabled)
rdpsnd_init(This);
#endif
if (This->lspci_enabled)
lspci_init(This);
rdpdr_init(This);
while (run_count < 2 && continue_connect) /* add support for Session Directory; only reconnect once */
{
if (run_count == 0)
{
if (!rdp_connect(This, server, flags, domain, password, shell, directory))
return 1;
}
else if (!rdp_reconnect
(This, server, flags, domain, password, shell, directory, This->redirect_cookie))
return 1;
/* By setting encryption to False here, we have an encrypted login
packet but unencrypted transfer of other packets */
if (!This->packet_encryption)
This->encryption = False;
DEBUG(("Connection successful.\n"));
memset(password, 0, sizeof(password));
if (run_count == 0)
if (!ui_create_window(This))
continue_connect = False;
if (continue_connect)
rdp_main_loop(This, &deactivated, &ext_disc_reason);
DEBUG(("Disconnecting...\n"));
rdp_disconnect(This);
if ((This->redirect == True) && (run_count == 0)) /* Support for Session Directory */
{
/* reset state of major globals */
rdesktop_reset_state(This);
STRNCPY(domain, This->redirect_domain, sizeof(domain));
STRNCPY(This->username, This->redirect_username, sizeof(This->username));
STRNCPY(password, This->redirect_password, sizeof(password));
STRNCPY(server, This->redirect_server, sizeof(server));
flags |= RDP_LOGON_AUTO;
This->redirect = False;
}
else
{
continue_connect = False;
ui_destroy_window(This);
break;
}
run_count++;
}
cache_save_state(This);
ui_deinit(This);
if (ext_disc_reason >= 2)
print_disconnect_reason(ext_disc_reason);
if (deactivated)
{
/* clean disconnect */
return 0;
}
else
{
if (ext_disc_reason == exDiscReasonAPIInitiatedDisconnect
|| ext_disc_reason == exDiscReasonAPIInitiatedLogoff)
{
/* not so clean disconnect, but nothing to worry about */
return 0;
}
else
{
/* return error */
return 2;
}
}
#endif
}
#ifdef EGD_SOCKET
/* Read 32 random bytes from PRNGD or EGD socket (based on OpenSSL RAND_egd) */
static BOOL
generate_random_egd(uint8 * buf)
{
struct sockaddr_un addr;
BOOL ret = False;
int fd;
fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd == -1)
return False;
addr.sun_family = AF_UNIX;
memcpy(addr.sun_path, EGD_SOCKET, sizeof(EGD_SOCKET));
if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
goto err;
/* PRNGD and EGD use a simple communications protocol */
buf[0] = 1; /* Non-blocking (similar to /dev/urandom) */
buf[1] = 32; /* Number of requested random bytes */
if (write(fd, buf, 2) != 2)
goto err;
if ((read(fd, buf, 1) != 1) || (buf[0] == 0)) /* Available? */
goto err;
if (read(fd, buf, 32) != 32)
goto err;
ret = True;
err:
close(fd);
return ret;
}
#endif
/* Generate a 32-byte random for the secure transport code. */
void
generate_random(uint8 * random)
{
struct stat st;
struct tms tmsbuf;
MD5_CTX md5;
uint32 *r;
int fd, n;
/* If we have a kernel random device, try that first */
if (((fd = open("/dev/urandom", O_RDONLY)) != -1)
|| ((fd = open("/dev/random", O_RDONLY)) != -1))
{
n = read(fd, random, 32);
close(fd);
if (n == 32)
return;
}
#ifdef EGD_SOCKET
/* As a second preference use an EGD */
if (generate_random_egd(random))
return;
#endif
/* Otherwise use whatever entropy we can gather - ideas welcome. */
r = (uint32 *) random;
r[0] = (getpid()) | (getppid() << 16);
r[1] = (getuid()) | (getgid() << 16);
r[2] = times(&tmsbuf); /* system uptime (clocks) */
gettimeofday((struct timeval *) &r[3], NULL); /* sec and usec */
stat("/tmp", &st);
r[5] = st.st_atime;
r[6] = st.st_mtime;
r[7] = st.st_ctime;
/* Hash both halves with MD5 to obscure possible patterns */
MD5_Init(&md5);
MD5_Update(&md5, random, 16);
MD5_Final(random, &md5);
MD5_Update(&md5, random + 16, 16);
MD5_Final(random + 16, &md5);
}
/* malloc; exit if out of memory */
void *
xmalloc(int size)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -