
Eyi ni atunyẹwo keji ni lẹsẹsẹ awọn nkan nipa idanwo awọn eto orisun ṣiṣi fun ṣiṣẹ pẹlu ilana RDP. Ninu rẹ a yoo wo onibara rdesktop ati olupin xrdp.
Ti a lo bi irinṣẹ lati ṣe idanimọ awọn aṣiṣe Ó jẹ́ olùṣàyẹ̀wò koodu àìdúró fún C, C++, C# àti Java, tí ó wà lórí àwọn ìkànnì ayélujára Windows, Linux и macOS.
Nkan naa ṣafihan awọn aṣiṣe yẹn nikan ti o dabi ẹni pe o nifẹ si mi. Sibẹsibẹ, awọn ise agbese jẹ kekere, nitorina awọn aṣiṣe diẹ wa :).
Daakọ. Nkan ti tẹlẹ nipa iṣeduro iṣẹ akanṣe FreeRDP ni a le rii .
rdesktop
— свободная реализация клиента RDP для UNIX-based систем. Его также можно использовать и под Windows, если собирать проект под Cygwin. Лицензирован под GPLv3.
Onibara yii jẹ olokiki pupọ - o jẹ lilo nipasẹ aiyipada ni ReactOS, ati pe o tun le rii awọn opin iwaju ayaworan ẹni-kẹta fun rẹ. Sibẹsibẹ, o jẹ arugbo: igbasilẹ akọkọ rẹ waye ni Oṣu Kẹrin Ọjọ 4, Ọdun 2001 - ni akoko kikọ, o jẹ ọmọ ọdun 17.
Gẹgẹbi mo ti ṣe akiyesi ni iṣaaju, iṣẹ naa kere pupọ. O ni isunmọ awọn laini koodu 30 ẹgbẹrun, eyiti o jẹ ajeji diẹ ni akiyesi ọjọ-ori rẹ. Fun lafiwe, FreeRDP ni awọn laini 320 ẹgbẹrun. Eyi ni abajade ti eto Cloc:

koodu ti ko le de ọdọ
koodu ti ko si ti ri. O ṣee ṣe pe aṣiṣe kan wa. rdesktop.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);
}Aṣiṣe naa pade wa lẹsẹkẹsẹ ninu iṣẹ naa akọkọ: a rii koodu ti nbọ lẹhin oniṣẹ pada - yi ajeku performs iranti ninu. Bibẹẹkọ, aṣiṣe naa ko ṣe eewu: gbogbo iranti ti a pin ni yoo parẹ nipasẹ ẹrọ iṣẹ lẹhin ti eto naa ba jade.
Ko si asise mimu
Iṣeduro orunkun ṣee ṣe. Iye 'n' atọka le de ọdọ -1. rdsktop.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);
}
....
}snippet koodu ninu ọran yii ka lati faili sinu ifipamọ kan titi faili yoo fi pari. Sibẹsibẹ, ko si aṣiṣe mimu nibi: ti nkan ba jẹ aṣiṣe, lẹhinna ka yoo pada -1, ati ki o si awọn orun yoo wa ni overrun o wu.
Lilo EOF ni iru char
EOF ko yẹ ki o ṣe afiwe pẹlu iye kan ti iru 'char'. Awọn '(c = fgetc(fp))' yẹ ki o jẹ ti iru '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++;
}
....
}Nibi a rii mimu ti ko tọ si ti de opin faili naa: ti fgetc da ohun kikọ pada ti koodu rẹ jẹ 0xFF, yoo tumọ si bi ipari faili (EOF).
EOF o jẹ kan ibakan, maa telẹ bi -1. Fun apẹẹrẹ, ninu koodu CP1251, lẹta ti o kẹhin ti alfabeti Russian ni koodu 0xFF, eyiti o baamu nọmba -1 ti a ba n sọrọ nipa oniyipada bii shaha. O wa ni jade wipe aami 0xFF, bi EOF (-1) ni itumọ bi opin faili naa. Lati yago fun iru awọn aṣiṣe, abajade iṣẹ naa jẹ fgetc yẹ ki o wa ni fipamọ ni a ayípadà bi int.
Awọn oriṣi
Abala 1
Ọrọ sisọ 'write_time' jẹ eke nigbagbogbo. disk.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; // <=
....
}Boya onkọwe koodu yii ni aṣiṣe || и && ni majemu. Jẹ ká ro ṣee ṣe iye kikọ_akoko и ayipada_akoko:
- Awọn oniyipada mejeeji jẹ dogba si 0: ninu ọran yii a yoo pari ni ẹka kan miran: oniyipada mod_akoko yoo ma jẹ 0 laiwo ti awọn tetele majemu.
- Ọkan ninu awọn oniyipada jẹ 0: mod_akoko yoo dogba si 0 (pese pe oniyipada miiran ni iye ti kii ṣe odi), nitori min yoo yan awọn kere ninu awọn meji awọn aṣayan.
- Awọn oniyipada mejeeji ko dọgba si 0: yan iye to kere julọ.
Nigbati o ba rọpo ipo pẹlu akoko_kikọ && akoko_ayipada iwa naa yoo dabi ti o tọ:
- Ọkan tabi awọn oniyipada mejeeji ko dọgba si 0: yan iye ti kii ṣe odo.
- Awọn oniyipada mejeeji ko dọgba si 0: yan iye to kere julọ.
Abala 2
Ọrọ sisọ jẹ otitọ nigbagbogbo. Boya oniṣẹ '&&' yẹ ki o lo nibi. disk.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;
....
}Nkqwe awọn oniṣẹ ti wa ni adalu soke nibi tun || и &&, tabi == и !=: Oniyipada ko le ni iye 20 ati 9 ni akoko kanna.
didaakọ laini ailopin
Ipe iṣẹ 'sprintf' yoo yorisi aponsedanu ti ifipamọ 'fullpath'. disk.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);
....
}Nigbati o ba wo iṣẹ naa ni kikun, yoo han gbangba pe koodu yii ko fa awọn iṣoro. Bibẹẹkọ, wọn le dide ni ọjọ iwaju: iyipada aibikita kan ati pe a yoo gba apọju ifipamọ kan - ṣẹṣẹ ko ni opin nipasẹ ohunkohun, nitorinaa nigbati o ba ṣajọpọ awọn ọna a le lọ kọja awọn aala ti orun. A ṣe iṣeduro lati ṣe akiyesi ipe yii lori snprintf (ona ni kikun, PATH_MAX, ….).
Apọju ipo
Apa kan ti ikosile majemu jẹ otitọ nigbagbogbo: fi> 0. scard.c 507
static void
inRepos(STREAM in, unsigned int read)
{
SERVER_DWORD add = 4 - read % 4;
if (add < 4 && add > 0)
{
....
}
}ayewo afikun > 0 ko si iwulo nibi: oniyipada yoo ma tobi ju odo lọ, nitori ka% 4 yoo da iyoku ipin pada, ṣugbọn kii yoo dogba si 4.
xrdp
- imuse ti olupin RDP pẹlu koodu orisun ṣiṣi. Ise agbese na ti pin si awọn ẹya meji:
- xrdp - imuse ilana. Pinpin labẹ iwe-aṣẹ Apache 2.0.
- xorgxrdp - Eto awọn awakọ Xorg fun lilo pẹlu xrdp. Iwe-aṣẹ - X11 (bii MIT, ṣugbọn ṣe idiwọ lilo ninu ipolowo)
Idagbasoke ti ise agbese na da lori awọn esi ti rdesktop ati FreeRDP. Ni ibẹrẹ, lati ṣiṣẹ pẹlu awọn eya aworan, o ni lati lo olupin VNC lọtọ, tabi olupin X11 pataki kan pẹlu atilẹyin RDP - X11rdp, ṣugbọn pẹlu dide ti xorgxrdp, iwulo fun wọn parẹ.
Ninu nkan yii a kii yoo bo xorgxrdp.
Ise agbese xrdp, bii ti iṣaaju, kere pupọ ati pe o ni awọn laini to 80 ẹgbẹrun.

Diẹ ẹ sii typos
Awọn koodu ni awọn gbigba ti awọn iru awọn bulọọki. Ṣayẹwo awọn nkan 'r', 'g', 'r' ni awọn ila 87, 88, 89. 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++;
}
....
}
....
}A gba koodu yii lati ile-ikawe librfxcodec, eyiti o ṣe imuse kodẹki jpeg2000 fun RemoteFX. Nibi, nkqwe, awọn ikanni data ayaworan ti dapọ - dipo awọ “bulu”, “pupa” ti gbasilẹ. O ṣeese julọ aṣiṣe yii han bi abajade ti daakọ-lẹẹmọ.
Iṣoro kanna waye ni iru iṣẹ kan rfx_encode_format_argb, eyiti oluyẹwo tun sọ fun wa:
Awọn koodu ni awọn gbigba ti awọn iru awọn bulọọki. Ṣayẹwo awọn ohun kan 'a', 'r', 'g', 'r' ni awọn ila 260, 261, 262, 263. rfxencode_rgb_to_yuv.c 260
while (x < 64)
{
*la_buf++ = a;
*lr_buf++ = r;
*lg_buf++ = g;
*lb_buf++ = r;
x++;
}Ìkéde orun
Ibanujẹ titobi le ṣee ṣe. Iye 'i — 8' atọka le de ọdọ 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];
....
}
....
}Ikede ati asọye ti orun ni awọn faili meji wọnyi ko ni ibamu - iwọn naa yatọ nipasẹ 1. Sibẹsibẹ, ko si awọn aṣiṣe ti o waye - iwọn to pe ni pato ninu faili evdev-map.c, nitorinaa ko si awọn opin. Nitorinaa eyi jẹ kokoro kan ti o le ṣe atunṣe ni irọrun.
Ifiwera ti ko tọ
Apa kan ti ikosile majemu jẹ eke nigbagbogbo: (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))
{
....
}
....
}Iṣẹ naa ka iru oniyipada kan kukuru ti a ko wole sinu oniyipada bi int. Ṣiṣayẹwo ko nilo nibi nitori pe a n ka oniyipada ti a ko fowo si ati fifun abajade si oniyipada nla, nitorinaa oniyipada ko le gba iye odi.
Awọn sọwedowo ti ko wulo
Apa kan ti ikosile ipo jẹ otitọ nigbagbogbo: (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;
}
....
}Awọn sọwedowo aidogba ko ni oye nibi nitori a ti ni afiwe tẹlẹ ni ibẹrẹ. O ṣee ṣe pe eyi jẹ typo ati olupilẹṣẹ fẹ lati lo oniṣẹ ẹrọ || lati ṣe àlẹmọ awọn ariyanjiyan ti ko tọ.
ipari
Lakoko iṣayẹwo, ko si awọn aṣiṣe to ṣe pataki ti a damọ, ṣugbọn ọpọlọpọ awọn aito ni a rii. Sibẹsibẹ, awọn aṣa wọnyi ni a lo ni ọpọlọpọ awọn ọna ṣiṣe, botilẹjẹpe kekere ni iwọn. Ise agbese kekere ko ni dandan ni ọpọlọpọ awọn aṣiṣe, nitorina o ko yẹ ki o ṣe idajọ iṣẹ olutupalẹ nikan lori awọn iṣẹ kekere. O le ka diẹ sii nipa eyi ninu nkan naa "".
O le ṣe igbasilẹ ẹya idanwo ti PVS-Studio lati ọdọ wa .
Ti o ba fẹ pin nkan yii pẹlu awọn olugbo ti o sọ Gẹẹsi, jọwọ lo ọna asopọ itumọ: Sergey Larin.
orisun: www.habr.com
