
ããã¯ãRDP ãããã³ã«ã§åäœãããªãŒãã³ ãœãŒã¹ ããã°ã©ã ã®ãã¹ãã«é¢ããäžé£ã®èšäºã® XNUMX çªç®ã®ã¬ãã¥ãŒã§ãã ãã®äžã§ãrdesktop ã¯ã©ã€ã¢ã³ããš xrdp ãµãŒããŒãèŠãŠãããŸãã
ãšã©ãŒãç¹å®ããããŒã«ãšããŠäœ¿çšããã ããã¯ãCãC++ãC#ãJava çšã®éçã³ãŒãã¢ãã©ã€ã¶ãŒã§ããã©ãããã©ãŒã ã§å©çšå¯èœã§ãã Windows, Linux О macOS.
ãã®èšäºã§ã¯ãç§ã«ãšã£ãŠè峿·±ããšæããããšã©ãŒã®ã¿ã玹ä»ããŸãã ãã ãããããžã§ã¯ãã¯å°ãããããééãã¯ã»ãšãã©ãããŸããã§ãã:)ã
泚æã FreeRDP ãããžã§ã¯ãã®æ€èšŒã«é¢ãã以åã®èšäºã¯ãã¡ããã芧ãã ããã .
rdesktop
â UNIXããŒã¹ã®ã·ã¹ãã çšã®RDPã¯ã©ã€ã¢ã³ãã®ç¡æå®è£ ã WindowsCygwinç°å¢ã§ãããžã§ã¯ãããã«ãããå ŽåãGPLv3ã©ã€ã»ã³ã¹ã
ãã®ã¯ã©ã€ã¢ã³ãã¯éåžžã«äººæ°ããããReactOS ã§ã¯ããã©ã«ãã§äœ¿çšãããŠããããµãŒãããŒãã£ã®ã°ã©ãã£ã«ã« ããã³ããšã³ããèŠã€ããããšãã§ããŸãã ãããã圌ã¯ããªãé«éœ¢ã§ããæåã®ãªãªãŒã¹ã¯ 4 幎 2001 æ 17 æ¥ã«è¡ããããã®èšäºã®å·çæç¹ã§åœŒã¯ XNUMX æ³ã§ãã
å ã»ã©ãè¿°ã¹ãããã«ããã®ãããžã§ã¯ãã¯éåžžã«å°èŠæš¡ã§ãã ããã«ã¯çŽ 30 è¡ã®ã³ãŒããå«ãŸããŠãããå€ããã®ãèãããšå°ãå¥åŠã§ãã æ¯èŒã®ããã«ãFreeRDP ã«ã¯ 320 äžè¡ãå«ãŸããŠããŸãã Cloc ããã°ã©ã ã®åºåã¯æ¬¡ã®ãšããã§ãã

å°éäžèœãªã³ãŒã
䜿çšã§ããªãã³ãŒããæ€åºãããŸããã ãšã©ãŒãååšããå¯èœæ§ããããŸãã rãã¹ã¯ããã.c 1502
int
main(int argc, char *argv[])
{
....
return handle_disconnect_reason(deactivated, ext_disc_reason);
if (g_redirect_username)
xfree(g_redirect_username);
xfree(g_username);
}ãšã©ãŒã¯é¢æ°å ã§ããã«çºçããŸã ã¡ã€ã³: æŒç®åã®åŸã«ã³ãŒããæ¥ãã®ãããããŸãã return â ãã®ãã©ã°ã¡ã³ãã¯ã¡ã¢ãª ã¯ãªãŒãã³ã°ãå®è¡ããŸãã ãã ãããã®ãšã©ãŒã¯è åšã§ã¯ãããŸãããå²ãåœãŠãããã¡ã¢ãªã¯ãã¹ãŠãããã°ã©ã ã®çµäºåŸã«ãªãã¬ãŒãã£ã³ã° ã·ã¹ãã ã«ãã£ãŠã¯ãªã¢ãããŸãã
ãšã©ãŒåŠçãªã
é åã¢ã³ããŒã©ã³ã®å¯èœæ§ããããŸãã ãnãã€ã³ããã¯ã¹ã®å€ã¯ -1 ã«éããå¯èœæ§ããããŸãã rãã¹ã¯ããã.c 1872
RD_BOOL
subprocess(char *const argv[], str_handle_lines_t linehandler, void *data)
{
int n = 1;
char output[256];
....
while (n > 0)
{
n = read(fd[0], output, 255);
output[n] = ' '; // <=
str_handle_lines(output, &rest, linehandler, data);
}
....
}ãã®å Žåã®ã³ãŒã ã¹ããããã¯ããã¡ã€ã«ãçµäºãããŸã§ãã¡ã€ã«ãããããã¡ãŒã«èªã¿åããŸãã ãã ããããã§ã¯ãšã©ãŒåŠçã¯è¡ãããŸãããäœãåé¡ãçºçããå Žåã¯ã read -1 ãè¿ãããé åã¯ãªãŒããŒã©ã³ããŸã åºå.
charåã§ã®EOFã®äœ¿çš
EOF ã¯ãcharãã¿ã€ãã®å€ãšæ¯èŒããªãã§ãã ããã '(c = fgetc(fp))' 㯠'int' åã§ããå¿ èŠããããŸãã ctrl.c 500
int
ctrl_send_command(const char *cmd, const char *arg)
{
char result[CTRL_RESULT_SIZE], c, *escaped;
....
while ((c = fgetc(fp)) != EOF && index < CTRL_RESULT_SIZE && c != 'n')
{
result[index] = c;
index++;
}
....
}ããã§ã¯ããã¡ã€ã«ã®æ«å°Ÿã«å°éãããšãã®åŠçãééã£ãŠããããšãããããŸãã fgetc ã³ãŒãã 0xFF ã®æåãè¿ããšããã¡ã€ã«ã®çµãããšããŠè§£éãããŸã (EOF).
EOF ããã¯å®æ°ã§ãããé垞㯠-1 ãšããŠå®çŸ©ãããŸãã ããšãã°ãCP1251 ãšã³ã³ãŒãã£ã³ã°ã§ã¯ããã·ã¢èªã®ã¢ã«ãã¡ãããã®æåŸã®æåã¯ã³ãŒã 0xFF ã§ãããæ¬¡ã®ãããªå€æ°ã«ã€ããŠè©±ããŠããå Žåãããã¯æ°å€ -1 ã«å¯Ÿå¿ããŸãã ãã£ãªãªããã ã·ã³ãã«0xFFã¯æ¬¡ã®ããã«ãªããŸãã EOF (-1) ã¯ãã¡ã€ã«ã®çµãããšããŠè§£éãããŸãã ãã®ãããªãšã©ãŒãé¿ããããã«ã颿°ã®çµæã¯æ¬¡ã®ããã«ãªããŸãã fgetc 次ã®ãããªå€æ°ã«æ ŒçŽããå¿ èŠããããŸã intå.
ã¿ã€ããã¹
ãã©ã°ã¡ã³ã 1
åŒãwrite_timeãã¯åžžã« false ã§ãã ãã£ã¹ã¯.c 805
RD_NTSTATUS
disk_set_information(....)
{
time_t write_time, change_time, access_time, mod_time;
....
if (write_time || change_time)
mod_time = MIN(write_time, change_time);
else
mod_time = write_time ? write_time : change_time; // <=
....
}ãããããã®ã³ãŒãã®äœæè ã¯ééããã®ã§ã¯ãªãã§ãããã || О && ç¶æ ã§ã å¯èœãªå€ã®ãªãã·ã§ã³ãæ€èšããŠã¿ãŸããã æžãèŸŒã¿æé О 倿޿é:
- äž¡æ¹ã®å€æ°ã 0 ã«çãã: ãã®å Žåãæçµçã«åå²ã«ãªããŸãã ã»ãã«ïŒ 倿° mod_time ãã®åŸã®æ¡ä»¶ã«é¢ä¿ãªããåžžã« 0 ã«ãªããŸãã
- 倿°ã® 0 ã€ã¯ XNUMX ã§ãã mod_time 㯠0 ã«ãªããŸã (ä»ã®å€æ°ã®å€ãè² ã§ãªãå Žå)ã MIN XNUMX ã€ã®ãªãã·ã§ã³ã®ãã¡å°ããæ¹ãéžæããŸãã
- äž¡æ¹ã®å€æ°ã 0 ã«çãããããŸãããæå°å€ãéžæããŠãã ããã
æ¡ä»¶ã次ã®ããã«çœ®ãæãããšã æžãèŸŒã¿æé && 倿޿é åäœã¯æ£ããèŠããã§ããã:
- 0 ã€ãŸãã¯äž¡æ¹ã®å€æ°ã XNUMX ã«çãããããŸããããŒã以å€ã®å€ãéžæããŠãã ããã
- äž¡æ¹ã®å€æ°ã 0 ã«çãããããŸãããæå°å€ãéžæããŠãã ããã
ãã©ã°ã¡ã³ã 2
åŒã¯åžžã« true ã§ãã ããããããã§ã¯ã&&ãæŒç®åã䜿çšããå¿ èŠããããŸãã ãã£ã¹ã¯.c 1419
static RD_NTSTATUS
disk_device_control(RD_NTHANDLE handle, uint32 request, STREAM in,
STREAM out)
{
....
if (((request >> 16) != 20) || ((request >> 16) != 9))
return RD_STATUS_INVALID_PARAMETER;
....
}ã©ãããããã§ããªãã¬ãŒã¿ãŒãæ··åãããŠããããã§ã || О &&ãŸã㯠== О !=: 倿°ã¯å€ 20 ãš 9 ãåæã«æã€ããšã¯ã§ããŸããã
ç¡å¶éã®è¡ã³ããŒ
ãsprintfã颿°ãåŒã³åºããšããããã¡ãfullpathãã®ãªãŒããŒãããŒãçºçããŸãã ãã£ã¹ã¯.c 1257
RD_NTSTATUS
disk_query_directory(....)
{
....
char *dirname, fullpath[PATH_MAX];
....
/* Get information for directory entry */
sprintf(fullpath, "%s/%s", dirname, pdirent->d_name);
....
}颿°å šäœãèŠããšããã®ã³ãŒããåé¡ãåŒãèµ·ãããªãããšãæããã«ãªããŸãã ãã ããå°æ¥çã«ã¯çºçããå¯èœæ§ããããŸããXNUMX ã€ã®äžæ³šæãªå€æŽã§ãããã¡ ãªãŒããŒãããŒãçºçããå¯èœæ§ããããŸãã ã¹ããªã³ã ã¯äœã«ãå¶éãããªãããããã¹ãé£çµãããšãã«é åã®å¢çãè¶ããããšãã§ããŸãã ãã®åŒã³åºãã«æ³šç®ããããšããå§ãããŸã snprintf(ãã«ãã¹, PATH_MAX, âŠ.).
åé·æ¡ä»¶
æ¡ä»¶åŒã®äžéšã¯åžžã« true ã§ã: add > 0ãshard.c 507
static void
inRepos(STREAM in, unsigned int read)
{
SERVER_DWORD add = 4 - read % 4;
if (add < 4 && add > 0)
{
....
}
}ÐÑПвеÑка > 0 ã远å ããã§ã¯ãã®å¿ èŠã¯ãããŸããã倿°ã¯åžžã«ãŒããã倧ãããªããŸãã %4 ãèªã¿åããŸã é€ç®ã®äœããè¿ããŸããã4 ã«çãããªãããšã¯ãããŸããã
xrdp
â ãªãŒãã³ãœãŒã¹ ã³ãŒãã䜿çšãã RDP ãµãŒããŒã®å®è£ ã ãããžã§ã¯ã㯠2 ã€ã®éšåã«åãããŠããŸãã
- xrdp - ãããã³ã«ã®å®è£ ã Apache 2.0 ã©ã€ã»ã³ã¹ã«åºã¥ããŠé åžãããŸãã
- xorgxrdp - xrdp ã§äœ¿çšãã Xorg ãã©ã€ããŒã®ã»ããã ã©ã€ã»ã³ã¹ - X11 (MIT ãšåæ§ã§ãããåºåã§ã®äœ¿çšãçŠæ¢ããŸã)
ãããžã§ã¯ãã®éçºã¯ãrdesktop ãš FreeRDP ã®çµæã«åºã¥ããŠããŸãã åœåãã°ã©ãã£ãã¯ã¹ãæäœããã«ã¯ãå¥ã® VNC ãµãŒããŒããŸã㯠RDP ãµããŒããåããç¹å¥ãª X11 ãµãŒã㌠(X11rdp) ã䜿çšããå¿ èŠããããŸããããxorgxrdp ã®ç»å Žã«ããããã®å¿ èŠã¯ãªããªããŸããã
ãã®èšäºã§ã¯ãxorgxrdp ã«ã€ããŠã¯æ±ããŸããã
xrdp ãããžã§ã¯ãã¯ãåã®ãããžã§ã¯ããšåæ§ã«éåžžã«å°ãããçŽ 80 è¡ãå«ãŸããŠããŸãã

ã¿ã€ããã¹ãå¢ãã
ã³ãŒãã«ã¯ãé¡äŒŒãããããã¯ã®ã³ã¬ã¯ã·ã§ã³ãå«ãŸããŠããŸãã 87ã88ã89 è¡ç®ã®é ç®ãrãããgãããrãã確èªããŠãã ããã rfxencode_rgb_to_yuv.c 87
static int
rfx_encode_format_rgb(const char *rgb_data, int width, int height,
int stride_bytes, int pixel_format,
uint8 *r_buf, uint8 *g_buf, uint8 *b_buf)
{
....
switch (pixel_format)
{
case RFX_FORMAT_BGRA:
....
while (x < 64)
{
*lr_buf++ = r;
*lg_buf++ = g;
*lb_buf++ = r; // <=
x++;
}
....
}
....
}ãã®ã³ãŒãã¯ãRemoteFX ã® jpeg2000 ã³ãŒããã¯ãå®è£ ãã librfxcodec ã©ã€ãã©ãªããååŸããããã®ã§ãã ããã§ã¯ãæããã«ã°ã©ãã£ã㯠ããŒã¿ ãã£ãã«ãæ··åãããŠããããéãè²ã®ä»£ããã«ãèµ€ããèšé²ãããŠããŸãã ãã®ãšã©ãŒã¯ãã³ããŒïŒããŒã¹ãã®çµæãšããŠçºçããå¯èœæ§ãé«ããªããŸãã
åæ§ã®æ©èœã§åãåé¡ãçºçããŸãã rfx_encode_format_argbãã¢ãã©ã€ã¶ãŒã¯æ¬¡ã®ããã«ãæããŠãããŸããã
ã³ãŒãã«ã¯ãé¡äŒŒãããããã¯ã®ã³ã¬ã¯ã·ã§ã³ãå«ãŸããŠããŸãã 260ã261ã262ã263 è¡ç®ã®é ç®ãaãããrãããgãããrãã確èªããŠãã ããã rfxencode_rgb_to_yuv.c 260
while (x < 64)
{
*la_buf++ = a;
*lr_buf++ = r;
*lg_buf++ = g;
*lb_buf++ = r;
x++;
}é å宣èš
é åãªãŒããŒã©ã³ã®å¯èœæ§ããããŸãã ãi â 8ãã€ã³ããã¯ã¹ã®å€ã¯ 129 ã«éããå¯èœæ§ããããŸãã genkeymap.c 142
// evdev-map.c
int xfree86_to_evdev[137-8+1] = {
....
};
// genkeymap.c
extern int xfree86_to_evdev[137-8];
int main(int argc, char **argv)
{
....
for (i = 8; i <= 137; i++) /* Keycodes */
{
if (is_evdev)
e.keycode = xfree86_to_evdev[i-8];
....
}
....
}ããã 1 ã€ã®ãã¡ã€ã«ã®é åã®å®£èšãšå®çŸ©ã«ã¯äºææ§ããããŸããããµã€ãºã XNUMX ç°ãªããŸãããã ãããšã©ãŒã¯çºçããŸãããevdev-map.c ãã¡ã€ã«ã«ã¯æ£ãããµã€ãºãæå®ãããŠãããããç¯å²å€ã¯çºçããŸããã ãããã£ãŠãããã¯ç°¡åã«ä¿®æ£ã§ããåãªããã°ã§ãã
誀ã£ãæ¯èŒ
æ¡ä»¶åŒã®äžéšã¯åžžã« false: (cap_len < 0)ã xrdp_caps.c 616
// common/parse.h
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
#define in_uint16_le(s, v) do
....
#else
#define in_uint16_le(s, v) do
{
(v) = *((unsigned short*)((s)->p));
(s)->p += 2;
} while (0)
#endif
int
xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
{
int cap_len;
....
in_uint16_le(s, cap_len);
....
if ((cap_len < 0) || (cap_len > 1024 * 1024))
{
....
}
....
}颿°ã¯å倿°ãèªã¿åããŸã æªçœ²åã®ã·ã§ãŒã ã®ãããªå€æ°ã« intåã 笊å·ãªã倿°ãèªã¿åãããã®çµæããã倧ããªå€æ°ã«ä»£å ¥ããŠããããã倿°ã¯è² ã®å€ãåãããšãã§ããªããããããã§ã¯ãã§ãã¯ã¯å¿ èŠãããŸããã
äžèŠãªãã§ãã¯
æ¡ä»¶åŒã®äžéšã¯åžžã« true ã«ãªããŸã: (bpp != 16)ã libxrdp.c 704
int EXPORT_CC
libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
char *data, char *mask, int x, int y, int bpp)
{
....
if ((bpp == 15) && (bpp != 16) && (bpp != 24) && (bpp != 32))
{
g_writeln("libxrdp_send_pointer: error");
return 1;
}
....
}æåã«æ¯èŒããã§ã«è¡ãããŠãããããããã§ã¯äžçåŒãã§ãã¯ã¯æå³ããããŸããã ããããããã¯ã¿ã€ããã¹ã§ãããéçºè ã¯æŒç®åã䜿çšãããã£ãã®ã§ãããã || ç¡å¹ãªåŒæ°ãé€å€ããŸãã
ãŸãšã
ç£æ»ã§ã¯é倧ãªãšã©ãŒã¯çºèŠãããŸããã§ããããå€ãã®æ¬ ç¹ãèŠã€ãããŸããã ãã ãããããã®èšèšã¯ãç¯å²ã¯çããšã¯ãããå€ãã®ã·ã¹ãã ã§äœ¿çšãããŠããŸãã å°èŠæš¡ãªãããžã§ã¯ãã«ã¯å¿ ãããå€ãã®ãšã©ãŒãå«ãŸããããã§ã¯ãªããããå°èŠæš¡ãªãããžã§ã¯ãã ãã§ã¢ãã©ã€ã¶ãŒã®ããã©ãŒãã³ã¹ã倿ãã¹ãã§ã¯ãããŸããã ããã«ã€ããŠã¯ãèšäºããã§è©³ããèªãããšãã§ããŸãã"
PVS-Studio ã®è©ŠçšçãåŒç€ŸããããŠã³ããŒãã§ããŸãã .
ãã®èšäºãè±èªåã®èªè
ãšå
±æãããå Žåã¯ã翻蚳ãªã³ã¯ã䜿çšããŠãã ãã: Sergey Larinã
åºæïŒ habr.com
